Skip to content

Commit 7282f64

Browse files
authored
feat: skip license page for cloud billing users (#41102)
## Description This PR enhances the signup success flow to automatically skip the license page when cloud billing is enabled, providing a smoother onboarding experience for cloud users. ## Key Changes ### 🚀 New Features - Added cloud billing detection using `useIsCloudBillingEnabled()` hook - Implemented automatic license page skipping for cloud billing users - Enhanced redirect logic with proper async/await handling ### 🔧 Improvements - Added redirect state management to prevent race conditions - Improved error handling in redirect flow with try-catch blocks - Extracted redirect conditions into `shouldAutoRedirect` variable for better readability - Added redirect protection to prevent multiple simultaneous redirects ### 🛠️ Technical Details - Added `isMultiOrgEnabled` flag to signup redirect parameters - Made `redirectUsingQueryParam` and `onGetStarted` functions async - Implemented `isRedirecting` state to track redirect status - Added proper dependency management in useEffect and useCallback hooks ## Impact - **Cloud billing users** will now bypass the license page automatically - **Improved UX** with more robust redirect handling and loading states - **Better performance** by preventing unnecessary redirect attempts - **Enhanced reliability** with proper error handling and state management ## Automation /ok-to-test tags="@tag.Sanity, @tag.Authentication, @tag.LicenseAndBilling" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/16167808138> > Commit: ab4247c > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=16167808138&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Sanity, @tag.Authentication, @tag.LicenseAndBilling` > Spec: > <hr>Wed, 09 Jul 2025 12:00:44 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved signup success experience with smarter automatic redirection based on user status and organization settings. * Added a loading spinner during redirection for better user feedback. * **Bug Fixes** * Prevented multiple redirects from occurring at the same time. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 3981590 commit 7282f64

File tree

1 file changed

+57
-36
lines changed

1 file changed

+57
-36
lines changed

app/client/src/pages/setup/SignupSuccess.tsx

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
22
import { requiresAuth } from "pages/UserAuth/requiresAuthHOC";
33
import React from "react";
4-
import { useCallback } from "react";
4+
import { useCallback, useState } from "react";
55
import { useEffect } from "react";
66
import { useDispatch, useSelector } from "react-redux";
77
import { getCurrentUser } from "selectors/usersSelectors";
@@ -16,6 +16,7 @@ import { redirectUserAfterSignup } from "ee/utils/signupHelpers";
1616
import { setUserSignedUpFlag } from "utils/storage";
1717
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
1818
import { getIsAiAgentInstanceEnabled } from "ee/selectors/aiAgentSelectors";
19+
import { useIsCloudBillingEnabled } from "hooks/useIsCloudBillingEnabled";
1920

2021
export function SignupSuccess() {
2122
const dispatch = useDispatch();
@@ -25,50 +26,78 @@ export function SignupSuccess() {
2526
"enableFirstTimeUserExperience",
2627
);
2728
const isAiAgentInstanceEnabled = useSelector(getIsAiAgentInstanceEnabled);
29+
const isMultiOrgEnabled = useIsCloudBillingEnabled();
2830
const validLicense = useSelector(isValidLicense);
2931
const user = useSelector(getCurrentUser);
3032
const isOnLoginPage = !useSelector(isWithinAnOrganization);
3133

34+
const [isRedirecting, setIsRedirecting] = useState(false);
35+
3236
useEffect(() => {
3337
user?.email && setUserSignedUpFlag(user?.email);
3438
}, []);
3539

3640
const isNonInvitedUser = shouldEnableFirstTimeUserOnboarding === "true";
3741

38-
const redirectUsingQueryParam = useCallback(
39-
() =>
40-
redirectUserAfterSignup({
42+
const redirectUsingQueryParam = useCallback(async () => {
43+
if (isRedirecting) return;
44+
45+
setIsRedirecting(true);
46+
47+
try {
48+
await redirectUserAfterSignup({
4149
redirectUrl,
4250
shouldEnableFirstTimeUserOnboarding,
4351
validLicense,
4452
dispatch,
4553
isAiAgentInstanceEnabled,
54+
isMultiOrgEnabled,
4655
isOnLoginPage,
47-
}),
48-
[
49-
dispatch,
50-
isNonInvitedUser,
51-
isOnLoginPage,
52-
redirectUrl,
53-
shouldEnableFirstTimeUserOnboarding,
54-
validLicense,
55-
],
56-
);
56+
});
57+
} catch (err) {
58+
setIsRedirecting(false);
59+
}
60+
}, [
61+
dispatch,
62+
isNonInvitedUser,
63+
isOnLoginPage,
64+
redirectUrl,
65+
shouldEnableFirstTimeUserOnboarding,
66+
validLicense,
67+
isAiAgentInstanceEnabled,
68+
isMultiOrgEnabled,
69+
]);
5770

58-
const onGetStarted = useCallback((proficiency?: string, useCase?: string) => {
59-
dispatch({
60-
type: ReduxActionTypes.UPDATE_USER_DETAILS_INIT,
61-
payload: {
71+
const onGetStarted = useCallback(
72+
async (proficiency?: string, useCase?: string) => {
73+
dispatch({
74+
type: ReduxActionTypes.UPDATE_USER_DETAILS_INIT,
75+
payload: {
76+
proficiency,
77+
useCase,
78+
},
79+
});
80+
AnalyticsUtil.logEvent("GET_STARTED_CLICKED", {
6281
proficiency,
63-
useCase,
64-
},
65-
});
66-
AnalyticsUtil.logEvent("GET_STARTED_CLICKED", {
67-
proficiency,
68-
goal: useCase,
69-
});
70-
redirectUsingQueryParam();
71-
}, []);
82+
goal: useCase,
83+
});
84+
await redirectUsingQueryParam();
85+
},
86+
[redirectUsingQueryParam],
87+
);
88+
89+
const shouldAutoRedirect =
90+
user?.isSuperUser ||
91+
((user?.role || user?.proficiency) && user?.useCase) ||
92+
shouldEnableFirstTimeUserOnboarding !== "true" ||
93+
isAiAgentInstanceEnabled ||
94+
isMultiOrgEnabled;
95+
96+
useEffect(() => {
97+
if (shouldAutoRedirect && !isRedirecting) {
98+
redirectUsingQueryParam();
99+
}
100+
}, [shouldAutoRedirect, redirectUsingQueryParam, isRedirecting]);
72101

73102
/*
74103
* Proceed with redirection,
@@ -78,15 +107,7 @@ export function SignupSuccess() {
78107
* We identify an invited user based on `enableFirstTimeUserExperience` flag in url.
79108
*/
80109
//TODO(Balaji): Factor in case, where user had closed the tab, while filling the form.And logs back in again.
81-
if (
82-
user?.isSuperUser ||
83-
((user?.role || user?.proficiency) && user?.useCase) ||
84-
shouldEnableFirstTimeUserOnboarding !== "true" ||
85-
isAiAgentInstanceEnabled
86-
) {
87-
redirectUsingQueryParam();
88-
89-
// Showing a loader until the redirect
110+
if (shouldAutoRedirect) {
90111
return (
91112
<Center>
92113
<Spinner size="lg" />

0 commit comments

Comments
 (0)