The Monitors tab is called Dashboard again

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-20 18:29:09 -07:00
co-authored by Claude Opus 5
parent 1e992ca1eb
commit 885b050d02
4 changed files with 9 additions and 8 deletions
+4 -3
View File
@@ -166,7 +166,7 @@ something long in one, switch away and back, refresh — it's all still there.
CPU (total + per core), memory/swap, load, uptime, hwmon temps and fans read straight
from `/sys` (no lm-sensors), per-interface network rates, per-disk read/write/busy
from `/proc/diskstats`, filesystem usage, UPS via `sudo -n pwrstat -status`. Sampled
every 2 s into an in-memory ring of 10 min; the UI (the **Monitors** tab
every 2 s into an in-memory ring of 10 min; the UI (the **Dashboard** tab
since 2026-09-19) reads it all through the sensor API — see Sensors below. **Customizable**: a
Customize mode reorders and hides modules (CPU, Memory, Load, Uptime, Temperatures,
Fans, Network, Disks, Filesystems, UPS) and hides individual rows (an interface, a
@@ -184,8 +184,9 @@ something long in one, switch away and back, refresh — it's all still there.
machine and a static schema would collapse to `sensor(id:)`), the same query as a live
SSE stream, Prometheus `/metrics`, read-only `sensors:read` tokens (never full tokens in
a URL), status sensors (services, updates, ZFS, SMART), a widget library, custom widgets
on the Monitors tab (was "Dashboard"; the view id and URL are still `dashboard`), and a
frameable `/embed/widget` for Glance and friends. The stock Monitors modules and the Disks
on the Dashboard tab (briefly renamed "Monitors" 2026-09-19, back to "Dashboard"
2026-09-20 at Mitchell's request; the view id and URL were always `dashboard`), and a
frameable `/embed/widget` for Glance and friends. The stock Dashboard modules and the Disks
tab read the sensor API too (`sampleAdapter.ts`); `/api/metrics` is retired.
Also per-service and per-container sensors (memory and CPU from cgroups), tokens limited
to ID patterns, and `/api/fleet/sensors/query` for the whole fleet in one request.
+2 -2
View File
@@ -151,7 +151,7 @@ A widget is a spec — `{type, sensor, title?}` — over this API and nothing el
`gauge`, `bar`, `spark`, and `list` for a pattern. Scale and colour come from the
sensor's own `min`/`max`/`warn`/`crit`.
- **In Ham Lab:** Monitors → Customize → **+ Add widget**. Saved with the layout,
- **In Ham Lab:** Dashboard → Customize → **+ Add widget**. Saved with the layout,
per machine; all of a page's widgets share one stream.
- **Widgets tab:** every widget type, then every sensor on the machine drawn once, live,
grouped by family (`web/src/Gallery.tsx`). Tap a tile to copy its sensor ID — the
@@ -199,7 +199,7 @@ GET /api/fleet/sensors/query?machines=grid,wyse&cpu=cpu.usage&failed=services.f
## What Ham Lab itself runs on
Since 2026-09-19 the Monitors tab (stock modules and custom widgets) and the Disks tab's
Since 2026-09-19 the Dashboard tab (stock modules and custom widgets) and the Disks tab's
live rates read only this API: the catalog once, one batch of histories, one stream —
closed while the page is hidden, refilled when it returns. `web/src/sampleAdapter.ts` is
the seam that hands the stock modules the object they were written against. The old
+2 -2
View File
@@ -49,7 +49,7 @@ const BellIcon = (
)
const GROUPS: Group[] = [
{ id: 'dashboard', label: 'Monitors', icon: '◔' },
{ id: 'dashboard', label: 'Dashboard', icon: '◔' },
{ id: 'procs', label: 'Processes', icon: '≡' },
{ id: 'terminal', label: 'Terminal', icon: '>_' },
{ id: 'services', label: 'Services', icon: '◈' },
@@ -283,7 +283,7 @@ export default function Shell({ me: hubMe, onLoggedOut }: { me: Me; onLoggedOut:
<span>{machine ? `${machine} · ` : ''}{me.version.startsWith('v') ? me.version : 'v' + me.version}</span>
<span>up {fmtUptime(me.uptime)}</span>
<span className="spacer" />
<span className="muted">{view === 'dashboard' ? 'Monitors' : view === 'widgets' ? 'Widgets' : view === 'docker' ? 'Docker' : view === 'alerts' ? 'Alerts' : view === 'services' ? 'Services' : view === 'cron' ? 'Cron' : view === 'updates' ? 'Updates' : view === 'disks' ? 'Disks' : view === 'files' ? 'Files' : view === 'procs' ? 'Processes' : view === 'machines' ? 'Machines' : view === 'settings' ? 'Settings' : activeTerm ? activeTerm.name : ''}</span>
<span className="muted">{view === 'dashboard' ? 'Dashboard' : view === 'widgets' ? 'Widgets' : view === 'docker' ? 'Docker' : view === 'alerts' ? 'Alerts' : view === 'services' ? 'Services' : view === 'cron' ? 'Cron' : view === 'updates' ? 'Updates' : view === 'disks' ? 'Disks' : view === 'files' ? 'Files' : view === 'procs' ? 'Processes' : view === 'machines' ? 'Machines' : view === 'settings' ? 'Settings' : activeTerm ? activeTerm.name : ''}</span>
</footer>
</div>
)
+1 -1
View File
@@ -1,4 +1,4 @@
// The stock Monitors modules were written against one Sample object. They now read the
// The stock Dashboard modules were written against one Sample object. They now read the
// sensor API like everything else; this file is the seam — it rebuilds that object from
// sensor values (the live stream) and sensor metadata (the catalog: labels, thresholds).
import { Sample, Series } from './api'