frontend: add <hive-tab-strip>, convert logs/credentials/core/builds tabbars

Every sub-page tabbar (logs.html, credentials.html, core.html,
builds.html) hand-wrote the same <nav class="hive-tabbar"><a
class="hive-tab">...</a></nav> boilerplate and then called
createTabStrip() on it after the fact. Add <hive-tab-strip>, a
markup-owning custom element (same reuse-boundary pattern as
<hive-menu>/<hive-side-panel>) that renders that markup from a
declarative tabs list, then wires the existing createTabStrip()
behaviour over what it just rendered — no behaviour duplication.

Convert all four sites to use it: each page's JS now calls
`.configure({ tabs, defaultId, onShow })` on the tabbar element instead
of `createTabStrip(el, opts)`, and configure() returns the identical
{ show, active } shape so nothing downstream changes. builds.js's
rebuild-queue count pill (builds-tab-count-rebuild) is expressed as a
tab's `badgeId` and renders nested in the same spot.

The dashboard's own tabbar and the two no-pane stats time-range
pickers are a different markup/behaviour shape and are intentionally
left alone.
This commit is contained in:
iris 2026-08-02 04:00:40 +02:00 committed by mara
commit 435ef193e1
10 changed files with 103 additions and 75 deletions

View file

@ -21,7 +21,7 @@
import { $, esc, fmtAgeSecs, renderServerWarnings } from './common.js';
import { el } from '@hive/shared/dom.js';
import { createTabStrip } from '@hive/shared/tabs.js';
import '@hive/shared/hive-tab-strip.js';
import { themedConfirm, themedToast } from '@hive/shared/modal.js';
let agents = [];
@ -507,7 +507,12 @@ async function init() {
$('gh-form').addEventListener('submit', submitGithub);
$('ef-form').addEventListener('submit', submitForgeAccount);
createTabStrip(document.getElementById('cred-tabbar'), {
document.getElementById('cred-tabbar').configure({
tabs: [
{ id: 'matrix', label: 'MATRIX' },
{ id: 'github', label: 'GITHUB' },
{ id: 'forges', label: 'FORGES' },
],
defaultId: 'matrix',
});