Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 16:24
· 38 commits to main since this release
f742246

Branching Diagram (new component — migrated from ignition-mustry-ui)

Fourteenth component: mustrysolutions.perspective.display.branching — a
left-to-right decision-tree / flow-path renderer, the one real component
in the ignition-mustry-ui repo, absorbed per
docs/branching-component-migration-plan.md (M0+M1 in one pass). Flat
data.nodes in (id/name/category/nextId/colour/icon/tooltip); pure BFS
layout — one column per depth, one row per category rank, re-referenced
nodes pushed forward with their subtree so arrows always point right —
with corridor-aware SVG connector routing, width-responsive column
spacing, Ignition icons, hover info cards, an inferred root
(output.hasRoot) and empty-state labels. Clicking a node writes
state.selectedNode (two-way highlight) and fires onNodeClick {id, name, category}. Ported to house standards: the ~250-line layout
extracted pure into branchingLogic.ts (12 jest cases — the source had
zero tests), React 16 class shell, all CSS namespaced mustry-branch-*
with --brn-* theme vars (source used unprefixed globals like .node),
sectioned config/data/state/output schema fixing the source's drift
(phantom rootId, undeclared nodeBorderWidth), 7-language labels.
A follow-up parity sweep against the source's shipped stylesheet and
README screenshot aligned the look 1:1: nodes CENTRE on their grid
points (connectors pass through disc centres), the label-halo pill
(padding/radius/config.backgroundColor) is back, names are absolutely
centred with the 200px cap, the info card is position:fixed, stays open
while hovered, and renders MARKDOWN again (react-markdown@4 — the
React-16-compatible major, replacing the source's React-18-only v9),
z-index layering and the original defaults (nodeSize 20, offsets 50)
restored. Two deliberate fixes over the source: the label overhang left
of the first column is reserved inside the scroll area (the source let it
spill via overflow: visible; this port scrolls, which would have clipped
it), and the info card gets width: max-content (the source's card shrank
to the ~40px node wrapper — a transformed ancestor is the containing
block for position: fixed — wrapping one word per line). Demo at /branching
(seeded production flow with a rework loop exercising duplicate
forwarding); 3 e2e tests. The source repo should now be archived.

A follow-up enhancement pass added three things, verified by loading BOTH
components (the original module built and installed alongside) on one view:

  • Backward/loop connector fix. The source's split-routing only handled
    forward edges; an edge whose origin sits in a LATER column than its
    target (the QA→Rework rework loop) computed a negative-width SVG that,
    under overflow: visible, painted a stray diagonal + stub. The
    five-segment routing is now a pure, node-tested computeConnector
    (min/max box so width is never negative; backward edges re-routed
    through the column midpoint). The original still shows the artifact; the
    new component no longer does.
  • config.showArrows (default off) — an arrowhead at each connector's
    target, trimmed to the disc edge and auto-oriented, so flow direction
    and loops read at a glance.
  • config.orientation horizontal (default) / vertical — vertical
    lays depth top-to-bottom, category across; label overhang is reserved on
    the cross axis so first-column labels don't clip. Widen config.yOffset
    in vertical mode so horizontal labels don't collide.
    Demos at /branching-arrows and /branching-vertical; +4 jest connector
    cases and +3 e2e tests.

Validation feedback (additive, revertible). When a dataset can't fully
draw, the reason is surfaced instead of a blank canvas: the empty state
distinguishes no-nodes / cycle (no entry point) / generic no-root, and a
new output.warnings (string[]) lists machine-readable issues — no edges,
a cycle, edges to unknown ids, and nodes unreachable from the root (which
the BFS layout silently drops). New config.labels.cyclic (7 languages);
pure diagnose() with 5 jest cases; demo at /branching-cycle; +1 e2e.

Edge labels (additive, revertible). Optional data.edgeLabels
([{from, to, label}]) tags connectors — Yes/No on a decision branch —
matched to existing edges by endpoint ids; edges without an entry stay
bare, so it's inert unless you supply labels. Rendered as a small chip on
the connector mid-point. Demo at /branching-labels (a decision tree);
+1 e2e.

Loop routing + arrow polish. Backward/loop connectors now rise close to
the TARGET instead of at the midpoint — the midpoint often landed on an
intermediate node (the rework loop visibly crossed the QA node); rising near
the target keeps the run clear of it. Arrowheads gained a halo-clearance
trim (the node's pill halo, above the connector layer, was covering the tip)
so they sit at the halo edge on the approach axis. +1 jest case.

BREAKING: full identity rename — "Mustry Perspective Components"

The module sheds the Ingots working name before any real deployments
freeze its identifiers (the sanctioned pre-1.0 window):

  • Repo: mustry-perspective-component-module (was mustry-ingots).
  • Module id: com.mustrysolutions.perspective.components (was
    com.mustrysolutions.ingots) — a gateway sees this as a different
    module
    : uninstall the old one, install the new; there is no in-place
    upgrade across the rename.
  • Component ids: mustrysolutions.perspective.<family>.<name> (was
    mustrysolutions.ingots.…) — views built against the old ids must be
    re-created
    (or their JSON search-replaced). The verify project is
    migrated in this commit and serves as the reference.
  • Display name "Mustry Perspective Components", modl
    Mustry-Perspective-Components.modl, Java packages/hook classes renamed
    to match. The web bundle name (MustryComponents.js), URL alias
    (mustry-components) and CSS prefixes (mustry-*) were already
    brand-level and are unchanged.

Distribution: EULA in the module + branded user manual

The .modl now carries license.html (staged into the module content and
referenced from module.xml — the gateway shows it at install time and
requires acceptance; pattern proven in the AMQP/observability modules).
The ops toolkit seeds acceptance unattended via the CRC32 of license.html
(licenseAgreementHash in modules.json), so ops/e2e.sh --fresh and CI
keep working headlessly. NOTE: the EULA text is a first draft modeled on
the observability module's — review before any public distribution.
Releases now also attach a branded user-manual PDF built from
docs/user_manual.md by scripts/build_manual_pdf.sh (Mustry fonts,
generated cover, footer stamping — pipeline ported from the observability
module), with real component screenshots in docs/images/.

Admin family: per-row ⋯ menu with Duplicate

Every admin rail row gains a ⋯ menu — hover-revealed for mouse users and
ALWAYS visible on the selected row so touch users reach it with one tap
(hover-only affordances don't exist on touch, which is why bare hover
delete icons were rejected). It holds Duplicate (enters the existing
create flow prefilled from the source — "Day Shift (copy)", or
"jdoe-copy" dash-style for usernames — so Save fires the usual
isNew: true event and NO new events were needed) and Delete
(two-step confirm inside the menu, works on any row without selecting
it; deleting the selected row clears the selection). Duplicating a user
copies roles/schedule/contacts/adjustments but never the password;
duplicating an alternating schedule copies week A. Gated by the existing
allowCreate (duplicate) / allowDelete (delete) flags. New shared
RowMenu + labels (7 languages, moreActions/duplicate override keys
across all four components).