Skip to content

Commit 75a2e56

Browse files
aksOpsclaude
andauthored
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

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
OtelContext is a self-hosted OTLP observability platform. Single Go binary with embedded React frontend.
66
- **Backend:** Go 1.25, native `net/http` (no frameworks), GORM ORM, gRPC + HTTP for OTLP ingestion
7-
- **Frontend:** React 19 + TypeScript + Mantine UI v8 + ECharts + ReactFlow
7+
- **Frontend:** React 19 + TypeScript + `@ossrandom/design-system` + ECharts + ReactFlow
88
- **Ports:** gRPC `:4317` (OTLP), HTTP `:8080` (API + HTTP OTLP + WebSocket + UI)
99

1010
## Strict Rules
1111

1212
- NO Express.js/Gin/Echo — use native Go `net/http`
13-
- NO Tailwind CSS — use Mantine UI v8 exclusively
13+
- NO Tailwind CSS, NO Mantine — use `@ossrandom/design-system` exclusively for UI components and tokens. Raw CSS only for layout escape hatches (root height, scrollbar overrides, virtualised list containers); no auxiliary visual styling.
1414
- Single-service architecture (no microservices split)
1515
- All internal DBs must be **embedded** (no external processes)
1616
- Relational DB (SQLite/MySQL/PostgreSQL/MSSQL) is the **single source of truth**
Binary file not shown.
69.3 KB
Binary file not shown.
26.7 KB
Binary file not shown.

internal/ui/dist/assets/cytoscape-cose-bilkent-nxdGmLq9.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/ui/dist/assets/cytoscape.esm-Dm6iss-N.js

Lines changed: 321 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/ui/dist/assets/design-system-BNhP-Tae.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/ui/dist/assets/design-system-DFjB0sSn.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/ui/dist/assets/design-system-IOKLDoaG.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/ui/dist/assets/index-Bi057qLa.js

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)