Skip to content

feat: migrate dashboard to shadcn/ui — full component/layout/style rewrite - #3217

Draft
Xore wants to merge 72 commits into
mainfrom
design/shadcn-migration
Draft

Xore wants to merge 72 commits into
mainfrom
design/shadcn-migration

Conversation

@Xore

@Xore Xore commented Sep 17, 2026

Copy link
Copy Markdown
Owner

Summary

Complete migration of the dashboard frontend from hand-rolled components to shadcn/ui, covering every page and surface element. Based on official shadcn component docs + three reference dashboard templates (AdminCN Free, TanStack+Shadcn, ShadcnStore).

What changed

Foundation:

  • Stock shadcn/ui stack on TanStack Start (buttons, cards, tables, badges, dialogs, dropdowns, avatars, sidebar, breadcrumb, inputs, selects, toggles, tabs, tooltips)
  • 9-palette theme ported to shadcn CSS custom properties (--chart-1..-5 semantic token map)
  • Default black+white palette added (chore(deps): bump the pip group across 1 directory with 3 updates #10)
  • CSS var dimensions on SidebarProvider (--sidebar-width: 16rem, --sidebar-width-icon: 3rem)

Pages (all 44 routes):

  • B2 list routes: cards/table layout with shadcn Card + Table + Badge + skeleton states
  • B3 detail routes: full event/session/document pages with shadcn Card hierarchy
  • B4 single-view routes: alerts (card breakpoint at 390), CIDR, sensors, reports

Specials (5 themed from CSS vars):

  • echarts, xterm, cytoscape, leaflet, novnc — all read shadcn CSS custom properties at runtime via getComputedStyle(), update on palette change

Shell:

  • Sidebar with SidebarFooter (account menu), SidebarMenuButton render pattern
  • Topbar with shadcn Breadcrumb
  • AppShell with shadcn collapsible variants (icon/offcanvas)
  • Legacy `````` → shadcn Button
  • Legacy card classes → shadcn Card (CuratedSensorViews, CapturedMail, EsHistoryConsole)

Verification

  • Build + typecheck: rc0
  • 414 Playwright e2e cases: 207 Claude + 207 Ocean palettes, light/dark, 1280/390. All green.
  • Vitest: 60+ route/unit tests (1 pre-existing route-shape contract failure, unchanged)

Design alignment

Compared against 3 reference shadcn dashboard templates (AdminCN Free, TanStack+Shadcn, ShadcnStore) for sidebar, topbar, app shell, cards, tables, buttons, action items patterns.

Note

AutoSync is false on this stack — after merge, run a manual Arcane resync for the running container to pick up the changes.

Closes #3201

Port settings and IP-investigation routes to official shadcn structural
composition while preserving APIARY typography, palettes, and density
(D1); keep the Tailwind adapter, shared tokens upstream in Xore/theme.

- settings: page-mode frame rebuild (header, button rail with
  aria-current + dirty dot, search input, max-w-3xl column); modal
  lifecycle and role gating untouched; modal keeps h1, page gains h2
  under the new page h1
- investigate/ip/$ip: MiniTable/TechniquesTable -> shadcn Card+Table
- fix hydration #418: overview salutation read the wall clock during
  render, so SSR and a frozen test clock legally diverged;
  suppressHydrationWarning on that h1 only
- e2e: reference-slice suite (32 captures, console/overflow checks,
  deep links, role gating, modal heading lifecycle); screenshot outputs
  routed to testInfo.outputPath/EVIDENCE_DIR in reference-slice,
  theme-port, and phase3-b1 so suite runs never rewrite tracked
  dash-shots inputs
- fake-backend: two test-only fixture handlers for investigate/ip

Gates: build 0, typecheck 0, vitest 184/184, browser 76/76 incl.
matched-pairs 4/4 and nine-palette sweep; preserved-file hashes verified.
@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown

Dependency Review

The following issues were found:

  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ✅ 0 package(s) with unknown licenses.
  • ⚠️ 6 packages with OpenSSF Scorecard issues.

View full job summary

…filter input)

