Skip to content

Commit

Permalink
feat: Setup wizard content updates and enforcing cloud connectivity (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagoevanp authored Oct 25, 2023
1 parent bd1c8b1 commit ee2c7d1
Show file tree
Hide file tree
Showing 14 changed files with 189 additions and 120 deletions.
5 changes: 5 additions & 0 deletions .changeset/six-pens-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': minor
---

feat: Setup wizard content updates and enforcing cloud connectivity
10 changes: 2 additions & 8 deletions apps/meteor/client/views/admin/cloud/hooks/useFeatureBullets.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTranslation } from '@rocket.chat/ui-contexts';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

type featureBulletsType = {
key: number;
Expand All @@ -9,7 +9,7 @@ type featureBulletsType = {
};

const useFeatureBullets = () => {
const t = useTranslation();
const { t } = useTranslation();

const featureBullets: featureBulletsType[] = useMemo(
() => [
Expand All @@ -31,12 +31,6 @@ const useFeatureBullets = () => {
description: t('RegisterWorkspace_Features_Omnichannel_Description'),
disconnect: t('RegisterWorkspace_Features_Omnichannel_Disconnect'),
},
{
key: 4,
title: t('RegisterWorkspace_Features_ThirdPartyLogin_Title'),
description: t('RegisterWorkspace_Features_ThirdPartyLogin_Description'),
disconnect: t('RegisterWorkspace_Features_ThirdPartyLogin_Disconnect'),
},
],
[t],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ type SetupWizarContextValue = {
goToStep: (step: number) => void;
registerAdminUser: (user: Omit<Parameters<ComponentProps<typeof AdminInfoPage>['onSubmit']>[0], 'keepPosted'>) => Promise<void>;
registerServer: (params: { email: string; resend?: boolean }) => Promise<void>;
registerPreIntent: () => Promise<void>;
saveWorkspaceData: () => Promise<void>;
saveOrganizationData: () => Promise<void>;
saveOrganizationData: (data: SetupWizardData['organizationData']) => Promise<void>;
completeSetupWizard: () => Promise<void>;
offline: boolean;
maxSteps: number;
};

Expand All @@ -48,7 +46,6 @@ export const SetupWizardContext = createContext<SetupWizarContextValue>({
serverData: {
agreement: false,
email: '',
registerType: 'registered',
updates: false,
},
registrationData: { cloudEmail: '', user_code: '', device_code: '' },
Expand All @@ -62,13 +59,11 @@ export const SetupWizardContext = createContext<SetupWizarContextValue>({
goToStep: () => undefined,
registerAdminUser: async () => undefined,
registerServer: async () => undefined,
registerPreIntent: async () => undefined,
saveWorkspaceData: async () => undefined,
saveOrganizationData: async () => undefined,
validateEmail: () => true,
currentStep: 1,
completeSetupWizard: async () => undefined,
offline: false,
maxSteps: 4,
});

Expand Down
42 changes: 34 additions & 8 deletions apps/meteor/client/views/setupWizard/hooks/useStepRouting.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { useRouteParameter, useRoute, useRole } from '@rocket.chat/ui-contexts';
import { useRouteParameter, useRouter, useRole, useSetting } from '@rocket.chat/ui-contexts';
import type { Dispatch, SetStateAction } from 'react';
import { useState, useEffect } from 'react';

export const useStepRouting = (): [number, Dispatch<SetStateAction<number>>] => {
const param = useRouteParameter('step');
const setupWizardRoute = useRoute('setup-wizard');
const router = useRouter();
const hasAdminRole = useRole('admin');
const initialStep = hasAdminRole ? 2 : 1;
const hasOrganizationData = !!useSetting('Organization_Name');

const [currentStep, setCurrentStep] = useState<number>(() => {
const initialStep = (() => {
switch (true) {
case hasOrganizationData: {
return 3;
}
case hasAdminRole: {
return 2;
}
default: {
return 1;
}
}
})();

if (!param) {
return initialStep;
}
Expand All @@ -22,12 +36,24 @@ export const useStepRouting = (): [number, Dispatch<SetStateAction<number>>] =>
});

useEffect(() => {
if (hasAdminRole && currentStep === 1) {
setCurrentStep(2);
}
switch (true) {
case (currentStep === 1 || currentStep === 2) && hasOrganizationData: {
setCurrentStep(3);
router.navigate(`/setup-wizard/3`);
break;
}

setupWizardRoute.replace({ step: String(currentStep) });
}, [setupWizardRoute, currentStep, hasAdminRole]);
case currentStep === 1 && hasAdminRole: {
setCurrentStep(2);
router.navigate(`/setup-wizard/2`);
break;
}

default: {
router.navigate(`/setup-wizard/${currentStep}`);
}
}
}, [router, currentStep, hasAdminRole, hasOrganizationData]);

return [currentStep, setCurrentStep];
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const initialData: ContextType<typeof SetupWizardContext>['setupWizardData'] = {
serverData: {
agreement: false,
email: '',
registerType: 'registered',
updates: false,
},
registrationData: { cloudEmail: '', device_code: '', user_code: '' },
Expand All @@ -43,7 +42,6 @@ const SetupWizardProvider = ({ children }: { children: ReactElement }): ReactEle
const [setupWizardData, setSetupWizardData] = useState<ContextType<typeof SetupWizardContext>['setupWizardData']>(initialData);
const [currentStep, setCurrentStep] = useStepRouting();
const { isSuccess, data } = useParameters();
const [offline, setOffline] = useState(false);
const dispatchToastMessage = useToastMessageDispatch();
const dispatchSettings = useSettingsDispatch();

Expand All @@ -52,7 +50,6 @@ const SetupWizardProvider = ({ children }: { children: ReactElement }): ReactEle
const defineUsername = useMethod('setUsername');
const loginWithPassword = useLoginWithPassword();
const setForceLogin = useSessionDispatch('forceLogin');
const registerPreIntentEndpoint = useEndpoint('POST', '/v1/cloud.registerPreIntent');
const createRegistrationIntent = useEndpoint('POST', '/v1/cloud.createRegistrationIntent');

const goToPreviousStep = useCallback(() => setCurrentStep((currentStep) => currentStep - 1), [setCurrentStep]);
Expand Down Expand Up @@ -122,34 +119,34 @@ const SetupWizardProvider = ({ children }: { children: ReactElement }): ReactEle
]);
}, [dispatchSettings, setupWizardData]);

const saveOrganizationData = useCallback(async (): Promise<void> => {
const {
organizationData: { organizationName, organizationIndustry, organizationSize, country },
} = setupWizardData;

await dispatchSettings([
{
_id: 'Country',
value: country,
},
{
_id: 'Industry',
value: organizationIndustry,
},
{
_id: 'Size',
value: organizationSize,
},
{
_id: 'Organization_Name',
value: organizationName,
},
]);
}, [dispatchSettings, setupWizardData]);
const saveOrganizationData = useCallback(
async (organizationData: ContextType<typeof SetupWizardContext>['setupWizardData']['organizationData']): Promise<void> => {
const { organizationName, organizationIndustry, organizationSize, country } = organizationData;

await dispatchSettings([
{
_id: 'Country',
value: country,
},
{
_id: 'Industry',
value: organizationIndustry,
},
{
_id: 'Size',
value: organizationSize,
},
{
_id: 'Organization_Name',
value: organizationName,
},
]);
},
[dispatchSettings],
);

const registerServer: HandleRegisterServer = useMutableCallback(async ({ email, resend = false }): Promise<void> => {
try {
await saveOrganizationData();
const { intentData } = await createRegistrationIntent({ resend, email });
queryClient.invalidateQueries(['licenses']);
queryClient.invalidateQueries(['getRegistrationStatus']);
Expand All @@ -162,22 +159,11 @@ const SetupWizardProvider = ({ children }: { children: ReactElement }): ReactEle
goToStep(4);
setShowSetupWizard('in_progress');
} catch (e) {
console.log(e);
}
});

const registerPreIntent = useMutableCallback(async (): Promise<void> => {
await saveOrganizationData();
try {
const { offline } = await registerPreIntentEndpoint();
setOffline(offline);
} catch (_) {
setOffline(true);
dispatchToastMessage({ type: 'error', message: t('Cloud_register_error') });
}
});

const completeSetupWizard = useMutableCallback(async (): Promise<void> => {
await saveOrganizationData();
dispatchToastMessage({ type: 'success', message: t('Your_workspace_is_ready') });
return setShowSetupWizard('completed');
});
Expand All @@ -193,15 +179,13 @@ const SetupWizardProvider = ({ children }: { children: ReactElement }): ReactEle
goToPreviousStep,
goToNextStep,
goToStep,
offline,
registerPreIntent,
registerAdminUser,
validateEmail: _validateEmail,
registerServer,
saveWorkspaceData,
saveOrganizationData,
completeSetupWizard,
maxSteps: data.serverAlreadyRegistered ? 2 : 3,
maxSteps: data.serverAlreadyRegistered ? 2 : 4,
}),
[
setupWizardData,
Expand All @@ -212,9 +196,7 @@ const SetupWizardProvider = ({ children }: { children: ReactElement }): ReactEle
goToPreviousStep,
goToNextStep,
goToStep,
offline,
registerAdminUser,
registerPreIntent,
_validateEmail,
registerServer,
saveWorkspaceData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const setIntervalTime = (interval?: number): number => (interval ? interval * 10
const CloudAccountConfirmation = (): ReactElement => {
const {
registerServer,
currentStep,
maxSteps,
goToStep,
setupWizardData: { registrationData },
saveWorkspaceData,
Expand All @@ -21,14 +23,16 @@ const CloudAccountConfirmation = (): ReactElement => {

const getConfirmation = useCallback(async () => {
try {
const { pollData } = await cloudConfirmationPoll({
deviceCode: registrationData.device_code,
});

if ('successful' in pollData && pollData.successful) {
await saveWorkspaceData();
dispatchToastMessage({ type: 'success', message: t('Your_workspace_is_ready') });
return setShowSetupWizard('completed');
if (registrationData.device_code) {
const { pollData } = await cloudConfirmationPoll({
deviceCode: registrationData.device_code,
});

if ('successful' in pollData && pollData.successful) {
await saveWorkspaceData();
dispatchToastMessage({ type: 'success', message: t('Your_workspace_is_ready') });
return setShowSetupWizard('completed');
}
}
} catch (error: unknown) {
dispatchToastMessage({ type: 'error', message: error });
Expand All @@ -43,6 +47,8 @@ const CloudAccountConfirmation = (): ReactElement => {

return (
<AwaitingConfirmationPage
currentStep={currentStep}
stepCount={maxSteps}
emailAddress={registrationData.cloudEmail}
securityCode={registrationData.user_code}
onResendEmailRequest={(): Promise<void> => registerServer({ email: registrationData.cloudEmail, resend: true })}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ const OrganizationInfoStep = (): ReactElement => {

const {
setupWizardData: { organizationData },
saveOrganizationData,
setSetupWizardData,
settings,
goToPreviousStep,
goToNextStep,
completeSetupWizard,
currentStep,
registerPreIntent,
skipCloudRegistration,
maxSteps,
} = useSetupWizardContext();
Expand All @@ -50,8 +50,11 @@ const OrganizationInfoStep = (): ReactElement => {
if (skipCloudRegistration) {
return completeSetupWizard();
}

setSetupWizardData((prevState) => ({ ...prevState, organizationData: data }));
await registerPreIntent();

await saveOrganizationData(data);

goToNextStep();
};

Expand Down
Loading

0 comments on commit ee2c7d1

Please sign in to comment.