Commit 75a2e56
refactor(ui): migrate Mantine UI v8 → @ossrandom/design-system v0.3.0 (#71)
* refactor(ui): migrate Mantine UI v8 to @ossrandom/design-system v0.3.0
Replace the Mantine dependency with the RandomCodeSpace design system per
project board direction. Per-component scope is small — the UI's only
direct Mantine surface is main.tsx (provider) plus two MCP components
(Modal/Tabs).
Changes:
- main.tsx — MantineProvider to ThemeProvider; ToastRegion mounted at root
- ToolCallModal.tsx — Mantine Modal to DS Modal. DS Modal API is stricter
(no padding=0, no classNames, no styles, no custom width) so the
hand-rolled header is collapsed into title/description props and the
modal sizes to lg instead of min(880px, 100vw-2rem).
- RPCPopup.tsx — Mantine Modal+Tabs to DS Modal+Tabs. Tabs API is items
rather than children, so the methods array maps to items={[{key,label}]}.
- @mantine/core and @mantine/hooks removed from package.json
- @ossrandom/design-system@0.3.0 added (public npm; no GHP/PAT setup)
- internal/ui/dist regenerated. Net bundle is -598 / +123 lines because
Mantine CSS is gone; DS ships variable woff2 fonts (Bricolage Grotesque,
Plus Jakarta Sans, Geist Mono) as separate ~30-130KB assets that load
on demand.
- CLAUDE.md project rules updated: NO Tailwind CSS, NO Mantine — use
@ossrandom/design-system exclusively for UI components and tokens.
Raw CSS only for layout escape hatches.
Out of scope (deliberate, follow-up PRs):
- Strip ui/src/styles/tokens.css and slim global.css to layout-only.
- Migrate ServiceMap.tsx / EChart.tsx from echarts to DS charts subpath.
- Replace inline style={{display:flex…}} with DS Space/Grid/Card.
Drive-by: pin react-window to ^1.8.10 (was ^2.2.7). The v2 API is
incompatible with current LogsPage.tsx / TracesPage.tsx imports
(VariableSizeList, FixedSizeList, ListChildComponentProps no longer
exported), and the build was broken on main even before this PR. The
v2 migration is its own concern; pinning back to v1 here keeps this PR
strictly about the DS swap and gets the build green.
Verification:
- npm run build: clean
- npm run test: 32/32 pass
- Live: HTTP_PORT=37778 ./otelcontext, GET / returns the DS-styled bundle
(fonts load on demand, /assets/index-*.js + /assets/index-*.css served).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* checkpoint: pre-yolo 2026-04-29T14:13:52
* checkpoint: pre-yolo 2026-04-29T14:27:59
* refactor(ui): bind legacy CSS tokens to DS variables for instant visual shift
Rewrite ui/src/styles/tokens.css so the legacy --bg-base / --text-primary /
--color-accent etc. names resolve to @ossrandom/design-system tokens
(--bg-0..3, --fg-1..4, --accent-fg, --border-1..3). Existing inline
`var(--*)` usage and the .card/.top-nav/.nav-link rules in global.css now
pick up the DS palette and fonts (Bricolage Grotesque, Plus Jakarta Sans,
Geist Mono, Cod Gray on Signal Red) without touching every component.
This is the thin transition shim called out as "out of scope" in the
parent commit's message — a follow-up PR will replace the class-based
styles in global.css with DS components and delete this file entirely.
Bundle delta: -21 CSS lines (light-theme block removed; DS owns theming
via ThemeProvider mode now). Live verified at oteliq.randomcodespace.dev:
the new CSS hash (index-BLTTK0qH.css) ships --bg-base:var(--bg-0) plus the
DS variable woff2 references for all three font families.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(ui): full migration to @ossrandom/design-system; drop echarts + custom CSS
- ServiceMap: replace echarts force-directed graph with DS ServiceMap (cose-bilkent)
- TracesPage / LogsPage / ServiceSidePanel: replace .card / .badge / .side-panel
classes with DS Card / Badge / Button / Alert / Input / Spin / Space
- TopNav / MCP console + modals: already on DS, polished tones (mono palette)
- ErrorBoundary: keep inline styles (must render if DS fails to load) but bind
to DS CSS vars with hex fallbacks for theme harmony
- Strip global.css to layout-only escape hatches (#root, scrollbar, code, html
height); strip tokens.css to box-sizing reset + colorJSON syntax palette
- Remove echarts dependency (-4 packages); delete unused EChart wrapper +
tierLayout (orphaned after migration)
- Net 1376 insertions / 1722 deletions; CSS bundle 49 KB (gzip 9.4 KB)
* refactor(ui): zero custom CSS — pure DS primitives (AppShell/PageHeader/Stat/Grid/CodeBlock)
- App: AppShell hosts header + main content; no inline styles
- TopNav: PageHeader + controlled Tabs + Stat strip; StatPill helper deleted
- ServiceSidePanel: KPI grid → DS Stat (4-up); upstream/downstream lists →
Card-bordered Buttons; health bar → DS Progress
- TracesPage / LogsPage: 12-col Grid + Card + ScrollDiv + Space; row buttons
built from DS Button + Space; pre-with-HTML eliminated
- ServiceMap: side-panel split moved to Grid (8/4); toolbar → Card extra slot
- MCP modals: pre+colorJSON HTML → DS CodeBlock (language="json", copyable)
- ToolCard / MCPConsole / ToolCallModal / RPCPopup: Grid + Space replace
inline grid/flex; Card title/extra/footer slots replace bespoke headers
- Drop tokens.css entirely (--syntax-* palette unused after CodeBlock swap);
global.css trimmed to browser reset only (3 rules: box-sizing, body margin,
#root height)
- utils.ts: drop unused colorJSON + esc helpers
Net: 619 insertions / 1078 deletions; CSS bundle 48.5 KB (gzip 9.2 KB).
* refactor(ui): per-page redesign — Drawer-based detail, DS Table for streams, MCP simplified
Each view now owns its own layout with PageHeader + Stat strip + a single full-width
data surface, instead of cramming a split-grid into a shared container.
- ServicesView: full-bleed DSServiceMap (height 620); right Drawer hosts the
service detail panel on node-click. 4-up Stat strip surfaces real-time
active services / error rate / total traces / total logs.
- TracesView: DS Table (compact, sticky header, striped) replaces the virtualized
card list; row click opens a right Drawer with the span waterfall. Stats:
in-view trace count, error count, avg duration, p95 (computed locally).
- LogsView: DS Table for the stream; severity Buttons + Input live in
Card.extra. "Find similar" opens a right Drawer instead of stealing a
side column. Stats: in-view / errors / warnings / info counts.
- MCPConsole rewritten: tool cards / Call / JSON-RPC modals removed entirely.
Single Card now shows the endpoint URL with copy button + three example
CodeBlocks (tools/list, tools/call, curl). useMCP hook deleted.
- TopNav: compact horizontal bar — brand, controlled Tabs, live/offline badge,
theme toggle. Stat strip moved into per-view PageHeaders.
- App: AppShell.header = TopNav; main = view switch. No serviceFilter/dashboard
global chrome — each view consumes what it needs.
Files removed: ToolCard.tsx, ToolCallModal.tsx, RPCPopup.tsx, useMCP.ts,
ServiceMap.tsx, TracesPage.tsx, LogsPage.tsx (all replaced).
Deps removed: react-window, @types/react-window (-3 packages); virtualization
is unnecessary at the 200-row cap.
Net 804 insertions / 1096 deletions; JS 247 KB / gzip 77 KB; CSS 48.5 KB / gzip 9.2 KB.
* fix(ui): mobile nav drawer + tighter layout + minimal MCP page
Mobile (≤760px) nav was unreachable — header overflowed off-screen with no
hamburger. Layout was also too heavy — every Stat was its own bordered Card.
- TopNav: useMediaQuery splits into compact (hamburger → left Drawer with DS
Menu vertical) and wide (Tabs inline) variants
- StatRow component: single Card with inline Stats separated by Divider —
replaces the 4-card 12-col Grid wrapper across all three views
- MCP page reduced to one Card: URL with Copy button + one paragraph on
HTTP-Streamable / JSON-RPC / Bearer auth. The 3 example CodeBlocks are
gone (they read as "tools" still being there).
- Drawer width: number on desktop, "92vw" on mobile so it doesn't overflow
- ServiceMap height: 660 desktop, 460 mobile (the map is the hero)
- PageHeaders use size="sm" with inlineSubtitle to reclaim vertical space
- ServicesView accepts string-or-number DBSizeMB from /api/stats (server
returns "1990.0" as string while old type expected number)
11 files changed, 269 insertions / 258 deletions.
* checkpoint: pre-yolo 2026-04-30T00:33:37
* fix(ui): show error rate to 2 decimals
ServicesView and ServiceSidePanel: toFixed(2) instead of toFixed(1).
* fix(ui): drop redundant Stat deltas; round p95 delta to 1 decimal
DS Stat renders delta.value verbatim, so passing a raw float showed e.g.
"↑15.661224321%". The error-rate / error-count / warn-count deltas were
also redundant with the main value (no period-over-period data).
- ServicesView / ServiceSidePanel: drop delta on error-rate Stat (showed
the same number as the value).
- LogsView: drop delta on errors / warnings (same — count == count).
- TracesView: keep p95 delta (it's a real comparison vs avg) but round
to 1 decimal at the source so DS doesn't print 10 decimals.
* checkpoint: pre-yolo 2026-04-30T01:25:30
* fix(ui): Services Stat strip uses cumulative DB counts, not recent counters
dashboard.total_traces / total_logs are *recent-window* counters, while
DBSizeMB reflects the entire on-disk dataset. The mismatch made 4 GB look
unjustified next to a small "Logs" number. Switch the Traces/Logs Stats
to /api/stats (TraceCount/LogCount) so they reconcile with DB size; fall
back to dashboard counters when /api/stats hasn't loaded yet.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent c924a83 commit 75a2e56
40 files changed
Lines changed: 1440 additions & 2985 deletions
File tree
- internal/ui/dist
- assets
- ui
- src
- components
- mcp
- observability
- hooks
- lib
- __tests__
- styles
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments