feat(canvas): templates, rename, Quill component pass, and showcase#2603
Conversation
Port feat/canvases-rename onto the new package graph and extend it. - Rename user-facing "dashboards" -> "canvases" (strings, breadcrumbs). - Templates: CanvasTemplatesService + schemas in @posthog/core, a canvas-templates host-router, per-template system prompt + component allow-list, and a New-canvas template picker. - canvas-gen now takes templateId + currentSpec; the system prompt is built in main from the template, and the working spec is re-seeded from the renderer each turn. - Charts via @posthog/quill-charts: Line/Bar/Sparkline + PieChart; plus a Progress bar. - Phase-2 palette (Hero/Markdown/Button/Section) and declarative interactivity (state/bindings/visible/actions, TextInput/Checkbox). - Render catalog components with @posthog/quill primitives (Card/Badge/Checkbox/Input/Table/Progress/Separator/Text); bump @posthog/quill to 0.3.0-beta.14 (+ base-ui override). - Gate the data toolbar (filter + refresh) to dashboard-template canvases. - Seed a built-in "Dashboard component Showcase" canvas into a channel on first visit (deduped by name). - Stamp creator at create time and show "Created by" on canvas cards. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
| const claimed = useRef(new Set<string>()); | ||
|
|
||
| useEffect(() => { | ||
| if (!channelId || isLoading || claimed.current.has(channelId)) return; | ||
| if (dashboards.some((d) => d.name === SHOWCASE_CANVAS_NAME)) { | ||
| claimed.current.add(channelId); | ||
| return; | ||
| } | ||
| // Claim before the async create so a re-render mid-flight can't double-seed. | ||
| claimed.current.add(channelId); | ||
| createDashboard( | ||
| channelId, | ||
| SHOWCASE_CANVAS_NAME, | ||
| SHOWCASE_SPEC, | ||
| "dashboard", | ||
| ).catch(() => { | ||
| // Creation failed — release the claim so a later render can retry. | ||
| claimed.current.delete(channelId); | ||
| }); |
There was a problem hiding this comment.
createDashboard reference changes on every render, causing the effect to re-run needlessly
createDashboard is a new arrow-function reference on every call to useDashboardMutations() (it wraps create.mutateAsync inline). Including it in the useEffect dependency array means the callback fires on every render of WebsiteDashboardsIndex, not just when the channel or loading state changes. The claim guard prevents double-seeding, but the effect still walks the full dashboards array each time. Removing createDashboard from the deps and capturing it inside the effect (or memoising it upstream) would limit the effect to the semantically meaningful changes.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/ui/src/features/canvas/hooks/useSeedShowcase.ts
Line: 22-40
Comment:
**`createDashboard` reference changes on every render, causing the effect to re-run needlessly**
`createDashboard` is a new arrow-function reference on every call to `useDashboardMutations()` (it wraps `create.mutateAsync` inline). Including it in the `useEffect` dependency array means the callback fires on every render of `WebsiteDashboardsIndex`, not just when the channel or loading state changes. The claim guard prevents double-seeding, but the effect still walks the full `dashboards` array each time. Removing `createDashboard` from the deps and capturing it inside the effect (or memoising it upstream) would limit the effect to the semantically meaningful changes.
How can I resolve this? If you propose a fix, please make it concise.Address PR review: - Replace the internal capability-test chips (INTERACTIVITY_TESTS / ALLOW_LIST_TEST) with real user-facing Blank-canvas suggestions (landing page, pricing, changelog, feedback form). They were dev jargon shown live in the empty-chat suggestions panel. - useSeedShowcase: hold createDashboard in a ref so it isn't an effect dependency, so the seed effect only re-runs on channel/loading/list changes instead of every render. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks @greptile-apps — addressed in 1b5b981:
|
|
All three fixes look good — thanks for the thorough follow-up.
Tip: You can customize Greptile's behavior for this repo with |
Ports
feat/canvases-renameonto the post-refactor package graph (on top offeat/canvas) and extends it with a Quill component pass + a built-in showcase.What's in it
CanvasTemplatesService+ schemas in@posthog/core, acanvas-templateshost-router, per-template system prompt + component allow-list, and a New-canvas template picker (Dashboard / Blank).templateId+currentSpec; the system prompt is built in main from the template, and the working spec is re-seeded from the renderer each turn (fixes reopen-edit wiping a board).@posthog/quill-charts: Line/Bar/Sparkline + PieChart; plus a Progress bar.@posthog/quillprimitives (Card/Badge/Checkbox/Input/Table/Progress/Separator/Text). Bumps@posthog/quill→0.3.0-beta.14(+ a@base-ui/reactoverride for that package's brokencatalog:dep).Verification
pnpm typecheck— 22/22node scripts/check-host-boundaries.mjs— no new violationsnpx react-doctor@0.4.2 . --blocking error— 0 errors (90/100)pnpm biome check(canvas dirs) — cleanNotes
feat/canvas, not main — this is the incremental port on top of the canvas MVP branch.meta); pre-existing canvases stay blank until recreated.🤖 Generated with Claude Code