docs: retire the stray top-level web-ui.md, fold it into web-ui/README.md
docs/web-ui.md duplicated the web-ui/ directory name at the top level -- the only such collision in docs/ (every other subsystem has just a directory, no sibling <dir>.md file). That's exactly why it rendered outside the directory structure in the docs site nav (mara's report, hyperhive#4054): the site build walks docs/ generically with no special-casing, so a loose top-level file next to a same-named directory shows up as its own flat top-level entry instead of nesting under that directory's section. web-ui.md's own first paragraph already said as much -- 'This doc has been split for readability... start at web-ui/README.md instead.' It was a leftover pointer from before the split, not a page carrying unique content on its own merit. Folded its two sections web-ui/README.md didn't already have (the swarm-ui design-guide link, and the task-oriented 'reading paths' quick-lookup list) into web-ui/README.md's existing 'More depth' section, then deleted the stray file and repointed every real reference at it: 3 in-tree doc cross-links, 3 doc prose mentions (retargeted to the more specific dashboard.md/shape.md sub-page each one was actually about), and ~28 frontend source comments (dashboard/agent/shared packages) that cited it as 'docs/web-ui.md::<heading>' for implementation context -- retargeted each to whichever of dashboard.md/shape.md/agent.md actually carries that heading now, verified against each file's real heading list rather than guessed. Verified via scripts/check-doc-refs.sh (the same lint CI runs): 0 dead pointers, both before write (confirming the tree was clean beforehand) and after (confirming nothing broke).
This commit is contained in:
parent
18de4b48c7
commit
77296aff35
21 changed files with 74 additions and 96 deletions
|
|
@ -448,7 +448,7 @@ Two visible consequences:
|
||||||
on every `rebuild_queue_changed` tick), not on the approvals panel
|
on every `rebuild_queue_changed` tick), not on the approvals panel
|
||||||
(which already moved the row to "approved"). A long meta-update
|
(which already moved the row to "approved"). A long meta-update
|
||||||
cascade renders as a parent DAG with one child rebuild per affected
|
cascade renders as a parent DAG with one child rebuild per affected
|
||||||
agent — see `docs/web-ui.md` for the layout.
|
agent — see `docs/web-ui/dashboard.md` for the layout.
|
||||||
- **Cancellation**: the dashboard's *× cancel* button on a still-queued
|
- **Cancellation**: the dashboard's *× cancel* button on a still-queued
|
||||||
DAG calls `POST /api/rebuild-queue/{id}/cancel`, which flips it to
|
DAG calls `POST /api/rebuild-queue/{id}/cancel`, which flips it to
|
||||||
`Cancelled` before any node runs (and fails the approval row instead
|
`Cancelled` before any node runs (and fails the approval row instead
|
||||||
|
|
@ -485,7 +485,7 @@ agent.
|
||||||
|
|
||||||
The dashboard deep-links into this org — a `config repo` link
|
The dashboard deep-links into this org — a `config repo` link
|
||||||
per container row and a `review PR on forge` link per config-PR
|
per container row and a `review PR on forge` link per config-PR
|
||||||
approval card. See `docs/web-ui.md`.
|
approval card. See `docs/web-ui/dashboard.md`.
|
||||||
|
|
||||||
### Submitting agent's view of config repos
|
### Submitting agent's view of config repos
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ JSON line-delimited over unix sockets in both directions (host admin
|
||||||
/ manager / agent). SSE streams (`/dashboard/stream` on hive-c0re,
|
/ manager / agent). SSE streams (`/dashboard/stream` on hive-c0re,
|
||||||
`/events/stream` on the per-agent web UIs) are `text/event-stream`;
|
`/events/stream` on the per-agent web UIs) are `text/event-stream`;
|
||||||
each frame carries a `seq` field for the snapshot-dedupe dance
|
each frame carries a `seq` field for the snapshot-dedupe dance
|
||||||
(see `docs/web-ui.md`). Request/response types live in `hive-sh4re`
|
(see `docs/web-ui/shape.md`). Request/response types live in `hive-sh4re`
|
||||||
— change them in one place. The dashboard event vocabulary lives
|
— change them in one place. The dashboard event vocabulary lives
|
||||||
in `hive-c0re::dashboard_events::DashboardEvent`.
|
in `hive-c0re::dashboard_events::DashboardEvent`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
# Web UI
|
|
||||||
|
|
||||||
Two web surfaces share the same skeleton: the dashboard (port 7000)
|
|
||||||
and the per-agent UIs (each container's port is a deterministic hash
|
|
||||||
in :8100-8999 — see
|
|
||||||
[`gotchas.md#web-ui-ports-collide-on-hash`](process/gotchas.md#web-ui-ports-collide-on-hash)
|
|
||||||
for the mechanics and the collision caveat).
|
|
||||||
Both are SPAs — `GET /` returns a static shell, `/api/state`
|
|
||||||
returns JSON, JS renders. No full-page reloads.
|
|
||||||
|
|
||||||
This doc has been split for readability. Pick the section you need —
|
|
||||||
or, if you're the operator looking for how to actually _use_ the
|
|
||||||
dashboard rather than how it's built, start at
|
|
||||||
**[web-ui/README.md](web-ui/README.md)** instead.
|
|
||||||
|
|
||||||
- **[Shape (shared by both)](web-ui/shape.md)** — shared SPA
|
|
||||||
skeleton, SSE multiplexing, terminal pane, listener bind,
|
|
||||||
per-agent relative paths, `data-async` form pattern, side panel,
|
|
||||||
atomic repaint.
|
|
||||||
- **[Dashboard layout](web-ui/dashboard.md)** — tab contents
|
|
||||||
(SW4RM, Y3R C4LL, P3RM1SS10NS, SCH3DUL3S) + standalone pages
|
|
||||||
(C0R3 `/core.html`, BU1LDS `/builds.html`, L0GS `/logs.html`,
|
|
||||||
CR3D3NTIALS `/credentials.html`), container row,
|
|
||||||
topology tree, selection bar, approval card, browser
|
|
||||||
notifications, dashboard endpoints + event channel.
|
|
||||||
- **[Per-agent page](web-ui/agent.md)** — header, main terminal,
|
|
||||||
composer, side panel + inbox, live view, slash commands,
|
|
||||||
per-agent endpoints, stats page.
|
|
||||||
- **[CSS theme variables](web-ui/css-vars.md)** — the Catppuccin
|
|
||||||
Mocha custom properties declared once in `base.css` and the rule
|
|
||||||
that per-page stylesheets reference (never redeclare) them.
|
|
||||||
- **[swarm-ui design guide](web-ui/design-guide.md)** — visual
|
|
||||||
language, motion, theming, error-UX, and component-first principles
|
|
||||||
for the swarm-level Preact app specifically (not this doc's
|
|
||||||
dashboard/agent UIs). `/components` on a running swarm-ui is the
|
|
||||||
companion living demo of every primitive it references.
|
|
||||||
|
|
||||||
## Reading paths
|
|
||||||
|
|
||||||
- **"How does the dashboard SPA stay live without polling?"** →
|
|
||||||
[`web-ui/shape.md`](web-ui/shape.md) (SSE multiplexing,
|
|
||||||
Worker-death self-heal, atomic repaint).
|
|
||||||
- **"What does a container row contain?"** →
|
|
||||||
[`web-ui/dashboard.md`](web-ui/dashboard.md) (Container row,
|
|
||||||
Topology tree, Selection bar).
|
|
||||||
- **"What endpoints does the dashboard expose?"** →
|
|
||||||
[`web-ui/dashboard.md`](web-ui/dashboard.md) (Dashboard
|
|
||||||
endpoints, Dashboard event channel).
|
|
||||||
- **"How does the per-agent terminal render tool calls?"** →
|
|
||||||
[`terminal-rendering.md`](web-ui/terminal-rendering.md) (full row
|
|
||||||
taxonomy + dispatch walkthrough); for a high-level summary see
|
|
||||||
[`web-ui/agent.md`](web-ui/agent.md) (Per-stream rendering).
|
|
||||||
- **"What slash commands does the agent accept?"** →
|
|
||||||
[`web-ui/agent.md`](web-ui/agent.md) (Terminal-embedded prompt).
|
|
||||||
- **"What are the per-agent HTTP endpoints?"** →
|
|
||||||
[`web-ui/agent.md`](web-ui/agent.md) (Per-agent endpoints).
|
|
||||||
- **"Which CSS variable do I use / where are colours defined?"** →
|
|
||||||
[`web-ui/css-vars.md`](web-ui/css-vars.md) (Palette, single-source
|
|
||||||
`base.css` rule).
|
|
||||||
|
|
@ -85,12 +85,49 @@ that agent's config repo.
|
||||||
|
|
||||||
## More depth
|
## More depth
|
||||||
|
|
||||||
|
Both the dashboard and the per-agent pages are SPAs sharing one
|
||||||
|
skeleton: `GET /` returns a static shell, `/api/state` returns JSON,
|
||||||
|
JS renders — no full-page reloads.
|
||||||
|
|
||||||
- **[Dashboard layout](dashboard.md)** — every tab and standalone page,
|
- **[Dashboard layout](dashboard.md)** — every tab and standalone page,
|
||||||
in full implementation detail: endpoint shapes, event wiring, exact
|
in full implementation detail: endpoint shapes, event wiring, exact
|
||||||
badge-derivation rules.
|
badge-derivation rules.
|
||||||
- **[Per-agent page](agent.md)** — the per-agent terminal, composer,
|
- **[Per-agent page](agent.md)** — the per-agent terminal, composer,
|
||||||
side panel, slash commands, and per-agent endpoints.
|
side panel, slash commands, and per-agent endpoints.
|
||||||
- **[Shape (shared by both)](shape.md)** — the SPA skeleton, SSE
|
- **[Shape (shared by both)](shape.md)** — the SPA skeleton, SSE
|
||||||
multiplexing, and other plumbing shared across every page.
|
multiplexing, terminal pane, listener bind, per-agent relative
|
||||||
- **[CSS theme variables](css-vars.md)** — the colour system, for
|
paths, `data-async` form pattern, side panel, atomic repaint.
|
||||||
anyone touching the frontend's CSS.
|
- **[CSS theme variables](css-vars.md)** — the Catppuccin Mocha custom
|
||||||
|
properties declared once in `base.css` and the rule that per-page
|
||||||
|
stylesheets reference (never redeclare) them.
|
||||||
|
- **[swarm-ui design guide](design-guide.md)** — visual language,
|
||||||
|
motion, theming, error-UX, and component-first principles for the
|
||||||
|
swarm-level Preact app specifically (not this page's dashboard/agent
|
||||||
|
UIs). `/components` on a running swarm-ui is the companion living
|
||||||
|
demo of every primitive it references.
|
||||||
|
|
||||||
|
### Implementation reading paths
|
||||||
|
|
||||||
|
Task-oriented jumps straight to the relevant section, for when you're
|
||||||
|
touching the code rather than using the UI:
|
||||||
|
|
||||||
|
- **"How does the dashboard SPA stay live without polling?"** →
|
||||||
|
[`shape.md`](shape.md) (SSE multiplexing, Worker-death self-heal,
|
||||||
|
atomic repaint).
|
||||||
|
- **"What does a container row contain?"** →
|
||||||
|
[`dashboard.md`](dashboard.md) (Container row, Topology tree,
|
||||||
|
Selection bar).
|
||||||
|
- **"What endpoints does the dashboard expose?"** →
|
||||||
|
[`dashboard.md`](dashboard.md) (Dashboard endpoints, Dashboard event
|
||||||
|
channel).
|
||||||
|
- **"How does the per-agent terminal render tool calls?"** →
|
||||||
|
[`terminal-rendering.md`](terminal-rendering.md) (full row taxonomy
|
||||||
|
and dispatch walkthrough); for a high-level summary see
|
||||||
|
[`agent.md`](agent.md) (Per-stream rendering).
|
||||||
|
- **"What slash commands does the agent accept?"** →
|
||||||
|
[`agent.md`](agent.md) (Terminal-embedded prompt).
|
||||||
|
- **"What are the per-agent HTTP endpoints?"** →
|
||||||
|
[`agent.md`](agent.md) (Per-agent endpoints).
|
||||||
|
- **"Which CSS variable do I use / where are colours defined?"** →
|
||||||
|
[`css-vars.md`](css-vars.md) (Palette, single-source `base.css`
|
||||||
|
rule).
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Per-agent page
|
# Per-agent page
|
||||||
|
|
||||||
> Part of [Web UI](../web-ui.md). See also:
|
> Part of [Web UI](README.md). See also:
|
||||||
> [Shape (shared)](shape.md) · [Dashboard layout](dashboard.md)
|
> [Shape (shared)](shape.md) · [Dashboard layout](dashboard.md)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Dashboard layout
|
# Dashboard layout
|
||||||
|
|
||||||
> Part of [Web UI](../web-ui.md). See also:
|
> Part of [Web UI](README.md). See also:
|
||||||
> [Shape (shared)](shape.md) · [Per-agent page](agent.md)
|
> [Shape (shared)](shape.md) · [Per-agent page](agent.md)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Shape (shared by both)
|
# Shape (shared by both)
|
||||||
|
|
||||||
> Part of [Web UI](../web-ui.md). See also:
|
> Part of [Web UI](README.md). See also:
|
||||||
> [Dashboard layout](dashboard.md) · [Per-agent page](agent.md)
|
> [Dashboard layout](dashboard.md) · [Per-agent page](agent.md)
|
||||||
|
|
||||||
## Shared routes
|
## Shared routes
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
/* ─── full-screen layout overrides ─────────────────────────────────
|
/* ─── full-screen layout overrides ─────────────────────────────────
|
||||||
The agent page mounts a full-viewport terminal under a fixed
|
The agent page mounts a full-viewport terminal under a fixed
|
||||||
frosted-glass header + composer pair. See docs/web-ui.md::Per-agent
|
frosted-glass header + composer pair. See docs/web-ui/agent.md::Per-agent
|
||||||
page for the layer / pill / side-panel structure; rules below
|
page for the layer / pill / side-panel structure; rules below
|
||||||
override the in-page defaults from @hive/shared. */
|
override the in-page defaults from @hive/shared. */
|
||||||
|
|
||||||
|
|
@ -175,7 +175,7 @@ h3 {
|
||||||
}
|
}
|
||||||
.agent-icon {
|
.agent-icon {
|
||||||
/* Square identity anchor — explicit 5em sizing + align-self.
|
/* Square identity anchor — explicit 5em sizing + align-self.
|
||||||
See docs/web-ui.md::Per-agent page (Agent icon) for the
|
See docs/web-ui/agent.md::Per-agent page (Agent icon) for the
|
||||||
intrinsic-dim-pushes-parent-flex-open + sticks-to-top
|
intrinsic-dim-pushes-parent-flex-open + sticks-to-top
|
||||||
rationale. */
|
rationale. */
|
||||||
width: 5em;
|
width: 5em;
|
||||||
|
|
@ -702,7 +702,7 @@ pre.diff {
|
||||||
the composer (z-30) so the pill sits on the top layer instead of
|
the composer (z-30) so the pill sits on the top layer instead of
|
||||||
being clipped by the floating chrome. (Pill is anchored in
|
being clipped by the floating chrome. (Pill is anchored in
|
||||||
`.agent-main` rather than `.terminal-wrap` — see
|
`.agent-main` rather than `.terminal-wrap` — see
|
||||||
docs/web-ui.md::Per-agent page Terminal-wrap paragraph for the
|
docs/web-ui/agent.md::Per-agent page Terminal-wrap paragraph for the
|
||||||
backdrop-filter stacking-context rationale.) */
|
backdrop-filter stacking-context rationale.) */
|
||||||
.agent-main .tail-pill {
|
.agent-main .tail-pill {
|
||||||
bottom: calc(var(--agent-composer-h) + 0.6em);
|
bottom: calc(var(--agent-composer-h) + 0.6em);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- Fit-to-window toggle ---
|
// --- Fit-to-window toggle ---
|
||||||
// See docs/web-ui.md::Per-agent endpoints (GET /screen) for the
|
// See docs/web-ui/agent.md::Per-agent endpoints (GET /screen) for the
|
||||||
// localStorage persistence + canvas-intrinsic-resolution +
|
// localStorage persistence + canvas-intrinsic-resolution +
|
||||||
// pointer-rescale model.
|
// pointer-rescale model.
|
||||||
let fitMode = localStorage.getItem("screen-fit") !== "off";
|
let fitMode = localStorage.getItem("screen-fit") !== "off";
|
||||||
|
|
@ -105,7 +105,7 @@
|
||||||
// Sends an RFB SetDesktopSize request so the VNC server (weston)
|
// Sends an RFB SetDesktopSize request so the VNC server (weston)
|
||||||
// changes its actual output resolution to match the browser
|
// changes its actual output resolution to match the browser
|
||||||
// viewport — sharper than fit-mode's CSS downscale. Gated on the
|
// viewport — sharper than fit-mode's CSS downscale. Gated on the
|
||||||
// server's ExtendedDesktopSize advert; see docs/web-ui.md::Per-agent
|
// server's ExtendedDesktopSize advert; see docs/web-ui/agent.md::Per-agent
|
||||||
// endpoints (GET /screen).
|
// endpoints (GET /screen).
|
||||||
let extDesktopSupported = false;
|
let extDesktopSupported = false;
|
||||||
let screenId = 1; // captured from the server's ExtendedDesktopSize advert
|
let screenId = 1; // captured from the server's ExtendedDesktopSize advert
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ export function renderApprovals() {
|
||||||
if (isMergePr && a.sha_short) head.append(el("code", {}, a.sha_short));
|
if (isMergePr && a.sha_short) head.append(el("code", {}, a.sha_short));
|
||||||
// When the approval was requested — relative time, right-aligned.
|
// When the approval was requested — relative time, right-aligned.
|
||||||
// Goes amber once it's been pending an hour so a stale request is
|
// Goes amber once it's been pending an hour so a stale request is
|
||||||
// obvious at a glance (see docs/web-ui.md::Approval card).
|
// obvious at a glance (see docs/web-ui/dashboard.md::Approval card).
|
||||||
if (a.requested_at != null) {
|
if (a.requested_at != null) {
|
||||||
const requestedSec = epochSec(a.requested_at);
|
const requestedSec = epochSec(a.requested_at);
|
||||||
const ageSec = Math.max(0, Math.floor(Date.now() / 1000 - requestedSec));
|
const ageSec = Math.max(0, Math.floor(Date.now() / 1000 - requestedSec));
|
||||||
|
|
|
||||||
|
|
@ -253,7 +253,7 @@ code {
|
||||||
}
|
}
|
||||||
/* M0V3 affordance (selection bar) — mauve reads as "structural
|
/* M0V3 affordance (selection bar) — mauve reads as "structural
|
||||||
change" rather than the destructive red / amber chrome of
|
change" rather than the destructive red / amber chrome of
|
||||||
destroy / rebuild. See docs/web-ui.md::Selection bar. */
|
destroy / rebuild. See docs/web-ui/dashboard.md::Selection bar. */
|
||||||
.btn-move {
|
.btn-move {
|
||||||
color: var(--purple);
|
color: var(--purple);
|
||||||
border-color: var(--purple);
|
border-color: var(--purple);
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export const form = (
|
||||||
// ─── shared-worker SSE pipe ─────────────────────────────────────────────
|
// ─── shared-worker SSE pipe ─────────────────────────────────────────────
|
||||||
// Returns an EventSource-shaped facade backed by a SharedWorker that
|
// Returns an EventSource-shaped facade backed by a SharedWorker that
|
||||||
// holds one upstream `new EventSource(url)` and fans events out to
|
// holds one upstream `new EventSource(url)` and fans events out to
|
||||||
// every connected tab. See docs/web-ui.md (SSE multiplexing paragraph)
|
// every connected tab. See docs/web-ui/shape.md (SSE multiplexing paragraph)
|
||||||
// for the design + Firefox throttling motivation; graceful fallback to
|
// for the design + Firefox throttling motivation; graceful fallback to
|
||||||
// direct EventSource on environments without SharedWorker.
|
// direct EventSource on environments without SharedWorker.
|
||||||
//
|
//
|
||||||
|
|
@ -105,7 +105,7 @@ function getSharedPort() {
|
||||||
// SharedWorker death detection: pings from the worker bump the
|
// SharedWorker death detection: pings from the worker bump the
|
||||||
// activity clock; a visibility-gated watchdog polls and re-subscribes
|
// activity clock; a visibility-gated watchdog polls and re-subscribes
|
||||||
// on a fresh port if the page has been silent past the threshold.
|
// on a fresh port if the page has been silent past the threshold.
|
||||||
// See docs/web-ui.md (Worker-death self-heal paragraph) for the
|
// See docs/web-ui/shape.md (Worker-death self-heal paragraph) for the
|
||||||
// timing rationale + Firefox reclaim symptom.
|
// timing rationale + Firefox reclaim symptom.
|
||||||
const WORKER_DEAD_THRESHOLD_MS = 90_000;
|
const WORKER_DEAD_THRESHOLD_MS = 90_000;
|
||||||
const WORKER_WATCHDOG_INTERVAL_MS = 15_000;
|
const WORKER_WATCHDOG_INTERVAL_MS = 15_000;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
/* ─── tabbed dashboard chrome ──────────────────────────────────────
|
/* ─── tabbed dashboard chrome ──────────────────────────────────────
|
||||||
Top-of-page sticky header with banner + tab strip. SSE stays
|
Top-of-page sticky header with banner + tab strip. SSE stays
|
||||||
alive across tab switches so count pills update live on inactive
|
alive across tab switches so count pills update live on inactive
|
||||||
tabs. See docs/web-ui.md::Chrome header + Tab strip for the
|
tabs. See docs/web-ui/dashboard.md::Chrome header + Tab strip for the
|
||||||
routing model. */
|
routing model. */
|
||||||
|
|
||||||
body.dashboard-shell {
|
body.dashboard-shell {
|
||||||
|
|
@ -200,7 +200,7 @@ body.dashboard-shell {
|
||||||
opacity 200ms ease,
|
opacity 200ms ease,
|
||||||
border-color 200ms ease;
|
border-color 200ms ease;
|
||||||
}
|
}
|
||||||
/* Topology indent ladder. See docs/web-ui.md::Topology tree (Indent
|
/* Topology indent ladder. See docs/web-ui/dashboard.md::Topology tree (Indent
|
||||||
+ lane geometry paragraph) for the 1.8em-per-depth-level
|
+ lane geometry paragraph) for the 1.8em-per-depth-level
|
||||||
rationale + CSS-attr()-not-yet-portable caveat. */
|
rationale + CSS-attr()-not-yet-portable caveat. */
|
||||||
.container-row[data-depth] {
|
.container-row[data-depth] {
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@
|
||||||
for per-target / whole-row cancel. Live updates via
|
for per-target / whole-row cancel. Live updates via
|
||||||
`schedules_changed` SSE; tab activation re-fetches as a
|
`schedules_changed` SSE; tab activation re-fetches as a
|
||||||
safety net for disconnect windows.
|
safety net for disconnect windows.
|
||||||
See docs/web-ui.md::SCH3DUL3S tab. -->
|
See docs/web-ui/dashboard.md::SCH3DUL3S tab. -->
|
||||||
<section
|
<section
|
||||||
class="tab-pane"
|
class="tab-pane"
|
||||||
id="tab-pane-schedules"
|
id="tab-pane-schedules"
|
||||||
|
|
@ -354,7 +354,7 @@
|
||||||
|
|
||||||
<!-- Selection action bar. Sticky-bottom strip that slides into
|
<!-- Selection action bar. Sticky-bottom strip that slides into
|
||||||
view when one or more agent cards is selected (click the icon
|
view when one or more agent cards is selected (click the icon
|
||||||
to toggle). See docs/web-ui.md::Selection bar for the bulk
|
to toggle). See docs/web-ui/dashboard.md::Selection bar for the bulk
|
||||||
action gating + clear semantics. -->
|
action gating + clear semantics. -->
|
||||||
<div
|
<div
|
||||||
id="selection-bar"
|
id="selection-bar"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* ─── /flow.html — full-page chat ─────────────────────────────────
|
/* ─── /flow.html — full-page chat ─────────────────────────────────
|
||||||
See docs/web-ui.md::FL0W page for the page-vs-pane rationale.
|
See docs/web-ui/dashboard.md::FL0W page for the page-vs-pane rationale.
|
||||||
Shape mirrors the per-agent live page (frosted-glass header +
|
Shape mirrors the per-agent live page (frosted-glass header +
|
||||||
composer, full-viewport terminal). */
|
composer, full-viewport terminal). */
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ body.flow-shell .flow-main-slim {
|
||||||
/* Tail pill (↓ N new): bottom offset clears the floating composer.
|
/* Tail pill (↓ N new): bottom offset clears the floating composer.
|
||||||
Pill is anchored on .flow-main (not .terminal-wrap) so the
|
Pill is anchored on .flow-main (not .terminal-wrap) so the
|
||||||
backdrop-filter stacking context doesn't trap its z-index — see
|
backdrop-filter stacking context doesn't trap its z-index — see
|
||||||
docs/web-ui.md::Per-agent page (Terminal-wrap) for the same
|
docs/web-ui/agent.md::Per-agent page (Terminal-wrap) for the same
|
||||||
gotcha on the agent page. */
|
gotcha on the agent page. */
|
||||||
.flow-main .tail-pill {
|
.flow-main .tail-pill {
|
||||||
bottom: calc(var(--flow-composer-h) + 0.6em);
|
bottom: calc(var(--flow-composer-h) + 0.6em);
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ import { epochSec } from "./util.js";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Anchor the `↓ N new` pill in `.flow-main` rather than the
|
// Anchor the `↓ N new` pill in `.flow-main` rather than the
|
||||||
// default `.terminal-wrap` parent — see docs/web-ui.md::Per-agent
|
// default `.terminal-wrap` parent — see docs/web-ui/agent.md::Per-agent
|
||||||
// page (Terminal-wrap) for the backdrop-filter stacking-context
|
// page (Terminal-wrap) for the backdrop-filter stacking-context
|
||||||
// gotcha (same shape on the flow page).
|
// gotcha (same shape on the flow page).
|
||||||
const flowMain = document.querySelector(".flow-main");
|
const flowMain = document.querySelector(".flow-main");
|
||||||
|
|
@ -236,7 +236,7 @@ import { epochSec } from "./util.js";
|
||||||
// since it routes every mutation kind into its derived stores.
|
// since it routes every mutation kind into its derived stores.
|
||||||
streamUrl:
|
streamUrl:
|
||||||
"/api/dashboard/stream?kinds=sent,delivered,container_state_changed,container_removed",
|
"/api/dashboard/stream?kinds=sent,delivered,container_state_changed,container_removed",
|
||||||
// Route through the SharedWorker — see docs/web-ui.md (SSE
|
// Route through the SharedWorker — see docs/web-ui/shape.md (SSE
|
||||||
// multiplexing paragraph). Worker keys on the full URL incl.
|
// multiplexing paragraph). Worker keys on the full URL incl.
|
||||||
// query string, so this filtered subscribe is its own upstream
|
// query string, so this filtered subscribe is its own upstream
|
||||||
// and won't accidentally share with tabs.js's wider subscribe.
|
// and won't accidentally share with tabs.js's wider subscribe.
|
||||||
|
|
|
||||||
|
|
@ -370,7 +370,7 @@ function renderSchedulesList() {
|
||||||
}
|
}
|
||||||
// Always-visible inline create row at the bottom of the table
|
// Always-visible inline create row at the bottom of the table
|
||||||
// — fill cells + click + to POST. See
|
// — fill cells + click + to POST. See
|
||||||
// docs/web-ui.md::SCH3DUL3S tab for the layout rationale.
|
// docs/web-ui/dashboard.md::SCH3DUL3S tab for the layout rationale.
|
||||||
tbody.append(renderInlineCreateRow(agents));
|
tbody.append(renderInlineCreateRow(agents));
|
||||||
table.append(tbody);
|
table.append(tbody);
|
||||||
const wrap = el("div", { class: "schedules-table-wrap" });
|
const wrap = el("div", { class: "schedules-table-wrap" });
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const containerRowCache = new Map();
|
||||||
const transientsState = new Map();
|
const transientsState = new Map();
|
||||||
|
|
||||||
// In-memory set of selected agent logical names backing the sticky
|
// In-memory set of selected agent logical names backing the sticky
|
||||||
// #selection-bar. See docs/web-ui.md::Selection bar for the
|
// #selection-bar. See docs/web-ui/dashboard.md::Selection bar for the
|
||||||
// interaction model (icon-click toggle, Esc/clear button drop,
|
// interaction model (icon-click toggle, Esc/clear button drop,
|
||||||
// tab-gated visibility).
|
// tab-gated visibility).
|
||||||
const selectionState = new Set();
|
const selectionState = new Set();
|
||||||
|
|
@ -227,7 +227,7 @@ function derivePortConflicts(containers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── topology tree ───────────────────────────────────────────────────────────
|
// ─── topology tree ───────────────────────────────────────────────────────────
|
||||||
// See docs/web-ui.md::Topology tree for the rendering contract
|
// See docs/web-ui/dashboard.md::Topology tree for the rendering contract
|
||||||
// (forest walk, alphabetical sort, orphan + cycle handling).
|
// (forest walk, alphabetical sort, orphan + cycle handling).
|
||||||
|
|
||||||
function buildAgentTree(containers) {
|
function buildAgentTree(containers) {
|
||||||
|
|
@ -277,7 +277,7 @@ function buildAgentTree(containers) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
// Builds the .tree-prefix DOM for a row at the given depth.
|
// Builds the .tree-prefix DOM for a row at the given depth.
|
||||||
// See docs/web-ui.md::Topology tree for why this is DOM-painted
|
// See docs/web-ui/dashboard.md::Topology tree for why this is DOM-painted
|
||||||
// (one positioned <span> per lane) rather than text-glyph-painted.
|
// (one positioned <span> per lane) rather than text-glyph-painted.
|
||||||
function treePrefixDom({ depth, ancestorIsLast, isLast }) {
|
function treePrefixDom({ depth, ancestorIsLast, isLast }) {
|
||||||
if (depth === 0) return null;
|
if (depth === 0) return null;
|
||||||
|
|
@ -650,7 +650,7 @@ function buildContainerLi(c, node, opts) {
|
||||||
|
|
||||||
// Per-card action buttons (R3ST4RT / ST0P / ST4RT / R3BU1LD /
|
// Per-card action buttons (R3ST4RT / ST0P / ST4RT / R3BU1LD /
|
||||||
// DESTR0Y / PURG3) live on the selection bar, not here — see
|
// DESTR0Y / PURG3) live on the selection bar, not here — see
|
||||||
// docs/web-ui.md::Selection bar. The contextual `needs update ↻`
|
// docs/web-ui/dashboard.md::Selection bar. The contextual `needs update ↻`
|
||||||
// chip in the head row stays — it's a state-hint, not an
|
// chip in the head row stays — it's a state-hint, not an
|
||||||
// action button.
|
// action button.
|
||||||
|
|
||||||
|
|
@ -830,7 +830,7 @@ export function renderContainers(s) {
|
||||||
|
|
||||||
// ─── selection bar ───────────────────────────────────────────────────────────
|
// ─── selection bar ───────────────────────────────────────────────────────────
|
||||||
// Sticky-bottom strip; visible when >=1 agent selected on the SW4RM
|
// Sticky-bottom strip; visible when >=1 agent selected on the SW4RM
|
||||||
// tab. See docs/web-ui.md::Selection bar for the interaction model
|
// tab. See docs/web-ui/dashboard.md::Selection bar for the interaction model
|
||||||
// and the per-action availability rules (disabled-with-tooltip for
|
// and the per-action availability rules (disabled-with-tooltip for
|
||||||
// actions that don't apply to the full selection). Actions POST per
|
// actions that don't apply to the full selection). Actions POST per
|
||||||
// agent in a loop (endpoints are individually idempotent /
|
// agent in a loop (endpoints are individually idempotent /
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// + notification deltas. Reads /api/state on cold load and after every
|
// + notification deltas. Reads /api/state on cold load and after every
|
||||||
// async-form submit; live updates run through `applyXxx` mutation
|
// async-form submit; live updates run through `applyXxx` mutation
|
||||||
// handlers triggered by the dashboard event stream (subscribed via
|
// handlers triggered by the dashboard event stream (subscribed via
|
||||||
// `openStream` from common.js). See docs/web-ui.md::Shape (shared by
|
// `openStream` from common.js). See docs/web-ui/shape.md::Shape (shared by
|
||||||
// both) for the broader contract.
|
// both) for the broader contract.
|
||||||
//
|
//
|
||||||
// Pure helpers (DOM, side panel, OS notifications, path linkification)
|
// Pure helpers (DOM, side panel, OS notifications, path linkification)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import { el } from "../dom.js";
|
||||||
import { attachShadowCss } from "../shadow-css.js";
|
import { attachShadowCss } from "../shadow-css.js";
|
||||||
import sidePanelCss from "./hive-side-panel.css";
|
import sidePanelCss from "./hive-side-panel.css";
|
||||||
|
|
||||||
// See docs/web-ui.md::Side panel for the hit-strip + pointer-capture +
|
// See docs/web-ui/agent.md::Side panel for the hit-strip + pointer-capture +
|
||||||
// localStorage persistence model; CSS clamps the stored value to min
|
// localStorage persistence model; CSS clamps the stored value to min
|
||||||
// 320px / max 96vw and out-of-range stored values are dropped silently.
|
// 320px / max 96vw and out-of-range stored values are dropped silently.
|
||||||
// Shared by both packages deliberately — see module header.
|
// Shared by both packages deliberately — see module header.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const NEAR_BOTTOM_PX = 48;
|
||||||
// "load older" fetch — fires via the scroll event handler so the operator
|
// "load older" fetch — fires via the scroll event handler so the operator
|
||||||
// never has to click the pill; the pill stays as a visual indicator.
|
// never has to click the pill; the pill stays as a visual indicator.
|
||||||
const LOAD_MORE_SCROLL_PX = 80;
|
const LOAD_MORE_SCROLL_PX = 80;
|
||||||
// Snap-to-bottom animation duration. See docs/web-ui.md::Shared
|
// Snap-to-bottom animation duration. See docs/web-ui/shape.md::Shared
|
||||||
// terminal pane (Sticky-bottom + snap animation) for the 140ms-vs-
|
// terminal pane (Sticky-bottom + snap animation) for the 140ms-vs-
|
||||||
// 500ms-browser-default + 24px short-circuit rationale.
|
// 500ms-browser-default + 24px short-circuit rationale.
|
||||||
const SCROLL_ANIM_MS = 140;
|
const SCROLL_ANIM_MS = 140;
|
||||||
|
|
@ -128,7 +128,7 @@ export function create(opts) {
|
||||||
// immediately so the MutationObserver stops re-firing snapToBottom()
|
// immediately so the MutationObserver stops re-firing snapToBottom()
|
||||||
// and the animation-guard window can expire naturally. Without this,
|
// and the animation-guard window can expire naturally. Without this,
|
||||||
// live events arriving < 220ms apart permanently block scroll-to-top
|
// live events arriving < 220ms apart permanently block scroll-to-top
|
||||||
// and loadMore() never fires. See docs/web-ui.md::Shared terminal
|
// and loadMore() never fires. See docs/web-ui/shape.md::Shared terminal
|
||||||
// pane (Mid-animation scroll-event guard).
|
// pane (Mid-animation scroll-event guard).
|
||||||
const inAnim = Date.now() < smoothScrollingUntil;
|
const inAnim = Date.now() < smoothScrollingUntil;
|
||||||
const nearBottom = isNearBottom();
|
const nearBottom = isNearBottom();
|
||||||
|
|
@ -571,7 +571,7 @@ export function create(opts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a DocumentFragment from `text`, turning bare http(s) URLs into
|
// Build a DocumentFragment from `text`, turning bare http(s) URLs into
|
||||||
// clickable links that open in a new tab. See docs/web-ui.md::Shared
|
// clickable links that open in a new tab. See docs/web-ui/shape.md::Shared
|
||||||
// terminal pane (linkify) for the text-node-only / no-innerHTML
|
// terminal pane (linkify) for the text-node-only / no-innerHTML
|
||||||
// XSS-safety + trailing-punctuation strip.
|
// XSS-safety + trailing-punctuation strip.
|
||||||
const LINKIFY_URL_RE = /https?:\/\/[^\s<>"']+/g;
|
const LINKIFY_URL_RE = /https?:\/\/[^\s<>"']+/g;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue