jobq-graph: replace the dep-edge gutter rail with a plain text line

mara reported the rail still didn't make dependencies visible
(screenshot on the PR). Root cause: the rail spans by sibling-array
position, but a sibling with its own nested subtree renders many
pixel-rows for one array slot -- in a real queue (agent_window with
7-ish children between two top-level siblings), the "line" breaks
into disconnected ticks around every real subtree, never reading as
a connection at all. My verification fixtures never tested a nested
subtree sitting between two related siblings, so this never showed up
before.

Replaced with a "waits on: <label>" text line under the dependent
node, resolved once in buildTree via a global id lookup (not scoped to
siblings, so a label still resolves even if a dep ever does cross a
group boundary despite the product decision that it shouldn't). Text
has no positional-gap failure mode: it's legible regardless of how
tall the node above or below it renders. No reordering, no rail, no
interleaving-of-independent-pairs class of bug possible anymore --
this is close to the original design proposed on the issue before the
heavier visual version was tried.

Re-verified against 6 fixture checks including the exact shape from
the screenshot (a dependency target with its own nested subtree
rendered between it and the dependent node).
This commit is contained in:
iris 2026-08-09 17:12:48 +02:00 committed by mara
commit a858739b28
2 changed files with 38 additions and 168 deletions

View file

@ -36,37 +36,6 @@
flex-wrap: wrap;
}
/* Dependency-edge gutter (only present on rows in a sibling list that has
at least one `Node`-kind dep among it see hive-jobq-graph.js
`renderGroup`). A plain rail (no line, no dot) on every other row in
that list keeps the state glyph aligned; rows outside such a list carry
no rail element at all, so the common case is untouched. */
.jg-edge-rail {
position: relative;
align-self: stretch;
flex: none;
width: 0.7em;
}
.jg-edge-rail.jg-edge-on::after {
content: '';
position: absolute;
left: 50%;
top: var(--jg-rail-top, 50%);
bottom: var(--jg-rail-bottom, 50%);
width: 0;
border-left: 2px solid var(--cyan);
}
.jg-edge-rail.jg-edge-dot::before {
content: '';
position: absolute;
left: calc(50% - 0.19em);
top: calc(50% - 0.19em);
width: 0.38em;
height: 0.38em;
border-radius: 50%;
background: var(--cyan);
}
.jg-state {
font-weight: bold;
min-width: 1.2em;
@ -95,6 +64,12 @@
.jg-data dt { font-weight: 600; }
.jg-data dd { margin: 0; word-break: break-word; }
.jg-waits-on {
margin: 0.1em 0 0 1.6em;
font-size: 0.85em;
color: var(--cyan);
}
.jg-error {
color: var(--red);
font-size: 0.85em;