From 7547bf374c6ef494d39c8beb72d41a7837d1832b Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Fri, 13 Mar 2026 22:10:08 +0530 Subject: [PATCH 1/3] Thread betas through buildPolicyData and openReportFromDeepLink to prepareOnboardingOnyxData. Signed-off-by: krishna2323 --- src/DeepLinkHandler.tsx | 5 +++-- src/components/SettlementButton/index.tsx | 1 + src/libs/actions/App.ts | 10 ++++++++++ src/libs/actions/IOU/index.ts | 2 ++ src/libs/actions/Link.ts | 13 ++++++++++--- src/libs/actions/Policy/Policy.ts | 4 ++++ src/libs/actions/Report/index.ts | 3 +++ .../BaseOnboardingInterestedFeatures.tsx | 1 + .../BaseOnboardingWorkspaceConfirmation.tsx | 3 +++ .../BaseOnboardingWorkspaceOptional.tsx | 2 ++ .../Travel/WorkspaceConfirmationForTravelPage.tsx | 2 ++ .../iou/request/step/IOURequestStepUpgrade.tsx | 3 +++ .../upgrade/PersonalCardUpgradePage.tsx | 2 ++ src/pages/workspace/WorkspaceConfirmationPage.tsx | 2 ++ 14 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/DeepLinkHandler.tsx b/src/DeepLinkHandler.tsx index e73386b23f086..dcfac3595d627 100644 --- a/src/DeepLinkHandler.tsx +++ b/src/DeepLinkHandler.tsx @@ -30,6 +30,7 @@ function DeepLinkHandler({onInitialUrl}: DeepLinkHandlerProps) { const [, sessionMetadata] = useOnyx(ONYXKEYS.SESSION); const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); + const [betas] = useOnyx(ONYXKEYS.BETAS); const isAuthenticated = useIsAuthenticated(); useEffect(() => { @@ -47,7 +48,7 @@ function DeepLinkHandler({onInitialUrl}: DeepLinkHandlerProps) { if (introSelected === undefined) { Log.info('[Deep link] introSelected is undefined when processing initial URL', false, {url}); } - openReportFromDeepLink(url, allReports, isAuthenticated, conciergeReportID, introSelected); + openReportFromDeepLink(url, allReports, isAuthenticated, conciergeReportID, introSelected, betas); } else { Report.doneCheckingPublicRoom(); } @@ -64,7 +65,7 @@ function DeepLinkHandler({onInitialUrl}: DeepLinkHandlerProps) { Log.info('[Deep link] introSelected is undefined when processing URL change', false, {url: state.url}); } const isCurrentlyAuthenticated = hasAuthToken(); - openReportFromDeepLink(state.url, allReports, isCurrentlyAuthenticated, conciergeReportID, introSelected); + openReportFromDeepLink(state.url, allReports, isCurrentlyAuthenticated, conciergeReportID, introSelected, betas); }); return () => { diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index 0c01b08c9a0ba..f2d876f455d8a 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -357,6 +357,7 @@ function SettlementButton({ activePolicyID, currentUserAccountIDParam: currentUserPersonalDetails.accountID, currentUserEmailParam: currentUserPersonalDetails.email ?? '', + betas, isSelfTourViewed, }).policyID; }; diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 08285a7a98fd4..de84e0220b6ed 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -567,6 +567,8 @@ type CreateWorkspaceWithPolicyDraftParams = { currentUserEmailParam: string; shouldCreateControlPolicy?: boolean; type?: PolicyType; + // TODO: Remove optional (?) once allBetas Onyx.connect is removed (https://github.com/Expensify/App/issues/66417) + betas?: OnyxEntry; }; /** @@ -591,6 +593,7 @@ function createWorkspaceWithPolicyDraftAndNavigateToIt(params: CreateWorkspaceWi shouldCreateControlPolicy, type, isSelfTourViewed, + betas, } = params; const policyIDWithDefault = policyID || generatePolicyID(); @@ -617,6 +620,7 @@ function createWorkspaceWithPolicyDraftAndNavigateToIt(params: CreateWorkspaceWi shouldCreateControlPolicy, type, isSelfTourViewed, + betas, }); Navigation.navigate(routeToNavigate, {forceReplace: !transitionFromOldDot}); }); @@ -637,6 +641,7 @@ function createWorkspaceWithPolicyDraft(params: CreateWorkspaceWithPolicyDraftPa currentUserEmailParam, shouldCreateControlPolicy, isSelfTourViewed, + betas, } = params; createDraftInitialWorkspace(introSelected, policyOwnerEmail, policyName, policyID, makeMeAdmin, currency, file); @@ -655,6 +660,7 @@ function createWorkspaceWithPolicyDraft(params: CreateWorkspaceWithPolicyDraftPa allReportsParam: allReports, shouldCreateControlPolicy, isSelfTourViewed, + betas, }); } @@ -674,6 +680,8 @@ type SavePolicyDraftByNewWorkspaceParams = { allReportsParam: OnyxCollection; shouldCreateControlPolicy?: boolean; type?: PolicyType; + // TODO: Remove optional (?) once allBetas Onyx.connect is removed (https://github.com/Expensify/App/issues/66417) + betas?: OnyxEntry; }; /** @@ -695,6 +703,7 @@ function savePolicyDraftByNewWorkspace({ shouldCreateControlPolicy, type, isSelfTourViewed, + betas, }: SavePolicyDraftByNewWorkspaceParams) { createWorkspace({ policyOwnerEmail, @@ -713,6 +722,7 @@ function savePolicyDraftByNewWorkspace({ shouldCreateControlPolicy, type, isSelfTourViewed, + betas, }); } diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index 034af497c9907..48d450dda4f75 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -3843,6 +3843,7 @@ function getTrackExpenseInformation(params: GetTrackExpenseInformationParams): T currentUserEmailParam, introSelected, activePolicyID, + betas, isSelfTourViewed, }); createdWorkspaceParams = workspaceData.params; @@ -9341,6 +9342,7 @@ function getPayMoneyRequestParams({ introSelected, activePolicyID: activePolicy?.id, companySize: introSelected?.companySize as OnboardingCompanySize, + betas, isSelfTourViewed, }); const {adminsChatReportID, adminsCreatedReportActionID, expenseChatReportID, expenseCreatedReportActionID, customUnitRateID, customUnitID, ownerEmail, policyName} = params; diff --git a/src/libs/actions/Link.ts b/src/libs/actions/Link.ts index b8bd5aad08fcb..8032e26f53836 100644 --- a/src/libs/actions/Link.ts +++ b/src/libs/actions/Link.ts @@ -28,7 +28,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; -import type {IntroSelected, Report} from '@src/types/onyx'; +import type {Beta, IntroSelected, Report} from '@src/types/onyx'; import {doneCheckingPublicRoom, navigateToConciergeChat, openReport} from './Report'; import {canAnonymousUserAccessRoute, isAnonymousUser, signOutAndRedirectToSignIn, waitForUserSignIn} from './Session'; import {setOnboardingErrorMessage} from './Welcome'; @@ -232,7 +232,14 @@ function openLink(href: string, environmentURL: string, isAttachment = false) { openExternalLink(href); } -function openReportFromDeepLink(url: string, reports: OnyxCollection, isAuthenticated: boolean, conciergeReportID: string | undefined, introSelected: OnyxEntry) { +function openReportFromDeepLink( + url: string, + reports: OnyxCollection, + isAuthenticated: boolean, + conciergeReportID: string | undefined, + introSelected: OnyxEntry, + betas: OnyxEntry, +) { const reportID = getReportIDFromLink(url); if (reportID && !isAuthenticated) { @@ -244,7 +251,7 @@ function openReportFromDeepLink(url: string, reports: OnyxCollection, is }); // Call the OpenReport command to check in the server if it's a public room. If so, we'll open it as an anonymous user - openReport({reportID, introSelected, parentReportActionID: '0', isFromDeepLink: true}); + openReport({reportID, introSelected, parentReportActionID: '0', isFromDeepLink: true, betas}); // Show the sign-in page if the app is offline if (networkStatus === CONST.NETWORK.NETWORK_STATUS.OFFLINE) { diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 23a3547335504..79e7125a0d106 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -197,6 +197,8 @@ type BuildPolicyDataOptions = { type?: typeof CONST.POLICY.TYPE.TEAM | typeof CONST.POLICY.TYPE.CORPORATE; // TODO: Make it required once we complete refactoring the buildPolicyData function to use isSelfTourViewed. Refactor issue: https://github.com/Expensify/App/issues/66424 isSelfTourViewed?: boolean; + // TODO: Remove optional (?) once allBetas Onyx.connect is removed (https://github.com/Expensify/App/issues/66417) + betas?: OnyxEntry; }; // TODO: Remove this type once we complete refactoring the buildPolicyData function to use isSelfTourViewed. Refactor issue: https://github.com/Expensify/App/issues/66424 @@ -2393,6 +2395,7 @@ function buildPolicyData(options: BuildPolicyDataOptions): OnyxData; }; type PregeneratedResponseParams = { diff --git a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx index 9429cd1531cca..bc9d4f06abb85 100644 --- a/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx +++ b/src/pages/OnboardingInterestedFeatures/BaseOnboardingInterestedFeatures.tsx @@ -203,6 +203,7 @@ function BaseOnboardingInterestedFeatures({shouldUseNativeStyles}: BaseOnboardin currentUserAccountIDParam: currentUserPersonalDetails.accountID, currentUserEmailParam: currentUserPersonalDetails.email ?? '', shouldAddGuideWelcomeMessage: false, + betas, isSelfTourViewed, }) : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; diff --git a/src/pages/OnboardingWorkspaceConfirmation/BaseOnboardingWorkspaceConfirmation.tsx b/src/pages/OnboardingWorkspaceConfirmation/BaseOnboardingWorkspaceConfirmation.tsx index f07a8e2dc9917..98e400e722340 100644 --- a/src/pages/OnboardingWorkspaceConfirmation/BaseOnboardingWorkspaceConfirmation.tsx +++ b/src/pages/OnboardingWorkspaceConfirmation/BaseOnboardingWorkspaceConfirmation.tsx @@ -34,6 +34,7 @@ function BaseOnboardingWorkspaceConfirmation({shouldUseNativeStyles}: BaseOnboar const styles = useThemeStyles(); const {translate} = useLocalize(); const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED); + const [betas] = useOnyx(ONYXKEYS.BETAS); const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); const [onboardingPolicyID] = useOnyx(ONYXKEYS.ONBOARDING_POLICY_ID); const [onboardingAdminsChatReportID] = useOnyx(ONYXKEYS.ONBOARDING_ADMINS_CHAT_REPORT_ID); @@ -83,6 +84,7 @@ function BaseOnboardingWorkspaceConfirmation({shouldUseNativeStyles}: BaseOnboar currentUserEmailParam: currentUserPersonalDetails.email ?? '', shouldAddGuideWelcomeMessage: false, onboardingPurposeSelected, + betas, isSelfTourViewed, }) : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; @@ -103,6 +105,7 @@ function BaseOnboardingWorkspaceConfirmation({shouldUseNativeStyles}: BaseOnboar currentUserPersonalDetails.accountID, currentUserPersonalDetails.email, introSelected, + betas, isSelfTourViewed, ], ); diff --git a/src/pages/OnboardingWorkspaceOptional/BaseOnboardingWorkspaceOptional.tsx b/src/pages/OnboardingWorkspaceOptional/BaseOnboardingWorkspaceOptional.tsx index 844c29059a534..b4f4cad2b52b9 100644 --- a/src/pages/OnboardingWorkspaceOptional/BaseOnboardingWorkspaceOptional.tsx +++ b/src/pages/OnboardingWorkspaceOptional/BaseOnboardingWorkspaceOptional.tsx @@ -169,6 +169,7 @@ function BaseOnboardingWorkspaceOptional({shouldUseNativeStyles}: BaseOnboarding currentUserEmailParam: currentUserPersonalDetails.email ?? '', shouldAddGuideWelcomeMessage: false, onboardingPurposeSelected, + betas, isSelfTourViewed, }) : {adminsChatReportID: onboardingAdminsChatReportID, policyID: onboardingPolicyID}; @@ -189,6 +190,7 @@ function BaseOnboardingWorkspaceOptional({shouldUseNativeStyles}: BaseOnboarding currentUserPersonalDetails.email, introSelected, activePolicyID, + betas, isSelfTourViewed, completeOnboarding, ]); diff --git a/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx b/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx index f0a88cdac079d..479511be66fba 100644 --- a/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx +++ b/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx @@ -17,6 +17,7 @@ type WorkspaceConfirmationForTravelPageProps = StackScreenProps Date: Fri, 13 Mar 2026 22:50:44 +0530 Subject: [PATCH 2/3] add betas to deps. Signed-off-by: krishna2323 --- src/DeepLinkHandler.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DeepLinkHandler.tsx b/src/DeepLinkHandler.tsx index dcfac3595d627..4d4010bb744be 100644 --- a/src/DeepLinkHandler.tsx +++ b/src/DeepLinkHandler.tsx @@ -72,7 +72,7 @@ function DeepLinkHandler({onInitialUrl}: DeepLinkHandlerProps) { linkingChangeListener.current?.remove(); }; // eslint-disable-next-line react-hooks/exhaustive-deps -- we only want this effect to re-run when conciergeReportID changes - }, [sessionMetadata?.status, conciergeReportID, introSelected]); + }, [sessionMetadata?.status, conciergeReportID, introSelected, betas]); return null; } From 9143e99985a4265e5de6d66c9e43698f1d14ac59 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Mon, 16 Mar 2026 12:50:48 +0530 Subject: [PATCH 3/3] add test. Signed-off-by: krishna2323 --- tests/actions/PolicyTest.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/actions/PolicyTest.ts b/tests/actions/PolicyTest.ts index 1d067d63c8b5e..42b508d18425d 100644 --- a/tests/actions/PolicyTest.ts +++ b/tests/actions/PolicyTest.ts @@ -541,6 +541,37 @@ describe('actions/Policy', () => { expect(policy?.approvalMode).toBe(CONST.POLICY.APPROVAL_MODE.BASIC); }); + it('creates a new workspace when betas are explicitly passed', async () => { + const policyID = Policy.generatePolicyID(); + Policy.createWorkspace({ + policyOwnerEmail: ESH_EMAIL, + makeMeAdmin: true, + policyName: WORKSPACE_NAME, + policyID, + engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, + introSelected: {choice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM}, + currentUserAccountIDParam: ESH_ACCOUNT_ID, + currentUserEmailParam: ESH_EMAIL, + isSelfTourViewed: false, + betas: [CONST.BETAS.SUGGESTED_FOLLOWUPS], + }); + await waitForBatchedUpdates(); + + const policy: OnyxEntry | OnyxCollection = await new Promise((resolve) => { + const connection = Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + callback: (workspace) => { + Onyx.disconnect(connection); + resolve(workspace); + }, + }); + }); + + expect(policy?.id).toBe(policyID); + expect(policy?.name).toBe(WORKSPACE_NAME); + expect(policy?.approvalMode).toBe(CONST.POLICY.APPROVAL_MODE.BASIC); + }); + it('creates a new workspace with OPTIONAL approval mode if the introSelected is TRACK_WORKSPACE', async () => { const policyID = Policy.generatePolicyID(); // When a new workspace is created with introSelected set to TRACK_WORKSPACE