openova/products/catalyst/bootstrap/ui/.pr-evidence
e3mrah 2997edc4f9
fix(catalyst-ui): rebuild Flow canvas to match provision-mockup-v4.png (#282)
Replaces the pill-card swimlane layout shipped in PR #245 — which the
operator rejected as "intentional divergence from the canonical
mockup" (issue #251) — with a circular-node, multi-region, bezier-edge
canvas that matches `marketing/mockups/provision-mockup-v4.png`.

What changed
------------
New geometry library (`src/lib/flowLayoutV4.ts`):
  • Multi-region partition — caller supplies FlowRegion[]; every
    region renders as a horizontal band stacked top → bottom.
  • Per-region longest-path stage assignment (Kahn) keyed on Job
    dependsOn + caller-supplied `extraDepIds` (component-graph edges
    surfaced from ApplicationDescriptor.dependencies so dense families
    like SPINE / GUARDIAN read as columns even when the test catalog
    has no per-job dependsOn yet).
  • Sub-column splitting at MAX_PER_COLUMN (8) so dense families
    stack vertically rather than fanning out into many sub-columns.
  • Caller-injected family palette (PRODUCTS taxonomy from
    componentGroups.ts) so the flow + the wizard StepComponents
    page colour-code identically.
  • Bezier router — straight for span=0 within-region, cubic-bezier
    for span≥1 and all cross-region edges (warm-amber dashed).

New presentation layer:
  • `FlowCanvasV4.tsx` — circular nodes with status-tinted progress
    arcs, family-colour rings, single-letter glyphs (✓ / ✕ / family
    initial), per-status arrow markers, region band frames, and
    stage column dividers + labels.
  • `FlowDeploymentTree.tsx` + `flowDeploymentTreeData.ts` — left
    "DEPLOYMENT PROGRESS" panel; static tree (NO accordion per the
    operator's standing rule), groups by region → family → job.
  • `FlowLogFeed.tsx` — right "LIVE LOG" panel; replays the focused
    job's recent reducer events, status-coloured, blinking cursor
    when live.

`FlowPage.tsx`:
  • Replaces the JobBubble pipelineLayout pipeline with the
    flowLayoutV4 + FlowCanvasV4 + tree + log triplet.
  • Wires region descriptors from `useWizardStore().regions` (with a
    fallback single-region for empty stores).
  • Derives stage hints — Phase 0 = stage 1, cluster-bootstrap =
    stage 2, components = 3 + componentGraphDepth.
  • Picks an initial focused job (running > failed > first) so the
    log feed always shows something on first paint.
  • Inlines the surface CSS so canvas + tree + log stay in lockstep.

Preserved testid contract
-------------------------
  data-testid="flow-canvas-svg"           — root <svg>
  data-testid="flow-job-<jobId>"          — every node group
  data-testid="flow-batch-<regionId>"     — every region band
  data-testid="flow-canvas-empty"         — empty placeholder

So the existing cosmetic-guards Test #6/#7/#8 continue to pass without
edit (Jobs↔Batches mode toggle + single-click → FloatingLogPane behaviour
is unchanged).

New testids for the upgraded V4 surface:
  data-testid="flow-node-circle-<jobId>"  — actual <circle>
  data-testid="flow-region-<regionId>"    — region band frame
  data-testid="flow-stage-<n>"            — stage column divider
  data-testid="flow-edge-<from>-<to>"     — directional edges
  data-testid="flow-deployment-tree"      — left tree
  data-testid="flow-log-feed"             — right log panel

Tests
-----
21 new unit tests in `src/lib/flowLayoutV4.test.ts` lock the layout
contract (multi-region partitioning, cross-region edge classification,
family palette mapping, bezier routing). All 500 vitest tests + tsc
typecheck green.

Per docs/INVIOLABLE-PRINCIPLES.md
---------------------------------
  #1 (waterfall) — full target shape ships in one PR: circular nodes,
                   multi-region bands, bezier edges, log feed,
                   deployment tree, family palette, stage hints.
  #2 (no compromise) — no graph library, no canvas; pure SVG so testids
                       work and the operator can right-click → inspect.
  #4 (never hardcode) — every dimension is in FlowGeometryV4 knobs;
                        every colour comes from the FlowFamily palette
                        (caller-injected, sourced from PRODUCTS).

Closes #251.

Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:32:02 +04:00
..
flow-AFTER-1440px-2026-04-30.png fix(catalyst-ui): rebuild Flow canvas to match provision-mockup-v4.png (#282) 2026-04-30 18:32:02 +04:00
flow-AFTER-dark-1440px-2026-04-30.png fix(catalyst-ui): rebuild Flow canvas to match provision-mockup-v4.png (#282) 2026-04-30 18:32:02 +04:00
flow-BEFORE-1440px-2026-04-30.png fix(catalyst-ui): rebuild Flow canvas to match provision-mockup-v4.png (#282) 2026-04-30 18:32:02 +04:00
mockup-v4.png fix(catalyst-ui): rebuild Flow canvas to match provision-mockup-v4.png (#282) 2026-04-30 18:32:02 +04:00