Skip to content

fix: onboarding issues#5301

Open
ogzhanolguncu wants to merge 12 commits intomainfrom
fix-onboarding-issues
Open

fix: onboarding issues#5301
ogzhanolguncu wants to merge 12 commits intomainfrom
fix-onboarding-issues

Conversation

@ogzhanolguncu
Copy link
Contributor

What does this PR do?

This PR:

  • Prevents "Deploy" button from being pressed when mutation is happening on onboarding configure step
  • Fixes a regression caused by a recent PR. Onboarding was trying to update setting to all envs but inner components was also setting to both envs. Now its simple we no longer need custom hooks on onboarding to save to both envs.
  • Removes "initSettings" hook instead we rely on create project tRPC which does all the initial settings for us.
  • Adds a banner to easily let people redeploy without leaving settings page.
  • Some of the stuff are using observable pattern to detect changes coz react components and tanstack db doesn't really talk to each other like a parent, child component so we needed to notify each other.
  • Since glow icon component being used in a couple of places now its now a shared component
image

@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboard Ready Ready Preview, Comment Mar 18, 2026 5:53pm

Request Review

@ogzhanolguncu ogzhanolguncu changed the title Fix onboarding issues fix: onboarding issues Mar 12, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR introduces a GlowIcon component and refactors deployment configuration with modularized steps, enhances environment context with isSaving tracking, adds a PendingRedeployBanner component, and implements save-state monitoring hooks via an external store.

Changes

Cohort / File(s) Summary
GlowIcon Component
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/glow-icon.tsx
New reusable GlowIcon component for rendering icons with configurable glow/animation variants; handles background color and visibility based on feature/error variant and glow state.
GlowIcon Integration
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/(deployment-progress)/deployment-step.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/deployment-domains-card.tsx
Replaces inline glow rendering logic with GlowIcon component usage, simplifying icon rendering in both deployment step and domains card.
Configure Deployment Refactoring
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/index.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/content.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/environment-provider.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/environment-inner.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/fallback.tsx
Modularizes ConfigureDeploymentStep into separate components for content rendering, environment setup, and loading states; introduces OnboardingEnvironmentSettingsProvider and OnboardingEnvironmentSettingsInner for context management during onboarding.
Configure Deployment Removal
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment.tsx
Removes original monolithic ConfigureDeploymentStep file; functionality moved to modularized index.tsx structure.
Onboarding Provider Cleanup
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/onboarding-environment-provider.tsx
Removes legacy OnboardingEnvironmentSettingsProvider and associated initialization/sync hooks; functionality refactored into environment-provider.tsx and environment-inner.tsx modules.
Environment Settings Context Enhancement
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/environment-provider.tsx
Adds isSaving boolean field to EnvironmentContextType; EnvironmentSettingsProvider now supplies isSaving in context value.
Save State Tracking
web/apps/dashboard/lib/collections/deploy/environment-settings.ts
Introduces saveStore for tracking pendingSaves and savedCount with observer pattern; adds public hooks useSettingsIsSaving() and useSettingsHasSaved() via useSyncExternalStore for external save-state monitoring.
Pending Redeploy Feature
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/pending-redeploy-banner.tsx, web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/page.tsx
New PendingRedeployBanner component displays when settings have pending changes; includes dismissible banner with redeploy action that invalidates cache and navigates; integrated into settings page. RedeployDialog now calls onClose() before navigation.
Redeploy Dialog Update
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/components/table/components/actions/redeploy-dialog.tsx
Adjusts onSuccess handler to call onClose() immediately after query invalidation, before navigation.

Sequence Diagram

sequenceDiagram
    participant User
    participant PendingRedeployBanner
    participant TRPC
    participant Cache
    participant Router

    User->>PendingRedeployBanner: Click Redeploy Button
    activate PendingRedeployBanner
    PendingRedeployBanner->>TRPC: deployments.redeploy mutation
    activate TRPC
    TRPC-->>PendingRedeployBanner: onSuccess (newDeploymentId)
    deactivate TRPC
    PendingRedeployBanner->>Cache: invalidate deployments cache
    PendingRedeployBanner->>Router: navigate to new deployment
    deactivate PendingRedeployBanner
    Router-->>User: Display deployment page
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: apply settings to every env #5165: Modifies environment-provider.tsx context exports and EnvironmentContext structure; directly intersects with this PR's EnvironmentContextType enhancement adding isSaving field.
🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers key changes but is missing required template sections: 'Fixes #' issue reference, 'Type of change' checkboxes, and 'How should this be tested?' section. Complete the PR description template by adding the issue number, selecting relevant change types, and documenting testing steps.
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'fix: onboarding issues' is vague and generic, using non-specific language that doesn't convey the meaningful details of the changes. Provide a more specific title that highlights the main change, such as 'fix: prevent deploy button during mutation and refactor onboarding settings' or similar.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-onboarding-issues
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/deployment-domains-card.tsx (1)

