Skip to content

Timeline / Sessions / Devices UI redesign

Date: 2026-09-08 Scope: frontend/ (admin console) and frontend-app/ (operator app) Trigger: operator report — "UI for timeline and session and device is a bit hard to understand".

Problem

Evidence gathered from the live consoles (logged in, 1440x900, zero pageerror).

Structural

Timeline is a top-level admin nav item, but everything under it is a view of an object reached elsewhere. /timeline is a picker that re-lists Facilities and Devices — a third copy of two lists that already have their own pages. Admin has no separate device detail page: /devices/:id/timeline is the device detail, and device rows already link to it.

/metadata and /metadata/:id appear in no navigation, but checking App.tsx showed they already redirect to /sessions — so there is nothing orphaned here and no work to do. Recorded because the first pass assumed otherwise.

The admin sidebar is 17 flat entries plus one Administration group.

Sessions (admin)

The row renders {device} · {streams.length} · {totalSamples}, so board1 v4 0046 · 23 · 0 means 23 streams, 0 samples — both unlabeled.

The leading dot is deviceColor(s.deviceId), aria-hidden, rendered only when no device filter is applied. It reads as a status light but encodes device identity. Admin shows no session status at all, while the operator app already renders a labeled active/closed StatusDot.

The right-hand half of the page is a permanent Select a session to view placeholder.

Devices (admin)

  • The table overflows horizontally at 1440px — Last seen is cut off.
  • Status stacks 1-4 badges vertically (Dark, Storage off, Identity conflict, Audio), so row heights swing ~90px to ~130px and nothing marks which badge matters most.
  • Info crams three unlabeled values: — 1.95 V -48 dBm.
  • Fault text is spliced into the device name: v1-0001 (HJNC 기계실 하부) — NVS LOST, posting as 0000.

Device timeline (admin)

  • 5053px tall — 5.6 screens for one device, one full-height chart per sensor, no overview.
  • Header stats run together: 24.97—44.32 avg 33.86 ▲ 28.58 % 504 pts.
  • Constant series still get full height (NOx reads 1.000—1.000).
  • Shaded vertical bands have no legend.

Constraints

From frontend/AGENTS.md:

  • Admin may use precise technical terms (session, stream, sample). The fix is to label 23 · 0, not to remove it.
  • Admin is where our-device hardware health belongs; the operator app must never show it. The two apps' "Devices" differ by policy.
  • New nav destinations go in both Sidebar and CommandPalette.
  • UI strings bilingual EN+KO in src/i18n/index.ts, kept in parity.
  • Every colour utility needs a dark: variant. Red is destructive-only.
  • Reuse shared primitives; mobile-first at 375/768/1280 with zero pageerror.

From frontend-app/AGENTS.md — the "Cleanup precedent": routes removed from navigation stay mounted so bookmarks resolve (/trends, /dashboard). This redesign follows that precedent rather than deleting routes.

Design

1. Navigation

  • Remove Timeline from the admin sidebar and command palette. Keep /timeline, /devices/:id/timeline and /facilities/:id/timeline mounted.
  • Add an explicit History link on each facility row so the facility timeline stays reachable without the index.
  • /metadata and /metadata/:id already redirect to /sessions; no change.
  • Group the remaining sidebar entries: Monitor / Analyze / Media / Administration.

2. Sessions

  • Label the counts (23 streams · 0 samples), locale-formatted.
  • Render the labeled active/closed status the operator app already has.
  • Bind the identity swatch to the device name so it no longer reads as status.
  • Replace the empty detail pane with a summary of the active filter.

3. Devices

  • Resolve the horizontal overflow; drop low-priority columns at narrow widths.
  • One primary status badge plus +N overflow, so row height is uniform.
  • Give Info labeled power / battery / signal values.
  • Move fault text out of the name into the status area.

4. Device timeline

  • Sticky overview strip of sparklines so all sensors are visible at once.
  • Collapse constant series by default, with the range stated.
  • Split the header into labeled min-max / avg / latest / points.
  • Legend for the shaded session bands.

5. Operator app

Its Sessions/Devices are already the better implementation. Adopt the same labeled-count wording; keep navigation at its current 6 entries.

Testing

  • tsc -b and the full vitest suite in both apps.
  • Playwright at 375 / 768 / 1280, asserting zero pageerror on the changed pages.
  • EN+KO key parity check.
  • A tripwire pinning that no nav entry points at a route that is not mounted.