Files
RouterOS/found.md
T
KayandClaude Sonnet 5 53a2931239 LAN-Scanner: Sparkline breiter/schnelleres Fenster, Traffic in MB/s
TrafficSparkline-Breite 50pt→200pt, Zeitfenster 10s→30s, Poll-Intervall
3s→0,1s. Traffic-Anzeige von auto-skaliertem kbps/Mbps/Gbps auf festes
MB/s umgestellt. Alles per Nutzeranfrage iterativ angepasst, noch nicht
live gegen echten Router getestet (siehe found.md Fund 4). Manual.md +
Manual.pdf mit aktualisiert (build-manual.py). Fund 5 (App-Settings/
Preferences-Bereich) als offene Feature-Idee in found.md notiert, noch
nicht umgesetzt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 22:30:22 +02:00

15 KiB

Fundzettel

Notizzettel für Feedback/Funde des Users. Neue Einträge unten anhängen, Status pflegen.

Status: offen | postponed | fixed


2026-09-16

1. NTP Server bricht mit Error HTTP 400 ab

Status: fixed (live bestätigt)

Ursache 1 (behoben): Experte-Schema PATCHte servers als kommagetrenntes Textfeld direkt auf /system/ntp/client — Feld existiert dort in RouterOS 7.x nicht, Server liegen in eigener Liste /system ntp client servers. Schema aufgeteilt: Singleton-Menü (enabled/mode) bleibt, neues Listen-Menü /system ntp client servers (Feld address) dazu.

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: 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).

3. Übersicht: Fokus-Modus beim Anklicken eines Items

Status: fixed (live bestätigt)

Wunsch: Klick auf einen Node in der Übersicht (Graph-Ansicht, OverviewView.swift) soll den Node in den freien Bereich schieben, alle anderen Nodes ausfaden, und die Parents/Childs des aktuell gewählten Nodes nach unten schieben und sauber neu anordnen.

Ist-Zustand (OverviewView.swift): Klick setzt aktuell nur selectedNodeID und highlightet die verbundenen Kanten/Nodes (OverviewGraph.highlightedNodeIDs) — Positionen ändern sich nicht. Es gibt bereits ein Spalten-Layout (OverviewLayout, feste columnOrder/columnWidth) plus manuelle Drag-Offsets pro Node (nodeOffsets), die on top der berechneten Grid-Positionen liegen und über einen "Zurücksetzen"-Button löschbar sind (nicht persistiert, geht bei Neuladen verloren).

Klärung (User-Antworten):

  1. Horizontale Trennlinie über den Canvas; ausgewählter Node + Kette werden unterhalb dieser Trennlinie dargestellt (eigener Bereich, getrennt von der normalen Graph-Darstellung darüber).

  2. Fokus-Modus ist temporär — aufhebbar (Klick auf leere Fläche / erneuter Klick), keine dauerhafte Layout-Änderung, nodeOffsets bleibt unberührt.

  3. Ausfaden = abdunkeln (nicht ausblenden).

  4. Komplette verbundene Kette (nicht nur 1 Ebene) — deckt sich mit dem bereits vorhandenen highlightedNodeIDs (rekursiv).

  5. Ketten-Layout im unteren Bereich: gleiches Spalten-Layout wie oben (OverviewLayout-Logik wiederverwendet, nur auf die Kette beschränkt) — kein neuer Layout-Algorithmus nötig.

