molecule-core/canvas
Hongming Wang 50b537849a refactor(canvas): split Canvas.tsx into hooks; parallelize batchNest
Two concerns in one commit (separate files, each self-contained):

## Canvas.tsx split (from ~680 to ~250 lines)

Canvas.tsx was holding drag gesture state + keyboard shortcuts +
viewport wiring + JSX. Each concern now lives in its own unit under
canvas/src/components/canvas/:

- dragUtils.ts          — pure: shouldDetach, clampChildIntoParent,
                          DETACH_FRACTION
- DropTargetBadge.tsx   — the floating "Drop into: <name>" label + the
                          dashed ghost preview at the target slot
- useDragHandlers.ts    — encapsulates onNodeDragStart / Drag / Stop,
                          findDropTarget hit-test, pendingNest state,
                          and confirmNest/cancelNest. Routes multi-
                          select drags through batchNest automatically.
- useKeyboardShortcuts  — Esc, Enter, Shift+Enter, Cmd+]/[, Z — one
                          window listener, one source of truth.
- useCanvasViewport     — pan-to-node + zoom-to-team CustomEvent
                          listeners and the debounced viewport save.

Canvas.tsx becomes a thin composition + JSX file. No behavioural
change; the refactor is covered by the existing 915 canvas tests.

## batchNest parallelization (2N round-trips → N, all in flight)

Previously nestNode fired two sequential PATCHes (parent_id then x/y)
and batchNest looped nestNode sequentially. For a 5-node selection on
a typical ~200ms link this was ~2s of serialized RPCs.

- nestNode now combines parent_id + x + y into ONE PATCH. The Go
  handler (workspace_crud.go Update) already reads all three from the
  same body — no backend change.
- batchNest rewritten: compute every re-parent plan against one
  snapshot, commit a single set(), then fire N PATCHes via
  Promise.allSettled in parallel. Per-node failures roll back only
  that node (others stay committed) — same semantics as the single-
  node path, just concurrent.
- The state math in the batch path also correctly shifts descendant
  zIndex by depthDelta when any re-parented node has a subtree.

## Also

- canvas-topology.ts: reverted P3.12's opt-in rescue to the auto-
  rescue default. When a child's stored relative position would render
  it outside the parent bbox (the visual regression the user saw after
  collapse → reload — Hermes child drawn outside Claude Code Agent on
  first paint), the child is placed in the next default grid slot.
  The "Arrange Children" context command stays for bigger teams.

All 915 canvas tests pass. No backend changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 19:43:18 -07:00
..
e2e Merge pull request #1445 from Molecule-AI/fix/tenant-dockerfile-uid-conflict 2026-04-21 08:58:09 -07:00
public chore: replace brand icon and add HANDOFF.md 2026-04-13 13:03:40 -07:00
src refactor(canvas): split Canvas.tsx into hooks; parallelize batchNest 2026-04-23 19:43:18 -07:00
.env.example fix(canvas): close 4 gaps in WS status indicator (env, toast, tests) 2026-04-14 08:26:38 +00:00
.gitignore feat(canvas): SaaS cross-origin — slug header + cookie credentials (Phase F) 2026-04-14 20:08:39 -07:00
components.json chore(canvas): initialize shadcn/ui — components.json + cn utility 2026-04-18 07:57:17 -07:00
Dockerfile fix(build): add missing fmt import + fix canvas Dockerfile GID (#1487) 2026-04-22 21:10:58 +00:00
next.config.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
package-lock.json fix(canvas): cascade-delete UX — require checkbox before Delete All (#1314) 2026-04-21 07:06:45 +00:00
package.json fix(quickstart): make README cp-paste flow bugless end-to-end (#1871) 2026-04-23 19:53:43 +00:00
playwright.config.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
playwright.staging.config.ts feat(e2e): canary + canvas Playwright workflows; delegation mechanics 2026-04-21 04:15:10 -07:00
postcss.config.js initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
tailwind.config.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
tsconfig.json initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
vitest.config.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00