refactor(web): rebuild dashboard UI on shadcn-svelte primitives - #97
Merged
flamboh merged 7 commits intoAug 22, 2026
Merged
Conversation
flamboh
force-pushed
the
t3code/refresh-frontend-experience
branch
from
August 22, 2026 09:54
937cde4 to
f9400dd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The dashboard had no component layer: buttons, cards, checkboxes, and four independent segmented-control implementations were hand-rolled inline and had drifted apart. Dark mode was 279 per-callsite
dark:variants. The three breakdown chart cards (IPChart/ProtocolChart/SpectrumStatsChart, ~2,800 lines) were near-clones sharing 19 identically named functions. A few Svelte 4 idioms survived (createEventDispatcher, awritablestore), and chart drag handlers wrote$stateon every raw mousemove.Solution
Five commits, each independently green:
src/lib/components/ui/, semantic theme tokens (bg-card,text-muted-foreground, …) mapped onto the existing palette (dark surfaces#0a0a0a/#111111/#1a1a1a/#2d2d2d, primary blue-600). Dark mode is now defined once in CSS variables.SegmentedControl(with tooltip-on-disabled) replaces all four hand-rolled variants; zerodark:variants remain in app code.ChartCardshell (header/controls/resizable well/loading-error-empty states/drag overlays) plus one parameterizedBreakdownChart+ per-kind config replaces the trio.createEventDispatcherretired app-wide for callback props,rangeSelectionmoved to a runes class, drag interactions rAF-batched. Chart.js configs preserved verbatim — a future chart-library swap now touches one file.--color-dark-*tokens removed.Tooltip.Providerin the root layout (bits-ui tooltips throw during SSR without one; found in browser verification, invisible to the home-only e2e test).Net: authored frontend code shrinks ~2,900 lines; ~1,300 lines of vendored primitives added.
Review fast path
Flows to exercise: home → dataset dashboard → toggle metric/granularity/chart-type controls, drag-select a range on a chart, drill down, reorder chart cards, alerts page (tabs + table), theme toggle, netflow files pages.
Setup: a local dataset DB on the current schema (
bucket_coveragetable). Older local v2/v3 databases render the chart cards' error states instead — that's pre-existing schema drift, not this PR.Expected: visually equivalent to before — same layout, density, and palette in both themes. No data-contract or API changes.
Decisions worth knowing:
<select>and<input type="date">kept (restyled with tokens) rather than adopting bits-ui Select — simpler and keeps native behavior.button[role=checkbox]instead of native inputs; aria labels and visible text preserved throughout.ChartCardwith parameterized copy.Verification
bun run format/lint/typecheckclean (svelte-check: 0 errors, 0 warnings)bun run test:web: 90/90 passingbun run test:e2e: passingvite build, Cloudflare adapter) succeedsRemaining manual check: a dark-mode visual pass (tokens make it a single-source change, but eyes on it are cheap insurance).
Directed by Claude Fable 5 (t3 code harness); implementation by gpt-5.6-sol agents via
codex exec.