Skip to content

feat: designer-facing card flags, deduped property chips, readable auto-fit, zone geometry - #12

Open
timurbazhirov wants to merge 7 commits into
mainfrom
claude/designer-card-flags-and-zone-geometry
Open

feat: designer-facing card flags, deduped property chips, readable auto-fit, zone geometry#12
timurbazhirov wants to merge 7 commits into
mainfrom
claude/designer-card-flags-and-zone-geometry

Conversation

@timurbazhirov

@timurbazhirov timurbazhirov commented Aug 16, 2026

Copy link
Copy Markdown
Member

Five wove-owned fixes from the workflow designer UX review (SOF-8024, mat3ra/workflow-designer#12). Each stands alone.

1. Flowchart IDs hidden behind showDeveloperInfo (default off)

CardHeader printed the flowchart UUID under every unit and subworkflow card. It identifies nothing to a person reading a card, and it consumes the entire subheader — it was the single most repeated element on the designer screen. Now off by default; hosts expose it behind a "developer info" toggle.

2. showStatus gates the run-status badge

Status belongs to a job's execution. In a designer, every unit is perpetually "idle", so the badge is pure noise. Threaded through UnitCard, WorkflowUnitCard, WorkflowUnitsFlowchart, UnitsFlowchartContainer and the react-flow NodeData so a designer can switch it off while job views keep it (default stays true — no change for existing consumers).

3. Property chips deduped and humanized

Several units in one subworkflow commonly report the same property (an scf and an nscf step both yield fermi_energy), and the subworkflow lists every occurrence — so the same chip rendered twice with nothing to tell the copies apart. Now deduped, with total_energy → "Total energy" and the raw key kept as the tooltip.

4. Auto-fit clamped to a readable zoom

fitView shrank long workflows until unit names were illegible — a ten-unit subworkflow landed around 6px type, on a canvas that was mostly empty grid anyway. Auto-fit now stops at a legible scale and lets the result scroll.

5. Brillouin zone geometry passed to the injected component

This addresses the standing TODO in context/utils.tsx:

Do not hardcode web-app public paths here (/images/brillouin_zone/...) … so wove stays path-agnostic.

imgSrc points at an asset that ships in no package — only the web app serves it, so every other consumer renders a broken image (confirmed 404 in the workflow-designer demo), and the absolute path cannot resolve under a non-root deployment base. One image per lattice type is lossy besides: a graphene monolayer and bulk GaN are both HEX, but the monolayer's vacuum padding flattens its zone.

ExtraImportantSettingsByContextProvider now also passes faces — the zone derived from the material's own reciprocal lattice — so components can draw it. Feature-detected against ReciprocalLattice.brillouinZone (mat3ra/made#295), so older made pins keep building and simply fall back to imgSrc; imgSrc is unchanged for hosts that do serve the artwork. Renderer: mat3ra/move#5.

Validation

  • Tests: npm test31 passing (3 new: zone geometry forwarded with the right face counts for FCC, and property-name humanizing).
  • Types: tsc --noEmit clean on src.
  • Lint: on the 13 source files this PR touches, this branch reports 34 errors / 40 warnings versus main's 41 / 39 — no new problems, and 7 fewer errors than before (running prettier over the touched files cleaned up existing formatting). The new test file is lint-clean; the single remaining error in extraImportantSettings.tests.tsx (@mat3ra/utils listed as extraneous) is pre-existing on main.
  • Demo: verified in wove's own standalone demo — unit cards render without UUIDs, everything else unchanged.

Note for maintainers: npm run lint cannot run from a clean checkout

package.json declares no eslint, prettier, or @exabyte-io/eslint-config dependencies, though .eslintrc.json extends that config and the lint script invokes both tools. To lint this branch I had to install the toolchain explicitly; the working combination is eslint 8 + eslint-plugin-prettier 5 + prettier 3 (plugin-prettier 4 breaks on prettier 3, and eslint 9+ rejects .eslintrc.json). Separately, main itself does not pass prettier --check src (6 files). Happy to open a small follow-up PR adding the devDependencies and formatting those files if that's wanted — kept out of this one deliberately.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV

claude added 2 commits August 16, 2026 20:54
…to-fit

Five changes the workflow designer needs from wove, from a UX review of
the designer (mat3ra/workflow-designer#12, SOF-8024):

- CardHeader: hide the flowchart ID behind showDeveloperInfo (now off by
  default). A UUID under every unit identifies nothing to a person
  reading a card and costs the whole subheader.
- CardHeader: showStatus gates the run-status badge, threaded through
  UnitCard, WorkflowUnitCard and the react-flow node data so a designer
  can turn it off. Status belongs to a job's execution; in a designer
  every unit is perpetually idle.
- Properties: dedupe property chips and humanize the labels
  (total_energy -> Total energy), keeping the raw key as the tooltip.
  Units within a subworkflow commonly report the same property, so the
  same chip rendered twice with nothing to tell the copies apart.
- UnitsFlowchart: clamp auto-fit at a legible zoom instead of shrinking
  a long workflow until its unit names are unreadable.
- ExtraImportantSettingsByContextProvider: pass Brillouin zone geometry
  derived from the material's own reciprocal lattice alongside imgSrc,
  addressing the TODO about hardcoded web-app image paths. The asset
  those paths point at ships in no package, so every consumer but the
  web app renders a broken image. Feature-detected, so older made pins
  keep building and fall back to imgSrc.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Sort imports and mark the injected component prop as intentional for
react/jsx-no-bind — it takes a component, not an event handler.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The allowlist named kpath, qpath and explicitKPath, leaving out ipath and
explicitKPath2PIBA — the other two subclasses of wode's PointsPathFormDataProvider.
Phonon Dispersions and both GW band-structure workflows therefore rendered a k-path
form with no zone beside it.

Adds the missing names and a test that walks all five, so the next one added upstream
fails here rather than silently losing its picture.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
claude added 4 commits August 17, 2026 07:09
The unit card's resting border was the literal string "white". It is meant to be
invisible — it reserves the width the selected border takes, so selecting a card does
not shift it — and white is only invisible on a white surface. On a dark canvas every
unselected card wore a bright 4px frame. It now follows the surface the card sits on.

The flowchart's dot grid was likewise a hardcoded near-black "000", invisible on a dark
background; it reads the canvas token.

Both prefer `theme.designer.*` (cove#98) and fall back to what they resolved to before,
so this works against the currently published cove and improves when the new one lands.

The colour choice moved into `getUnitCardBorderColors` so it can be asserted rather than
screenshotted: five tests cover light, dark, with and without the tokens, and that the
resting and selected colours never coincide.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
With the flowchart ID hidden — it identifies nothing to a person reading a card — the
subheader was empty, so a canvas showed unit names and nothing else. A card now states
the engine and the flavor it runs: "espresso 6.3 · pw_scf", which is what separates
pw_scf from pw_bands at a glance. The flavor is preferred over the executable, since
every espresso unit of a workflow runs the same pw.x.

Alongside it, the unit type's own icon, tinted with the type accent. Colour is not the
only signal of a unit's kind that way — colour-vision deficiency and greyscale both
flatten the accent stripe, the icon survives them. Types cove ships no glyph for fall
back rather than rendering blank.

CardHeader also takes `isModified`, drawn as a small dot beside the name, for hosts that
can derive it from `provider.isEdited`; it prefers `theme.designer.state.modified`
(cove#98) and falls back to the palette's warning colour.

Part of SOF-8024 portion 5, item 1.2. The edge "+" insert affordance from the same item
is not here — it needs the canvas work portion 5 still owes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
…flags-and-zone-geometry

# Conflicts:
#	dist/components/common/CardHeader.d.ts
#	dist/components/common/CardHeader.js
#	dist/components/reactflow/customNodes/UnitNode.js
#	dist/components/reactflow/hooks/useNodeData.d.ts
#	dist/components/reactflow/hooks/useNodeData.js
#	dist/components/reactflow/hooks/useTransformUnitsToNodesAndEdges.d.ts
#	dist/components/reactflow/hooks/useTransformUnitsToNodesAndEdges.js
#	dist/components/subworkflows/Properties.d.ts
#	dist/components/subworkflows/Properties.js
#	dist/components/units/UnitCard.d.ts
#	dist/components/units/UnitCard.js
#	dist/components/units/UnitCard.styled.d.ts
#	dist/components/units/UnitCard.styled.js
#	dist/components/units/UnitsFlowchart.d.ts
#	dist/components/units/UnitsFlowchart.js
#	dist/components/units/UnitsFlowchartContainer.d.ts
#	dist/components/units/UnitsFlowchartContainer.js
#	dist/components/units/types.d.ts
#	dist/components/units/utils.d.ts
#	dist/components/units/utils.js
#	dist/components/workflows/WorkflowUnitCard.d.ts
#	dist/components/workflows/WorkflowUnitCard.js
#	dist/components/workflows/WorkflowUnitsFlowchart.d.ts
#	dist/components/workflows/WorkflowUnitsFlowchart.js
#	dist/context/utils.d.ts
#	dist/context/utils.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants