feat: improve async handling for org onboarding cases (#6342)

This commit is contained in:
Yunus M 2024-11-01 23:55:29 +05:30 committed by GitHub
parent 4978fb9599
commit c7d0598ec0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 205 additions and 250 deletions

View File

@ -9,7 +9,7 @@ import ROUTES from 'constants/routes';
import useLicense from 'hooks/useLicense'; import useLicense from 'hooks/useLicense';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import history from 'lib/history'; import history from 'lib/history';
import { isEmpty } from 'lodash-es'; import { isEmpty, isNull } from 'lodash-es';
import { ReactChild, useEffect, useMemo, useState } from 'react'; import { ReactChild, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
@ -35,13 +35,18 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
const location = useLocation(); const location = useLocation();
const { pathname } = location; const { pathname } = location;
const { org, orgPreferences } = useSelector<AppState, AppReducer>( const [isLoading, setIsLoading] = useState<boolean>(true);
(state) => state.app,
);
const [isOnboardingComplete, setIsOnboardingComplete] = useState< const {
boolean | null org,
>(null); orgPreferences,
user,
role,
isUserFetching,
isUserFetchingError,
isLoggedIn: isLoggedInState,
isFetchingOrgPreferences,
} = useSelector<AppState, AppReducer>((state) => state.app);
const mapRoutes = useMemo( const mapRoutes = useMemo(
() => () =>
@ -56,30 +61,19 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
[pathname], [pathname],
); );
useEffect(() => { const isOnboardingComplete = useMemo(
if (orgPreferences && !isEmpty(orgPreferences)) { () =>
const onboardingPreference = orgPreferences?.find( orgPreferences?.find(
(preference: Record<string, any>) => preference.key === 'ORG_ONBOARDING', (preference: Record<string, any>) => preference.key === 'ORG_ONBOARDING',
); )?.value,
[orgPreferences],
if (onboardingPreference) { );
setIsOnboardingComplete(onboardingPreference.value);
}
}
}, [orgPreferences]);
const { const {
data: licensesData, data: licensesData,
isFetching: isFetchingLicensesData, isFetching: isFetchingLicensesData,
} = useLicense(); } = useLicense();
const {
isUserFetching,
isUserFetchingError,
isLoggedIn: isLoggedInState,
isFetchingOrgPreferences,
} = useSelector<AppState, AppReducer>((state) => state.app);
const { t } = useTranslation(['common']); const { t } = useTranslation(['common']);
const localStorageUserAuthToken = getInitialUserTokenRefreshToken(); const localStorageUserAuthToken = getInitialUserTokenRefreshToken();
@ -135,7 +129,8 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
// Check if the onboarding should be shown based on the org users and onboarding completion status, wait for org users and preferences to load // Check if the onboarding should be shown based on the org users and onboarding completion status, wait for org users and preferences to load
const shouldShowOnboarding = (): boolean => { const shouldShowOnboarding = (): boolean => {
// Only run this effect if the org users and preferences are loaded // Only run this effect if the org users and preferences are loaded
if (!isLoadingOrgUsers) {
if (!isLoadingOrgUsers && !isFetchingOrgPreferences) {
const isFirstUser = checkFirstTimeUser(); const isFirstUser = checkFirstTimeUser();
// Redirect to get started if it's not the first user or if the onboarding is complete // Redirect to get started if it's not the first user or if the onboarding is complete
@ -145,6 +140,26 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
return false; return false;
}; };
const handleRedirectForOrgOnboarding = (key: string): void => {
if (
isLoggedInState &&
!isFetchingOrgPreferences &&
!isLoadingOrgUsers &&
!isEmpty(orgUsers?.payload) &&
!isNull(orgPreferences)
) {
if (key === 'ONBOARDING' && isOnboardingComplete) {
history.push(ROUTES.APPLICATION);
}
const isFirstTimeUser = checkFirstTimeUser();
if (isFirstTimeUser && !isOnboardingComplete) {
history.push(ROUTES.ONBOARDING);
}
}
};
const handleUserLoginIfTokenPresent = async ( const handleUserLoginIfTokenPresent = async (
key: keyof typeof ROUTES, key: keyof typeof ROUTES,
): Promise<void> => { ): Promise<void> => {
@ -166,15 +181,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
response.payload.refreshJwt, response.payload.refreshJwt,
); );
const showOnboarding = shouldShowOnboarding(); handleRedirectForOrgOnboarding(key);
if (
userResponse &&
showOnboarding &&
userResponse.payload.role === 'ADMIN'
) {
history.push(ROUTES.ONBOARDING);
}
if ( if (
userResponse && userResponse &&
@ -203,7 +210,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
) { ) {
handleUserLoginIfTokenPresent(key); handleUserLoginIfTokenPresent(key);
} else { } else {
// user does have localstorage values handleRedirectForOrgOnboarding(key);
navigateToLoginIfNotLoggedIn(isLocalStorageLoggedIn); navigateToLoginIfNotLoggedIn(isLocalStorageLoggedIn);
} }
@ -241,9 +248,9 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
}, [org]); }, [org]);
const handleRouting = (): void => { const handleRouting = (): void => {
const showOnboarding = shouldShowOnboarding(); const showOrgOnboarding = shouldShowOnboarding();
if (showOnboarding) { if (showOrgOnboarding && !isOnboardingComplete) {
history.push(ROUTES.ONBOARDING); history.push(ROUTES.ONBOARDING);
} else { } else {
history.push(ROUTES.APPLICATION); history.push(ROUTES.APPLICATION);
@ -251,17 +258,27 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
}; };
useEffect(() => { useEffect(() => {
// Only run this effect if the org users and preferences are loaded const { isPrivate } = currentRoute || {
if (!isLoadingOrgUsers && isOnboardingComplete !== null) { isPrivate: false,
const isFirstUser = checkFirstTimeUser(); };
// Redirect to get started if it's not the first user or if the onboarding is complete if (isLoggedInState && role && role !== 'ADMIN') {
if (isFirstUser && !isOnboardingComplete) { setIsLoading(false);
history.push(ROUTES.ONBOARDING);
}
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isLoadingOrgUsers, isOnboardingComplete, orgUsers]); if (!isPrivate) {
setIsLoading(false);
}
if (
!isEmpty(user) &&
!isFetchingOrgPreferences &&
!isEmpty(orgUsers?.payload) &&
!isNull(orgPreferences)
) {
setIsLoading(false);
}
}, [currentRoute, user, role, orgUsers, orgPreferences]);
// eslint-disable-next-line sonarjs/cognitive-complexity // eslint-disable-next-line sonarjs/cognitive-complexity
useEffect(() => { useEffect(() => {
@ -284,7 +301,6 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
handlePrivateRoutes(key); handlePrivateRoutes(key);
} else { } else {
// no need to fetch the user and make user fetching false // no need to fetch the user and make user fetching false
if (getLocalStorageApi(LOCALSTORAGE.IS_LOGGED_IN) === 'true') { if (getLocalStorageApi(LOCALSTORAGE.IS_LOGGED_IN) === 'true') {
handleRouting(); handleRouting();
} }
@ -311,13 +327,20 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
history.push(ROUTES.SOMETHING_WENT_WRONG); history.push(ROUTES.SOMETHING_WENT_WRONG);
} }
})(); })();
}, [dispatch, isLoggedInState, currentRoute, licensesData]); }, [
dispatch,
isLoggedInState,
currentRoute,
licensesData,
orgUsers,
orgPreferences,
]);
if (isUserFetchingError) { if (isUserFetchingError) {
return <Redirect to={ROUTES.SOMETHING_WENT_WRONG} />; return <Redirect to={ROUTES.SOMETHING_WENT_WRONG} />;
} }
if (isUserFetching || (isLoggedInState && isFetchingOrgPreferences)) { if (isUserFetching || isLoading) {
return <Spinner tip="Loading..." />; return <Spinner tip="Loading..." />;
} }