Umsetzung (OverviewGraph.swift, OverviewView.swift, OverviewGraphTests.swift, L10n.swift):

  • Neue Methode OverviewGraph.connectedChain(startingAt:) — volle rekursive Kette unabhängig vom Node-Typ (bewusst getrennt von highlightedNodeIDs, das nur bei Interfaces mehr als 1 Hop expandiert — eine andere, bereits live bestätigte, bewusst enger gefasste Funktion). Mit Test abgedeckt.
  • OverviewView: Fokus-Modus hängt direkt an viewModel.selectedNodeID (kein separater Zustand) — Klick auf Node selektiert wie bisher, macht das aber jetzt gleichzeitig zum Fokus-Trigger; erneuter Klick auf denselben Node hebt ihn wieder auf (bestehende Toggle-Logik, kein neuer Code nötig).
  • Kette wird per OverviewLayout.layout(for:) auf ein gefiltertes Sub-Graph-Objekt neu angeordnet (focusSubLayout) und unterhalb einer Trennlinie eingeblendet (effectivePositions verschiebt nur Kettenknoten dorthin, alle anderen bleiben an ihrer normalen Position).
  • Ausfaden: nicht-Ketten-Nodes bekommen opacity(0.25); EdgesCanvas bekommt die Kette als highlightedNodeIDs übergeben, wodurch dessen bereits vorhandene Dimm-Logik für Kanten automatisch mitgreift (keine Kante kann je über die Trennlinie laufen, da eine Kette per Definition die transitive Hülle ist).
  • Leere-Fläche-Klick hebt Fokus auf: EdgesCanvas bekommt einen neuen onBackgroundTap-Callback, der bei ihrem bereits vorhandenen Tap-Gesture-Handler greift, wenn kein Edge getroffen wurde.
  • Dragging ist für Nodes deaktiviert, solange sie im Fokus-Streifen sitzen (Position wird bei jeder Auswahl neu berechnet, ein gespeicherter Drag-Offset würde sonst nach Verlassen des Fokus unerwartet wieder auftauchen).

Build grün, alle Tests (inkl. neuem testConnectedChainExpandsTransitivelyForEveryNodeKind) grün, App startet ohne Absturz. Noch nicht visuell/live geprüft — kein Tool für native-macOS-UI-Interaktion hier verfügbar, bitte im Übersicht-Tab gegentesten (Klick auf Node → Fokus-Streifen unten, Klick auf leere Fläche/erneuter Klick → Fokus verlassen, anderen Kettenknoten anklicken → Fokus wechselt).

Nachbesserung 1 (User-Feedback: nach Klick soll die Fokus-Ebene in den sichtbaren Viewport geschoben werden, ohne Scrollbars) — inzwischen durch Nachbesserung 2 ersetzt: viewportSize per GeometryReader mitverfolgt, Auto-Zoom+Auto-Scroll auf einen "focusAnchor"-Marker im Fokus-Streifen.

