feat(apollo-react): add support for sequential canvas#951
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Dependency License Review
License distribution
Excluded packages
|
There was a problem hiding this comment.
Pull request overview
Adds a new “sequential” canvas view to apollo-react/canvas, providing an n8n/Zapier-style vertical projection of the existing flow graph while keeping the canonical nodes/edges (and flow positions) as the source of truth. This introduces a projection/layout engine, new sequential UI components (rows, connectors, insert/move/collapse affordances), a flow↔sequential view switcher with persisted view + viewport restore, and supporting docs/i18n/test coverage.
Changes:
- Introduce sequential graph utilities (projection, layout, merge analysis, fingerprint memoization, slot/preview helpers, and mutations support).
- Add Sequential Canvas UI layer (SequentialCanvas, view switcher/context, sequential nodes/edges, insertion + move actions, collapse gutter, accessibility fallback list, story harness + stories).
- Extend shared canvas infrastructure to support sequential behavior (BaseNode “bar” variant, shared edge-label primitive, preview-handle resolution, and BaseCanvas opt-out of refit-on-node-set-change).
Reviewed changes
Copilot reviewed 104 out of 104 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/apollo-react/src/test/canvas-mocks.ts | Extend xyflow mock to include EdgeLabelRenderer for sequential edge label rendering in tests. |
| packages/apollo-react/src/canvas/utils/sequential/sequential.types.ts | Define sequential “frozen contract” types for projection/layout/connectors/slots/mutations. |
| packages/apollo-react/src/canvas/utils/sequential/previewRow.ts | Add pure helper to splice a preview row/connectors into a projection during Add Node preview. |
| packages/apollo-react/src/canvas/utils/sequential/previewRow.test.ts | Unit tests for preview-row splicing and geometry shift correctness. |
| packages/apollo-react/src/canvas/utils/sequential/mergeAnalysis.ts | Add structured merge-point approximation to support branch merge rendering/degradation. |
| packages/apollo-react/src/canvas/utils/sequential/layoutSequence.ts | Implement pure sequential layout pass and connector waypoint generation. |
| packages/apollo-react/src/canvas/utils/sequential/index.ts | Sequential utils barrel export. |
| packages/apollo-react/src/canvas/utils/sequential/graph-helpers.ts | Pure graph indexing/traversal helpers for projection/merge/layout. |
| packages/apollo-react/src/canvas/utils/sequential/fingerprint.ts | Structural fingerprint for projection/layout memoization. |
| packages/apollo-react/src/canvas/utils/sequential/fingerprint.test.ts | Tests for fingerprint invariants and invalidation triggers. |
| packages/apollo-react/src/canvas/utils/index.ts | Re-export sequential utils from canvas utils. |
| packages/apollo-react/src/canvas/storybook-utils/sequential/wireframeManifests.ts | Add manifests needed for sequential wireframe story node types. |
| packages/apollo-react/src/canvas/storybook-utils/sequential/SequentialCanvasStoryHarness.tsx | Story-only harness for controlled sequential graphs with registry manifests. |
| packages/apollo-react/src/canvas/storybook-utils/sequential/index.ts | Local barrel for sequential story helpers. |
| packages/apollo-react/src/canvas/README.md | Document sequential view model, usage, and degraded-graph behavior. |
| packages/apollo-react/src/canvas/locales/en.json | Add English strings for sequential canvas UI. |
| packages/apollo-react/src/canvas/locales/de.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/es.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/es-MX.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/fr.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/ja.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/ko.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/pt.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/pt-BR.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/ro.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/ru.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/tr.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/zh-CN.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/locales/zh-TW.json | Add sequential canvas message keys (currently English placeholders). |
| packages/apollo-react/src/canvas/hooks/usePreviewNode.ts | Improve preview-edge filtering and resolve existing-node handle ids for derived views. |
| packages/apollo-react/src/canvas/hooks/usePreviewNode.test.ts | Tests for preview-handle resolution behavior. |
| packages/apollo-react/src/canvas/constants.ts | Add sequential geometry constants and default target handle id. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/ViewSwitcher.tsx | Add segmented Flow/Sequential control with i18n + controlled state. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/ViewSwitcher.test.tsx | Test view switcher behavior and callback invocation. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/useSequentialMoveActionsValue.ts | Provide stable context value for move actions with latest-graph commit behavior. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/useSequentialMoveActionsValue.test.ts | Tests for identity stability and correct commit forwarding. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/useCanvasViewMode.ts | Persist view choice via useStorageState (localStorage). |
| packages/apollo-react/src/canvas/components/SequentialCanvas/ToggleHarness.tsx | Demo harness for view toggle + flow-position synthesis on return to flow. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/synthesizePositionsForFlow.ts | Place sequential-inserted nodes into non-overlapping flow positions on toggle. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/synthesizePositionsForFlow.test.ts | Tests for placement guarantees and marker cleanup. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialViewContext.tsx | Provide optional view + per-view viewport save/restore context. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialMoveActionsContext.tsx | Context for move-option calculation and commit wiring (optional outside canvas). |
| packages/apollo-react/src/canvas/components/SequentialCanvas/sequentialMoveActions.ts | Pure move-option computation, loop/bare-branch safety gates, slot resolution helpers. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialInsertStateContext.tsx | Provider to share pending insert slot state across hook instances. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialInsertGapContext.tsx | Provider for “active insert slot” reporting to drive preview-gap behavior. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialGutter.tsx | Step-number rail gutter with collapse/expand chevrons and leader lines. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/sequentialGraph.constants.ts | Shared sequential graph constants (synthetic ids/types, full-render threshold). |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialCollapsedRowsContext.tsx | Context to pass collapsed-row ids to step nodes without mutating node data. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialCanvas.types.ts | Public SequentialCanvas props + ViewSwitcher props types. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialCanvas.roundtrip.test.ts | Acceptance test for insert → toggle-to-flow placement → re-project identity. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialAccessibleList.tsx | Screen-reader fallback list for very large graphs when visual virtualization is enabled. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/useSequentialMoveMenuItems.tsx | Build localized “move” kebab items (design-mode only) for sequential steps. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/useSequentialMoveMenuItems.test.tsx | Tests for menu item availability, disabled-state, and commit callbacks. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/SequentialStepNode.tsx | Wrapper rendering BaseNode in “bar” variant with collapse + move menu integration. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/SequentialStepNode.test.tsx | Lightweight wrapper test for bar variant rendering. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/SequentialStartNode.tsx | Synthetic start-row bar with optional “Add trigger” CTA and bottom handle. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/SequentialPlaceholderNode.tsx | Synthetic placeholder row/plus variants for empty lanes and append points. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/SequentialPlaceholderNode.test.tsx | Tests for placeholder variants and add behavior gated by mode. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/SequentialInsertPreviewNode.tsx | Sequential-specific Add Node preview bar rendering matching bar layout. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/index.ts | Local barrel and synthetic nodeTypes map for sequential view. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/nodes/BarVariant.stories.tsx | Story to compare card vs bar rendering drift and show synthetic rows. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/index.ts | Export sequential canvas components/hooks from SequentialCanvas package index. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/useSequentialInsert.ts | Hook wiring sequential insert affordance to existing preview + AddNodeManager pipeline. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/useSequentialInsert.test.tsx | Tests for slot publishing and shared pending-slot state across hook instances. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/SequentialInsertButton.tsx | Centered connector “plus” affordance rendered via EdgeLabelRenderer. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/sequentialConnectorStyle.ts | Map connector kind to stroke style (solid vs dashed). |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/sequentialConnectorStyle.test.ts | Tests for connector stroke-style mapping coverage. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/SequentialConnectorEdge.types.ts | Define SequentialConnectorData contract for reference-stable edge rendering. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/SequentialConnectorEdge.test.tsx | Tests for stroke style, insert affordance, left-entry arrow centering, and labels. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/SequentialBranchHeader.tsx | Render branch-entry header label using shared edge-label treatment. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/SequentialBranchHeader.test.tsx | Test branch header positioning + selected styling. |
| packages/apollo-react/src/canvas/components/SequentialCanvas/edges/index.ts | Local barrel for sequential edges/insert pipeline (kept out of public barrel until GA). |
| packages/apollo-react/src/canvas/components/index.ts | Export SequentialCanvas from the canvas components barrel. |
| packages/apollo-react/src/canvas/components/Edges/shared/primitives/index.ts | Export EdgeLabelContent in primitives barrel. |
| packages/apollo-react/src/canvas/components/Edges/shared/primitives/EdgeLabel.tsx | Factor shared label styling into EdgeLabelContent used by SVG + portal labels. |
| packages/apollo-react/src/canvas/components/Edges/shared/hooks/useEdgeGeometry.ts | Add configurable borderRadius for waypoint rounded-path generation. |
| packages/apollo-react/src/canvas/components/canvas-gallery.stories.tsx | Add Sequential Canvas to component gallery and align TaskIcon type usage. |
| packages/apollo-react/src/canvas/components/BaseNode/BaseNode.tsx | Add BaseNode “bar” render variant, sequential sizing/handles, and extra menu items support. |
| packages/apollo-react/src/canvas/components/BaseCanvas/BaseCanvas.types.ts | Add refitOnNodeSetChange option to control auto-layout refit behavior. |
| packages/apollo-react/src/canvas/components/BaseCanvas/BaseCanvas.tsx | Wire refitOnNodeSetChange into auto-layout hook. |
| packages/apollo-react/src/canvas/components/BaseCanvas/BaseCanvas.hooks.ts | Implement one-shot fit behavior when refit-on-node-set-change is disabled. |
| "sequential-canvas.start.add-trigger": "Add trigger", | ||
| "sequential-canvas.step.aria-label": "Step {stepNumber} of {total}: {label}", | ||
| "sequential-canvas.placeholder.add": "Add step", | ||
| "sequential-canvas.new-step": "New step", |
📊 Coverage + size by packagePer-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.
"Coverage" is each package's own |
| let stackLeftX = 0; | ||
| for (const position of positions.values()) { | ||
| if (position.x < stackLeftX) stackLeftX = position.x; | ||
| } |
| * TOPOLOGY mutation (D4), so -- like the ⊕ insert affordance | ||
| * (`SequentialConnectorEdge`'s `showInsert`) -- they only appear in design | ||
| * mode; outside a `SequentialMoveActionsContext` provider (isolated node | ||
| * stories/tests) this returns an empty array rather than throwing. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 114 out of 114 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialGutter.tsx:91
- The comment says the gutter reads the stack’s left edge from actual row positions (so it won’t assume
x = 0), butstackLeftXis initialized to0and only updates when a position is negative. If a future layout change shifts all rows to a positive x-offset, the gutter will still anchor at 0 and desync. Compute the true minimum x instead.
let stackLeftX = 0;
for (const position of positions.values()) {
if (position.x < stackLeftX) stackLeftX = position.x;
}
const columnLeftX = stackLeftX - SEQ_GUTTER_COLUMN_WIDTH_PX - SEQ_GUTTER_LEADER_GAP_PX;
| const onEdgesChange = useCallback( | ||
| (changes: Parameters<typeof applyEdgeChanges<Edge>>[0]) => | ||
| setEdges((current) => applyEdgeChanges(changes, current)), | ||
| [] | ||
| ); |
| /** | ||
| * Preserves an independent viewport for each presentation, even when the | ||
| * optional persisted SequentialViewProvider is absent. | ||
| */ |
Introduce a sequential (list-style) canvas view for apollo-react as an alternative to the graph layout, with round-trip-safe view switching. - Projection and layout engine mapping the graph to ordered rows, with subtree-aware move operations and slot-based navigation - BaseNode bar render variant and sequential node shells aligned with card behavior for icons, selection, display, and a11y - Connector edges with smooth-step corners, shared branch spines, and dashed container merge-back routing - Insert pipeline with preview gap, shared cross-instance pending state, and container-aware parenting - Gutter, keyboard navigation, and aria labels - Virtualization past a node ceiling to avoid mount-burst loops, fitView on entry, and perf-loop fixes - Stories, i18n catalog, docs, and hardening tests Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
51fd856 to
cf24732
Compare
|
Apollo Coded App preview deployments are ready.
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 117 out of 117 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
packages/apollo-react/src/canvas/components/SequentialCanvas/SequentialGutter.tsx:90
stackLeftXis initialized to 0 and only updated when a row is further left. If all row x positions are > 0 (or if a future layout introduces a positive left margin), the gutter will still assume the stack starts at x=0 and render the rail/leader too far left. Initialize from the actual min x (or from the first position) so the gutter truly derives the left edge frompositions.
// The stack's own left edge: `layoutSequence` always anchors depth-0 rows at
// x = 0 (utils/sequential/layoutSequence.ts, read-only reference), but this
// reads it from the actual positions rather than assuming it, so a future
// layout change (e.g. a reference chip rendered further left) can't silently
// desync the rail from the bars it labels.
let stackLeftX = 0;
for (const position of positions.values()) {
if (position.x < stackLeftX) stackLeftX = position.x;
}
| "sequential-canvas.step.aria-label": "Step {stepNumber} of {total}: {label}", | ||
| "sequential-canvas.steps.aria-label": "Workflow steps", | ||
| "sequential-canvas.placeholder.add": "Add step", | ||
| "sequential-canvas.insert-step": "Insert step", | ||
| "sequential-canvas.continues-at-step": "Continues at step {stepNumber}", |
No description provided.