Repository navigation
feat: wrap up and enhanced canvas page - #2302
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds a Canvas playground: JSON-spec editor + live preview, streaming LLM spec generation API, chart primitives and chart components, templates and exports (PNG/PDF), Canvas UI/sidebar, and theme/navigation updates across the playground. ChangesCanvas Editor Implementation
Sequence Diagram(s)sequenceDiagram
participant User
participant Canvas as CanvasPageClient
participant API as POST /api/canvas/generate
participant Auth as getUser()
participant Gateway as LLM Gateway
participant Storage as Preview/Spec State
User->>Canvas: click generate with prompt
Canvas->>API: POST {prompt, model}
API->>Auth: validate user
Auth-->>API: user data
API->>Gateway: streamText with catalog system prompt
Gateway-->>API: stream chunks
API-->>Canvas: text stream
Canvas->>Canvas: compileSpecStream incrementally
Canvas->>Storage: update preview + editor
Canvas-->>User: render live preview
sequenceDiagram
participant User
participant Canvas as CanvasPageClient
participant HTMLtoImg as html-to-image
participant JSPDF as jspdf
User->>Canvas: click export
Canvas->>Canvas: detect background color
User->>Canvas: select PNG or PDF
Canvas->>HTMLtoImg: convert preview DOM to PNG
HTMLtoImg-->>Canvas: PNG blob
Canvas-->>User: download PNG
Canvas->>JSPDF: create PDF with dimensions
JSPDF->>HTMLtoImg: convert to image for PDF
HTMLtoImg-->>JSPDF: image data
JSPDF-->>Canvas: PDF blob
Canvas-->>User: download PDF
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/playground/src/app/api/canvas/generate/route.ts`:
- Around line 25-27: Wrap the JSON parsing in route.ts that calls await
req.json() (the code that assigns body as CanvasGenerateBody and extracts
prompt/model and systemPrompt) in a try/catch to handle malformed JSON;
specifically catch SyntaxError from req.json() and return a 400 response with a
clear error message instead of letting it bubble up to a 500, then proceed with
existing validation/processing only when parsing succeeds.
- Around line 16-71: This Next.js route's backend logic (POST, createLLMGateway,
streamText, cookieApiKey, selectedModel, systemPrompt, messages) must be moved
behind the internal API layer: either implement a new backend endpoint in the
API app that encapsulates the current generation logic (create the POST handler
in the API service that performs auth, reads cookie API key, builds
createLLMGateway, calls streamText and returns the stream) or replace this
route's body with a call to the generated typed internal API client from the
playground app (invoke the new API endpoint, forwarding prompt/model and letting
the API handle auth and gateway creation), then return the client response as
the route response; make sure to remove direct LLM gateway usage from the
playground and reference the same symbols (selectedModel, systemPrompt,
messages) when moving logic so behavior remains identical.
In `@apps/playground/src/app/canvas/page.tsx`:
- Around line 59-61: The selection logic for selectedOrganization uses (orgId ?
organizations.find((o) => o.id === orgId) : organizations[0]) ?? null which
makes selectedOrganization null when orgId exists but find returns undefined;
change the logic in the page component so that when orgId is provided but no
matching organization is found you fall back to organizations[0] (or null only
if organizations is empty). Update the expression that computes
selectedOrganization (referencing selectedOrganization, orgId, and
organizations) to prefer the found organization if present, otherwise default to
the first organization in the list.
In `@apps/playground/src/components/playground/canvas-page-client.tsx`:
- Around line 150-158: Replace the raw fetch call that posts to
"/api/canvas/generate" with the typed client from "`@/lib/fetch-client`"
(useFetchClient or useApi); locate the fetch usage inside the function where
prompt, selectedModel and abortRef.current.signal are used and call the
generated client method for the canvas.generate endpoint instead, passing the
same payload ({ prompt, model: selectedModel }) and the abort signal, then
handle the typed response and errors consistently with the rest of the component
(e.g., preserve existing response handling logic and error/cleanup behavior).
- Around line 252-253: The dynamic import of html-to-image (and analogous
dynamic import of jspdf) inside the client component should be replaced with
top-level imports to satisfy the TS/TSX guideline; remove the await
import("html-to-image") and instead add top-level imports for html-to-image
(e.g., import { toPng } from "html-to-image") and jspdf (e.g., import jsPDF from
"jspdf") at the top of
apps/playground/src/components/playground/canvas-page-client.tsx, then update
the code that calls toPng and jsPDF to use the imported symbols directly (ensure
any existing variable names like toPng and jsPDF are referenced consistently).
In `@apps/playground/src/components/ui/chart.tsx`:
- Around line 239-243: The tooltip currently hides numeric zero because it uses
a truthy guard on item.value; update the render condition in the tooltip (the
JSX block that checks item.value and renders the <span> with className
"font-mono font-medium text-foreground tabular-nums") to explicitly allow 0 by
checking for null/undefined instead (e.g., item.value != null or item.value !==
null && item.value !== undefined) so zero values are displayed while still
hiding null/undefined.
- Around line 83-101: The injected stylesheet built in the style tag using
dangerouslySetInnerHTML directly interpolates id, theme keys from THEMES and
color strings from colorConfig; fix by escaping and validating all CSS tokens
before interpolation: use CSS.escape(id) and CSS.escape(theme) for selectors,
map config keys through CSS.escape for variable names, and validate/whitelist
color values (e.g., allow only hex/#rgb(a) or known color names) or otherwise
skip invalid colors before building the string in the style block; update the
code around THEMES, id, and colorConfig usage inside the dangerouslySetInnerHTML
construction to apply these sanitizers and drop/nullify any invalid entries so
no untrusted values are injected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 67a0471d-4f37-465b-bf6b-5dc07d5e8ece
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (22)
apps/playground/next.config.tsapps/playground/package.jsonapps/playground/src/app/api/canvas/generate/route.tsapps/playground/src/app/canvas/page.tsxapps/playground/src/components/playground/canvas-page-client.tsxapps/playground/src/components/playground/canvas-sidebar.tsxapps/playground/src/components/playground/chat-sidebar.tsxapps/playground/src/components/playground/chat-ui.tsxapps/playground/src/components/playground/group-chat-client.tsxapps/playground/src/components/playground/image-header.tsxapps/playground/src/components/playground/image-sidebar.tsxapps/playground/src/components/playground/org-header.tsxapps/playground/src/components/playground/org-sidebar.tsxapps/playground/src/components/playground/video-header.tsxapps/playground/src/components/playground/video-sidebar.tsxapps/playground/src/components/ui/card.tsxapps/playground/src/components/ui/chart.tsxapps/playground/src/lib/canvas/catalog.tsapps/playground/src/lib/canvas/chart-components.tsxapps/playground/src/lib/canvas/chart-definitions.tsapps/playground/src/lib/canvas/registry.tsxapps/playground/src/lib/canvas/templates.ts
💤 Files with no reviewable changes (4)
- apps/playground/src/components/playground/group-chat-client.tsx
- apps/playground/src/components/playground/video-header.tsx
- apps/playground/src/components/playground/image-header.tsx
- apps/playground/src/components/playground/org-header.tsx
Summary by CodeRabbit
New Features
UX