mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* fix(web): decouple privacy banner from onboarding and Settings lifecycles
The first-run privacy banner used to be tightly bound to two unrelated
surfaces: it was hidden whenever Settings was open, and the onboarding
panel only navigated in after the user had resolved the banner. The
coupling existed because the banner's z-index sat below modal backdrops,
so showing both at once collided visually, and the banner+onboarding
were linearized to avoid a "two unfinished things on screen" feel.
This change makes the three surfaces independent:
- Lift `.privacy-consent-banner` z-index above the modal-backdrop layer
so the banner stays visible (and clickable) when Settings is open. The
banner is already `pointer-events: none` with opt-in on its actionable
children, so it does not steal clicks from the layer below.
- Drop the `!settingsOpen` guard from `showPrivacyConsent`.
- Drop the `privacyDecisionAt != null` guard from the bootstrap
onboarding route; first-run users land on `/onboarding` purely based
on `!onboardingCompleted`, and the banner sits on top in parallel.
- Drop the `navigate(... onboarding)` side effect from the banner's
`onAccept` — the banner only persists the privacy decision now.
Bootstrap also had to be reshaped: the merged config is now computed
outside the `setConfig` updater so navigation can happen synchronously
after the state update. Calling `navigate` inside the updater triggered
a React "setState while rendering" warning, and reading a captured flag
after `setConfig` was unreliable because React 18+ batches the updater
to the next render — the navigate condition was never observed.
Existing test that asserted the old coupling ("banner unmounts while
Settings is open") is inverted to lock in the new contract.
* fix(web): defer privacy banner until onboarding is done and user lands on home
Product feedback on the previous lifecycle change: the banner should not
appear during the welcome panel. It should surface only:
- immediately after the user Skips onboarding (lands directly on home), or
- after the user finishes the design-system step and later returns to a
home view from the project view they were dropped into.
To capture both paths with a single rule, the banner now requires:
1. Daemon config hydrated (unchanged).
2. No privacy decision recorded yet (unchanged).
3. onboardingCompleted === true.
4. The current route is a home route (route.kind === 'home').
The Skip path already routes through finishOnboarding, which calls
onCompleteOnboarding() + changeView('home') — that satisfies all four
gates the moment Skip is clicked.
The finish path (step 2: create design system) previously navigated to a
project view without marking onboardingCompleted. This commit mirrors the
Skip path by calling handleCompleteOnboarding() from the App-level
renderDesignSystemCreation onCreated callback (the onboarding-specific use
of DesignSystemCreationFlow). The shared DesignSystemFlow component is left
untouched so the create-from-Settings entry point keeps its existing
semantics.
The route gate keeps the banner suppressed while the user is reading their
just-created design system project. As soon as they navigate back to the
entry shell (home route), the banner appears.
Tests:
- "withholds the privacy banner until onboarding completes" — covers
gate 3 (onboardingCompleted=false while still on onboarding/home).
- "withholds the privacy banner outside the home route" — covers gate 4
(user is on a project route, onboardingCompleted=true).
- Existing "keeps the first-run privacy banner mounted while settings is
open" still passes; the Settings/banner z-index relationship is
independent of these gates.
* fix(web): allow privacy banner to surface on non-home routes after onboarding
Follow-up to the previous lifecycle change. After exercising the design-
system finish path end-to-end, product wants the banner to appear in the
project view the user is dropped into — the first generation is running
in the background and the user is already waiting, so the disclosure can
be acknowledged inline rather than being held back until they navigate
back to a home view.
The Skip path is unchanged: Skip routes the user to home and the banner
appears there.
This drops the `route.kind === 'home'` guard and the matching test, and
adds a contract test that locks in banner visibility on a project route
when `onboardingCompleted=true` and no privacy decision has been made.
|
||
|---|---|---|
| .. | ||
| home-hero | ||
| Theater | ||
| AgentIcon.test.tsx | ||
| App.connectors.test.tsx | ||
| App.mediaProviders.test.tsx | ||
| assistant-message-tool-status.test.tsx | ||
| assistant-message-unfinished-todos.test.tsx | ||
| AssistantMessage.test.ts | ||
| AssistantMessage.test.tsx | ||
| auto-open-file.test.ts | ||
| BoardComposerPopover.pod-chip-hover.test.tsx | ||
| BoardComposerPopover.pod-remove.test.tsx | ||
| chat-feedback.test.tsx | ||
| chat-scroll-preservation.test.tsx | ||
| ChatComposer.context-pickers.test.tsx | ||
| ChatComposer.import-menu.test.tsx | ||
| ChatComposer.infinite-render.test.tsx | ||
| ChatComposer.search.test.tsx | ||
| ChatPane.resume-conversation.test.tsx | ||
| ChatPane.streaming.test.tsx | ||
| CommentTargetOverlay.hover-class.test.tsx | ||
| ConnectorsBrowser.test.tsx | ||
| ContinueInCliButton.test.tsx | ||
| conversation-timestamps.test.tsx | ||
| CustomSelect.test.tsx | ||
| DesignFilesPanel.test.tsx | ||
| DesignsTab.select-mode.test.tsx | ||
| DesignsTab.test.ts | ||
| DesignSystemFlow.test.tsx | ||
| DesignSystemsTab.test.tsx | ||
| EntryView.test.ts | ||
| examples-tab-filter-counts.test.tsx | ||
| examples-tab-preview-dispatch.test.tsx | ||
| examples-tab-retry.test.tsx | ||
| ExamplesTab.test.tsx | ||
| file-viewer-markdown-copy.test.tsx | ||
| file-viewer-render-mode.test.ts | ||
| FileOpsSummary.test.tsx | ||
| FileViewer.manual-edit-history.test.tsx | ||
| FileViewer.manual-edit.test.tsx | ||
| FileViewer.test.tsx | ||
| FileWorkspace.design-system.test.tsx | ||
| FileWorkspace.test.tsx | ||
| GenUISurfaceRenderer.diff-review.test.tsx | ||
| GenUISurfaceRenderer.schema-form.test.tsx | ||
| GenUISurfaceRenderer.test.tsx | ||
| HomeHero.plugin-picker.test.tsx | ||
| HomeHero.rail.test.tsx | ||
| HomeView.context-picker.test.tsx | ||
| HomeView.media-options.test.tsx | ||
| HomeView.plugin-i18n.test.tsx | ||
| HomeView.prefill.test.tsx | ||
| InlinePluginsRail.test.tsx | ||
| ManualEditPanel.test.tsx | ||
| MarketplaceView.test.tsx | ||
| McpClientSection.oauth.test.tsx | ||
| McpJsonHelper.test.tsx | ||
| MemorySection.test.tsx | ||
| modelOptions.test.tsx | ||
| NewAutomationModal.context-picker.test.tsx | ||
| NewProjectModal.test.tsx | ||
| NewProjectPanel.media.test.tsx | ||
| NewProjectPanel.test.ts | ||
| NewProjectPanel.test.tsx | ||
| pet-task-center.test.ts | ||
| PetOverlay.test.tsx | ||
| PluginDetailsModal.dispatch.test.tsx | ||
| pluginFolderActions.test.ts | ||
| PluginInputsForm.test.tsx | ||
| plugins-home-facets.test.ts | ||
| plugins-home-html-surface.test.tsx | ||
| plugins-home-preview.test.ts | ||
| plugins-home-section.test.tsx | ||
| plugins-home-visualScore.test.ts | ||
| PluginShareMenu.test.tsx | ||
| PluginsSection.test.tsx | ||
| PluginsView.test.tsx | ||
| preview-modal-error-state.test.tsx | ||
| preview-modal-fullscreen.test.tsx | ||
| preview-modal-unavailable-state.test.tsx | ||
| PreviewDrawOverlay.test.tsx | ||
| PreviewModal.test.tsx | ||
| PrivacyConsentModal.test.tsx | ||
| PrivacySection.test.tsx | ||
| ProjectDesignSystemPicker.test.tsx | ||
| ProjectView.api-empty-response.test.tsx | ||
| ProjectView.deleteConversation.test.tsx | ||
| ProjectView.pendingPrompt.test.tsx | ||
| ProjectView.projectInstructions.test.tsx | ||
| ProjectView.resume-conversation.test.tsx | ||
| ProjectView.run-cleanup.test.tsx | ||
| ProjectView.run-isolation.test.tsx | ||
| ProjectView.tabs-navigation.test.tsx | ||
| QuestionForm.test.tsx | ||
| QuickSwitcher.test.tsx | ||
| RecentProjectsStrip.test.tsx | ||
| RoutinesSection.test.tsx | ||
| SettingsDialog.execution.test.tsx | ||
| SettingsDialog.media.test.tsx | ||
| SettingsDialog.orbit.test.tsx | ||
| SettingsDialog.test.ts | ||
| sketch-model.test.ts | ||
| SkillsSection.test.tsx | ||
| TasksView.history.test.tsx | ||
| TasksView.templates.test.tsx | ||
| Toast.test.tsx | ||
| TrustBadge.test.tsx | ||
| UpdaterPopup.test.tsx | ||
| use-everywhere-agent-guide.test.ts | ||
| WorkingDirPill.test.tsx | ||
| WorkspaceTabsBar.test.tsx | ||