Skip to main content

Console UI Revamp

Status

Implemented. Branch feature/console-ui-revamp.

  • Admin Console v1.0 look-and-feel; client §5 "no UI-only features" (every surface stays backed by the same APIs). Demo-freeze polish for the Anil walkthrough.

Problem Statement

The console was dark-only with an ad-hoc theme. The freeze needed a single sophisticated design language, a real light/dark toggle, a credible terminal, and seamless replay of the now-real SSH session recordings (OP-D089) — all without changing a single existing journey.

Architectural Intent

The UI is Tailwind + shadcn-style design tokens, so the entire console is re-skinned by redefining the token set rather than editing components. This keeps all component logic, labels, navigation, and data-testids intact (61 tests stayed green) while changing only the design layer.

What Was Implemented

  • Dual-theme token system (globals.css): a light "paper + ink" default and a refined dark counterpart sharing one confident blue accent. :root = light, .dark = dark; surfaces are solid + hairline + soft-shadow in light, glass in dark.
  • Light/dark toggle (theme-toggle.tsx) persisted to localStorage with a no-flash init script in layout.tsx (honors saved choice then system preference).
  • Display serif headings, Inter body, JetBrains Mono — applied via tokens and a .font-display utility on page titles.
  • macOS terminal chrome (traffic lights, dark window) on the live SSH terminal; the terminal stays dark in both themes (the one true terminal surface).
  • Seamless session-recording replay (ssh-recording-replay.tsx): for any session with a real recording (recordingSha256 = sha256:…), an operator/auditor can replay the captured transcript in an xterm with a light streaming cadence. Fetched via the new proxy route /console-api/oneprotect/rmm/ssh-sessions/{id}/recording.

Components Involved

  • globals.css, tailwind.config.ts, layout.tsx, theme-toggle.tsx, app-shell.tsx, page-primitives.tsx, ssh-terminal.tsx, ssh-recording-replay.tsx, console-pages.tsx, console-api recording proxy route.

APIs / Events / Schemas

No backend change. Replay consumes the existing GET /api/v1/rmm/ssh-sessions/{id}/recording (OP-D089) via the operator proxy.

Security / Tenant Isolation

Replay reuses the operator-auth proxy and the backend's tenant-scoped, role-gated recording read (operator-owner / auditor / admin). No new exposure.

Validation Steps

UI Validation

Toggle light/dark in the topbar (persists). Navigate every page — all journeys unchanged. On an asset with a completed SSH session, press Replay session to watch the recorded transcript play back in the terminal.

Smoke / Tests

frontend: typecheck + 62 tests green (incl. ssh-recording-replay.test.tsx asserting the replay fetches the recording endpoint).

Known Limitations

  • Replay streams output at a fixed cadence (no per-keystroke timing); asciicast-style timed replay is a follow-up.
  • Recording is available only for completed sessions on the live backend (fixture mode shows a graceful "unavailable" state).

Follow-Up Work

  • Timed asciicast replay; per-page density polish; optional theme = "system".

Round 2 — full-size terminal & replay modal

The live terminal and recording replay were cramped in the ~380px asset side column. They now launch in a fixed, centered modal (components/ui/modal.tsx: backdrop + Escape + click-outside + close button), max-w-5xl with a 60vh terminal. The terminal connects when the modal opens and tears down on close (open → effect → openTerminal; close → dispose socket + xterm), so it can be opened, closed, and replayed any number of times cleanly. The inline panels are now compact launchers. Functionality, journeys, and test-ids unchanged (typecheck + 62 tests green).

Acceptance Criteria Mapping

Admin Console look-and-feel refreshed with light/dark + terminal + seamless recording replay, all existing functionality preserved (token-driven re-skin; green tests).