dashboard: add toc-sidebar utility; move live indicator into TOC column

Extracts the TOC-injection pattern into a reusable component:

  src/components/toc-sidebar.js
    injectTocTop(id, element) — prepends an element to #observablehq-toc,
    removing any previous instance with the same id first so reactive cells
    can re-inject on each poll without accumulating duplicates.

decisions.md now uses injectTocTop to place a single widget (live
indicator + Decision Health KPI box) into the right-column sidebar,
removing the standalone live-indicator cell and the ad-hoc id/remove
pattern that was previously inlined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 14:42:38 +01:00
parent 5b743196db
commit 902aafcfb1
2 changed files with 37 additions and 13 deletions

View File

@@ -103,7 +103,8 @@ function fmtDuration(ms) {
# Decisions
```js
import {withDocHelp} from "./components/doc-overlay.js";
import {withDocHelp} from "./components/doc-overlay.js";
import {injectTocTop} from "./components/toc-sidebar.js";
// ── KPI computation (uses full data, not filtered) ──────────────────────────
const _resolved5 = data
@@ -150,22 +151,16 @@ const _kpiBox = html`<div class="kpi-infobox">
withDocHelp(_kpiBox, "/docs/decisions-kpi");
// ── Inject into the TOC sidebar (right column, non-scrolling) ───────────────
_kpiBox.id = "decisions-kpi-box";
const _toc = document.querySelector("#observablehq-toc");
if (_toc) {
document.getElementById("decisions-kpi-box")?.remove();
_toc.prepend(_kpiBox);
} else display(html`<div style="float:right;width:215px;margin-left:1rem">${_kpiBox}</div>`);
```
```js
display(html`<div class="live-indicator">
// ── Build sidebar widget: live indicator + KPI box ──────────────────────────
const _liveEl = html`<div class="live-indicator">
<span style="color:${_ok ? 'var(--theme-foreground-focus)' : 'red'}">●</span>
${_ok
? `Live · updated ${_ts?.toLocaleTimeString()}`
: html`<span style="color:red">Offline — run: <code>make api</code></span>`}
</div>`);
</div>`;
const _tocInjected = injectTocTop("decisions-sidebar", html`<div>${_liveEl}${_kpiBox}</div>`);
if (!_tocInjected) display(html`<div style="float:right;width:215px;margin-left:1rem">${_liveEl}${_kpiBox}</div>`);
```
## Resolution History