From bd610b0a8cc679394a94b683d2961b34549d893b Mon Sep 17 00:00:00 2001 From: Kay Date: Tue, 15 Sep 2026 14:20:09 +0200 Subject: [PATCH] =?UTF-8?q?=C3=9Cbersicht:=20Verbindungs-Label=20klarer,?= =?UTF-8?q?=20Verbindungszeilen=20anklickbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nutzerfrage: was bedeutet "Optionen" bei einer IP-Adresse verknüpften DHCP-Netzwerk-Zeile? Umbenannt zu "DHCP-Optionen". Zusätzlich: die "Verbindungen"-Zeilen im Detailpanel eines Knotens sind jetzt anklickbar (springt zum verbundenen Element, wie bei Linien-Klicks) und zeigen beim Hovern eine Klartext-Erklärung als Tooltip (OverviewStyle. explanation(for:), bereits für EdgeDetailView gebaut). 59 Unit-Tests grün. Manual.md/HANDOFF.md aktualisiert. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG --- HANDOFF.md | 9 +++++++ Manual.md | 8 +++++-- .../Features/Overview/OverviewView.swift | 24 +++++++++++++------ .../Features/Overview/OverviewViewModel.swift | 2 +- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/HANDOFF.md b/HANDOFF.md index 646a264..231ab08 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -588,6 +588,15 @@ Sichtbarwerden des Tabs neu) — Änderungen aus dem Experte-Tab (z.B. eine neu angelegte Route) erscheinen jetzt automatisch beim Reinschauen, ohne manuellen "Aktualisieren"-Klick. +**Verbindungs-Label "Optionen" im Detailpanel unklar, Zeile nicht +anklickbar** — Nutzerfrage nach Klick auf eine IP-Adresse: was bedeutet +"Optionen" bei der verknüpften DHCP-Netzwerk-Zeile? Umbenannt zu +"DHCP-Optionen"; die "Verbindungen"-Zeilen im Detailpanel (`NodeDetailView`) +sind jetzt anklickbar (springt zum verbundenen Knoten, wie schon bei +Linien-Klicks) und zeigen beim Hovern einen Tooltip mit der +Klartext-Erklärung (`OverviewStyle.explanation(for:)`, bereits für +`EdgeDetailView` gebaut, hier wiederverwendet). + ## `xcodebuild test` hängt — Gatekeeper, kein Code-Bug `xcodebuild ... test` kann exakt beim App-Start für ~5 Minuten hängen, diff --git a/Manual.md b/Manual.md index 26e3b07..ee7a397 100644 --- a/Manual.md +++ b/Manual.md @@ -91,7 +91,9 @@ Grafisches Diagramm des kompletten aktuellen Router-Zustands: angeklickt wird). - **Klick auf eine Verbindungslinie** zeigt rechts eine verständliche Erklärung, was diese Verbindung bedeutet, plus Sprung zu den beiden - verbundenen Elementen. + verbundenen Elementen. Die "Verbindungen"-Liste im Detailpanel eines + Knotens ist ebenfalls klickbar (springt direkt zum verbundenen + Element) und zeigt beim Hovern eine kurze Erklärung als Tooltip. - **Direktes Bearbeiten**: IP-Adressen, Pools, DHCP-Server/-Netzwerke/ -Clients, Routen, Firewall-Filter-/NAT-Regeln und WireGuard-Peers lassen sich anklicken und über "Bearbeiten" direkt ändern — schreibt @@ -213,7 +215,9 @@ Graphical diagram of the router's complete current state: clicked). - **Clicking a connection line** shows a plain-language explanation of what it means in the right-hand panel, plus a jump to both connected - elements. + elements. The "Connections" list in a node's detail panel is also + clickable (jumps straight to the connected element) and shows a short + explanation as a tooltip on hover. - **Direct editing**: IP addresses, pools, DHCP servers/networks/ clients, routes, firewall filter/NAT rules and WireGuard peers can be clicked and changed via "Edit" — writes back to the router diff --git a/RouterOSAssistant/Features/Overview/OverviewView.swift b/RouterOSAssistant/Features/Overview/OverviewView.swift index bb6a941..bdb58ac 100644 --- a/RouterOSAssistant/Features/Overview/OverviewView.swift +++ b/RouterOSAssistant/Features/Overview/OverviewView.swift @@ -204,7 +204,10 @@ struct OverviewView: View { viewModel.selectedNodeID = nodeID } } else if let id = viewModel.selectedNodeID, let node = viewModel.graph.nodes.first(where: { $0.id == id }) { - NodeDetailView(node: node, graph: viewModel.graph, onEdit: editNode) + NodeDetailView(node: node, graph: viewModel.graph, onEdit: editNode) { nodeID in + selectedEdge = nil + viewModel.selectedNodeID = nodeID + } } else { LegendView() } @@ -536,6 +539,7 @@ private struct NodeDetailView: View { let node: OverviewNode let graph: OverviewGraph let onEdit: (OverviewNode) -> Void + let onSelectNode: (String) -> Void var body: some View { ScrollView { @@ -578,12 +582,18 @@ private struct NodeDetailView: View { ForEach(connected) { edge in let otherID = edge.from == node.id ? edge.to : edge.from let otherTitle = graph.nodes.first(where: { $0.id == otherID })?.title ?? otherID - Label( - edge.label.map { "\(otherTitle) (\($0))" } ?? otherTitle, - systemImage: edge.from == node.id ? "arrow.right" : "arrow.left" - ) - .foregroundStyle(OverviewStyle.color(for: edge.kind)) - .font(.caption) + Button { + onSelectNode(otherID) + } label: { + Label( + edge.label.map { "\(otherTitle) (\($0))" } ?? otherTitle, + systemImage: edge.from == node.id ? "arrow.right" : "arrow.left" + ) + .foregroundStyle(OverviewStyle.color(for: edge.kind)) + .font(.caption) + } + .buttonStyle(.plain) + .help(OverviewStyle.explanation(for: edge.kind)) } } } diff --git a/RouterOSAssistant/Features/Overview/OverviewViewModel.swift b/RouterOSAssistant/Features/Overview/OverviewViewModel.swift index 3e160e6..631763f 100644 --- a/RouterOSAssistant/Features/Overview/OverviewViewModel.swift +++ b/RouterOSAssistant/Features/Overview/OverviewViewModel.swift @@ -189,7 +189,7 @@ final class OverviewViewModel: ObservableObject { )) let networkPart = address.split(separator: "/").first.map(String.init) ?? address if let addressID = networkToAddressID[networkPart] { - edges.append(OverviewEdge(from: addressID, to: id, label: "Optionen", kind: .dhcp)) + edges.append(OverviewEdge(from: addressID, to: id, label: "DHCP-Optionen", kind: .dhcp)) } }