Watch
0
0
Fork
You've already forked hyperhive
0

hive ui: remove the counters on the tabs

The pills on 4G3NTS, R3BU1LD QU3U3 and K3PT ST4T3, the poll that fed them, the
two count helpers, their styles, and the tab strip's unused badge option.
This commit is contained in:
iris 2026-11-01 15:37:33 +01:00
commit a781addcfe
5 changed files with 7 additions and 93 deletions

View file

@ -247,21 +247,6 @@ function renderRebuildLiveLog() {
);
}
// ─── rebuild-queue count pill ─────────────────────────────────────────────────
// The queue's in-flight count, for the R3BU1LD QU3U3 tab's pill (tabs.js
// reads it on its refresh tick). Pending/Running/Finishing = in flight
// (Finishing = own work done, a sub-node still running — still counts).
// Root nodes only: each is one queue entry.
export function rebuildCount() {
return jobqNodes.filter(
(n) =>
n.parent == null &&
(n.state === "Pending" ||
n.state === "Running" ||
n.state === "Finishing"),
).length;
}
// ─── BUILD L0GS tab ───────────────────────────────────────────────────────────
// All-agents build log history with expand-to-detail. Live builds stream in
// real time. Lazy-loaded on first tab activation; auto-refreshes (debounced

View file

@ -12,8 +12,7 @@
/* ─── tabbed dashboard chrome ──────────────────────────────────────
Top-of-page sticky header with banner + tab strip. SSE stays
alive across tab switches so count pills update live on inactive
tabs. See docs/web-ui/dashboard.md::Chrome header + Tab strip for the
alive across tab switches. See docs/web-ui/dashboard.md::Chrome header + Tab strip for the
routing model. */
body.dashboard-shell {
@ -112,23 +111,6 @@ body.dashboard-shell {
font-weight: bold;
white-space: nowrap;
}
.tab-count {
display: inline-block;
background: var(--purple-dim);
color: var(--purple);
border-radius: 999px;
padding: 0 0.55em;
min-width: 1.6em;
text-align: center;
font-size: 0.82em;
font-variant-numeric: tabular-nums;
font-weight: bold;
}
/* `display` above beats the UA's `[hidden]` rule, so an empty count (the
4G3NTS and R3BU1LD QU3U3 pills at zero) would otherwise draw a "0". */
.tab-count[hidden] {
display: none;
}
/* Tab pane visibility — createTabStrip (@hive/shared/tabs.js) sets the
`hidden` attribute on every inactive pane (resolved from the URL hash;

View file

@ -27,7 +27,6 @@
data-tab="agents"
>
<span class="tab-label">◆ 4G3NTS ◆</span>
<span class="tab-count" id="tab-count-agents" hidden></span>
</a>
<!-- The build lifecycle is two tabs here (builds.js): the rebuild
queue with its live log, and the build log history. Kept state
@ -41,7 +40,6 @@
data-tab="rebuild"
>
<span class="tab-label">◆ R3BU1LD QU3U3 ◆</span>
<span class="tab-count" id="tab-count-rebuild" hidden></span>
</a>
<a
@ -63,7 +61,6 @@
data-tab="kept"
>
<span class="tab-label">◆ K3PT ST4T3 ◆</span>
<span class="tab-count" id="tab-count-kept" hidden></span>
</a>
<!-- (Peer hives are no longer a tab — they render as a headline

View file

@ -23,11 +23,6 @@ const fmtAgeDays = (ts) => {
return d + " days ago";
};
/** Number of kept-state entries, for the tab's count pill. */
export function keptCount() {
return tombstonesState.length;
}
export function syncKeptFromSnapshot(s) {
tombstonesState = (s.tombstones || []).slice();
}

View file

@ -28,11 +28,9 @@ import {
initBuilds,
onBuildsTabShown,
onRebuildQueueChanged,
rebuildCount,
} from "./builds.js";
import {
applyTombstonesChanged,
keptCount,
renderKept,
syncKeptFromSnapshot,
} from "./kept.js";
@ -286,41 +284,6 @@ import { renderUserMenu } from "./user-menu.js";
// (default 4G3NTS), toggles the active tab/pane + aria-selected, and
// fires activateTab for the per-tab side-effects on every change.
createTabStrip($("tabbar"), { defaultId: "agents", onShow: activateTab });
// The rebuild queue mounts now, not on first show, so its tab's count pill
// is live from the start.
// The rebuild queue mounts now, not on first show.
initBuilds();
// Tab count pills — pure derived data from the existing state
// stores so SSE-driven updates flow through without extra plumbing.
// Set `hidden` when the count is zero so the pill doesn't draw
// attention to an empty room.
function setTabCount(tab, n) {
const el_ = $("tab-count-" + tab);
if (!el_) return;
el_.textContent = String(n);
el_.hidden = n <= 0;
}
/** Recompute every tab's count from the current state. Called on
* every renderXxx that's tab-relevant. */
function refreshTabCounts() {
// 4G3NTS — flag any container that's stale (needs_update). Empty
// when everyone's current. Container-row pulse signals state
// transitions; the pill catches "deploy-pending" specifically.
let stale = 0;
for (const c of containersState.values()) {
if (c.needs_update) stale++;
}
setTabCount("agents", stale);
// R3BU1LD QU3U3 — rebuilds in flight.
setTabCount("rebuild", rebuildCount());
// K3PT ST4T3 — entries of kept state.
setTabCount("kept", keptCount());
}
// Poll the state stores on a 1s tick to keep the pill counts in
// sync. The state stores are mutated synchronously by every SSE
// event + refreshState call, so polling them is correct and cheap
// — no per-renderer hookup needed.
refreshTabCounts();
setInterval(refreshTabCounts, 1000);
})();