View File

@ -312,7 +312,7 @@ export default function Onboarding(): JSX.Element {
<div <div
onClick={(): void => { onClick={(): void => {
logEvent('Onboarding V2: Skip Button Clicked', {}); logEvent('Onboarding V2: Skip Button Clicked', {});
history.push('/'); history.push(ROUTES.APPLICATION);
}} }}
className="skip-to-console" className="skip-to-console"
> >

View File

@ -10,6 +10,7 @@ import {
ArrowLeft, ArrowLeft,
ArrowRight, ArrowRight,
CheckCircle, CheckCircle,
Loader2,
Plus, Plus,
TriangleAlert, TriangleAlert,
X, X,
@ -33,6 +34,7 @@ interface TeamMember {
} }
interface InviteTeamMembersProps { interface InviteTeamMembersProps {
isLoading: boolean;
teamMembers: TeamMember[] | null; teamMembers: TeamMember[] | null;
setTeamMembers: (teamMembers: TeamMember[]) => void; setTeamMembers: (teamMembers: TeamMember[]) => void;
onNext: () => void; onNext: () => void;
@ -40,6 +42,7 @@ interface InviteTeamMembersProps {
} }
function InviteTeamMembers({ function InviteTeamMembers({
isLoading,
teamMembers, teamMembers,
setTeamMembers, setTeamMembers,
onNext, onNext,
@ -67,8 +70,6 @@ function InviteTeamMembers({
const [disableNextButton, setDisableNextButton] = useState<boolean>(false); const [disableNextButton, setDisableNextButton] = useState<boolean>(false);
const [allInvitesSent, setAllInvitesSent] = useState<boolean>(false);
const defaultTeamMember: TeamMember = { const defaultTeamMember: TeamMember = {
email: '', email: '',
role: 'EDITOR', role: 'EDITOR',
@ -157,7 +158,6 @@ function InviteTeamMembers({
setError(null); setError(null);
setHasErrors(false); setHasErrors(false);
setInviteUsersErrorResponse(null); setInviteUsersErrorResponse(null);
setAllInvitesSent(true);
setInviteUsersSuccessResponse(successfulInvites); setInviteUsersSuccessResponse(successfulInvites);
@ -358,33 +358,36 @@ function InviteTeamMembers({
</div> </div>
)} )}
{inviteUsersSuccessResponse && (
<div className="success-message-container invite-users-success-message-container">
{inviteUsersSuccessResponse?.map((success, index) => (
<Typography.Text
className="success-message"
// eslint-disable-next-line react/no-array-index-key
key={`${success}-${index}`}
>
<CheckCircle size={14} /> {success}
</Typography.Text>
))}
</div>
)}
{hasErrors && ( {hasErrors && (
<div className="error-message-container invite-users-error-message-container"> <>
{inviteUsersErrorResponse?.map((error, index) => ( {/* show only when invites are sent successfully & partial error is present */}
<Typography.Text {inviteUsersSuccessResponse && inviteUsersErrorResponse && (
className="error-message" <div className="success-message-container invite-users-success-message-container">
type="danger" {inviteUsersSuccessResponse?.map((success, index) => (
// eslint-disable-next-line react/no-array-index-key <Typography.Text
key={`${error}-${index}`} className="success-message"
> // eslint-disable-next-line react/no-array-index-key
<TriangleAlert size={14} /> {error} key={`${success}-${index}`}
</Typography.Text> >
))} <CheckCircle size={14} /> {success}
</div> </Typography.Text>
))}
</div>
)}
<div className="error-message-container invite-users-error-message-container">
{inviteUsersErrorResponse?.map((error, index) => (
<Typography.Text
className="error-message"
type="danger"
// eslint-disable-next-line react/no-array-index-key
key={`${error}-${index}`}
>
<TriangleAlert size={14} /> {error}
</Typography.Text>
))}
</div>
</>
)} )}
</div> </div>
@ -413,17 +416,23 @@ function InviteTeamMembers({
type="primary" type="primary"
className="next-button" className="next-button"
onClick={handleNext} onClick={handleNext}
loading={isSendingInvites || disableNextButton} loading={isSendingInvites || isLoading || disableNextButton}
> >
{allInvitesSent ? 'Invites Sent' : 'Send Invites'} Send Invites
<ArrowRight size={14} />
{allInvitesSent ? <CheckCircle size={14} /> : <ArrowRight size={14} />}
</Button> </Button>
</div> </div>
<div className="do-later-container"> <div className="do-later-container">
<Button type="link" onClick={handleDoLater}> <Button
I&apos;ll do this later type="link"
className="do-later-button"
onClick={handleDoLater}
disabled={isSendingInvites || disableNextButton}
>
{isLoading && <Loader2 className="animate-spin" size={16} />}
<span>I&apos;ll do this later</span>
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -189,6 +189,15 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-top: 24px; margin-top: 24px;
.do-later-button {
font-size: 12px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
}
} }
.question { .question {

View File

@ -314,7 +314,7 @@ function OptimiseSignozNeeds({
<div className="do-later-container"> <div className="do-later-container">
<Button type="link" onClick={handleWillDoLater}> <Button type="link" onClick={handleWillDoLater}>
Skip for now I&apos;ll do this later
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -1,31 +1,24 @@
import './OnboardingQuestionaire.styles.scss'; import './OnboardingQuestionaire.styles.scss';
import { Skeleton } from 'antd';
import { NotificationInstance } from 'antd/es/notification/interface'; import { NotificationInstance } from 'antd/es/notification/interface';
import logEvent from 'api/common/logEvent';
import updateProfileAPI from 'api/onboarding/updateProfile'; import updateProfileAPI from 'api/onboarding/updateProfile';
import getAllOrgPreferences from 'api/preferences/getAllOrgPreferences'; import getAllOrgPreferences from 'api/preferences/getAllOrgPreferences';
import getOrgPreference from 'api/preferences/getOrgPreference';
import updateOrgPreferenceAPI from 'api/preferences/updateOrgPreference'; import updateOrgPreferenceAPI from 'api/preferences/updateOrgPreference';
import getOrgUser from 'api/user/getOrgUser';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { SOMETHING_WENT_WRONG } from 'constants/api'; import { SOMETHING_WENT_WRONG } from 'constants/api';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { InviteTeamMembersProps } from 'container/OrganizationSettings/PendingInvitesContainer'; import { InviteTeamMembersProps } from 'container/OrganizationSettings/PendingInvitesContainer';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import history from 'lib/history'; import history from 'lib/history';
import { isEmpty } from 'lodash-es'; import { useEffect, useState } from 'react';
import { Dispatch, useEffect, useState } from 'react';
import { useMutation, useQuery } from 'react-query'; import { useMutation, useQuery } from 'react-query';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { import {
UPDATE_IS_FETCHING_ORG_PREFERENCES, UPDATE_IS_FETCHING_ORG_PREFERENCES,
UPDATE_ORG_PREFERENCES, UPDATE_ORG_PREFERENCES,
} from 'types/actions/app'; } from 'types/actions/app';
import AppReducer from 'types/reducer/app'; import AppReducer from 'types/reducer/app';
import { USER_ROLES } from 'types/roles';
import { import {
AboutSigNozQuestions, AboutSigNozQuestions,
@ -70,15 +63,14 @@ const INITIAL_OPTIMISE_SIGNOZ_DETAILS: OptimiseSignozDetails = {
function OnboardingQuestionaire(): JSX.Element { function OnboardingQuestionaire(): JSX.Element {
const { notifications } = useNotifications(); const { notifications } = useNotifications();
const { org, role, isLoggedIn: isLoggedInState } = useSelector< const { org } = useSelector<AppState, AppReducer>((state) => state.app);
AppState, const dispatch = useDispatch();
AppReducer
>((state) => state.app);
const [currentStep, setCurrentStep] = useState<number>(1); const [currentStep, setCurrentStep] = useState<number>(1);
const [orgDetails, setOrgDetails] = useState<OrgDetails>(INITIAL_ORG_DETAILS); const [orgDetails, setOrgDetails] = useState<OrgDetails>(INITIAL_ORG_DETAILS);
const [signozDetails, setSignozDetails] = useState<SignozDetails>( const [signozDetails, setSignozDetails] = useState<SignozDetails>(
INITIAL_SIGNOZ_DETAILS, INITIAL_SIGNOZ_DETAILS,
); );
const [ const [
optimiseSignozDetails, optimiseSignozDetails,
setOptimiseSignozDetails, setOptimiseSignozDetails,
@ -87,113 +79,12 @@ function OnboardingQuestionaire(): JSX.Element {
InviteTeamMembersProps[] | null InviteTeamMembersProps[] | null
>(null); >(null);
const { data: orgUsers, isLoading: isLoadingOrgUsers } = useQuery({
queryFn: () =>
getOrgUser({
orgId: (org || [])[0].id,
}),
queryKey: ['getOrgUser', org?.[0].id],
});
const dispatch = useDispatch<Dispatch<AppActions>>();
const [currentOrgData, setCurrentOrgData] = useState<OrgData | null>(null); const [currentOrgData, setCurrentOrgData] = useState<OrgData | null>(null);
const [isOnboardingComplete, setIsOnboardingComplete] = useState<boolean>(
false,
);
const { const [
data: onboardingPreferenceData, updatingOrgOnboardingStatus,
isLoading: isLoadingOnboardingPreference, setUpdatingOrgOnboardingStatus,
} = useQuery({ ] = useState<boolean>(false);
queryFn: () => getOrgPreference({ preferenceID: 'ORG_ONBOARDING' }),
queryKey: ['getOrgPreferences', 'ORG_ONBOARDING'],
enabled: role === USER_ROLES.ADMIN,
});
const { data: orgPreferences, isLoading: isLoadingOrgPreferences } = useQuery({
queryFn: () => getAllOrgPreferences(),
queryKey: ['getOrgPreferences'],
enabled: isOnboardingComplete && role === USER_ROLES.ADMIN,
});
useEffect(() => {
if (orgPreferences && !isLoadingOrgPreferences) {
dispatch({
type: UPDATE_IS_FETCHING_ORG_PREFERENCES,
payload: {
isFetchingOrgPreferences: false,
},
});
dispatch({
type: UPDATE_ORG_PREFERENCES,
payload: {
orgPreferences: orgPreferences.payload?.data || null,
},
});
}
}, [orgPreferences, dispatch, isLoadingOrgPreferences]);
useEffect(() => {
if (isLoggedInState && role !== USER_ROLES.ADMIN) {
dispatch({
type: UPDATE_IS_FETCHING_ORG_PREFERENCES,
payload: {
isFetchingOrgPreferences: false,
},
});
}
}, [isLoggedInState, role, dispatch]);
useEffect(() => {
if (
!isLoadingOnboardingPreference &&
!isEmpty(onboardingPreferenceData?.payload?.data)
) {
const preferenceId = onboardingPreferenceData?.payload?.data?.preference_id;
const preferenceValue =
onboardingPreferenceData?.payload?.data?.preference_value;
if (preferenceId === 'ORG_ONBOARDING') {
setIsOnboardingComplete(preferenceValue as boolean);
}
}
}, [onboardingPreferenceData, isLoadingOnboardingPreference]);
const checkFirstTimeUser = (): boolean => {
const users = orgUsers?.payload || [];
const remainingUsers = users.filter(
(user) => user.email !== 'admin@signoz.cloud',
);
return remainingUsers.length === 1;
};
useEffect(() => {
// Only run this effect if the org users and preferences are loaded
if (!isLoadingOrgUsers && !isLoadingOnboardingPreference) {
const isFirstUser = checkFirstTimeUser();
// Redirect to get started if it's not the first user or if the onboarding is complete
if (!isFirstUser || isOnboardingComplete) {
history.push(ROUTES.GET_STARTED);
logEvent('User Onboarding: Redirected to Get Started', {
isFirstUser,
isOnboardingComplete,
});
} else {
logEvent('User Onboarding: Started', {});
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
isLoadingOrgUsers,
isLoadingOnboardingPreference,
isOnboardingComplete,
orgUsers,
]);
useEffect(() => { useEffect(() => {
if (org) { if (org) {
@ -207,6 +98,35 @@ function OnboardingQuestionaire(): JSX.Element {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [org]); }, [org]);
const { refetch: refetchOrgPreferences } = useQuery({
queryFn: () => getAllOrgPreferences(),
queryKey: ['getOrgPreferences'],
enabled: false,
refetchOnWindowFocus: false,
onSuccess: (response) => {
dispatch({
type: UPDATE_IS_FETCHING_ORG_PREFERENCES,
payload: {
isFetchingOrgPreferences: false,
},
});
dispatch({
type: UPDATE_ORG_PREFERENCES,
payload: {
orgPreferences: response.payload?.data || null,
},
});
setUpdatingOrgOnboardingStatus(false);
history.push(ROUTES.GET_STARTED);
},
onError: () => {
setUpdatingOrgOnboardingStatus(false);
},
});
const isNextDisabled = const isNextDisabled =
optimiseSignozDetails.logsPerDay === 0 && optimiseSignozDetails.logsPerDay === 0 &&
optimiseSignozDetails.hostsPerDay === 0 && optimiseSignozDetails.hostsPerDay === 0 &&
@ -226,10 +146,12 @@ function OnboardingQuestionaire(): JSX.Element {
const { mutate: updateOrgPreference } = useMutation(updateOrgPreferenceAPI, { const { mutate: updateOrgPreference } = useMutation(updateOrgPreferenceAPI, {
onSuccess: () => { onSuccess: () => {
setIsOnboardingComplete(true); refetchOrgPreferences();
}, },
onError: (error) => { onError: (error) => {
showErrorNotification(notifications, error as AxiosError); showErrorNotification(notifications, error as AxiosError);
setUpdatingOrgOnboardingStatus(false);
}, },
}); });
@ -258,6 +180,7 @@ function OnboardingQuestionaire(): JSX.Element {
}; };
const handleOnboardingComplete = (): void => { const handleOnboardingComplete = (): void => {
setUpdatingOrgOnboardingStatus(true);
updateOrgPreference({ updateOrgPreference({
preferenceID: 'ORG_ONBOARDING', preferenceID: 'ORG_ONBOARDING',
value: true, value: true,
@ -271,55 +194,46 @@ function OnboardingQuestionaire(): JSX.Element {
</div> </div>
<div className="onboarding-questionaire-content"> <div className="onboarding-questionaire-content">
{(isLoadingOnboardingPreference || isLoadingOrgUsers) && ( {currentStep === 1 && (
<div className="onboarding-questionaire-loading-container"> <OrgQuestions
<Skeleton /> currentOrgData={currentOrgData}
</div> orgDetails={orgDetails}
onNext={(orgDetails: OrgDetails): void => {
setOrgDetails(orgDetails);
setCurrentStep(2);
}}
/>
)} )}
{!isLoadingOnboardingPreference && !isLoadingOrgUsers && ( {currentStep === 2 && (
<> <AboutSigNozQuestions
{currentStep === 1 && ( signozDetails={signozDetails}
<OrgQuestions setSignozDetails={setSignozDetails}
currentOrgData={currentOrgData} onBack={(): void => setCurrentStep(1)}
orgDetails={orgDetails} onNext={(): void => setCurrentStep(3)}
onNext={(orgDetails: OrgDetails): void => { />
setOrgDetails(orgDetails); )}
setCurrentStep(2);
}}
/>
)}
{currentStep === 2 && ( {currentStep === 3 && (
<AboutSigNozQuestions <OptimiseSignozNeeds
signozDetails={signozDetails} isNextDisabled={isNextDisabled}
setSignozDetails={setSignozDetails} isUpdatingProfile={isUpdatingProfile}
onBack={(): void => setCurrentStep(1)} optimiseSignozDetails={optimiseSignozDetails}
onNext={(): void => setCurrentStep(3)} setOptimiseSignozDetails={setOptimiseSignozDetails}
/> onBack={(): void => setCurrentStep(2)}
)} onNext={handleUpdateProfile}
onWillDoLater={(): void => setCurrentStep(4)} // This is temporary, only to skip gateway api call as it's not setup on staging yet
/>
)}
{currentStep === 3 && ( {currentStep === 4 && (
<OptimiseSignozNeeds <InviteTeamMembers
isNextDisabled={isNextDisabled} isLoading={updatingOrgOnboardingStatus}
isUpdatingProfile={isUpdatingProfile} teamMembers={teamMembers}
optimiseSignozDetails={optimiseSignozDetails} setTeamMembers={setTeamMembers}
setOptimiseSignozDetails={setOptimiseSignozDetails} onBack={(): void => setCurrentStep(3)}
onBack={(): void => setCurrentStep(2)} onNext={handleOnboardingComplete}
onNext={handleUpdateProfile} />
onWillDoLater={(): void => setCurrentStep(4)} // This is temporary, only to skip gateway api call as it's not setup on staging yet
/>
)}
{currentStep === 4 && (
<InviteTeamMembers
teamMembers={teamMembers}
setTeamMembers={setTeamMembers}
onBack={(): void => setCurrentStep(3)}
onNext={handleOnboardingComplete}
/>
)}
</>
)} )}
</div> </div>
</div> </div>

View File

@ -261,7 +261,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
values, values,
async (): Promise<void> => { async (): Promise<void> => {
if (isOnboardingEnabled && isCloudUser()) { if (isOnboardingEnabled && isCloudUser()) {
history.push(ROUTES.ONBOARDING); history.push(ROUTES.GET_STARTED);
} else { } else {
history.push(ROUTES.APPLICATION); history.push(ROUTES.APPLICATION);
} }