diff --git a/src/CONST/index.ts b/src/CONST/index.ts index f2d66c6656c65..ab9a72ed9772f 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -6373,6 +6373,7 @@ const CONST = { ONBOARDING_RHP_VARIANT: { RHP_CONCIERGE_DM: 'rhpConciergeDm', RHP_ADMINS_ROOM: 'rhpAdminsRoom', + RHP_HOME_PAGE: 'rhpHomePage', CONTROL: 'control', }, ACTIONABLE_TRACK_EXPENSE_WHISPER_MESSAGE: 'What would you like to do with this expense?', diff --git a/src/components/SidePanel/RHPVariantTest/index.native.ts b/src/components/SidePanel/RHPVariantTest/index.native.ts index 466080a1b07d8..53127b64b42c4 100644 --- a/src/components/SidePanel/RHPVariantTest/index.native.ts +++ b/src/components/SidePanel/RHPVariantTest/index.native.ts @@ -3,11 +3,13 @@ import type {HandleRHPVariantNavigation, ShouldOpenRHPVariant} from './types'; /** * Side Panel is not supported on native platforms, so we always return false. */ -const shouldOpenRHPVariant: ShouldOpenRHPVariant = () => false; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const shouldOpenRHPVariant: ShouldOpenRHPVariant = (_variantOverride) => false; /** * No-op on native platforms since Side Panel is not supported. */ -const handleRHPVariantNavigation: HandleRHPVariantNavigation = () => {}; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const handleRHPVariantNavigation: HandleRHPVariantNavigation = (_onboardingPolicyID, _variantOverride) => {}; export {shouldOpenRHPVariant, handleRHPVariantNavigation}; diff --git a/src/components/SidePanel/RHPVariantTest/index.ts b/src/components/SidePanel/RHPVariantTest/index.ts index 43cfe8e7d11d2..1f6ba8f3393e2 100644 --- a/src/components/SidePanel/RHPVariantTest/index.ts +++ b/src/components/SidePanel/RHPVariantTest/index.ts @@ -29,13 +29,19 @@ Onyx.connectWithoutView({ /** * Determines if the user should be navigated to the RHP variant side panel after onboarding. * The RHP variant is only shown to micro companies that are part of the RHP experiment. + * + * Accepts an optional variantOverride to bypass the module-level Onyx variable, avoiding a race + * condition where the Onyx callback hasn't fired yet when this is called immediately after the + * CompleteGuidedSetup API response. */ -const shouldOpenRHPVariant: ShouldOpenRHPVariant = () => { +const shouldOpenRHPVariant: ShouldOpenRHPVariant = (variantOverride) => { + const variant = variantOverride ?? onboardingRHPVariant; const isMicroCompany = onboardingCompanySize === CONST.ONBOARDING_COMPANY_SIZE.MICRO; - const isRHPConciergeDM = onboardingRHPVariant === CONST.ONBOARDING_RHP_VARIANT.RHP_CONCIERGE_DM; - const isRHPAdminsRoom = onboardingRHPVariant === CONST.ONBOARDING_RHP_VARIANT.RHP_ADMINS_ROOM; + const isRHPConciergeDM = variant === CONST.ONBOARDING_RHP_VARIANT.RHP_CONCIERGE_DM; + const isRHPAdminsRoom = variant === CONST.ONBOARDING_RHP_VARIANT.RHP_ADMINS_ROOM; + const isRHPHomePage = variant === CONST.ONBOARDING_RHP_VARIANT.RHP_HOME_PAGE; - return isMicroCompany && (isRHPConciergeDM || isRHPAdminsRoom); + return isMicroCompany && (isRHPConciergeDM || isRHPAdminsRoom || isRHPHomePage); }; /** @@ -43,8 +49,18 @@ const shouldOpenRHPVariant: ShouldOpenRHPVariant = () => { * - Control: navigate to the last accessed report on small screens, do not open side panel * - RHP Concierge DM: navigate to the workspace overview and open the side panel with the Concierge DM * - RHP Admins Room: navigate to the workspace overview and open the side panel with the Admins Room + * - RHP Home Page: navigate to the Home page and open the side panel with the Concierge DM + * + * Accepts an optional variantOverride for the same race-condition reason as shouldOpenRHPVariant. */ -const handleRHPVariantNavigation: HandleRHPVariantNavigation = (onboardingPolicyID) => { +const handleRHPVariantNavigation: HandleRHPVariantNavigation = (onboardingPolicyID, variantOverride) => { + const variant = variantOverride ?? onboardingRHPVariant; + if (variant === CONST.ONBOARDING_RHP_VARIANT.RHP_HOME_PAGE) { + Navigation.navigate(ROUTES.HOME); + SidePanelActions.openSidePanel(true); + return; + } + Navigation.navigate(ROUTES.WORKSPACE_OVERVIEW.getRoute(onboardingPolicyID)); SidePanelActions.openSidePanel(true); }; diff --git a/src/components/SidePanel/RHPVariantTest/types.ts b/src/components/SidePanel/RHPVariantTest/types.ts index 7efd441c05264..15dff41a1af68 100644 --- a/src/components/SidePanel/RHPVariantTest/types.ts +++ b/src/components/SidePanel/RHPVariantTest/types.ts @@ -1,4 +1,6 @@ -type ShouldOpenRHPVariant = () => boolean; -type HandleRHPVariantNavigation = (onboardingPolicyID?: string) => void; +import type {OnboardingRHPVariant} from '@src/types/onyx'; + +type ShouldOpenRHPVariant = (variantOverride?: OnboardingRHPVariant | null) => boolean; +type HandleRHPVariantNavigation = (onboardingPolicyID?: string, variantOverride?: OnboardingRHPVariant | null) => void; export type {ShouldOpenRHPVariant, HandleRHPVariantNavigation}; diff --git a/src/libs/navigateAfterOnboarding.ts b/src/libs/navigateAfterOnboarding.ts index cfb8de469374a..8c7b4b8e0bacd 100644 --- a/src/libs/navigateAfterOnboarding.ts +++ b/src/libs/navigateAfterOnboarding.ts @@ -1,5 +1,6 @@ import {handleRHPVariantNavigation, shouldOpenRHPVariant} from '@components/SidePanel/RHPVariantTest'; import ROUTES from '@src/ROUTES'; +import type {OnboardingRHPVariant} from '@src/types/onyx'; import {setDisableDismissOnEscape} from './actions/Modal'; import shouldOpenOnAdminRoom from './Navigation/helpers/shouldOpenOnAdminRoom'; import Navigation from './Navigation/Navigation'; @@ -50,11 +51,12 @@ function navigateAfterOnboarding( onboardingPolicyID?: string, onboardingAdminsChatReportID?: string, shouldPreventOpenAdminRoom = false, + onboardingRHPVariant?: OnboardingRHPVariant | null, ) { setDisableDismissOnEscape(false); - if (shouldOpenRHPVariant()) { - handleRHPVariantNavigation(onboardingPolicyID); + if (shouldOpenRHPVariant(onboardingRHPVariant)) { + handleRHPVariantNavigation(onboardingPolicyID, onboardingRHPVariant); return; } @@ -83,6 +85,7 @@ function navigateAfterOnboardingWithMicrotaskQueue( onboardingPolicyID?: string, onboardingAdminsChatReportID?: string, shouldPreventOpenAdminRoom = false, + onboardingRHPVariant?: OnboardingRHPVariant | null, ) { Navigation.dismissModal(); Navigation.setNavigationActionToMicrotaskQueue(() => { @@ -94,6 +97,7 @@ function navigateAfterOnboardingWithMicrotaskQueue( onboardingPolicyID, onboardingAdminsChatReportID, shouldPreventOpenAdminRoom, + onboardingRHPVariant, ); }); } diff --git a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx index 9429cd1531cca..2351f302218e1 100644 --- a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx +++ b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx @@ -33,6 +33,7 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import type {OnboardingRHPVariant} from '@src/types/onyx'; import type {BaseOnboardingInterestedFeaturesProps, Feature, SectionObject} from './types'; function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardingInterestedFeaturesProps) { @@ -212,7 +213,7 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin setOnboardingPolicyID(policyID); } - await completeOnboarding({ + const response = await completeOnboarding({ engagementChoice: onboardingPurposeSelected, onboardingMessage: onboardingMessages[onboardingPurposeSelected], adminsChatReportID, @@ -228,6 +229,11 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin betas, }); + // Extract the RHP variant directly from the API response to avoid a race condition + // where the Onyx callback hasn't fired yet when navigateAfterOnboarding is called. + const rhpVariantUpdate = (response?.onyxData as Array<{key: string; value: unknown}> | undefined)?.find((update) => update.key === ONYXKEYS.NVP_ONBOARDING_RHP_VARIANT); + const rhpVariant = rhpVariantUpdate?.value as OnboardingRHPVariant | undefined; + // Avoid creating new WS because onboardingPolicyID is cleared before unmounting // eslint-disable-next-line @typescript-eslint/no-deprecated InteractionManager.runAfterInteractions(() => { @@ -246,6 +252,7 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin // Onboarding tasks would show in Concierge instead of admins room for testing accounts, we should open where onboarding tasks are located // See https://github.com/Expensify/App/issues/57167 for more details (session?.email ?? '').includes('+'), + rhpVariant, ); } catch (error) { Log.warn('[BaseOnboardingInterestedFeatures] Error completing onboarding', {error}); diff --git a/src/types/onyx/OnboardingRHPVariant.ts b/src/types/onyx/OnboardingRHPVariant.ts index 271e1977e7370..9ac25b94c31cc 100644 --- a/src/types/onyx/OnboardingRHPVariant.ts +++ b/src/types/onyx/OnboardingRHPVariant.ts @@ -1,9 +1,10 @@ /** - * The variant of the onboarding RHP for A/B/C testing + * The variant of the onboarding RHP for A/B/C/D testing * @description 'control' - The variant with the Concierge DM * @description 'rhpConciergeDm' - Admin of workspace with Concierge DM * @description 'rhpAdminsRoom' - Admin of workspace with the admins room + * @description 'rhpHomePage' - Navigate to Home page with Concierge Anywhere accessible in #admins room */ -type OnboardingRHPVariant = 'rhpConciergeDm' | 'rhpAdminsRoom' | 'control'; +type OnboardingRHPVariant = 'rhpConciergeDm' | 'rhpAdminsRoom' | 'rhpHomePage' | 'control'; export default OnboardingRHPVariant;