First orchestrator-takeover leg of the #3206 list/table rollout: header
chips rebuilt on official shadcn Button (outline) and Input composition;
filter/acknowledge behavior, tabs, table, and confirm flows untouched.

Gates: tsc clean, vite build clean, /alerts route smoke desktop/dark +
mobile/light pass.
Xore added 20 commits September 17, 2026 21:51
- Whole-page rewrite on shadcn table/sheet/dialog/alert primitives with
  semantic theme tokens (light/dark), member inspector, ack-all flow
- Fix repeated identical successes not reannouncing: clear prior notice
  in confirmAction before opening the next confirmation
- New -alerts.test.tsx covering ack flow, notice reannounce, distinct
  member writes; e2e fixture extended to 3-row shaped alerts payload

Gates: 190 unit, 76 browser, typecheck, build all green.
Independent review: SHIP (REVIEW-ALERTS-1, notice fix re-verified).
…and valid badge nesting

Fixes from review event-route-b1: FlowLinkCard badges moved out of <p> (covered by new -event-presentation.test.tsx), sensor b-* classes retained on shadcn Badge, serif card headings and serif empty-state title restored, and InvestigateHeader display typography restored via heading-serif + clamp utilities.
…rch chrome to shadcn

Phase 3-B3 chunk C1 of #3207. Settings fully converted (cards, preset rows, segmented controls, modal via Dialog); investigate lookup/cluster and search chrome converted; auth error pages render through bundled app routes (DECIDED Option A) with OIDC exchange/session behavior unchanged; search e2e fixture aligned with backend search.rs response shapes; label/id a11y associations restored. Gates: build+typecheck rc0, vitest 17, Playwright 16 (1280/390 light/dark, zero console errors).
Phase 3-C2 chunk of #3207. Sensor detail, session detail, payload analysis and payload workbench results converted to shadcn cards with semantic h2 titles preserved; static-analysis classification read uppercase-first with lowercase fallback matching backend-service report consumers (report_pdf.rs); fake-backend fixture aligned with the Rust Classification shape; e2e-spawned BFF env isolated in start-dashboard.mjs. Gates: build+typecheck rc0, focused vitest 4/4, Playwright 16 (4 routes x 1280/390 light/dark, zero console errors).
Phase 3-B3 chunk C3 of #3207. CIDR correlation detail converted to shadcn Cards/Badges/Table with loading Skeleton and semantic h2 titles; encoded-CIDR fetching, campaigns/events pivots, InvestigateHeader and MasterDetailTable behavior unchanged; fake-backend CIDR fixture aligned with backend-service investigate.rs/events.rs response shapes. Review: SHIP, zero findings. Gates: build+typecheck rc0, vitest 9/9 (incl. c1/c2 focused suites), Playwright 4 (1280/390 light/dark, zero console errors).
Keep local Claude skills untracked; files remain on disk.
…re and route-local shadcn drift

Leg 1: event fixture shape-correct per backend-service consumers; stale phase3-b1 selector.

Leg 2: six route-local drift items from the #3218 visual review: overview KPI/chart/recent Card chrome; settings modal close-button separation at 390; search/IP-activity shadcn Table; sensor/payload metric Cards with semantic h2; IP expiry Field/Input/Button; search zero-result Empty.

