swarm-ui: header links menu for swarm-wide services (hyperhive#3289)

Single 🔗 button in the Shell header (direction 1 of 3 proposed on the
issue) — one fixed element regardless of link count, so it can't
clutter as the list grows, and visible on every route since Shell
wraps all of them. Opens a popover listing whatever GET /api/links
returns (icon + label, opens in a new tab); hidden entirely when the
list is empty, same "don't render a dead affordance" rule the old
dashboard's H0M3 tiles follow for Forge/Matrix.

Docs: docs/swarm/ui.md gets a short section on the feature + the
contribute-your-own-entry idiom.

Verified: npm run build + npm run typecheck clean, headless-chromium
screenshots of both the closed and (temporarily forced open for the
screenshot only) open states, pixel-sampled to confirm the popover is
actually using the dark theme vars and not just looking that way in a
downscaled preview.
This commit is contained in:
iris 2026-08-15 13:47:31 +02:00 committed by mara
commit 8542f2ca42
4 changed files with 161 additions and 0 deletions

View file

@ -89,6 +89,24 @@ parent — no CA in the hierarchy issues for it implicitly. Left out, the
vhost falls back to the hive leaf and the swarm's front page opens with a
name mismatch.
## Quick links
The swarm UI's header carries a single 🔗 button, visible on every route,
opening a popover of links to other swarm-wide services — authelia,
matrix, forge, this UI's own swagger docs. Backed by `GET /api/links`
(swarm-controller), which serves `services.hyperhive.swarm.controller.links`
(a `listOf { label, icon, url }`, same shape as the per-agent
`hyperhive.dashboardLinks`).
Rather than one central hardcoded list, each service's own module
contributes its own entry when it's actually enabled on the controller's
host — `swarm-authelia.nix`, `hive-matrix.nix` and `hive-forge/default.nix`
all do, the same list-merge idiom `gateway.localNames` uses above. Adding a
link for a new service is a nix-only change to that service's own module
(or an operator adding an entry directly); no swarm-controller or swarm-ui
change needed. Empty list hides the button rather than showing an empty
popover.
## Cross-references
- [`sso.md`](sso.md) — the authelia instance itself, and the user store.