From 9d2f6c28a98d31f12097e57ae05600c6e9a1fc07 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Fri, 14 Aug 2026 12:45:24 +0700 Subject: [PATCH 1/3] migrate TRAVEL_WORKSPACE_CONFIRMATION --- config/eslint/eslint.seatbelt.tsv | 2 +- src/ROUTES.ts | 15 +++++++-------- src/SCREENS.ts | 2 +- .../ModalStackNavigators/index.tsx | 2 +- .../Navigation/linkingConfig/OldRoutes.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 2 +- src/libs/Navigation/types.ts | 5 +---- src/libs/Permissions.ts | 2 +- src/pages/Travel/DynamicTravelUpgrade.tsx | 5 +++-- ...micWorkspaceConfirmationForTravelPage.tsx} | 19 +++++++------------ tests/navigation/getMatchingNewRouteTest.ts | 5 +++++ .../workspaceConfirmationEntryScreensTest.ts | 2 +- 12 files changed, 30 insertions(+), 32 deletions(-) rename src/pages/Travel/{WorkspaceConfirmationForTravelPage.tsx => DynamicWorkspaceConfirmationForTravelPage.tsx} (77%) diff --git a/config/eslint/eslint.seatbelt.tsv b/config/eslint/eslint.seatbelt.tsv index da8748ebe2b7..09d352d6e132 100644 --- a/config/eslint/eslint.seatbelt.tsv +++ b/config/eslint/eslint.seatbelt.tsv @@ -1053,8 +1053,8 @@ "../../src/pages/Travel/DynamicDomainSelectorPage.tsx" "no-restricted-imports" 1 "../../src/pages/Travel/DynamicTravelTerms.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 "../../src/pages/Travel/DynamicTravelUpgrade.tsx" "no-restricted-imports" 1 +"../../src/pages/Travel/DynamicWorkspaceConfirmationForTravelPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 2 "../../src/pages/Travel/TravelUpgrade.tsx" "react-hooks/set-state-in-effect" 1 -"../../src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 2 "../../src/pages/TripChatNameEditPage.tsx" "@typescript-eslint/no-deprecated/deprecatedGetReportName" 1 "../../src/pages/UnreportedExpenseListItem.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 "../../src/pages/ValidateLoginPage/index.web.tsx" "react-hooks/set-state-in-effect" 1 diff --git a/src/ROUTES.ts b/src/ROUTES.ts index f6fa9525aea6..7be3a28066d4 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -175,11 +175,15 @@ const DYNAMIC_ROUTES = { }, WORKSPACE_CONFIRMATION_CURRENCY: { path: 'currency', - entryScreens: [SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.TRAVEL.WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE], + entryScreens: [SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE], }, WORKSPACE_CONFIRMATION_PLAN_TYPE: { path: 'plan-type', - entryScreens: [SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.TRAVEL.WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE], + entryScreens: [SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE], + }, + TRAVEL_WORKSPACE_CONFIRMATION: { + path: 'workspace-confirmation', + entryScreens: [SCREENS.TRAVEL.DYNAMIC_UPGRADE], }, MIGRATED_USER_WELCOME: { path: 'migrated-user-welcome', @@ -355,7 +359,7 @@ const DYNAMIC_ROUTES = { SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.WORKSPACE_CONFIRMATION.OWNER_SELECTOR, SCREENS.WORKSPACE_DUPLICATE.ROOT, - SCREENS.TRAVEL.WORKSPACE_CONFIRMATION, + SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE, SCREENS.REPORT_DETAILS.DYNAMIC_ROOT, ], @@ -3820,11 +3824,6 @@ const ROUTES = { return getUrlWithBackToParam(`r/${reportID}/trip/${transactionID}/${pnr}/${sequenceIndex}`, backTo); }, }, - TRAVEL_WORKSPACE_CONFIRMATION: { - route: 'travel/upgrade/workspace/confirmation', - - getRoute: (backTo?: string) => getUrlWithBackToParam(`travel/upgrade/workspace/confirmation`, backTo), - }, TRAVEL_VERIFY_ACCOUNT: { route: `travel/${VERIFY_ACCOUNT}`, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index e759c4b922ae..6b39ee33e8a7 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -35,7 +35,7 @@ const SCREENS = { TRIP_SUMMARY: 'Travel_TripSummary', TRIP_DETAILS: 'Travel_TripDetails', DYNAMIC_PUBLIC_DOMAIN_ERROR: 'Dynamic_Travel_PublicDomainError', - WORKSPACE_CONFIRMATION: 'Travel_WorkspaceConfirmation', + DYNAMIC_WORKSPACE_CONFIRMATION: 'Dynamic_Travel_WorkspaceConfirmation', TRAVEL_DOT_LINK_WEB_VIEW: 'Travel_DotLinkWebView', VERIFY_ACCOUNT: 'Travel_VerifyAccount', ENABLE: 'Travel_Enable', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index a0a72f581889..b236b4c315a4 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -239,7 +239,7 @@ const TravelModalStackNavigator = createModalStackNavigator require('../../../../pages/Travel/TripDetailsPage').default, [SCREENS.TRAVEL.DYNAMIC_DOMAIN_PERMISSION_INFO]: () => require('../../../../pages/Travel/DynamicDomainPermissionInfoPage').default, [SCREENS.TRAVEL.DYNAMIC_PUBLIC_DOMAIN_ERROR]: () => require('../../../../pages/Travel/DynamicPublicDomainErrorPage').default, - [SCREENS.TRAVEL.WORKSPACE_CONFIRMATION]: () => require('../../../../pages/Travel/WorkspaceConfirmationForTravelPage').default, + [SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION]: () => require('../../../../pages/Travel/DynamicWorkspaceConfirmationForTravelPage').default, [SCREENS.TRAVEL.VERIFY_ACCOUNT]: () => require('../../../../pages/Travel/VerifyAccountPage').default, [SCREENS.TRAVEL.ENABLE]: () => require('../../../../pages/Travel/EnableTravel').default, }); diff --git a/src/libs/Navigation/linkingConfig/OldRoutes.ts b/src/libs/Navigation/linkingConfig/OldRoutes.ts index 968752c401e2..4e5f3ecf3908 100644 --- a/src/libs/Navigation/linkingConfig/OldRoutes.ts +++ b/src/libs/Navigation/linkingConfig/OldRoutes.ts @@ -73,6 +73,7 @@ const oldRoutes: Record = { '/workspaces/$1/accounting/quickbooks-online/advanced/quickbooks-online-autosync/quickbooks-online-accounting-method', '/workspaces/*/connections/quickbooks-online/advanced/autosync': '/workspaces/$1/accounting/quickbooks-online/advanced/quickbooks-online-autosync', '/travel/upgrade': '/travel/travel-upgrade', + '/travel/upgrade/workspace/confirmation': '/travel/travel-upgrade/workspace-confirmation', '/workspaces/*/accounting/quickbooks-desktop/export/company-card-expense-account': '/workspaces/$1/accounting/quickbooks-desktop/export/qbd-company-card-expense-account', '/workspaces/*/accounting/quickbooks-desktop/export/company-card-expense-account-select': '/workspaces/$1/accounting/quickbooks-desktop/export/qbd-company-card-expense-account-select', '/workspaces/*/accounting/quickbooks-desktop/export/company-card-expense-account/account-select': diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index de84f77a078d..b0d30d2fcd27 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1930,7 +1930,7 @@ const config: LinkingOptions['config'] = { }, [SCREENS.TRAVEL.DYNAMIC_DOMAIN_PERMISSION_INFO]: DYNAMIC_ROUTES.TRAVEL_DOMAIN_PERMISSION_INFO.path, [SCREENS.TRAVEL.DYNAMIC_PUBLIC_DOMAIN_ERROR]: DYNAMIC_ROUTES.TRAVEL_PUBLIC_DOMAIN_ERROR.path, - [SCREENS.TRAVEL.WORKSPACE_CONFIRMATION]: ROUTES.TRAVEL_WORKSPACE_CONFIRMATION.route, + [SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION]: DYNAMIC_ROUTES.TRAVEL_WORKSPACE_CONFIRMATION.path, [SCREENS.TRAVEL.VERIFY_ACCOUNT]: ROUTES.TRAVEL_VERIFY_ACCOUNT.route, [SCREENS.TRAVEL.ENABLE]: {path: ROUTES.TRAVEL_ENABLE.route, exact: true}, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 3cef807e1afb..8f4db4facbe3 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2795,10 +2795,7 @@ type TravelNavigatorParamList = { domain: string; policyID?: string; }; - [SCREENS.TRAVEL.WORKSPACE_CONFIRMATION]: { - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; - }; + [SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION]: undefined; [SCREENS.TRAVEL.DYNAMIC_PUBLIC_DOMAIN_ERROR]: { policyID?: string; }; diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 66cc2e2cd991..f664626c1bcf 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -6,7 +6,7 @@ import type {OnyxEntry} from 'react-native-onyx'; // eslint-disable-next-line rulesdir/no-beta-handler function canUseAllBetas(betas: OnyxEntry): boolean { - return !!betas?.includes(CONST.BETAS.ALL); + return true; } /** diff --git a/src/pages/Travel/DynamicTravelUpgrade.tsx b/src/pages/Travel/DynamicTravelUpgrade.tsx index 5837b88eaf90..6887cf8601cf 100644 --- a/src/pages/Travel/DynamicTravelUpgrade.tsx +++ b/src/pages/Travel/DynamicTravelUpgrade.tsx @@ -9,6 +9,7 @@ import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import {getActivePolicies, isPaidGroupPolicy} from '@libs/PolicyUtils'; @@ -17,7 +18,7 @@ import UpgradeIntro from '@pages/workspace/upgrade/UpgradeIntro'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import React from 'react'; @@ -34,7 +35,7 @@ function DynamicTravelUpgrade() { const isUpgraded = groupPaidPolicies.length > 0; const openWorkspaceConfirmation = () => { - Navigation.navigate(ROUTES.TRAVEL_WORKSPACE_CONFIRMATION.getRoute(Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRAVEL_WORKSPACE_CONFIRMATION.path)); }; return ( diff --git a/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx b/src/pages/Travel/DynamicWorkspaceConfirmationForTravelPage.tsx similarity index 77% rename from src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx rename to src/pages/Travel/DynamicWorkspaceConfirmationForTravelPage.tsx index ddf5f8b96581..42a618d9599b 100644 --- a/src/pages/Travel/WorkspaceConfirmationForTravelPage.tsx +++ b/src/pages/Travel/DynamicWorkspaceConfirmationForTravelPage.tsx @@ -4,27 +4,21 @@ import type {WorkspaceConfirmationSubmitFunctionParams} from '@components/Worksp import useActivePolicy from '@hooks/useActivePolicy'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useHasActiveAdminPolicies from '@hooks/useHasActiveAdminPolicies'; import useOnyx from '@hooks/useOnyx'; import {createDraftWorkspace, createWorkspace} from '@libs/actions/Policy/Policy'; -import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; -import type {TravelNavigatorParamList} from '@libs/Navigation/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; -import type SCREENS from '@src/SCREENS'; - -import type {StackScreenProps} from '@react-navigation/stack'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import {hasSeenTourSelector} from '@selectors/Onboarding'; import React from 'react'; -type WorkspaceConfirmationForTravelPageProps = StackScreenProps; - -function WorkspaceConfirmationForTravelPage({route}: WorkspaceConfirmationForTravelPageProps) { +function DynamicWorkspaceConfirmationForTravelPage() { const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED); const [betas] = useOnyx(ONYXKEYS.BETAS); const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector}); @@ -34,9 +28,10 @@ function WorkspaceConfirmationForTravelPage({route}: WorkspaceConfirmationForTra const activePolicy = useActivePolicy(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const hasActiveAdminPolicies = useHasActiveAdminPolicies(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRAVEL_WORKSPACE_CONFIRMATION.path); const goBack = () => { - Navigation.goBack(route.params?.backTo ?? createDynamicRoute(DYNAMIC_ROUTES.TRAVEL_UPGRADE.path, ROUTES.TRAVEL_MY_TRIPS.route)); + Navigation.goBack(backPath); }; const onSubmit = (params: WorkspaceConfirmationSubmitFunctionParams) => { @@ -70,7 +65,7 @@ function WorkspaceConfirmationForTravelPage({route}: WorkspaceConfirmationForTra return ( { expect(getMatchingNewRoute('/travel/upgrade?backTo=/home')).toBe('/travel/travel-upgrade?backTo=/home'); }); + it('redirects old travel workspace confirmation path to dynamic route', () => { + expect(getMatchingNewRoute('/travel/upgrade/workspace/confirmation')).toBe('/travel/travel-upgrade/workspace-confirmation'); + expect(getMatchingNewRoute('/travel/upgrade/workspace/confirmation?backTo=/home')).toBe('/travel/travel-upgrade/workspace-confirmation?backTo=/home'); + }); + it('redirects legacy new task flat routes to the new nested dynamic routes', () => { expect(getMatchingNewRoute('/new/task/details')).toBe('/task-details'); expect(getMatchingNewRoute('/new/task')).toBe('/task-details/task-confirm'); diff --git a/tests/navigation/workspaceConfirmationEntryScreensTest.ts b/tests/navigation/workspaceConfirmationEntryScreensTest.ts index 1ea15d53321c..526d389139fb 100644 --- a/tests/navigation/workspaceConfirmationEntryScreensTest.ts +++ b/tests/navigation/workspaceConfirmationEntryScreensTest.ts @@ -12,7 +12,7 @@ describe('WORKSPACE_CONFIRMATION_CURRENCY', () => { it('allows opening the currency selector from every screen that hosts the confirm workspace form', () => { expect(currencyEntryScreens).toEqual( - expect.arrayContaining([SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.TRAVEL.WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE]), + expect.arrayContaining([SCREENS.WORKSPACE_CONFIRMATION.DYNAMIC_ROOT, SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION, SCREENS.MONEY_REQUEST.STEP_UPGRADE]), ); }); From 314dacf7025c704d5e1985764fc3d340723f55b7 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Fri, 14 Aug 2026 13:03:26 +0700 Subject: [PATCH 2/3] migrate TRAVEL_VERIFY_ACCOUNT --- src/ROUTES.ts | 11 ++++++----- src/SCREENS.ts | 2 +- src/components/BookTravelButton.tsx | 4 ++-- .../AppNavigator/ModalStackNavigators/index.tsx | 4 ++-- src/libs/Navigation/linkingConfig/OldRoutes.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 2 +- src/libs/Navigation/types.ts | 5 +---- ...untPage.tsx => DynamicVerifyAccountPage.tsx} | 17 ++++++++++------- src/pages/Travel/EnableTravel/index.tsx | 5 +++-- tests/navigation/getMatchingNewRouteTest.ts | 5 +++++ tests/unit/components/BookTravelButtonTest.tsx | 5 +++-- 11 files changed, 35 insertions(+), 26 deletions(-) rename src/pages/Travel/{VerifyAccountPage.tsx => DynamicVerifyAccountPage.tsx} (75%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 7be3a28066d4..f200b5d48801 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1172,6 +1172,12 @@ const DYNAMIC_ROUTES = { path: 'travel-upgrade', entryScreens: [SCREENS.TRAVEL.MY_TRIPS, SCREENS.WORKSPACE.TRAVEL, SCREENS.SEARCH.ROOT], }, + TRAVEL_VERIFY_ACCOUNT: { + path: 'travel-verify-account', + entryScreens: [SCREENS.TRAVEL.MY_TRIPS, SCREENS.WORKSPACE.TRAVEL, SCREENS.SEARCH.ROOT, SCREENS.TRAVEL.ENABLE], + getRoute: (policyID?: string) => getUrlWithParams('travel-verify-account', {policyID}), + queryParams: ['policyID'], + }, REPORT_CHANGE_APPROVER: { path: 'change-approver', entryScreens: [SCREENS.REPORT, SCREENS.RIGHT_MODAL.SEARCH_REPORT, SCREENS.RIGHT_MODAL.EXPENSE_REPORT, SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT], @@ -3824,11 +3830,6 @@ const ROUTES = { return getUrlWithBackToParam(`r/${reportID}/trip/${transactionID}/${pnr}/${sequenceIndex}`, backTo); }, }, - TRAVEL_VERIFY_ACCOUNT: { - route: `travel/${VERIFY_ACCOUNT}`, - - getRoute: (domain?: string, policyID?: string, backTo?: string) => getUrlWithBackToParam(getUrlWithParams(`travel/${VERIFY_ACCOUNT}`, {domain, policyID}), backTo), - }, TRAVEL_ENABLE: { route: 'travel/enable/:policyID/:subPage?/:action?', getRoute: (policyID: string, subPage?: string, action?: 'edit') => { diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 6b39ee33e8a7..83aede6716e1 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -37,7 +37,7 @@ const SCREENS = { DYNAMIC_PUBLIC_DOMAIN_ERROR: 'Dynamic_Travel_PublicDomainError', DYNAMIC_WORKSPACE_CONFIRMATION: 'Dynamic_Travel_WorkspaceConfirmation', TRAVEL_DOT_LINK_WEB_VIEW: 'Travel_DotLinkWebView', - VERIFY_ACCOUNT: 'Travel_VerifyAccount', + DYNAMIC_VERIFY_ACCOUNT: 'Dynamic_Travel_VerifyAccount', ENABLE: 'Travel_Enable', MISSING_PERSONAL_DETAILS_CONFIRM_VALIDATE_CODE: 'Travel_MissingPersonalDetails_ConfirmValidateCode', }, diff --git a/src/components/BookTravelButton.tsx b/src/components/BookTravelButton.tsx index 75f6e01ded7b..7248ca86253f 100644 --- a/src/components/BookTravelButton.tsx +++ b/src/components/BookTravelButton.tsx @@ -167,7 +167,7 @@ function BookTravelButton({ // Legacy request-access path for not-yet-provisioned workspaces when the self-serve provisioning beta is off. if (!isPolicyProvisioned && !isBetaEnabled(CONST.BETAS.IS_TRAVEL_VERIFIED)) { if (!isUserValidated) { - Navigation.navigate(ROUTES.TRAVEL_VERIFY_ACCOUNT.getRoute(undefined, activePolicyID, Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRAVEL_VERIFY_ACCOUNT.getRoute(activePolicyID))); return; } if (shouldShowVerifyAccountModal) { @@ -198,7 +198,7 @@ function BookTravelButton({ // replaced with the verify URL a render later. if (!isUserValidated) { setTravelProvisioningNextStep(enableTravelRoute); - Navigation.navigate(ROUTES.TRAVEL_VERIFY_ACCOUNT.getRoute(undefined, activePolicyID, Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRAVEL_VERIFY_ACCOUNT.getRoute(activePolicyID))); return; } Navigation.navigate(enableTravelRoute); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index b236b4c315a4..f8ba589f887c 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -95,7 +95,7 @@ const OPTIONS_PER_SCREEN: Partial [SCREENS.SEARCH.TRANSACTIONS_CHANGE_REPORT_SEARCH_RHP]: { animation: Animations.NONE, }, - [SCREENS.TRAVEL.VERIFY_ACCOUNT]: { + [SCREENS.TRAVEL.DYNAMIC_VERIFY_ACCOUNT]: { animationTypeForReplace: 'push', }, [SCREENS.MULTIFACTOR_AUTHENTICATION.REVOKE]: { @@ -240,7 +240,7 @@ const TravelModalStackNavigator = createModalStackNavigator require('../../../../pages/Travel/DynamicDomainPermissionInfoPage').default, [SCREENS.TRAVEL.DYNAMIC_PUBLIC_DOMAIN_ERROR]: () => require('../../../../pages/Travel/DynamicPublicDomainErrorPage').default, [SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION]: () => require('../../../../pages/Travel/DynamicWorkspaceConfirmationForTravelPage').default, - [SCREENS.TRAVEL.VERIFY_ACCOUNT]: () => require('../../../../pages/Travel/VerifyAccountPage').default, + [SCREENS.TRAVEL.DYNAMIC_VERIFY_ACCOUNT]: () => require('../../../../pages/Travel/DynamicVerifyAccountPage').default, [SCREENS.TRAVEL.ENABLE]: () => require('../../../../pages/Travel/EnableTravel').default, }); diff --git a/src/libs/Navigation/linkingConfig/OldRoutes.ts b/src/libs/Navigation/linkingConfig/OldRoutes.ts index 4e5f3ecf3908..606d493bb04a 100644 --- a/src/libs/Navigation/linkingConfig/OldRoutes.ts +++ b/src/libs/Navigation/linkingConfig/OldRoutes.ts @@ -74,6 +74,7 @@ const oldRoutes: Record = { '/workspaces/*/connections/quickbooks-online/advanced/autosync': '/workspaces/$1/accounting/quickbooks-online/advanced/quickbooks-online-autosync', '/travel/upgrade': '/travel/travel-upgrade', '/travel/upgrade/workspace/confirmation': '/travel/travel-upgrade/workspace-confirmation', + '/travel/verify-account': '/travel/travel-verify-account', '/workspaces/*/accounting/quickbooks-desktop/export/company-card-expense-account': '/workspaces/$1/accounting/quickbooks-desktop/export/qbd-company-card-expense-account', '/workspaces/*/accounting/quickbooks-desktop/export/company-card-expense-account-select': '/workspaces/$1/accounting/quickbooks-desktop/export/qbd-company-card-expense-account-select', '/workspaces/*/accounting/quickbooks-desktop/export/company-card-expense-account/account-select': diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index b0d30d2fcd27..b24cba22c03e 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1931,7 +1931,7 @@ const config: LinkingOptions['config'] = { [SCREENS.TRAVEL.DYNAMIC_DOMAIN_PERMISSION_INFO]: DYNAMIC_ROUTES.TRAVEL_DOMAIN_PERMISSION_INFO.path, [SCREENS.TRAVEL.DYNAMIC_PUBLIC_DOMAIN_ERROR]: DYNAMIC_ROUTES.TRAVEL_PUBLIC_DOMAIN_ERROR.path, [SCREENS.TRAVEL.DYNAMIC_WORKSPACE_CONFIRMATION]: DYNAMIC_ROUTES.TRAVEL_WORKSPACE_CONFIRMATION.path, - [SCREENS.TRAVEL.VERIFY_ACCOUNT]: ROUTES.TRAVEL_VERIFY_ACCOUNT.route, + [SCREENS.TRAVEL.DYNAMIC_VERIFY_ACCOUNT]: DYNAMIC_ROUTES.TRAVEL_VERIFY_ACCOUNT.path, [SCREENS.TRAVEL.ENABLE]: {path: ROUTES.TRAVEL_ENABLE.route, exact: true}, }, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 8f4db4facbe3..465fbcffe6d9 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2800,11 +2800,8 @@ type TravelNavigatorParamList = { policyID?: string; }; [SCREENS.TRAVEL.DYNAMIC_UPGRADE]: undefined; - [SCREENS.TRAVEL.VERIFY_ACCOUNT]: { - domain?: string; + [SCREENS.TRAVEL.DYNAMIC_VERIFY_ACCOUNT]: { policyID?: string; - // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md - backTo?: Routes; }; [SCREENS.TRAVEL.ENABLE]: {policyID: string; subPage?: string; action?: 'edit'}; }; diff --git a/src/pages/Travel/VerifyAccountPage.tsx b/src/pages/Travel/DynamicVerifyAccountPage.tsx similarity index 75% rename from src/pages/Travel/VerifyAccountPage.tsx rename to src/pages/Travel/DynamicVerifyAccountPage.tsx index 8a0bdac326f9..a1e5a2615ecf 100644 --- a/src/pages/Travel/VerifyAccountPage.tsx +++ b/src/pages/Travel/DynamicVerifyAccountPage.tsx @@ -1,3 +1,4 @@ +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useOnyx from '@hooks/useOnyx'; import usePermissions from '@hooks/usePermissions'; @@ -10,16 +11,18 @@ import VerifyAccountPageBase from '@pages/settings/VerifyAccountPageBase'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect} from 'react'; -type VerifyAccountPageProps = StackScreenProps; +type DynamicVerifyAccountPageProps = StackScreenProps; -function VerifyAccountPage({route}: VerifyAccountPageProps) { - const {backTo, policyID} = route.params; +function DynamicVerifyAccountPage({route}: DynamicVerifyAccountPageProps) { + const {policyID} = route.params ?? {}; + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRAVEL_VERIFY_ACCOUNT.path); const [travelProvisioning] = useOnyx(ONYXKEYS.TRAVEL_PROVISIONING); const {isBetaEnabled} = usePermissions(); @@ -40,12 +43,12 @@ function VerifyAccountPage({route}: VerifyAccountPageProps) { }, []); const handleClose = useCallback(() => { - Navigation.goBack(backTo); - }, [backTo]); + Navigation.goBack(backPath); + }, [backPath]); return ( { expect(getMatchingNewRoute('/travel/upgrade/workspace/confirmation?backTo=/home')).toBe('/travel/travel-upgrade/workspace-confirmation?backTo=/home'); }); + it('redirects old travel verify account path to dynamic route', () => { + expect(getMatchingNewRoute('/travel/verify-account')).toBe('/travel/travel-verify-account'); + expect(getMatchingNewRoute('/travel/verify-account?policyID=123')).toBe('/travel/travel-verify-account?policyID=123'); + }); + it('redirects legacy new task flat routes to the new nested dynamic routes', () => { expect(getMatchingNewRoute('/new/task/details')).toBe('/task-details'); expect(getMatchingNewRoute('/new/task')).toBe('/task-details/task-confirm'); diff --git a/tests/unit/components/BookTravelButtonTest.tsx b/tests/unit/components/BookTravelButtonTest.tsx index 25f4ed2efcd5..b653656ee336 100644 --- a/tests/unit/components/BookTravelButtonTest.tsx +++ b/tests/unit/components/BookTravelButtonTest.tsx @@ -6,11 +6,12 @@ import {LocaleContextProvider} from '@components/LocaleContextProvider'; import OnyxListItemProvider from '@components/OnyxListItemProvider'; import {cleanupTravelProvisioningSession, setTravelProvisioningNextStep} from '@libs/actions/Travel'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {Policy} from '@src/types/onyx'; import React from 'react'; @@ -135,7 +136,7 @@ describe('BookTravelButton', () => { // forward-navigate back to once validated (this avoids a URL blink from double-navigating through the // stepper, which would otherwise immediately redirect to this same verify-account page anyway) expect(setTravelProvisioningNextStep).toHaveBeenCalledWith(ENABLE_TRAVEL_ROUTE); - expect(Navigation.navigate).toHaveBeenCalledWith(ROUTES.TRAVEL_VERIFY_ACCOUNT.getRoute(undefined, POLICY_ID, '')); + expect(Navigation.navigate).toHaveBeenCalledWith(createDynamicRoute(DYNAMIC_ROUTES.TRAVEL_VERIFY_ACCOUNT.getRoute(POLICY_ID))); expect(Navigation.navigate).not.toHaveBeenCalledWith(ENABLE_TRAVEL_ROUTE); }); }); From 3b59ff97bd37144ee4935dae9b95635d79f18282 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Fri, 14 Aug 2026 13:04:59 +0700 Subject: [PATCH 3/3] remove code debug --- src/libs/Permissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index f664626c1bcf..66cc2e2cd991 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -6,7 +6,7 @@ import type {OnyxEntry} from 'react-native-onyx'; // eslint-disable-next-line rulesdir/no-beta-handler function canUseAllBetas(betas: OnyxEntry): boolean { - return true; + return !!betas?.includes(CONST.BETAS.ALL); } /**