Skip to content

Code Review Phase 10: Canvas System — The Heart of the App #31

@jitu5

Description

@jitu5

Code Review Phase 10: Canvas System — The Heart of the App

Purpose: Review the visual pipeline canvas — custom ReactFlow nodes, edges, and the 9 canvas hooks that orchestrate drag, drop, connect, select, copy/paste, and keyboard shortcuts.

Prerequisites: Phases 2-4, 8 (Constants, Domain, Redux, UI Primitives)
Estimated time: 2.5 hours (largest phase — reviewers should be well-prepared by now)
Files: 29


Canvas Component Hierarchy

  PipelineCanvas (orchestrator)
  ├── ReactFlow (library wrapper)
  │   ├── CustomNode ──────── Kedro function node (memo)
  │   │   └── Handle (in/out connection points)
  │   ├── DatasetNode ─────── Kedro dataset node (memo)
  │   │   └── Handle (in/out connection points)
  │   └── CustomEdge ──────── Bezier connection line (memo)
  ├── CanvasOverlay
  │   ├── EmptyState ──────── "Drop components here"
  │   └── BulkActionsToolbar ─ Multi-select actions
  ├── CanvasControls ──────── Zoom, fit-view, minimap
  ├── EdgeContextMenu ─────── Right-click on edges
  └── GhostPreview ────────── Preview during connection drag

  9 Canvas Hooks (all used by PipelineCanvas):
  ┌──────────────────────────┐
  │ useCanvasState           │ Redux ──▶ ReactFlow format
  │ useNodeHandlers          │ Drop, click, delete
  │ useConnectionHandlers    │ Connect, validate, cycle check
  │ useSelectionHandlers     │ Multi-select, bulk ops
  │ useCanvasKeyboardShorts  │ Del, Cmd+C/V, Escape, Space
  │ useCopyPaste             │ Clone with new IDs
  │ useDragToCreate          │ Drag connection → new node
  │ useGhostPreview          │ Visual drag feedback
  │ useDeleteConfirmation    │ Confirm before bulk delete
  └──────────────────────────┘

Files to Review (in order)

Canvas Hooks (read these first — they contain the logic)

Custom ReactFlow Components

Canvas Chrome (UI around the canvas)

Orchestrator (read last — ties everything together)

Tests


Key Concepts

  • nodeTypes and edgeTypes must be declared OUTSIDE the component to prevent recreation on every render (critical ReactFlow optimization)
  • useCanvasState converts the normalized Redux state (byId/allIds) into the flat array format ReactFlow requires
  • useConnectionHandlers enforces the bipartite graph constraint — connections can only go node↔dataset
  • useCopyPaste must regenerate IDs for pasted nodes/datasets using generateCopyId to avoid collisions

Focus Areas

  • Does useCanvasState correctly memoize the Redux → ReactFlow conversion? Known issue: useLayoutEffect replaces the nodes/edges arrays on every relevant Redux change, which defeats React.memo() on CustomNode/DatasetNode. This is a known architectural issue tracked for future optimization (ADR-002).
  • Does useConnectionHandlers properly prevent node-to-node and dataset-to-dataset connections? It now uses useAppSelector for connection and node state (no longer uses store.getState() anti-pattern).
  • Does useCopyPaste correctly regenerate all IDs AND update source/target references in pasted connections?
  • Are CustomNode and DatasetNode using React.memo? (They are, but the memo is defeated by array replacement — see known issue above.)
  • Does PipelineCanvas pass deleteKeyCode={null} — disabling ReactFlow's built-in delete for custom handling?
  • Are keyboard shortcuts checking for input focus to avoid triggering while typing in forms?
  • Is the nodeTypes/edgeTypes object declared outside the component?
  • useCanvasState no longer carries unused theme from the canvas selector — verify theme-dependent functionality still works via its own selector.

Next: Phase 11 (Code Generation & Export)

Metadata

Metadata

Assignees

No one assigned

    Labels

    code-reviewStructured code review phases

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions