Repository navigation
feat(surveys): add intro screen to the hosted survey canvas - #116329
Conversation
|
Risk: No findings This delta pins Sentinel reviewed |
🤖 CI report✅ Trunk lane — non-backend laneThis PR is assigned to the non-backend lane. It does not run backend Python tests and may merge in parallel with PRs in other lanes.
|
| Function | Location | Complexity | Limit |
|---|---|---|---|
buildCanvasStyles |
frontend/src/scenes/surveys/hosted-canvas/HostedSurveyCanvas.tsx:115 |
18 | 10 |
QuestionCanvas |
frontend/src/scenes/surveys/hosted-canvas/HostedSurveyCanvas.tsx:219 |
15 | 10 |
HostedSurveySettingsPanel |
frontend/src/scenes/surveys/hosted-canvas/HostedSurveySettingsPanel.tsx:66 |
15 | 10 |
HostedSurveyEdit |
frontend/src/scenes/surveys/HostedSurveyEdit.tsx:437 |
11 | 10 |
✅ Duplication (Python) — clean
New Python code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.
⚠️ Duplication (TypeScript) — 1 new duplicated block (worst 93 tokens)
New TypeScript code duplication introduced by this branch. Fails at 70+ tokens in app code, or 150+ tokens when both copies live in test files. Advisory while the gate proves itself: extract a shared helper instead of copying.
| First copy | Second copy | Lines | Tokens |
|---|---|---|---|
frontend/src/scenes/surveys/hosted-canvas/HostedSurveyCanvas.tsx:657 |
frontend/src/scenes/surveys/hosted-canvas/IntroCanvas.tsx:12 |
11 | 93 |
⚠️ Bundle size — 🔺 +51 B (+0.0%)
Uncompressed size of every built .js bundle, compared against the base branch.
Total: 75.87 MiB · 🔺 +51 B (+0.0%)
No file changed by more than 1000 B.
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1005.8 KiB · 23 files | no change | █████████░ 85.8% of 1.14 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
2.87 MiB · 606 files | no change | █████████░ 94.5% of 3.03 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.33 MiB · 2,533 files | no change | ██████████ 95.9% of 7.64 MiB |
dashboard scenesrc/scenes/dashboard/Dashboard.tsx |
9.57 MiB · 3,618 files | no change | █████████░ 93.0% of 10.30 MiB |
today home pathsrc/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx |
7.35 MiB · 2,543 files | no change | █████████░ 93.2% of 7.89 MiB |
events scenesrc/scenes/activity/explore/EventsScene.tsx |
9.15 MiB · 3,446 files | no change | █████████░ 92.7% of 9.88 MiB |
replay detail scenesrc/scenes/session-recordings/detail/SessionRecordingDetail.tsx |
11.93 MiB · 4,287 files | no change | ████████░░ 79.3% of 15.05 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/index.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/lemon-ui/LemonMarkdown/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/RichContentEditor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/CodeSnippet/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/taxonomy/core-filter-definitions-by-group.json stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/zod/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/billing/billingLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/lib/components/ProductEmptyState/productSetupPreloadLogic.ts stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 products/dashboards/frontend/widgets/previews/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 zod/v4/locales/de.js stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/svg/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 node_modules/@posthog/brand/dist/generated/hoggies/components/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/dashboard/Dashboard.tsx
🟢 src/scenes/project-homepage/ai-first/AiFirstHomepage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/project-homepage/today/TodayReportPage.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/queries/Query/Query.tsx stays out of src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
🟢 src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
🟢 src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx stays out of src/scenes/activity/explore/EventsScene.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 1.3 KiB | src/index.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 839 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 69.0 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 38.7 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
| 28.7 KiB | src/scenes/scenes.ts |
| 27.6 KiB | src/lib/constants.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Largest files eagerly shipped from src/scenes/dashboard/Dashboard.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.9 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx + src/scenes/project-homepage/ProjectHomepage.tsx + src/scenes/project-homepage/today/TodayHome.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
Largest files eagerly shipped from src/scenes/activity/explore/EventsScene.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.9 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
Largest files eagerly shipped from src/scenes/session-recordings/detail/SessionRecordingDetail.tsx
| Size | File |
|---|---|
| 319.8 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 316.0 KiB | ../node_modules/.pnpm/posthog-js@1.438.8_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/rrweb.js |
| 280.8 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 220.8 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 181.9 KiB | src/queries/validators.js |
| 153.7 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 113.2 KiB | ../packages/quill/packages/quill/dist/index.js |
| 103.2 KiB | src/products.tsx |
| 99.6 KiB | src/lib/api.ts |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.23 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.23 MiB · 19 files | no change | ████░░░░░░ 39.0% of 5.72 MiB |
| Deferred (lazy) | 2.10 MiB · 40 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.2 KiB | no change | █░░░░░░░░░ 6.0% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 874.8 KiB | dist/toolbar/toolbar-app-3ZTHQS4E.css |
| 664.0 KiB | dist/toolbar/chunk-chunk-BGAZTCLU.js |
| 257.8 KiB | dist/toolbar/chunk-chunk-IVAG7WAO.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 129.6 KiB | dist/toolbar/chunk-chunk-6OD756QW.js |
| 74.7 KiB | dist/toolbar/toolbar-app-VYQLG45N.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-3II7CUPB.js |
| 21.7 KiB | dist/toolbar/chunk-chunk-II4PNXNA.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +32.3 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1009.90 MiB · 🔺 +32.3 KiB (+0.0%)
⚠️ Playwright — 2 flaky
🎭 Playwright report · View test results →
- create experiment via wizard, add metrics, and launch (chromium)
- Materialize view pane (chromium)
These issues are not necessarily caused by your changes.
Annoyed by this section? Help fix flakies and failures and it will go green!
✅ Hogbox preview — ready, open the preview
▶ Open the preview
| 🔑 Login | test@posthog.com / 12345678 (demo data) |
| 🧩 Running | this PR's backend and frontend, on the PostHog :master base |
| 🔗 Link | stable across rebuilds: a re-push swaps the box underneath, the URL stays |
| 🔒 Access | tailnet only (PostHog VPN) |
| 🛠️ Admin | inspect & debug state in hogland |
| 💤 Idle | sleeps after ~30 min idle (snapshot to S3, zero node cost) and wakes on your next visit in ~30s, behind a brief "waking up" screen |
commit cbf14bf · box box-7164b0d9f5a6 · ready in 1215s (push → usable) · build log · rebuilds on every push, torn down on close
|
[Medium impact] Adds intro screen feature to hosted survey canvas. Split the new components into separate files before merging to meet the frontend guide. Reviews (1) · Last reviewed commit: "feat(surveys): add intro screen to the h..." · Reviewed by Greptile |
|
2da5c0a to
a82cf8c
Compare
a82cf8c to
e63e448
Compare
|
✅ Visual changes approved by @lucasheriques — baseline updated in 1 changed. Install the Visual Review Chrome extension to see visual review results at the top of your pull requests. |
A new stamphog review started for this PR — the fresh verdict replaces this approval.
There was a problem hiding this comment.
Not approved — this change needs a human reviewer.
Re-add the stamphog label to request another review once you have addressed this.
Strong author familiarity provides assurance for the security-sensitive rendering change, but @PostHog's open editing concern remains in the current code. Set the description content type to text when committing plain-text edits in IntroCanvas.tsx, add a regression test for editing twice, and re-request review.
- Author wrote 92% of the modified lines and has 92 merged PRs in these paths (familiarity STRONG).
- PostHog Review (Standard) reviewed the current head: no findings.
- 👍 on the PR from greptile-apps[bot].
- @PostHog — frontend/src/scenes/surveys/hosted-canvas/IntroCanvas.tsx: the open concern remains unfixed. Committing an initially empty description updates only its text, preserving an unset or HTML content type; the helper defaults an unset type to HTML, so the newly nonempty description switches to the non-editable rendered branch.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 271L, 8F substantive, 484L/11F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1d-complex (484L, 11F, single-area, feat) |
| stamphog 2.5.0 | .stamphog/policy.yml @ c582edd · reviewed head c582edd |
c582edd to
9ae4956
Compare
9ae4956 to
3e94472
Compare
3e94472 to
8d61813
Compare
8d61813 to
d38b3e7
Compare
A new stamphog review started for this PR — the fresh verdict replaces this approval.
There was a problem hiding this comment.
Approved.
The HTML-rendering surface has independent current-head assurance and a STRONG-familiarity author; sanitization is verified in the source. No substantive unresolved concerns were provided; Greptile's component-organization request is stylistic rather than blocking.
- Author wrote 94% of the modified lines and has 55 merged PRs in these paths (familiarity STRONG).
- PostHog Review (Standard) reviewed the current head: no findings.
- 👍 on the PR from greptile-apps[bot].
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 274L, 7F substantive, 522L/10F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1d-complex (522L, 10F, single-area, feat) |
| stamphog 2.5.0 | .stamphog/policy.yml @ d38b3e7 · reviewed head d38b3e7 |
d38b3e7 to
c68b03b
Compare
c68b03b to
c3a4d12
Compare
|
😎 Stack merged successfully - details. |
|
/trunk merge |
|
This PR is already queued as a stacked merge. Cancel it first to re-submit. |
What: the hosted survey editor gets an "Intro" entry at the top of the flow rail (or an "Add intro screen" button), an IntroCanvas with inline-editable header, description and button label, and intro settings in the right panel with a remove action. hosted-survey.css and the canvas SCSS style the .intro-screen, .intro-screen-header and .intro-screen-body classes that the SDK renders. An HTML intro description is shown through the same sanitizeHTML path as the confirmation canvas, never raw.
Why: hosted surveys render the same SDK intro screen, and the canvas editor had no way to author or preview it. The canvas previously told its two screen kinds apart with an isConfirmation boolean. A third kind made two exclusive booleans, so the canvas and settings panel now take one HostedSurveyPageKind ('intro' | 'question' | 'confirmation') from getHostedSurveyPageKind. The rail's intro and confirmation entries share a small HostedSurveyRailScreen button.
Tested:
- pnpm --filter=@posthog/frontend typescript:check: no errors
- jest src/scenes/surveys: 26 suites / 461 tests pass, including the new parameterized getHostedSurveyPageKind cases
- oxlint and oxfmt on changed files: clean
Notes for the reviewer: not driven in a browser (no dev stack here), so the hosted canvas styling is unchecked visually.
Typing a description into an intro whose content type was unset left the type unset, which renders as HTML, so the canvas swapped the field for the read-only HTML view. Canvas edits are plain text, so they now pin the type to text. Tested: jest src/scenes/surveys/hosted-canvas passes; the new two-edit test fails without the fix.
c3a4d12 to
cbf14bf
Compare
Problem
Hosted survey authors can now add and edit an intro page in the hosted survey canvas. The canvas sits behind the
surveys-hosted-editorflag. Builds on #116326.Changes
sanitizeHTML, the same path the confirmation canvas uses.HostedSurveyPageKind(intro | question | confirmation) replaces theisConfirmationboolean. Progress keys off it, and the public hosted page gets intro styles.New surface, so there are no before screenshots.
How did you test this code?
typescript:checkandjest src/scenes/surveys: pass.Test rationale:
HostedSurveyCanvas.test.tsxrenders the canvas with a French preview, edits the intro and confirmation headers, and checks the other fields keep their base text. It fails without the fix.hostedSurveyPageKindtests catch the canvas misclassifying the intro or confirmation page.Release status
Docs update
None.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (planning, review, verification) and Claude Sonnet 5.5 (implementation)
/writing-ui-components,/writing-user-facing-copy,/writing-tests,/writing-code-comments,/adding-activity-logging,/stacking-prs,/writing-pr-descriptions.