[FEATURE] Migrating ui to react#1147
[FEATURE] Migrating ui to react#1147nicolastakashi wants to merge 61 commits intoopen-telemetry:mainfrom
Conversation
dc08128 to
0a97b0d
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1147 +/- ##
=======================================
- Coverage 80.1% 80.0% -0.1%
=======================================
Files 108 108
Lines 8440 8440
=======================================
- Hits 6763 6760 -3
- Misses 1677 1680 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
jsuereth
left a comment
There was a problem hiding this comment.
Not sure how exactly to review this, but lots of meta comments about architectural decisions here.
From my perspective, I don't care if we use svelte or react. I do care if the code is maintainable and extendable. I think, architecturally, we should clean up some of the decisions in typescript vs. react here, so we have clean logic in typescript, and save REACT for layout and simple callbacks.
I think this means more code moving out of .tsx into .ts file, e.g. making sure api.ts returns typed responses, and adding helper methods to those types.
| return response.json() as Promise<T>; | ||
| } | ||
|
|
||
| export interface RegistryStats { |
There was a problem hiding this comment.
For @jerbly too - Do you think we can auto-generate these from the rust code in some way?
Or at least detect when they fall out of date with each other.
There was a problem hiding this comment.
Yes! It's a little bit circular but you could generate the openapi doc from utoipa (like we do to use it in rapidocs). Then use this doc to generate the typescript.
There was a problem hiding this comment.
Should this file name change now they're we're not vite?
There was a problem hiding this comment.
Sorry @jsuereth, I'm afraid I didn't understand your question.
There was a problem hiding this comment.
Do we need a vite.config.js file if we're not using vite?
| oneOf?: SchemaProperty[]; | ||
| anyOf?: SchemaProperty[]; | ||
| definitions?: Record<string, SchemaDefinition>; | ||
| $defs?: Record<string, SchemaDefinition>; |
There was a problem hiding this comment.
this seems like an inconsistency we could fix on the Rust side - why do we have both defs and definitions?
There was a problem hiding this comment.
Oh, I don't think we need definitions any more. It changed to $defs when we moved to the new JSON schema which happened when we updated schemars recently.
- Create ui-react/ directory with Vite React+TypeScript template - Configure package.json with name weaver-ui-react and scripts (dev, build, preview) - Configure build output to ui-react/dist directory - Add index.html with React root mount point (#root) - Add main.tsx importing global CSS (index.css) This establishes the foundation for the UI migration from Svelte to React.
Add comprehensive plan for migrating UI from Svelte (ui/) to React (ui-react/) using Vite + React + TypeScript with TanStack Router and Tailwind + DaisyUI.
- Install Tailwind 3.4.19, PostCSS 8.5.6, Autoprefixer 10.4.23, DaisyUI 4.12.24 - Create postcss.config.js with Tailwind + Autoprefixer plugins - Create tailwind.config.js with React content globs and light/dark themes - Port global CSS stability badges from ui/src/app.css Build verified: daisyUI 4.12.24 with 2 themes (light, dark)
- Switch from PostCSS approach to @tailwindcss/vite plugin per official docs - Use @import "tailwindcss" and @plugin "daisyui" in CSS instead of @tailwind directives - Remove postcss.config.js and tailwind.config.js (not needed with v4) - Upgrade DaisyUI to 5.5.14 with @plugin directive Official Vite installation: https://tailwindcss.com/docs/installation/using-vite
- Install @tanstack/react-router and @tanstack/react-router-devtools - Set up route tree structure with all required routes - Create placeholder route components for all pages - Update main.tsx to use RouterProvider - Remove unused App.tsx and App.css files Routes added: - / (index) - /search - /stats - /schema - /api-docs - /attribute/:key - /metric/:name - /span/:type - /event/:name - /entity/:type
Mirror Svelte proxy configuration from ui/vite.config.js
- Create AppLayout component mirroring Svelte drawer layout - Implement responsive drawer with mobile toggle and desktop sidebar - Add navbar with Weaver title and theme toggle (sun/moon icons) - Implement sidebar with Registry, Schema, Developer sections - Theme persistence via localStorage with data-theme attribute
- Create ui-react/src/lib/api.ts with BASE_URL = '/api/v1' - Implement fetchJSON() with same error semantics as Svelte (throw on !ok) - Add TypeScript types: RegistryStats, SearchResult, SearchResponse - Implement all API functions: getRegistryStats, getAttribute, getMetric, getSpan, getEvent, getEntity - Implement unified search() with URLSearchParams for query/type/stability/limit/offset
- Create SpanDetail component with full feature parity - Fetch span data via getSpan API - Implement copy-to-clipboard with 2s feedback - Render kind badge with 'internal' default - Show attributes table with sampling relevant indicator - Add loading/error/deprecation states matching Svelte - Update plan.md to mark Span task complete
- Add Event detail route component at /event/:name - Fetch event by name using getEvent API - Implement loading and error states - Add copy-to-clipboard with 2s indicator - Render name, stability, and deprecated badges - Show deprecated warning with renamed_to link - Display description and note using Markdown component - Render event attributes table with requirement level badges - Match Svelte EventDetail.svelte parity exactly
- Add getSchema API function to fetch schema JSON - Create full Schema route component with TypeScript types - Implement schema query param parsing (default ForgeRegistryV2) - Fetch schema from /api/v1/schema/:name on mount/param change - Render left sidebar with definition list + root card - Parse type query param (root or definition name) - Implement selectDefinition/selectRoot URL updates via history.pushState - Port type formatting logic (array/map/union/allOf/oneOf/anyOf) - Implement clickable type references navigation - Verify browser back/forward behavior via popstate listener - Update plan.md to mark task 12 complete
Verified strict parity between Svelte and React implementations: - Search filters: Same type and stability options in both apps - Pagination: Same itemsPerPage=50, offset calc, display - Link targets: Same route paths for detail pages - URL handling: Hash vs history routing (acceptable per requirements) - Search triggering: Both trigger on keystroke and Enter key
- Verified ui/ build continues unchanged (outputs to ui/dist/) - Verified ui-react/ build output stays at ui-react/dist/ - Confirmed docs/ui.md documents how to run/build each app separately - Both apps remain independent with separate build directories
…dist) - Update src/serve/ui.rs to embed ui-react/dist instead of ui/dist - Update comment to reflect new build source directory - Update docs/ui.md Production Deployment section - Mark task as complete in plan.md - Cargo check passes
- Update build_ui() function to use ui-react directory - Update comment to clarify React UI build - Update plan.md to mark task as complete - Update AGENTS.md with build process documentation
- All section 17 notes are documented in docs/ui.md and AGENTS.md
TanStack Router uses HTML5 History API by default (createRouter with default options). The server's serve_ui function correctly implements SPA fallback: - Serves exact files when they exist - Falls back to index.html for any non-file paths This enables History API routing to work correctly.
Deleted ui/ directory as all UI functionality has been migrated to ui-react/: - Rust embed (src/serve/ui.rs) now uses ui-react/dist - Build script (build.rs) builds from ui-react/ - No remaining ui/ references in codebase - React UI builds and works correctly This completes the UI migration from Svelte to React.
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
Move duplicated TypeScript interfaces (MetricResponse, SpanResponse, EventResponse, EntityAttribute, AttributeResponse) from individual route components to api.ts for better type sharing and maintainability. All route files now import from the centralized location. Ultraworked with Sisyphus Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
Signed-off-by: Nicolas Takashi <nicolas.takashi@coralogix.com>
e8b40b3 to
e2b3134
Compare
jerbly
left a comment
There was a problem hiding this comment.
I didn't really know how to review this. I checked out your branch and ran it and everything seems to function well.
So I asked Claude with its new Opus 4.6 model to provide a thorough review. Take this with a pinch of salt and don't necessarily implement it all but I do think there are some important fixes we should get in:
Full code review:
https://gist.github.com/jerbly/4c82f5887339eaf8fc9eede73e532eb0TL;DR: 3 critical security issues (XSS in markdown rendering, no error
boundaries, unsanitized CDN script), significant code duplication across
5 detail routes, and accessibility gaps. See gist for full details and
prioritized recommendations.


