feat(onboarding): add a personalize onboarding section#2781
Conversation
- Add SectionOnboarding component with 4-step checklist (workspace, cluster, environment, service)
- Fetch onboarding status from new GET /organization/{id}/onboarding endpoint
- Persist dismiss via POST /organization/{id}/onboarding with status DISMISSED
- Hide section for existing orgs (null status) and invited members
- Show animated deploying/failed states with cluster and service log links
- Add McpSuggestionCard when no cluster exists
- Add dev-only reset button to clear dismissed state
- Simplify section-production-health (cluster creation moved to onboarding)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent_status for service step Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cluster: require both status===DEPLOYED and is_deployed to avoid showing as done when cluster is unavailable (stale status field) - Service: use state===DEPLOYED for running check; add isServiceStopped visual state showing "Service stopped" link when no service is running - Remove unused ServiceDeploymentStatusEnum import Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Old orgs have no onboarding record or use_cases=null — only show the section when use_cases is set (new orgs that went through the wizard). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Preview environments link only if ephemeral-environments was selected, AI Builder Portal only if rde was selected. Invite teammates always shown. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@copilot resolve the merge conflicts in this pull request |
…ction # Conflicts: # package.json # yarn.lock
Merge conflicts resolved in commit |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ons moved to onboarding Cluster option cards (Qovery managed, BYOC, Local machine) and MCP skills card were moved to SectionOnboarding. Tests now reflect the simplified EmptyState with a single "Create cluster" CTA. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## staging #2781 +/- ##
===========================================
- Coverage 47.44% 46.77% -0.67%
===========================================
Files 1267 1248 -19
Lines 26812 26687 -125
Branches 7913 7788 -125
===========================================
- Hits 12721 12483 -238
- Misses 11892 12052 +160
+ Partials 2199 2152 -47
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ction # Conflicts: # package.json # yarn.lock
There was a problem hiding this comment.
Pull request overview
Adds a “Getting started” onboarding checklist to the organization overview page, backed by new organization onboarding API endpoints, to guide new users through initial setup and first deployment.
Changes:
- Bump
qovery-typescript-axiosto consume the new organization onboarding endpoints. - Add organization onboarding query/mutation (and unit tests) and a new
SectionOnboardingUI rendered on the org overview page. - Simplify the org overview “Production health” empty state and add an
onSuccessescape hatch to the clone/create environment modal.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Locks qovery-typescript-axios to 1.1.919. |
| package.json | Bumps qovery-typescript-axios to 1.1.919. |
| libs/shared/auth/src/lib/use-auth/use-auth.tsx | Clears React Query cache on logout. |
| libs/domains/organizations/data-access/src/lib/domains-organizations-data-access.ts | Adds onboarding query key + update mutation calling new endpoints. |
| libs/domains/organizations/data-access/src/lib/domains-organizations-data-access.spec.ts | Adds unit tests for onboarding query and update mutation. |
| libs/domains/environments/feature/src/lib/create-clone-environment-modal/create-clone-environment-modal.tsx | Adds optional onSuccess(environmentId) callback to override default navigation. |
| libs/domains/clusters/feature/src/lib/section-production-health/section-production-health.tsx | Removes the previous “cluster options” onboarding-like UI, leaving a simpler empty state CTA. |
| libs/domains/clusters/feature/src/lib/section-production-health/section-production-health.spec.tsx | Updates tests to match the simplified empty state behavior. |
| apps/console/src/routes/_authenticated/organization/$organizationId/overview.tsx | Renders the new onboarding section above production health. |
| apps/console/src/app/components/section-onboarding/use-update-user-signup.ts | Introduces a user signup mutation hook (currently unused). |
| apps/console/src/app/components/section-onboarding/use-rde-access.ts | Introduces an RDE access query hook (currently unused). |
| apps/console/src/app/components/section-onboarding/use-organization-onboarding.ts | Adds onboarding query + update-status mutation hooks. |
| apps/console/src/app/components/section-onboarding/section-onboarding.tsx | Implements the onboarding checklist UI, progress calculation, and completion modal flow. |
| apps/console/src/app/components/header/user-menu/user-menu.tsx | Changes displayed email to userToken?.email only (drops communication_email fallback). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const COMPLETION_ILLUSTRATION_ROW_TONES = [ | ||
| '366333336963333366366333336963333366366333336963333366', | ||
| '369633333663366333336963333366336633333696333336633663333', | ||
| '366336633333696333366336633333696333366336633333696333', | ||
| '333336963333366336633333696333336633663333369633333663366', | ||
| '333336633663333369333336633663333369333336633663333369', | ||
| '336633333636333336633663333363633333663366333336363333366', | ||
| '366333336963333366336633333696333336633663333369633333663', | ||
| '696333336633663333696333336633663333696333336633663333', | ||
| '366336633333696333333663366333336963333336633663333369633333', | ||
| '333369633333663366333336963333366336633333696333336633663', | ||
| '333336633663333369633333366336633333696333333663366333336963', | ||
| '366333336963333366366333336963333366366333336963333366', | ||
| '369633333663366333336963333366336633333696333336633663333', | ||
| '366336633333696333366336633333696333366336633333696333', | ||
| '333336963333366336633333696333336633663333369633333663366', | ||
| '333336633663333369333336633663333369333336633663333369', | ||
| '336633333636333336633663333363633333663366333336363333366', | ||
| ] as const | ||
|
|
||
| const COMPLETION_ILLUSTRATION_HEX_FILL = { | ||
| 3: 'var(--positive-3)', | ||
| 6: 'var(--positive-6)', | ||
| 9: 'var(--positive-9)', | ||
| } as const | ||
|
|
||
| type CompletionIllustrationHexTone = keyof typeof COMPLETION_ILLUSTRATION_HEX_FILL | ||
|
|
||
| const COMPLETION_ILLUSTRATION_HEX_GAP = 10.5 | ||
| const COMPLETION_ILLUSTRATION_HEX_PATH = 'M0 0L3.89711 2.25V6.75L0 9L-3.89711 6.75V2.25L0 0Z' | ||
| const COMPLETION_ILLUSTRATION_HEX_COLUMN_COUNT = 50 | ||
| const COMPLETION_ILLUSTRATION_HEX_HALF_WIDTH = 3.89711 | ||
| const COMPLETION_ILLUSTRATION_HEX_HEIGHT = 9 | ||
| const COMPLETION_ILLUSTRATION_ROW_START_Y = -5 | ||
| const COMPLETION_ILLUSTRATION_ROW_GAP = 9 | ||
| const COMPLETION_ILLUSTRATION_ROW_OFFSET = { | ||
| even: -13.25, | ||
| odd: -8, | ||
| } as const | ||
|
|
||
| const COMPLETION_ILLUSTRATION_PATTERN_MIN_X = Math.floor( | ||
| Math.min(COMPLETION_ILLUSTRATION_ROW_OFFSET.even, COMPLETION_ILLUSTRATION_ROW_OFFSET.odd) - | ||
| COMPLETION_ILLUSTRATION_HEX_HALF_WIDTH | ||
| ) | ||
| const COMPLETION_ILLUSTRATION_PATTERN_MAX_X = Math.ceil( | ||
| Math.max(COMPLETION_ILLUSTRATION_ROW_OFFSET.even, COMPLETION_ILLUSTRATION_ROW_OFFSET.odd) + | ||
| (COMPLETION_ILLUSTRATION_HEX_COLUMN_COUNT - 1) * COMPLETION_ILLUSTRATION_HEX_GAP + | ||
| COMPLETION_ILLUSTRATION_HEX_HALF_WIDTH | ||
| ) | ||
| const COMPLETION_ILLUSTRATION_PATTERN_MAX_Y = | ||
| COMPLETION_ILLUSTRATION_ROW_START_Y + | ||
| (COMPLETION_ILLUSTRATION_ROW_TONES.length - 1) * COMPLETION_ILLUSTRATION_ROW_GAP + | ||
| COMPLETION_ILLUSTRATION_HEX_HEIGHT | ||
| const COMPLETION_ILLUSTRATION_PATTERN_BOUNDS = { | ||
| x: COMPLETION_ILLUSTRATION_PATTERN_MIN_X, | ||
| y: COMPLETION_ILLUSTRATION_ROW_START_Y, | ||
| width: COMPLETION_ILLUSTRATION_PATTERN_MAX_X - COMPLETION_ILLUSTRATION_PATTERN_MIN_X, | ||
| height: COMPLETION_ILLUSTRATION_PATTERN_MAX_Y - COMPLETION_ILLUSTRATION_ROW_START_Y, | ||
| } as const | ||
|
|
||
| const COMPLETION_ILLUSTRATION_ROWS = COMPLETION_ILLUSTRATION_ROW_TONES.map((tones, index) => ({ | ||
| x: index % 2 === 0 ? COMPLETION_ILLUSTRATION_ROW_OFFSET.even : COMPLETION_ILLUSTRATION_ROW_OFFSET.odd, | ||
| y: COMPLETION_ILLUSTRATION_ROW_START_Y + index * COMPLETION_ILLUSTRATION_ROW_GAP, | ||
| tones, | ||
| })) |
There was a problem hiding this comment.
Oops this one is on my it's for the final illustration 😁
Will try to put it in a svg 👍
There was a problem hiding this comment.
@rmnbrd I've put the illustration in a specific file, it's a pattern which requires the design token to work in light and dark so I did it this way. Other option would be to duplicate the asset for dark/light and call it as an image in background, you tell me if you prefer that I do it this way!
| * Authentification logout | ||
| */ | ||
| const authLogout = useCallback(async () => { | ||
| queryClient.clear() |
…ntegrate into section onboarding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Summary
JIRA ticket: QOV-2052
Adds a Getting Started onboarding checklist on the organization overview page, guiding new users through their first deployment on Qovery.
What's new
Onboarding checklist (SectionOnboarding) displayed at the top of the org overview with:
API integration
Key behaviors
Screenshots / Recordings
https://www.loom.com/share/72fa2c62139040649152b8036edf9e65
Testing
yarn testoryarn test -u(if you need to regenerate snapshots)yarn formatyarn lintPR Checklist
.cursor/rules)feat(service): add new Terraform service) - required for semantic-release