From b2fe9cadb988fd9c23ed80284d0d7d44039822cb Mon Sep 17 00:00:00 2001 From: allgandalf Date: Mon, 16 Dec 2024 16:08:37 +0530 Subject: [PATCH 01/11] add privateDomainOnboardingCheck beta Signed-off-by: allgandalf --- src/CONST.ts | 1 + src/libs/Permissions.ts | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/CONST.ts b/src/CONST.ts index 204ccaccf394..f123ee5a2304 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -686,6 +686,7 @@ const CONST = { CATEGORY_AND_TAG_APPROVERS: 'categoryAndTagApprovers', PER_DIEM: 'newDotPerDiem', PRODUCT_TRAINING: 'productTraining', + PRIVATE_DOMAIN_ONBOARDING_CHECK: 'privateDomainOnboardingCheck', }, BUTTON_STATES: { DEFAULT: 'default', diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 4a7bba3932a3..148ca1631f9a 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -9,6 +9,10 @@ function canUseAllBetas(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.ALL); } +function canUsePrivateDomainOnboardingCheck(betas: OnyxEntry): boolean { + return !!betas?.includes(CONST.BETAS.PRIVATE_DOMAIN_ONBOARDING_CHECK) || canUseAllBetas(betas); +} + function canUseDefaultRooms(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.DEFAULT_ROOMS) || canUseAllBetas(betas); } @@ -43,6 +47,7 @@ function canUseLinkPreviews(): boolean { } export default { + canUsePrivateDomainOnboardingCheck, canUseDefaultRooms, canUseLinkPreviews, canUseSpotnanaTravel, From a11d3ee83e240cbc16c441d1fdf49c79d1d7e1bd Mon Sep 17 00:00:00 2001 From: allgandalf Date: Mon, 16 Dec 2024 16:13:43 +0530 Subject: [PATCH 02/11] add new onyx props to Onboarding key Signed-off-by: allgandalf --- src/types/onyx/Onboarding.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/types/onyx/Onboarding.ts b/src/types/onyx/Onboarding.ts index 2cf8eccba1c2..f5323b554cfc 100644 --- a/src/types/onyx/Onboarding.ts +++ b/src/types/onyx/Onboarding.ts @@ -1,5 +1,6 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +import type * as OnyxCommon from './OnyxCommon'; /** Model of onboarding */ type Onboarding = { @@ -14,6 +15,15 @@ type Onboarding = { /** A Boolean that tells whether the user has seen navattic tour */ selfTourViewed?: boolean; + + /** A Boolean that tells whether the user should be redirected to OD after merging work email */ + shouldRedirectToClassicAfterMerge?: boolean; + + /** A Boolean that informs whether the user needs to validate their work email */ + shouldValidate?: boolean; + + /** Field-specific server side errors keyed by microtime */ + errorFields?: OnyxCommon.Errors; }; export default Onboarding; From 55caf7606f95a222a0ae49d71e93e02948f69757 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Mon, 16 Dec 2024 16:21:42 +0530 Subject: [PATCH 03/11] add onboardingWorkEmailForm form and its onyx key --- src/ONYXKEYS.ts | 3 +++ src/types/form/OnboardingWorkEmailForm.ts | 18 ++++++++++++++++++ src/types/form/index.ts | 1 + 3 files changed, 22 insertions(+) create mode 100644 src/types/form/OnboardingWorkEmailForm.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index bd77ed7e8af4..aeb82f2ff73c 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -721,6 +721,8 @@ const ONYXKEYS = { RULES_MAX_EXPENSE_AGE_FORM_DRAFT: 'rulesMaxExpenseAgeFormDraft', DEBUG_DETAILS_FORM: 'debugDetailsForm', DEBUG_DETAILS_FORM_DRAFT: 'debugDetailsFormDraft', + ONBOARDING_WORK_EMAIL_FORM: 'onboardingWorkEmailForm', + ONBOARDING_WORK_EMAIL_FORM_Draft: 'onboardingWorkEmailFormDraft', }, } as const; @@ -814,6 +816,7 @@ type OnyxFormValuesMapping = { [ONYXKEYS.FORMS.RULES_MAX_EXPENSE_AGE_FORM]: FormTypes.RulesMaxExpenseAgeForm; [ONYXKEYS.FORMS.SEARCH_SAVED_SEARCH_RENAME_FORM]: FormTypes.SearchSavedSearchRenameForm; [ONYXKEYS.FORMS.DEBUG_DETAILS_FORM]: FormTypes.DebugReportForm | FormTypes.DebugReportActionForm | FormTypes.DebugTransactionForm | FormTypes.DebugTransactionViolationForm; + [ONYXKEYS.FORMS.ONBOARDING_WORK_EMAIL_FORM]: FormTypes.OnboardingWorkEmailForm; }; type OnyxFormDraftValuesMapping = { diff --git a/src/types/form/OnboardingWorkEmailForm.ts b/src/types/form/OnboardingWorkEmailForm.ts new file mode 100644 index 000000000000..4e9b7caba5e1 --- /dev/null +++ b/src/types/form/OnboardingWorkEmailForm.ts @@ -0,0 +1,18 @@ +import type {ValueOf} from 'type-fest'; +import type Form from './Form'; + +const INPUT_IDS = { + ONBOARDING_WORK_EMAIL: 'onboardingWorkEmail', +} as const; + +type InputID = ValueOf; + +type OnboardingWorkEmailForm = Form< + InputID, + { + [INPUT_IDS.ONBOARDING_WORK_EMAIL]: string; + } +>; + +export type {OnboardingWorkEmailForm}; +export default INPUT_IDS; diff --git a/src/types/form/index.ts b/src/types/form/index.ts index e8e37bebef9a..4cf90f0b889a 100644 --- a/src/types/form/index.ts +++ b/src/types/form/index.ts @@ -87,3 +87,4 @@ export type {WorkspaceCompanyCardFeedName} from './WorkspaceCompanyCardFeedName' export type {SearchSavedSearchRenameForm} from './SearchSavedSearchRenameForm'; export type {WorkspaceCompanyCardEditName} from './WorkspaceCompanyCardEditName'; export type {PersonalDetailsForm} from './PersonalDetailsForm'; +export type {OnboardingWorkEmailForm} from './OnboardingWorkEmailForm'; From 7b65e57d94d6728aff43149e443adcf45562f191 Mon Sep 17 00:00:00 2001 From: allgandalf Date: Mon, 16 Dec 2024 17:59:07 +0530 Subject: [PATCH 04/11] add basic screen to add work email --- src/ONYXKEYS.ts | 2 +- src/ROUTES.ts | 4 + src/SCREENS.ts | 1 + src/components/Form/FormProvider.tsx | 4 +- src/components/Form/FormWrapper.tsx | 7 +- src/components/Form/types.ts | 3 + src/components/FormAlertWithSubmitButton.tsx | 7 +- src/hooks/useOnboardingFlow.ts | 7 +- src/languages/en.ts | 11 + src/languages/es.ts | 11 + .../Navigators/OnboardingModalNavigator.tsx | 5 + src/libs/Navigation/NavigationRoot.tsx | 5 +- src/libs/Navigation/linkingConfig/config.ts | 6 +- src/libs/Navigation/types.ts | 3 + src/libs/actions/Welcome/OnboardingFlow.ts | 23 +- .../BaseOnboardingWorkEmail.tsx | 230 ++++++++++++++++++ .../OnboardingWorkEmail/index.native.tsx | 17 ++ src/pages/OnboardingWorkEmail/index.tsx | 20 ++ src/pages/OnboardingWorkEmail/types.ts | 15 ++ 19 files changed, 365 insertions(+), 16 deletions(-) create mode 100644 src/pages/OnboardingWorkEmail/BaseOnboardingWorkEmail.tsx create mode 100644 src/pages/OnboardingWorkEmail/index.native.tsx create mode 100644 src/pages/OnboardingWorkEmail/index.tsx create mode 100644 src/pages/OnboardingWorkEmail/types.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index aeb82f2ff73c..595f7b36acc8 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -722,7 +722,7 @@ const ONYXKEYS = { DEBUG_DETAILS_FORM: 'debugDetailsForm', DEBUG_DETAILS_FORM_DRAFT: 'debugDetailsFormDraft', ONBOARDING_WORK_EMAIL_FORM: 'onboardingWorkEmailForm', - ONBOARDING_WORK_EMAIL_FORM_Draft: 'onboardingWorkEmailFormDraft', + ONBOARDING_WORK_EMAIL_FORM_DRAFT: 'onboardingWorkEmailFormDraft', }, } as const; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index b9544d81bece..d67cd9251ef4 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1393,6 +1393,10 @@ const ROUTES = { route: 'onboarding/join-workspaces', getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/join-workspaces`, backTo), }, + ONBOARDING_WORK_EMAIL: { + route: 'onboarding/work-email', + getRoute: (backTo?: string) => getUrlWithBackToParam(`onboarding/work-email`, backTo), + }, WELCOME_VIDEO_ROOT: 'onboarding/welcome-video', EXPLANATION_MODAL_ROOT: 'onboarding/explanation', MIGRATED_USER_WELCOME_MODAL: 'onboarding/migrated-user-welcome', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 6c4547e94c37..4b72fe085f59 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -583,6 +583,7 @@ const SCREENS = { EMPLOYEES: 'Onboarding_Employees', ACCOUNTING: 'Onboarding_Accounting', WORKSPACES: 'Onboarding_Workspaces', + WORK_EMAIL: 'Onboarding_Work_Email', }, WELCOME_VIDEO: { diff --git a/src/components/Form/FormProvider.tsx b/src/components/Form/FormProvider.tsx index 2731d6bd1f98..7992cd91eee1 100644 --- a/src/components/Form/FormProvider.tsx +++ b/src/components/Form/FormProvider.tsx @@ -106,7 +106,7 @@ function FormProvider( FormActions.clearErrorFields(formID); const validateErrors: GenericFormInputErrors = validate?.(trimmedStringValues) ?? {}; - + console.log('validateErrors', validateErrors) if (!allowHTML) { // Validate the input for html tags. It should supersede any other error Object.entries(trimmedStringValues).forEach(([inputID, inputValue]) => { @@ -396,7 +396,7 @@ function FormProvider( [draftValues, inputValues, formState?.errorFields, errors, submit, setTouchedInput, shouldValidateOnBlur, onValidate, hasServerError, formID, shouldValidateOnChange], ); const value = useMemo(() => ({registerInput}), [registerInput]); - + console.log('errorserrorserrors', errors) return ( {/* eslint-disable react/jsx-props-no-spreading */} diff --git a/src/components/Form/FormWrapper.tsx b/src/components/Form/FormWrapper.tsx index 64bb2173f5b0..131469941b4d 100644 --- a/src/components/Form/FormWrapper.tsx +++ b/src/components/Form/FormWrapper.tsx @@ -21,7 +21,7 @@ type FormWrapperProps = ChildrenProps & FormProps & { /** Submit button styles */ submitButtonStyles?: StyleProp; - + /** Whether to apply flex to the submit button */ submitFlexEnabled?: boolean; @@ -36,6 +36,9 @@ type FormWrapperProps = ChildrenProps & /** Callback to submit the form */ onSubmit: () => void; + + /** should render the extra button above submit button */ + shouldRenderFooterAboveSubmit?: boolean; }; function FormWrapper({ @@ -57,6 +60,7 @@ function FormWrapper({ shouldHideFixErrorsAlert = false, disablePressOnEnter = false, isSubmitDisabled = false, + shouldRenderFooterAboveSubmit = false, }: FormWrapperProps) { const styles = useThemeStyles(); const {paddingBottom: safeAreaInsetPaddingBottom} = useStyledSafeAreaInsets(); @@ -122,6 +126,7 @@ function FormWrapper({ isSubmitActionDangerous={isSubmitActionDangerous} disablePressOnEnter={disablePressOnEnter} enterKeyEventListenerPriority={1} + shouldRenderFooterAboveSubmit={shouldRenderFooterAboveSubmit} /> )} diff --git a/src/components/Form/types.ts b/src/components/Form/types.ts index ab9260a6b5d9..a5fc2f5d333b 100644 --- a/src/components/Form/types.ts +++ b/src/components/Form/types.ts @@ -160,6 +160,9 @@ type FormProps = { /** Disable press on enter for submit button */ disablePressOnEnter?: boolean; + + /** Render extra button above submit button */ + shouldRenderFooterAboveSubmit?: boolean; }; type FormRef = { diff --git a/src/components/FormAlertWithSubmitButton.tsx b/src/components/FormAlertWithSubmitButton.tsx index fabb5e54cb60..1c121516bf54 100644 --- a/src/components/FormAlertWithSubmitButton.tsx +++ b/src/components/FormAlertWithSubmitButton.tsx @@ -62,6 +62,9 @@ type FormAlertWithSubmitButtonProps = { /** The priority to assign the enter key event listener to buttons. 0 is the highest priority. */ enterKeyEventListenerPriority?: number; + + /** should render the extra button above submit button */ + shouldRenderFooterAboveSubmit?: boolean; }; function FormAlertWithSubmitButton({ @@ -83,6 +86,7 @@ function FormAlertWithSubmitButton({ useSmallerSubmitButtonSize = false, errorMessageStyle, enterKeyEventListenerPriority = 0, + shouldRenderFooterAboveSubmit = false, }: FormAlertWithSubmitButtonProps) { const styles = useThemeStyles(); const style = [!footerContent ? {} : styles.mb3, buttonStyles]; @@ -104,6 +108,7 @@ function FormAlertWithSubmitButton({ > {(isOffline: boolean | undefined) => ( + {shouldRenderFooterAboveSubmit && footerContent} {isOffline && !enabledWhenOffline ? (