From dfd92a7da943cf3fde14c60cc801167cb03e4d43 Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 3 Aug 2026 18:21:01 +0200 Subject: [PATCH] frontend: shared component for inline warning banners Consolidates three independently-written instances of the same thing: .cred-warning (credentials.html, static markup), .tombstone-warn (core.js, JS-built), .port-conflict (swarm.js, JS-built) -- the first two differed only by an undeliberate 10% vs 8% tint, the strongest argument this was drift rather than three genuinely different needs. New autonomous custom element, frontend/packages/shared/src/hive-warn/, matching the established one-component-one-dir shadow-DOM pattern (hive-btn, hive-toast, hive-dialog). Purely presentational -- no lifecycle beyond attaching its shadow root once, no attributeChangedCallback needed since severity/pulse are read directly by :host([...]) CSS selectors rather than mirrored onto an inner element. Content passes through via a single default , so every call site keeps writing its existing / markup unchanged. API: (amber, default) / for an active incident vs a standing caveat, plus an opt-in pulse boolean modifier (only the port-collision banner wants it -- a banner that's always present and always pulsing just trains you to stop seeing it). Tint is a single canonical 8% for both severities now, replacing the 10%/8% split. Registered once in dashboard's common.js (same side-effect-import pattern as ) so every dashboard page picks it up without a per-file import, since all three call sites (core.js, swarm.js, credentials.js) already transitively import it. Verified: npm run build clean for both dashboard and agent packages, grepped source for leftover cred-warning/tombstone-warn/port-conflict references (none), confirmed hive-warn/HiveWarn/hive-warn-pulse present in every affected dist bundle, confirmed the still-live questions-pulse keyframe (.questions) untouched. --- frontend/packages/dashboard/src/common.js | 1 + frontend/packages/dashboard/src/core.js | 2 +- .../packages/dashboard/src/credentials.css | 9 ---- .../packages/dashboard/src/credentials.html | 4 +- frontend/packages/dashboard/src/dashboard.css | 33 +++---------- frontend/packages/dashboard/src/swarm.js | 2 +- frontend/packages/shared/package.json | 1 + .../shared/src/hive-warn/hive-warn.css | 49 +++++++++++++++++++ .../shared/src/hive-warn/hive-warn.js | 37 ++++++++++++++ 9 files changed, 99 insertions(+), 39 deletions(-) create mode 100644 frontend/packages/shared/src/hive-warn/hive-warn.css create mode 100644 frontend/packages/shared/src/hive-warn/hive-warn.js diff --git a/frontend/packages/dashboard/src/common.js b/frontend/packages/dashboard/src/common.js index 6d34c7a7..7637d161 100644 --- a/frontend/packages/dashboard/src/common.js +++ b/frontend/packages/dashboard/src/common.js @@ -6,6 +6,7 @@ import { linkify as termLinkify } from '@hive/shared/terminal.js'; import { el } from '@hive/shared/dom.js'; import '@hive/shared/side-panel.js'; // registers — side-effect import +import '@hive/shared/hive-warn.js'; // registers — side-effect import import DOMPurify from 'dompurify'; // ─── helpers ──────────────────────────────────────────────────────────── diff --git a/frontend/packages/dashboard/src/core.js b/frontend/packages/dashboard/src/core.js index 3f056d6c..f0bc9e8f 100644 --- a/frontend/packages/dashboard/src/core.js +++ b/frontend/packages/dashboard/src/core.js @@ -50,7 +50,7 @@ function renderTombstones(s) { // Wording is deliberately about what the list *is* rather than what it // isn't: nothing records a destroy, so "container absent" is the only thing // the backend can actually tell. - const warn = el('p', { class: 'tombstone-warn' }); + const warn = el('hive-warn', {}); warn.append( el('strong', {}, 'shows every agent whose container is absent'), ' — not only destroyed ones. An agent part-way through being spawned ' + diff --git a/frontend/packages/dashboard/src/credentials.css b/frontend/packages/dashboard/src/credentials.css index fc1a9f13..becd1d94 100644 --- a/frontend/packages/dashboard/src/credentials.css +++ b/frontend/packages/dashboard/src/credentials.css @@ -27,15 +27,6 @@ body.cred-shell { .cred-pane[hidden] { display: none; } -.cred-warning { - border: 1px solid var(--amber); - border-radius: 4px; - padding: 0.7rem 0.9rem; - margin: 0.6rem 0 1.1rem; - font-size: 0.9rem; - background: color-mix(in srgb, var(--amber) 10%, transparent); -} - .gh-status { margin: 0.5rem 0 1.2rem; } .gh-status-line { display: flex; diff --git a/frontend/packages/dashboard/src/credentials.html b/frontend/packages/dashboard/src/credentials.html index c30ac25a..98042d12 100644 --- a/frontend/packages/dashboard/src/credentials.html +++ b/frontend/packages/dashboard/src/credentials.html @@ -90,7 +90,7 @@ Security-warning banner + a link to generate a PAT. -->