frontend: drop the Panel forwarding object and the side-panel-body compat class
Per mara's review: '2 and maybe 1, but 3 also sounds reasonable on first
glance' (against 3 options I posted). Doing 2 and 1, leaving open()/
openNamed() as-is (option 3, tentative only).
Both dashboard/common.js and agent/app.js now export/use the
<hive-side-panel> element instance directly (sidePanel) instead of a
thin Panel = { open, openNamed, refresh, close } object that existed
purely to keep the old call-site shape unchanged. All 6 real call sites
updated to call the element's own methods directly.
The .side-panel-body class each wrapper stamped onto its own instance,
purely so common.css/agent.css's pre-existing content-styling selectors
kept matching, is gone too -- those selectors now use the element's own
tag name as the root (hive-side-panel .md, hive-side-panel .agent-inbox),
which already uniquely identifies the light-DOM instance without a
compatibility class. Verified via headless Chromium/CDP that the
tag-name selectors resolve correctly with no class needed.
Drive-by: removed an unrelated dead Panel import in call.js.
This commit is contained in:
parent
996899fcad
commit
399a837e17
8 changed files with 73 additions and 90 deletions
|
|
@ -901,10 +901,10 @@ pre.diff {
|
|||
element's own shadow tree) and the styling for the panel's own
|
||||
content types, which the shared element's shadow tree can never
|
||||
reach (see @hive/shared/side-panel/hive-side-panel.css's header
|
||||
comment). `.side-panel-body` below is the compatibility class
|
||||
app.js's `Panel` wrapper puts directly on its `<hive-side-panel>`
|
||||
instance so these rules keep reaching the slotted content by
|
||||
ordinary light-DOM descendant matching. */
|
||||
comment). The `hive-side-panel .agent-inbox …` rules below use the
|
||||
element's own tag name as the selector root — no compatibility class
|
||||
needed, the tag name already uniquely identifies the light-DOM
|
||||
instance app.js's `sidePanel` creates. */
|
||||
body.side-panel-resizing {
|
||||
user-select: none;
|
||||
}
|
||||
|
|
@ -913,12 +913,12 @@ body.side-panel-resizing * { cursor: ew-resize !important; }
|
|||
legacy <details>-collapsible variant of .agent-inbox is gone, so
|
||||
here we strip the inbox-only chrome (background, border-left) and
|
||||
let the panel body's own padding own the framing. */
|
||||
.side-panel-body .agent-inbox {
|
||||
hive-side-panel .agent-inbox {
|
||||
margin: 0;
|
||||
font-size: inherit;
|
||||
color: var(--fg);
|
||||
}
|
||||
.side-panel-body .agent-inbox ul {
|
||||
hive-side-panel .agent-inbox ul {
|
||||
background: transparent;
|
||||
border-left: 0;
|
||||
padding: 0;
|
||||
|
|
|
|||
|
|
@ -38,26 +38,17 @@ window.marked = marked;
|
|||
bindAsyncForms(() => refreshState());
|
||||
|
||||
// ─── side panel (singleton drawer for inbox + loose-ends flyouts) ──────
|
||||
// Thin wrapper around the shared `<hive-side-panel>` element (see
|
||||
// @hive/shared/side-panel.js) — created once, eagerly, when this
|
||||
// The shared `<hive-side-panel>` element (see @hive/shared/side-panel.js
|
||||
// for the chrome/behavior it owns), created once, eagerly, when this
|
||||
// module's IIFE runs (ES modules execute after the document is
|
||||
// parsed, so `document.body` already exists; no per-call lazy-init
|
||||
// guard to remember for any method, present or future). This UI's
|
||||
// `open(name, title, content)` always takes an owner name, so it maps
|
||||
// straight onto the shared element's `openNamed`; `side-panel-body`
|
||||
// is a plain compatibility class this wrapper puts on its own
|
||||
// instance so `agent.css`'s existing `.side-panel-body .agent-inbox
|
||||
// …` rules keep reaching the slotted content by ordinary light-DOM
|
||||
// descendant matching.
|
||||
const panelEl = document.createElement('hive-side-panel');
|
||||
panelEl.classList.add('side-panel-body');
|
||||
document.body.append(panelEl);
|
||||
const Panel = {
|
||||
open: (name, title, content) => panelEl.openNamed(name, title, content),
|
||||
close: () => panelEl.close(),
|
||||
refresh: (name, title, content) => panelEl.refresh(name, title, content),
|
||||
currentOwner: () => panelEl.currentOwner(),
|
||||
};
|
||||
// parsed, so `document.body` already exists). Used directly — this
|
||||
// UI's opens always take an owner name, so call sites use the
|
||||
// element's own `openNamed(name, title, content)` rather than the
|
||||
// untyped `open`. `agent.css` reaches the slotted content via a plain
|
||||
// `hive-side-panel .agent-inbox …` tag-name selector (no compat class
|
||||
// needed — the element's own tag name already identifies it).
|
||||
const sidePanel = document.createElement('hive-side-panel');
|
||||
document.body.append(sidePanel);
|
||||
|
||||
// Wire the header pills to open the side panel. Pre-built (vs
|
||||
// re-building per-click) so the freshest snapshot already lives
|
||||
|
|
@ -67,14 +58,14 @@ window.marked = marked;
|
|||
const inboxPill = $('inbox-pill');
|
||||
if (inboxPill) {
|
||||
inboxPill.addEventListener('click', () => {
|
||||
Panel.open('inbox', 'inbox · ' + lastInbox.length,
|
||||
sidePanel.openNamed('inbox', 'inbox · ' + lastInbox.length,
|
||||
buildInboxList(lastInbox));
|
||||
});
|
||||
}
|
||||
const todosPill = $('todos-pill');
|
||||
if (todosPill) {
|
||||
todosPill.addEventListener('click', () => {
|
||||
Panel.open('todos', 'todos · ' + lastTodos.length,
|
||||
sidePanel.openNamed('todos', 'todos · ' + lastTodos.length,
|
||||
buildTodosList(lastTodos));
|
||||
});
|
||||
}
|
||||
|
|
@ -336,7 +327,7 @@ window.marked = marked;
|
|||
else closeOverflowMenu();
|
||||
}
|
||||
// Wire once on boot. The trigger itself + click-outside + Escape
|
||||
// dismissal pattern matches the side-panel flyout (Panel).
|
||||
// dismissal pattern matches the side-panel flyout (sidePanel).
|
||||
(function bindOverflowMenu() {
|
||||
const btn = $('overflow-btn');
|
||||
if (!btn) return;
|
||||
|
|
@ -807,7 +798,7 @@ window.marked = marked;
|
|||
function buildLooseEndsList(threads) {
|
||||
// Returns the <div> the side panel renders. The structural shape
|
||||
// mirrors the legacy <details>-collapsible block — same CSS rules
|
||||
// apply via `.side-panel-body .agent-inbox`.
|
||||
// apply via `hive-side-panel .agent-inbox`.
|
||||
const wrap = el('div', { class: 'agent-inbox' });
|
||||
if (!threads.length) {
|
||||
wrap.append(el('p', { class: 'side-panel-empty' },
|
||||
|
|
@ -907,7 +898,7 @@ window.marked = marked;
|
|||
const count = $('todos-count');
|
||||
if (count) count.textContent = todos.length;
|
||||
if (pill) pill.hidden = todos.length === 0;
|
||||
Panel.refresh('todos', 'todos · ' + todos.length,
|
||||
sidePanel.refresh('todos', 'todos · ' + todos.length,
|
||||
buildTodosList(todos));
|
||||
}
|
||||
|
||||
|
|
@ -1073,7 +1064,7 @@ window.marked = marked;
|
|||
const count = $('inbox-count');
|
||||
if (count) count.textContent = rows.length;
|
||||
if (pill) pill.hidden = rows.length === 0;
|
||||
Panel.refresh('inbox', 'inbox · ' + rows.length, buildInboxList(rows));
|
||||
sidePanel.refresh('inbox', 'inbox · ' + rows.length, buildInboxList(rows));
|
||||
}
|
||||
// Harness reachability badge: derived from the same `s.status` the
|
||||
// status block reads. Each status maps to a glyph + label + colour
|
||||
|
|
|
|||
Loading…
Reference in a new issue