Nachbesserung 2 (User-Feedback: statt Trennlinie/eingebettetem Bereich ein separates Panel mit Breite des Original-Viewports, Höhe automatisch an Inhalt angepasst, eigener Close-Button) — ersetzt Nachbesserung 1 komplett: Der Divider-Ansatz (Kette in denselben zoombaren Canvas verschoben, Auto-Fit-Zoom+Auto-Scroll) ist raus. Hauptdiagramm bleibt jetzt unverändert an Ort und Stelle (keine Repositionierung mehr, kein combinedCanvasSize/fitScale/ScrollViewReader mehr) — nicht zur Kette gehörende Nodes werden weiterhin abgedunkelt (opacity(0.25)). Neues focusPanel(subGraph:subLayout:) erscheint als eigener Bereich unterhalb der Haupt-ScrollView (in einem VStack, kein Overlay): Breite = viewportSize.width (Breite der Haupt-Diagramm-Scrollview, per GeometryReader gemessen), Höhe = subLayout.canvasSize.height + 56 (passt sich der Kettengröße an, kein künstliches Clamping). Eigene Kopfzeile mit "Fokus"-Titel + xmark.circle.fill-Button zum Schließen. Kette selbst per eigenem EdgesCanvas+Node-Loop gerendert (gleiches OverviewLayout, alle internen Kanten hell da komplett als highlightedNodeIDs durchgereicht), eigener Hover/Tooltip-State (panelHoveredEdge/panelHoverPoint), da eigener Koordinatenraum, getrennt von der Haupt-Diagramm-Tooltip-Logik. Klick auf einen Node im Panel wechselt den Fokus (kein Toggle-Aus mehr dort, dafür gibt's jetzt den Close-Button); Hintergrund-Klick/erneuter Klick auf denselben Node oben im Hauptdiagramm schließen weiterhin zusätzlich. Drag-Deaktivierung für Kettenknoten ist wieder raus (nicht mehr nötig, da Hauptdiagramm nicht mehr verschoben wird). Build+Tests grün, App startet ohne Absturz. Noch nicht live geprüft.

Nachbesserung 3 (User-Feedback: von Panel auf Popup wechseln) — inzwischen durch Nachbesserung 4 ersetzt: eigenes ZStack-Overlay mit Scrim + abgerundeter Karte statt fester VStack-Zeile.

Nachbesserung 4 (User-Feedback: "passt nicht", stattdessen wie beim Bearbeiten-Formular — Größe/Breite automatisch anpassen, Scrollbalken verhindern, Close-Button) — Sizing-Teil bleibt, Präsentation wurde in Nachbesserung 5 wieder korrigiert: natives .sheet(isPresented:) (gleiches Muster wie ExpertItemEditView), kein ScrollView mehr, .fixedSize() auf subLayout.canvasSize (exakte Content-Größe statt fixer Viewport-Breite).

Nachbesserung 5 (User-Feedback: Seitenleiste muss gleichzeitig bedienbar bleiben, um Knoten zu bearbeiten): .sheet ist ein echtes macOS-Modal — blockiert das gesamte Fenster inkl. der rechten Seitenleiste (detailPanel, "Bearbeiten"-Button), das war der Bug. Zurück auf nicht-modales ZStack-Overlay + Scrim (wie Nachbesserung 3), aber mit der exakten Content-Größe aus Nachbesserung 4 (kein ScrollView, .fixedSize() auf subLayout.canvasSize) statt der alten festen Viewport-Breite. isFocusPresented-Binding wieder entfernt. Sidebar bleibt jetzt durchgehend bedienbar, da sie eine eigene HSplitView-Pane ist, die vom Overlay nie erreicht wird. Build+Tests grün, App startet ohne Absturz.

Nachbesserung 6 (User-Wunsch: den Close-Button-Stil aus dem Fokus-Popup bei allen anderen Formularen/Sheets ebenfalls nachziehen) — betrifft nicht mehr nur Fund #3, sondern alle Sheet-Formulare der App: ExpertItemEditView (Experte-Bearbeiten-Sheet, ExpertMenuDetailView.swift) bekommt eine neue Kopfzeile mit Menü-Titel + xmark.circle.fill-Button (schließt via cancelEditing()+dismiss(), wie das bestehende "Abbrechen" unten — bleibt zusätzlich erhalten, da es semantisch mehr ist als nur schließen). Die drei Devices-Sheets (RawFieldsSheet, NetworkToolResultSheet, PortScanResultSheet in DevicesView.swift) hatten je nur einen "Schließen"-Textbutton unten — durch dieselbe Kopfzeile mit X-Button ersetzt (kein doppelter Close mehr). Neue L10n-Zeile "Schließen, ohne zu speichern" ergänzt.

Nachbesserung 7 (User-Feedback: alle Close-Buttons müssen in der Header-Leiste des Popups liegen, nicht doppelt): das untere "Abbrechen" in ExpertItemEditView war seit Nachbesserung 6 doppelt zum neuen Kopfzeilen-X — entfernt, einziger Close-Button ist jetzt der im Header. "Anlegen"/"Speichern" bleibt unten als reine Save-Aktion (kein Close). Geprüft: alle übrigen "Abbrechen"-Vorkommen in der App gehören zu nativen .confirmationDialog/.alert-Dialogen (keine Header-Leiste, nicht betroffen).

Nachbesserung 8 (User-Wunsch: Verhalten+Layout des Close-Buttons bei ALLEN Popups exakt wie beim Fokus-Popup der Übersicht) — Rückfrage gestellt, ob der Header beim Experte-Bearbeiten-Sheet dafür aus der scrollenden Form raus und fest oben stehen soll (mehr Umbau) oder nur optisch angeglichen wird; User: fest oben, wie Fokus-Popup. Umgesetzt in allen vier Popups (ExpertItemEditView, RawFieldsSheet, NetworkToolResultSheet, PortScanResultSheet): identische Struktur wie OverviewView.focusPanelHStack{Titel; Spacer; xmark.circle.fill-Button}.padding(10) gefolgt direkt von Divider(), außerhalb jeder Form/ScrollView/Section, bleibt beim Scrollen des restlichen Inhalts immer sichtbar. Beim Experte-Sheet wanderte der Header dafür vor die Form (Mindesthöhe leicht erhöht: 480→520/idealHeight 620→660, damit durch den zusätzlichen festen Header nichts gestaucht wirkt). Bei den drei Devices-Sheets wurde die bisher gemeinsame Erklärungs-Caption+Divider+Content-Gruppe vom Header getrennt und bekam eigenes Padding. Build+Tests grün, App startet ohne Absturz. Noch nicht live geprüft — bisher nur der Fokus-Popup-Teil (Fund #3) wurde live bestätigt "sieht gut", der Rest noch nicht.

4. LAN-Scanner: Sparkline-Breite + Abfrage-Intervall

Status: offen (implementiert, bitte live testen)

Wunsch: Sparkline-Breite verdoppeln, Traffic-Abfrage auf 0,5s setzen (statt 3s).

Umsetzung: TrafficSparkline-Frame in DevicesView.swift von 50pt auf 100pt Breite; DevicesViewModel.startTrafficPolling von .seconds(3) auf .milliseconds(500). Bewusst nur den LAN-Scanner-Poll geändert, nicht ConnectViewModels separate 3s-Schleife (die nur den Link-Punkt treibt, nicht die Sparkline) — User-Scope war explizit "im lan-scanner".

Nachbesserung 1 (User-Wunsch: nochmal doppelt so breit): 100pt → 200pt.

Nachbesserung 2 (User-Wunsch: Trafficanzeige in MB, Sparkline-Zeitfenster auf 30s): formatBitsPerSecond (kbps/Mbps/Gbps auto-skaliert) ersetzt durch festes formatMegabytesPerSecond (Bits/8/1.000.000, 2 Nachkommastellen, "MB/s"). Sparkline-Fenster in DevicesViewModel.appendTrafficHistory von 10s auf 30s (cutoff). Manual.md-Textstelle + build-manual.py-Lauf (PDF neu) mit aktualisiert.

Nachbesserung 3 (User-Wunsch: Aktualisierungsrate auf 0,1s): startTrafficPolling von .milliseconds(500) auf .milliseconds(100) — bei 30s-Fenster damit bis zu 300 Punkte pro Sparkline/Port (bisher ~60). Nicht weiter geprüft, ob das bei vielen Ports spürbar CPU kostet — bei Bedarf zurückmelden. Manual.md "Abfrage alle 0,1s" + PDF mit aktualisiert. Build grün, App startet ohne Absturz. Noch nicht live geprüft.

5. App-Einstellungen / Settings — eigener Menüpunkt

Status: offen (nur Feature-Idee notiert, noch nicht umgesetzt)

Wunsch: eigener Einstellungen-Bereich für Personalisierung, Layout, Farbverwaltung, Refreshraten, Updates, Schriftgrößen, Responsiveness, etc.

Ist-Zustand: es gibt aktuell eine einzige persistierte App-Einstellung (@AppStorage("appLanguage"), DE/EN-Umschalter in der Toolbar). Alles andere, was unter "Settings" fallen würde, ist im Code hart verdrahtet und über die Session verstreut — u.a. gerade erst in diesem Fund-Zettel mehrfach angefasste Werte:

  • Refreshraten: LAN-Scanner-Traffic-Poll DevicesViewModel.startTrafficPolling (aktuell 0,1s), Verbinden-Tab-Traffic-Poll ConnectViewModel.startTrafficPolling (3s, separat)
  • Sparkline-Zeitfenster (DevicesViewModel.appendTrafficHistory, aktuell 30s) und -Breite (TrafficSparkline, aktuell 200pt)
  • Farben: OverviewStyle.color(for:) (Node-Kategorien, Kanten-Arten), Firewall-Icons, Status-Farben im LAN-Scanner (Port-Scan rot/grün/grau)
  • Übersicht-Zoom-Standardwert, Fokus-Popup-Größe/Verhalten

Keine echte Settings-Infrastruktur (kein Settings-Tab/-Fenster, kein zentrales Preferences-Model) vorhanden — müsste komplett neu aufgebaut werden. Größerer, noch nicht spezifizierter Umbau; sollte vor Umsetzung geklärt werden: eigener Tab vs. natives macOS-Settings-Fenster (⌘,), welche der o.g. Werte tatsächlich zuerst einstellbar sein sollen, ob pro-Gerät oder global.