From 7908332168eebb4eb1d3c9dcac1e0be80bf16386 Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 27 Jul 2026 20:41:35 +0200 Subject: [PATCH] frontend: render Skipped node state as a quiet 'not run' glyph MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes hyperhive#2788. State::Skipped now rides the wire (per hive-host-sock's dag_view, no longer filtered) — this was the last missing piece: the frontend had no glyph for it, so a skipped node's per-node chip fell through to QUEUE_STATE_GLYPH's '?' fallback. Added a 'skipped' entry (·, same quiet glyph hivectl already uses for the same state — no contract between them, just consistent taste) and a .rqe-node-skipped CSS rule (dimmed only, no strikethrough — deliberately distinct from .rqe-node-cancelled: a skipped node wasn't dropped mid-flight, it was never going to run, so it should read as expected/quiet rather than alarming). rollupState's defensive arm (every(n => skipped || done) => done) already landed in #2799 and needed no changes here. buildNodeTree has no state-based filtering, so skipped nodes render in the tree exactly like any other node kind — no other changes needed. Verified with a full frontend build; nix fmt clean. --- frontend/packages/dashboard/src/builds.js | 8 ++++++++ frontend/packages/dashboard/src/system-sections.css | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/frontend/packages/dashboard/src/builds.js b/frontend/packages/dashboard/src/builds.js index 59eed2f7..848694c2 100644 --- a/frontend/packages/dashboard/src/builds.js +++ b/frontend/packages/dashboard/src/builds.js @@ -157,6 +157,14 @@ const QUEUE_STATE_GLYPH = { done: '✔', failed: '✖', cancelled: '⊘', + // Not-taken branch of an outcome split (e.g. the failure tail on a + // successful deploy) — expected, not an error, so a quiet glyph rather + // than an attention-grabbing one. Only ever visible while the owning + // DAG is still live/failed — a fully-settled green DAG drops off the + // wire entirely (see hive-host-sock::jobs::dag_view). Same glyph + // hivectl uses for the same state (no contract between them, just + // consistent taste). + skipped: '·', }; function firstFailedNode(entry) { diff --git a/frontend/packages/dashboard/src/system-sections.css b/frontend/packages/dashboard/src/system-sections.css index 1f848ac5..131979a8 100644 --- a/frontend/packages/dashboard/src/system-sections.css +++ b/frontend/packages/dashboard/src/system-sections.css @@ -210,6 +210,10 @@ .rqe-node-done { color: var(--green); border-color: color-mix(in srgb, var(--green) 45%, transparent); } .rqe-node-failed { color: var(--red); border-color: var(--red); } .rqe-node-cancelled { opacity: 0.55; text-decoration: line-through; } +/* Not-taken outcome branch — expected, quiet, distinct from cancelled + (dimmed only, no strikethrough: this wasn't dropped mid-flight, it was + never going to run). */ +.rqe-node-skipped { opacity: 0.5; } .rqe-node-arrow { color: var(--muted); } .rqe-node-log { margin-left: 0.1em; text-decoration: none; }