M17-M19: Bekannte Router, Live-Traffic-Anzeige, Übersicht-Animation+Drag

M17: "Bekannte Router" im Verbinden-Tab (SavedRouter/SavedRoutersStore),
Standort-Freitextfeld, Scroll-Cap ab 4 Einträgen. Bugfix: Umbenennen-
TextField steckte in einem sich selbst deaktivierenden Button.

M18: Live-Traffic-Punkt an Interfaces (InterfaceTrafficMonitor, eigene
SSH-Verbindung, monitor-traffic-Polling). Dabei zwei reale CLI-Parser-Bugs
gefunden und gefixt: running/disabled-Flags werden als Buchstaben vor dem
ersten Feld codiert, nicht als key=value; monitor-traffic liefert
"50.7kbps" statt einer reinen Zahl.

M19: Übersicht-Tab — animierte Flussrichtung auf allen Verbindungslinien
(TimelineView+dashPhase), frei verschiebbare Knoten mit Live-folgenden
Linien, Zurücksetzen-Button.

Zusätzlich (noch nicht live getestet, nur Build+Unit-Tests grün):
LAN-Port-Konflikt-Prüfung im Einrichten-Assistenten mit doppelter
Sicherheitsbestätigung, "Fertig"-Button nach erfolgreichem Anwenden.

82 Tests grün. HANDOFF.md/README.md/Manual.md/CHATLOG.md aktualisiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
This commit is contained in:
Kay
2026-09-15 21:40:46 +02:00
co-authored by Claude Sonnet 5
parent 9b26677dc2
commit 31607b7270
24 changed files with 1400 additions and 61 deletions
+57
View File
@@ -889,3 +889,60 @@ Test, WLAN/Bonding/PPPoE-Live-Tests).
visuelle Live-Prüfung des Diagramms selbst steht noch aus (nur die
Logik ist getestet), auf ausdrücklichen Nutzerwunsch trotzdem
gespeichert.
- "beim Einrichten unter Einrichten/Experte, wenn man ein neues LAN
anlegt, mache vorher eine prüfung, ob der entsprechende port frei
ist..." → LAN-Port-Konflikt-Prüfung gebaut: `PortConflict`-Modell,
`ConnectionService.checkPortConflict(interfaceName:)` (liest Bridge-
Mitgliedschaft/IP-Adresse/DHCP-Client/PPPoE-Client parallel per
`async let`), `LanStepView`s neue Warnbox mit zwei aufeinanderfolgenden
Bestätigungsdialogen. "bitte nach erfolgreichen Einrichten einen
'Fertig'-Button" → `SetupViewModel.finish()` setzt den Assistenten
nach erfolgreichem Anwenden zurück. Beides nur Build+Unit-Test-
verifiziert, noch nicht live getestet.
- "ich würde gerne mehrere Logins hinterlegen können, quasi eine Liste
bekannter Router..." → M17: `SavedRouter`/`SavedRoutersStore`
(JSON in UserDefaults), Anzeigename defaultet auf `RouterDeviceInfo.
boardName` beim ersten Connect, bleibt danach unverändert außer bei
explizitem Umbenennen. "ich sehe 'Bekannte Router' nicht" → Liste
füllt sich nur bei einer neuen Verbindung nach dem Rebuild, nicht
rückwirkend. "das umbenennen funktioniert nicht" → TextField steckte
in einem `.disabled(isRenaming)`-Button, der auch das TextField
deaktivierte — Fix: kein umschließender Button mehr, `.onTapGesture`
für Zeilen-Auswahl. "ein Standort... müssten noch als Freitextfelder"
→ `SavedRouter.location` ergänzt, Menü "Umbenennen"→"Bearbeiten"
(Name+Standort zusammen), rückwärtskompatibles Decoding. "wenn die
Liste länger als 4 bekannte Router wird, mach einen Scrollbalken" →
eigene `ScrollView` mit Höhen-Cap statt das Formular wachsen zu
lassen. Alle live bestätigt außer dem Scroll-Cap (kein explizites
Feedback, kein Einwand).
- "kannst du die Punkt vor der Interfaces-Bezeichnung einfärben oder
sogar animieren (grün), wenn sie aktuell in Verwendung sind und Daten
übertragen?" → M18: neue `InterfaceTraffic`/`InterfaceTrafficMonitor`
(eigene dedizierte SSH-Verbindung, `/interface monitor-traffic` hat
kein REST-Äquivalent), 3s-Polling. "alle buttons sind grau, keine
Animation" → Nutzer bot direkten Router-Zugriff an; da ich keine
Zugangsdaten habe und ungern ein Passwort im Chat sehen wollte, um
zwei Diagnose-Befehle gebeten (`/interface print without-paging
terse`, `/interface monitor-traffic ... once`) statt zu raten. Zwei
reale Bugs gefunden: (1) `running=`/`disabled=` existieren in echtem
Terse-Output gar nicht — RouterOS codiert das als Buchstaben-Flags vor
dem ersten Feld (R/X/S), ein vorbestehender, nie zuvor aufgefallener
Parser-Bug; (2) `monitor-traffic` liefert `"50.7kbps"` statt einer
reinen Zahl, `Int(...)` scheiterte lautlos zu 0. Beide gefixt, 82
Tests grün (inkl. 2 Tests mit dem exakten Nutzer-Output). Live
bestätigt ("sehr gut").
- "im Übersicht-tab... die Linien auch animiert haben, mit einer
animierten Flußrichtung" → M19a: `EdgesCanvas` in `TimelineView(.
animation)` gewickelt, `dashPhase` wandert über die Zeit in Richtung
"von→nach". "kann man die einzelnen Kästchen verschiebbar machen? ...
ein Button für den Reset" → M19b: `nodeOffsets`-State +
`@GestureState` fürs laufende Draggen, `effectivePositions` kombiniert
beides für Knoten-Karten UND `EdgesCanvas`. "der Button ... fehlt" →
`Label` (Icon+Text) vermutlich in Toolbar-Overflow verschwunden, Fix
auf Icon-only. "verwirrend, ähnlich wie Refresh" → auf reinen
Text-Button "Zurücksetzen" umgestellt (wie der bereits funktionierende
"100%"-Button). Alle drei Teile live bestätigt. "commit+push, bitte
die Readme.md nicht vergessen" → HANDOFF.md/README.md/Manual.md/
CHATLOG.md aktualisiert, Commit + Push (inkl. der noch nicht live
getesteten Port-Konflikt-Prüfung + Fertig-Button, auf ausdrücklichen
Nutzerwunsch mitgespeichert).