From 684e1c184af6d04980d90f6be06355036a26e89b Mon Sep 17 00:00:00 2001 From: Kay Date: Wed, 16 Sep 2026 20:06:45 +0200 Subject: [PATCH] Bug 39: "Weitere Parameter"-Liste im Experte-Sheet zweispaltig + lesbarer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../Expert/ExpertMenuDetailView.swift | 76 ++++++++++++++++--- found.md | 12 ++- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/RouterOSAssistant/Features/Expert/ExpertMenuDetailView.swift b/RouterOSAssistant/Features/Expert/ExpertMenuDetailView.swift index 017d9ae..50e8734 100644 --- a/RouterOSAssistant/Features/Expert/ExpertMenuDetailView.swift +++ b/RouterOSAssistant/Features/Expert/ExpertMenuDetailView.swift @@ -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( diff --git a/found.md b/found.md index bb27132..41be606 100644 --- a/found.md +++ b/found.md @@ -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).