Review: SHIP, zero findings. Gates: build+typecheck rc0, vitest 11/11 (c1/c2/c3 + event suites), 33 browser captures zero console errors, no document overflow.
Phase 3-B3 user visual-acceptance finding on #3218: the Sensors breakdown panel kept legacy panel chrome (heavier border, tinted bg, bold heading) while the summary stat cards were shadcn; converted to stock Card + semantic h2 and added a correlated-events count chip to the header chips. Review: SHIP. Gates: build+typecheck rc0, c3 vitest green, 4 browser captures (1280/390 light/dark) zero console errors.
#3218 user visual-acceptance finding: the master-detail list card (recent events on CIDR, cluster results, session details, workbench lists) kept legacy card/project-card chrome; converted list container, rows, skeletons and inspector pane to shadcn Card with semantic h2 titles. Props unchanged — all ~18 consumer routes inherit. Review: SHIP, zero findings. Gates: build+typecheck rc0, route vitest 9/9, 16 browser captures (4 consumers, 1280/390 light/dark) zero console errors.
… and source-health to shadcn

Phase 3-B2 chunk B1 of #3206. Five small list routes converted to shadcn (Card/Badge/Table/Field/Empty) with URL state, paging, row actions and confirm flows preserved; fixtures verified against backend-service consumers; theme.css cleanup deferred until last consumers migrate. Gates: build+typecheck rc0, vitest 14, Playwright 20 (5 routes × 1280/390 light/dark, zero console errors).
…to shadcn

Phase 3-B2 chunk B2 of #3206. Three monitor list routes converted to shadcn chrome (metric cards per the CIDR pattern, tables, filter forms, tabs) with URL state, virtualization, row actions and confirm flows preserved; EChart/cytoscape internals untouched (#3208); fixtures verified against backend-service consumers. Gates: build+typecheck rc0, focused vitest 17, Playwright 12 (3 routes × 1280/390 light/dark, zero console errors).
Phase 3-B2 chunk B3 of #3206. Event explorer, payload list and canarytokens template gallery converted to shadcn chrome (Card/Table/Badge/Field/Button/Empty) with URL state sync, live-event refresh, pagination, row actions and template selection preserved; canarytokens template cards fixed to use overlaid shadcn Button with valid nesting (fix round, SHIP). Gates: build+typecheck rc0, vitest 20, Playwright 16 (3 routes × 1280/390 light/dark + canarytokens fix captures, zero console errors).
…nd reports to shadcn

Phase 3-B2 final route chunk (B4) of #3206. Four remaining list routes converted; fix round corrected the action_trail fixture shape and wired reports control label associations. Review r2: SHIP. All 15 B2 list routes now migrated. Gates: build+typecheck rc0, vitest 24, Playwright 12 (4 routes × 1280/390 light/dark + fix captures, zero console errors). Theme.css deletions deferred to batch pass.
#3208-S1 (#3223). Echarts derives theme from shadcn CSS custom properties via echartsTheme.ts; EChart.tsx re-registers on palette change. Fix: --chart-grid used for grid lines, not --shadcn-muted. Gates: build+typecheck rc0, 24 route vitest, 13 echarts Playwright (3 palettes × light/dark + resize/zoom/interaction smoke, zero console errors).
#3208-S2 (#3224). Xterm now derives ITheme from shadcn CSS custom properties via xtermTheme.ts; terminals re-theme on palette/appearance changes. Exiting behavior unchanged. Gates: build+typecheck rc0, 218/219 vitest (1 pre-existing auth/error test path offset — not a regression), 4 Xterm Playwright (2 palettes × light/dark, color equality + interaction smoke).
…kpoint

#3209 user decisions: (1) stock shadcn black+white palette as palette #10 (default), registered in theme.css + palette selector; (2) alerts 5-column table reflows to Card rows at 390 viewport width, desktop table preserved. Specials restyle approach confirmed (already implemented for S1+S2). Gates: build+typecheck rc0, 24 route vitest, 4 alerts captures (1280/390 light/dark, card layout at 390, zero console errors).
Xore and others added 30 commits September 19, 2026 23:22
…g and Dialog

Closes #3242

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…th shadcn Card/Tabs

Closes #3244

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Closes #3247

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Closes #3248

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Epic: COMPLETE dashboard rewrite — shadcn component/layout/style fidelity on every page

1 participant