20-24: ⚠️ Potential issue | 🟡 Minor

Coerce the optional glow prop before passing it to GlowIcon.

GlowIcon treats undefined as true, but this component still treats an omitted glow prop as false for iconClassName. That changes the default rendering from a plain icon to a pulsing one whenever callers leave glow unset.

💡 Minimal fix
               <GlowIcon
                 icon={<Cube iconSize="md-medium" className="size-[18px]" />}
-                glow={glow}
+                glow={Boolean(glow)}
                 className="w-full h-full"
               />

Also applies to: 63-69

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/components/deployment-domains-card.tsx
around lines 20 - 24, The component DeploymentDomainsCard treats an omitted glow
prop differently from GlowIcon (GlowIcon treats undefined as true), so coerce
the optional glow into an explicit boolean before use (e.g., const showGlow =
glow !== false) and use that showGlow when calling GlowIcon and when computing
iconClassName so both places have the same default behavior; update all
occurrences in the component (including the other block referenced around lines
63-69) to reference showGlow instead of the raw glow prop.
🧹 Nitpick comments (2)
web/apps/dashboard/lib/trpc/routers/deploy/project/create.ts (1)

160-173: Guard the regional settings insert when regions is empty.

Drizzle ORM throws with 'values() must be called with at least one value' when .values([]) is passed. This code will fail project creation if the regions table is unseeded, since [prodEnvId, previewEnvId].flatMap(...) produces an empty array when regions is empty. Add a guard to avoid that failure mode.

Suggested minimal patch
         const regions = await tx.query.regions.findMany({ columns: { id: true } });