This pull request introduces a new React-based UI for the Weaver project, establishing a parallel implementation alongside the existing Svelte UI. It includes extensive documentation, configuration, and planning materials to support the migration, as well as initial scaffolding and setup for the React app. The changes ensure strict parity between the two UIs, clarify the project's structure and conventions, and improve developer experience with updated documentation and tooling.
UI Migration and Documentation:
plan.md) detailing the step-by-step process for creating a React app (ui-react/) to match the current Svelte UI, including route mapping, component parity, API usage, theming, and deployment strategy.docs/ui.md) describing the React UI's tech stack, development workflow, API integration, and deployment requirements.AGENTS.md) summarizing the overall architecture, conventions, anti-patterns, and unique styles of the Weaver project, as well as guidance for navigating the codebase and building the UI.React UI Scaffolding and Configuration:
ui/, including a Vite-based setup, ESLint configuration (eslint.config.js), and a new.gitignoretailored for Node/React development. [1] [2]ui/index.htmlandui/package.jsonfor React, including new mount point, entry script, and app naming. [1] [2]Build and Integration Adjustments:
build.rsthat the build step now targets the React UI, ensuring the correct assets are built and embedded in the Rust server.These changes lay the groundwork for a smooth migration from Svelte to React, provide clear guidance for developers, and establish best practices for UI development and integration within the Weaver project.