Qt-removal R7.5b-2: Orthogonal Routing canvas visual#149
Merged
Conversation
Ports the legacy scene's orthogonal-routing toggle into the React Flow canvas - the second of R7.5's 3 remaining canvas-visual parity gaps. Adds the first custom React Flow edge component in this codebase (OrthogonalEdge.tsx), rendering a right-angle step path for eligible node-kind pairs, plus a documented node-kind eligibility classifier ported from the legacy connection-type taxonomy. Deliberate translation, not a transcription: legacy's default connections used a horizontal mid-X step (Qt's layout ran left-to-right), but every node view in this app uses top-to-bottom Handle layout, so the mid-Y variant (legacy's GroupSummaryConnectionItem shape) is used as the general case here instead. Same bare-bool/"scene"-topic shape as fade-connections; intent name matches the legacy GridControlBridge's own Slot name 1:1.
This was referenced Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports the legacy scene's orthogonal routing toggle into the new React Flow canvas — the second of R7.5's three canvas-visual parity gaps (faded connections → orthogonal routing → smart guides, shipping in that order). When enabled, eligible connections render as right-angle "step" paths instead of curves.
This adds the first custom React Flow edge component in this codebase (
OrthogonalEdge.tsx) plus a node-kind eligibility classifier ported from the legacy connection-type taxonomy (confirmed via fresh recon ofgraphlink_connections.py, not reimplemented from memory).The deliberate translation call
Legacy's default connections used a horizontal mid-X step (
start → midX,startY → midX,endY → end) because the legacy Qt canvas laid branches out left-to-right. Every node view in this app instead usesHandle target=Top / source=Bottom— branches lay out top-to-bottom — so the geometrically correct translation is the mid-Y step (start → startX,midY → targetX,midY → end), which is the shape legacy used for exactly one connection type (GroupSummaryConnectionItem, a vertical connection) rather than its own default. This is used as the general case here.This was flagged in design review as the highest-judgment call in the spec and was verified three independent ways:
@xyflow/react@12.11.2BaseEdge/EdgePropsshapes against the type definitions innode_modules(not just the source code), including tracing into React Flow's compiledEdgeWrapperto confirmtype: undefinedcorrectly falls through to the default bezier.What changed
backend/canvas.py:orthogonal_routing: boolonSceneDocument, asetOrthogonalConnectionsintent (name matches the legacyGridControlBridge's own Slot name 1:1) — same shape as the existingsetFadeConnections.graphlink_app/graphlink_scene_payload.py: matching wire field on the codegen source-of-truth dataclass.web_ui/src/app/canvas/OrthogonalEdge.tsx(new): the step-path edge component described above. Forwardsstyleso it composes correctly with faded connections when both toggles are on.web_ui/src/app/canvas/SceneCanvas.tsx: a new exportedisOrthogonalEligible(sourceKind, targetKind)classifier — source"note"never eligible; target in{code, document, image, thinking}never eligible; target in{chat, conversation, html}eligible; every other kind (web_research/artifact/gitlink/pycoder/code_sandbox/frame/container/chart) explicitly defaulted not eligible, documented as a deliberate call since no legacy connection-type precedent exists for them.toFlowEdgesnow setstype: "orthogonal"per-edge when both the toggle is on and the pair is eligible; a newedgeTypesregistration wires it into React Flow.web_ui/src/app/chrome/ViewPopover.tsx: a new "Orthogonal Routing" checkbox, same pattern as the existing toggles.web_ui/src/app/chrome/help-data/sections.ts: Help text updated (smart guides remains the one honestly-still-unavailable item).Test plan
backend/tests/test_canvas.py: new intent testSceneCanvas.test.tsx: fullisOrthogonalEligibletruth-table coverage (every documented rule),toFlowEdgestype-assignment tests, and a composition test with fade-connections both enabledOrthogonalEdge.test.tsx(new): asserts the exact rendered SVG path string for two distinct geometries, plus style forwardingViewPopover.test.tsx: new checkbox coverage@xyflow/reactAPI usage against actual installed type definitions and re-ran the full test suite directly — zero confirmed defectsdocument.visibilityState === "hidden",requestAnimationFramenever firing,document.timeline.currentTimefrozen at 0, and a ResizeObserver on a plain resized div never delivering. React Flow measures nodes via ResizeObserver and skips edges whose nodes are unmeasured, so no frames → no edges (the identity viewport transform —fitViewalso never ran — corroborated this). Once the pane was displayed: frames flowed, nodes measured, and the orthogonal edge rendered with pathM 361,197 L 361,286 L 661,286 L 661,375— exactly the mid-Y formula (midY = 197 + (375−197)/2 = 286), under classreact-flow__edge-orthogonal, withfitViewcompleting. Toggling fade-connections on simultaneously dimmed the same path toopacity: 0.08, confirming the composition end-to-end. Screenshot verified: a clean right-angle elbow between the two chat nodes.