-        await tx.insert(schema.appRegionalSettings).values(
-          [prodEnvId, previewEnvId].flatMap((environmentId) =>
-            regions.map((r) => ({
-              workspaceId: ctx.workspace.id,
-              appId,
-              environmentId,
-              regionId: r.id,
-              replicas: 1,
-              createdAt: Date.now(),
-              updatedAt: Date.now(),
-            })),
-          ),
-        );
+        const regionalSettings = [prodEnvId, previewEnvId].flatMap((environmentId) =>
+          regions.map((r) => ({
+            workspaceId: ctx.workspace.id,
+            appId,
+            environmentId,
+            regionId: r.id,
+            replicas: 1,
+            createdAt: Date.now(),
+            updatedAt: Date.now(),
+          })),
+        );
+
+        if (regionalSettings.length > 0) {
+          await tx.insert(schema.appRegionalSettings).values(regionalSettings);
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/apps/dashboard/lib/trpc/routers/deploy/project/create.ts` around lines
160 - 173, The insert into appRegionalSettings calls .values(...) with a
flattened array from regions and will throw if regions is empty; to fix, build
the payload array (e.g., map over regions for each of prodEnvId and
previewEnvId) and only call
tx.insert(schema.appRegionalSettings).values(payload) when payload.length > 0
(guarding against regions.length === 0), referencing the existing variables
regions, prodEnvId, previewEnvId, ctx.workspace.id and appId so no insert is
attempted with an empty array.
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/glow-icon.tsx (1)

24-30: Minor: Redundant ternary branches.

The glowVisible logic has identical outcomes for glow === true in both transition branches ("animate-pulse opacity-20"). This could be simplified, but the current structure may be intentional for future differentiation.

♻️ Optional simplification
  const glowVisible = transition
-   ? glow
-     ? "animate-pulse opacity-20"
-     : "opacity-0 transition-opacity duration-300"
-   : glow
-     ? "animate-pulse opacity-20"
-     : "hidden";
+   ? glow
+     ? "animate-pulse opacity-20"
+     : "opacity-0 transition-opacity duration-300"
+   : glow
+     ? "animate-pulse opacity-20"
+     : "hidden";

If transition behavior should differ in the future, the current structure is fine. Otherwise:

- const glowVisible = transition
-   ? glow
-     ? "animate-pulse opacity-20"
-     : "opacity-0 transition-opacity duration-300"
-   : glow
-     ? "animate-pulse opacity-20"
-     : "hidden";
+ const glowVisible = glow
+   ? "animate-pulse opacity-20"
+   : transition
+     ? "opacity-0 transition-opacity duration-300"
+     : "hidden";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/components/glow-icon.tsx
around lines 24 - 30, The conditional for glowVisible currently repeats the same
branch for glow === true; simplify by checking glow first: if glow is true
return "animate-pulse opacity-20", otherwise return transition ? "opacity-0
transition-opacity duration-300" : "hidden". Update the glowVisible assignment
(the variable named glowVisible that uses transition and glow) to use this
simplified logic so behavior is unchanged but redundant ternary branches are
removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/pending-redeploy-banner.tsx:
- Around line 35-45: The onSuccess handler for the redeploy mutation (redeploy
in trpc.deploy.deployment.redeploy.useMutation) currently calls
queryClient.invalidateQueries(...).then(() => router.push(...)) but does not
return that Promise, so the mutation becomes non-pending before navigation
starts; fix by returning the Promise from onSuccess (make the onSuccess async
and await/return queryClient.invalidateQueries(...) before calling router.push
or simply return queryClient.invalidateQueries(...).then(...)) and ensure you
reference currentDeploymentRef.current and router.push to perform navigation
after the awaited invalidation.

In `@web/apps/dashboard/lib/collections/deploy/environment-settings.ts`:
- Around line 53-58: _wrap each subscriber invocation in _notifySaveSubscribers
so that callbacks from _saveSubscribers are executed inside a try/catch that
prevents exceptions from bubbling; log or ignore the error but do not rethrow,
ensuring the caller (dispatchSettingsMutations) can always reach its finally
block and decrement _pendingSaves; apply the same defensive try/catch pattern to
the other subscriber loop mentioned (the saved-listener loop around lines
303-314) so listener exceptions cannot convert a successful save into a rejected
update or leave _pendingSaves stuck.

---

Outside diff comments:
In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/components/deployment-domains-card.tsx:
- Around line 20-24: The component DeploymentDomainsCard treats an omitted glow
prop differently from GlowIcon (GlowIcon treats undefined as true), so coerce
the optional glow into an explicit boolean before use (e.g., const showGlow =
glow !== false) and use that showGlow when calling GlowIcon and when computing
iconClassName so both places have the same default behavior; update all
occurrences in the component (including the other block referenced around lines
63-69) to reference showGlow instead of the raw glow prop.

---

Nitpick comments:
In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/[projectId]/components/glow-icon.tsx:
- Around line 24-30: The conditional for glowVisible currently repeats the same
branch for glow === true; simplify by checking glow first: if glow is true
return "animate-pulse opacity-20", otherwise return transition ? "opacity-0
transition-opacity duration-300" : "hidden". Update the glowVisible assignment
(the variable named glowVisible that uses transition and glow) to use this
simplified logic so behavior is unchanged but redundant ternary branches are
removed.

In `@web/apps/dashboard/lib/trpc/routers/deploy/project/create.ts`:
- Around line 160-173: The insert into appRegionalSettings calls .values(...)
with a flattened array from regions and will throw if regions is empty; to fix,
build the payload array (e.g., map over regions for each of prodEnvId and
previewEnvId) and only call
tx.insert(schema.appRegionalSettings).values(payload) when payload.length > 0
(guarding against regions.length === 0), referencing the existing variables
regions, prodEnvId, previewEnvId, ctx.workspace.id and appId so no insert is
attempted with an empty array.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6585f684-9a59-4e41-b519-4b011022b1e3

📥 Commits

Reviewing files that changed from the base of the PR and between 53ddcdf and 32afe94.

📒 Files selected for processing (16)
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]/(deployment-progress)/deployment-step.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/components/table/components/actions/redeploy-dialog.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/environment-provider.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/page.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/pending-redeploy-banner.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/deployment-domains-card.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/components/glow-icon.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/content.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/environment-inner.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/environment-provider.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/fallback.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment/index.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/onboarding-environment-provider.tsx
  • web/apps/dashboard/lib/collections/deploy/environment-settings.ts
  • web/apps/dashboard/lib/trpc/routers/deploy/project/create.ts
💤 Files with no reviewable changes (2)
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/configure-deployment.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/new/steps/onboarding-environment-provider.tsx

Copy link
Collaborator

@mcstepp mcstepp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢

@chronark
Copy link
Collaborator

@mcstepp is that emoji supposed to mean it's good?
can you approve please

@chronark chronark enabled auto-merge March 18, 2026 17:42
@chronark chronark requested a review from mcstepp March 18, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants