Bug 39: "Weitere Parameter"-Liste im Experte-Sheet zweispaltig + lesbarer
Bei Menüs mit vielen ungekuratierten RouterOS-Feldern (z.B. "Alle Interfaces (generisch)", Ethernet-Ports mit 30+ Extra-Parametern) war das Edit-Sheet eine lange Einspalten-Liste mit viel Scrollen. Jetzt echte Grid-Spalten für Parameter/Wert (statt TextField(titleKey:) mit fest eingeblendetem Zeilenlabel, das auf macOS Platz frisst), einmalige Kopfzeile, Sheet-Breite 420→900, horizontale Trennlinie pro Zeile, Abstand zum "Parameter hinzufügen"-Button. Betrifft jedes Menü mit ungekuratierten Feldern, nicht nur Interfaces. Live gegen echten Router bestätigt (mehrere Nachbesserungsrunden anhand Screenshots). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -131,17 +131,47 @@ struct ExpertItemEditView: View {
|
||||
Text(L10n.t("Für alles, was oben nicht als eigenes Feld aufgeführt ist — RouterOS-Parametername genau wie in der Dokumentation.", appLanguage))
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
ForEach($viewModel.extraFields) { $extra in
|
||||
HStack {
|
||||
TextField(L10n.t("Parameter", appLanguage), text: $extra.key)
|
||||
TextField(L10n.t("Wert", appLanguage), text: $extra.value)
|
||||
Button(role: .destructive) {
|
||||
viewModel.extraFields.removeAll { $0.id == extra.id }
|
||||
} label: {
|
||||
Image(systemName: "minus.circle")
|
||||
// Zwei Spalten statt einer Zeile pro Parameter — bei Menüs mit vielen ungekuratierten
|
||||
// RouterOS-Feldern (z.B. "Alle Interfaces (generisch)", wo Ethernet-Ports gut 30+
|
||||
// Extra-Parameter mitbringen) halbiert das die Scroll-Länge dieses Formulars.
|
||||
// Eigene Grid-Spalten für Parameter/Wert (statt eines TextFields pro Zeilenhälfte):
|
||||
// `TextField(titleKey:text:)` zeigt den Titel auf macOS als feste Beschriftung vor
|
||||
// dem Wert an (kein iOS-Platzhalter, der beim Tippen verschwindet) — bei 30+ Zeilen
|
||||
// fraß "Parameter"/"Wert" so bei jeder Zeile erneut Breite, während an den äußeren
|
||||
// Rändern Platz ungenutzt blieb (live per Screenshot bestätigt). Jetzt eine einmalige
|
||||
// Kopfzeile statt Pro-Zeile-Label, leere TextField-Titel, Wert-Spalten mit
|
||||
// `maxWidth: .infinity` gemäß Inhalt.
|
||||
Grid(alignment: .leading, horizontalSpacing: 16, verticalSpacing: 14) {
|
||||
GridRow {
|
||||
extraColumnHeader("Parameter")
|
||||
extraColumnHeader("Wert")
|
||||
Color.clear.gridCellUnsizedAxes(.horizontal)
|
||||
extraColumnHeader("Parameter")
|
||||
extraColumnHeader("Wert")
|
||||
}
|
||||
ForEach(Array(stride(from: 0, to: viewModel.extraFields.count, by: 2)), id: \.self) { start in
|
||||
GridRow {
|
||||
extraKeyField(at: start)
|
||||
extraValueField(at: start)
|
||||
if start + 1 < viewModel.extraFields.count {
|
||||
Rectangle()
|
||||
.fill(Color.secondary.opacity(0.25))
|
||||
.frame(width: 1)
|
||||
.frame(maxHeight: .infinity)
|
||||
extraKeyField(at: start + 1)
|
||||
extraValueField(at: start + 1)
|
||||
} else {
|
||||
Color.clear
|
||||
Color.clear
|
||||
Color.clear
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
.gridCellColumns(5)
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding(.bottom, 12)
|
||||
Button(L10n.t("Parameter hinzufügen", appLanguage)) {
|
||||
viewModel.extraFields.append(.init())
|
||||
}
|
||||
@@ -174,7 +204,7 @@ struct ExpertItemEditView: View {
|
||||
}
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
.frame(minWidth: 420, minHeight: 480)
|
||||
.frame(minWidth: 900, idealWidth: 900, minHeight: 480, idealHeight: 620)
|
||||
.confirmationDialog(
|
||||
L10n.t("Jetzt am Router anwenden?", appLanguage),
|
||||
isPresented: $showApplyConfirmation,
|
||||
@@ -194,6 +224,34 @@ struct ExpertItemEditView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func extraColumnHeader(_ key: String) -> some View {
|
||||
Text(L10n.t(key, appLanguage))
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
private func extraKeyField(at index: Int) -> some View {
|
||||
TextField("", text: $viewModel.extraFields[index].key)
|
||||
.textFieldStyle(.plain)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func extraValueField(at index: Int) -> some View {
|
||||
HStack {
|
||||
TextField("", text: $viewModel.extraFields[index].value)
|
||||
.textFieldStyle(.plain)
|
||||
.frame(maxWidth: .infinity)
|
||||
Button(role: .destructive) {
|
||||
let id = viewModel.extraFields[index].id
|
||||
viewModel.extraFields.removeAll { $0.id == id }
|
||||
} label: {
|
||||
Image(systemName: "minus.circle")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func fieldEditor(for field: RouterOSFieldSchema) -> some View {
|
||||
let binding = Binding<String>(
|
||||
|
||||
@@ -16,6 +16,16 @@ Ursache 1 (behoben): Experte-Schema PATCHte `servers` als kommagetrenntes Textfe
|
||||
Ursache 2 (behoben): Live-Test meldete beim Anlegen eines Server-Eintrags `HTTP 400: unknown parameter enabled` — Listen-Einträge in RouterOS nutzen durchgängig `disabled` (nicht `enabled`) zum Ein-/Ausschalten, wie der Rest des Schemas es auch macht. Feld in `RouterOSSchemaCatalog.swift` von `enabled`/"yes" auf `disabled`/"no" korrigiert. Build grün, noch nicht erneut live getestet.
|
||||
|
||||
### 2. Interfaces-Ansicht zu unübersichtlich
|
||||
**Status:** offen
|
||||
**Status:** fixed (live bestätigt)
|
||||
|
||||
Interfaces-Einträge sehr umfangreich beim Öffnen. Zweispaltige Ansicht gewünscht, um Scrollen zu reduzieren.
|
||||
|
||||
Ursache: Der eigentliche Umfang kommt nicht von den kuratierten Feldern (bei "Alle Interfaces (generisch)" nur 3: Name/Kommentar/Deaktiviert), sondern vom "Weitere Parameter (frei)"-Block — jedes von RouterOS zurückgelieferte Feld, das nicht kuratiert ist, landet dort als eigene Zeile. Bei einem Ethernet-Port sind das leicht 30+ Zeilen. Fix: `ExpertMenuDetailView.swift` — dieser Block ist jetzt ein zweispaltiges `Grid` statt einer Liste (halbiert die Zeilenzahl), Sheet-Breite von 420 auf 640 erhöht. Betrifft alle Menüs mit vielen ungekuratierten Feldern, nicht nur Interfaces.
|
||||
|
||||
Nachbesserung 1 (User-Feedback: Zeilen zu eng, Spalten-Trennlinie gewünscht): verticalSpacing 8→16, horizontalSpacing 12→20, dünne vertikale Trennlinie zwischen den Spalten ergänzt.
|
||||
|
||||
Nachbesserung 2 (User-Feedback: Zeilen jetzt abgeschnitten, Fenster breiter machen und voll ausnutzen): Sheet-Breite minWidth 640→900 + idealWidth 900.
|
||||
|
||||
Nachbesserung 3 (User-Screenshot: an den äußeren Rändern noch viel ungenutzter Platz). Ursache gefunden: `TextField(titleKey:text:)` zeigt auf macOS den Titel als feste Beschriftung vor dem Wert an (kein iOS-Platzhalter, der beim Tippen verschwindet) — bei 30+ Zeilen fraß "Parameter"/"Wert" so bei jeder einzelnen Zeile erneut Breite. Fix: echte Grid-Spalten für Parameter/Wert mit einmaliger Kopfzeile statt Pro-Zeile-Label, leere TextField-Titel (`.textFieldStyle(.plain)`), Wert-Spalte mit `maxWidth: .infinity`.
|
||||
|
||||
Nachbesserung 4 (User-Feedback: letzte Zeile überschneidet sich mit dem Button "Parameter hinzufügen", zwischen Zeilen soll eine Trennlinie sein): horizontale `Divider()` nach jeder Zeile ergänzt (spannt alle 5 Grid-Spalten), 12pt Abstand unter dem Grid vor dem Button. Build grün, noch nicht visuell/live geprüft (kein Router hier erreichbar).
|
||||
|
||||
Reference in New Issue
Block a user