From 742ab5fe197be59ad52c5123ca59e7e44314bc21 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:42:49 +0700 Subject: [PATCH 1/6] migrate WORKSPACE_OVERVIEW_PLAN --- src/ROUTES.ts | 10 ++++------ src/SCREENS.ts | 2 +- .../AppNavigator/ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +--- ...ge.tsx => DynamicWorkspaceOverviewPlanTypePage.tsx} | 4 ++-- src/pages/workspace/WorkspaceOverviewPage.tsx | 5 +++-- 6 files changed, 12 insertions(+), 15 deletions(-) rename src/pages/workspace/{WorkspaceOverviewPlanTypePage.tsx => DynamicWorkspaceOverviewPlanTypePage.tsx} (98%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 23188706a6e2..f0c6e3c7842d 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -112,6 +112,10 @@ const DYNAMIC_ROUTES = { getRoute: (country = '') => `country?country=${country}`, queryParams: ['country'], }, + WORKSPACE_OVERVIEW_PLAN: { + path: 'plan', + entryScreens: [SCREENS.WORKSPACE.PROFILE], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -1599,12 +1603,6 @@ const ROUTES = { return getUrlWithBackToParam(`workspaces/${policyID}/overview/address` as const, backTo); }, }, - WORKSPACE_OVERVIEW_PLAN: { - route: 'workspaces/:policyID/overview/plan', - - // eslint-disable-next-line no-restricted-syntax -- Legacy route generation - getRoute: (policyID: string, backTo?: string) => getUrlWithBackToParam(`workspaces/${policyID}/overview/plan` as const, backTo), - }, WORKSPACE_ACCOUNTING: { route: 'workspaces/:policyID/accounting', getRoute: (policyID: string) => `workspaces/${policyID}/accounting` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 6c2599a91dc5..63c7bce128db 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -716,7 +716,7 @@ const SCREENS = { TAG_GL_CODE: 'Tag_GL_Code', CURRENCY: 'Workspace_Overview_Currency', ADDRESS: 'Workspace_Overview_Address', - PLAN: 'Workspace_Overview_Plan_Type', + DYNAMIC_WORKSPACE_OVERVIEW_PLAN: 'Dynamic_Workspace_Overview_Plan_Type', WORKFLOWS: 'Workspace_Workflows', WORKFLOWS_PAYER: 'Workspace_Workflows_Payer', WORKFLOWS_APPROVALS_NEW: 'Workspace_Approvals_New', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 30d5ba47887e..c6e258110063 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -511,7 +511,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/categories/CategorySettingsPage').default, [SCREENS.WORKSPACE.CATEGORY_REQUIRED_FIELDS]: () => require('../../../../pages/workspace/categories/CategoryRequiredFieldsPage').default, [SCREENS.WORKSPACE.ADDRESS]: () => require('../../../../pages/workspace/WorkspaceOverviewAddressPage').default, - [SCREENS.WORKSPACE.PLAN]: () => require('../../../../pages/workspace/WorkspaceOverviewPlanTypePage').default, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_OVERVIEW_PLAN]: () => require('../../../../pages/workspace/DynamicWorkspaceOverviewPlanTypePage').default, [SCREENS.WORKSPACE.CATEGORIES_SETTINGS]: () => require('../../../../pages/workspace/categories/WorkspaceCategoriesSettingsPage').default, [SCREENS.WORKSPACE.CATEGORIES_IMPORT]: () => require('../../../../pages/workspace/categories/ImportCategoriesPage').default, [SCREENS.WORKSPACE.CATEGORIES_IMPORTED]: () => require('../../../../pages/workspace/categories/ImportedCategoriesPage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index b533a716fbef..5b930dd5cc4b 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -523,9 +523,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ADDRESS]: { path: ROUTES.WORKSPACE_OVERVIEW_ADDRESS.route, }, - [SCREENS.WORKSPACE.PLAN]: { - path: ROUTES.WORKSPACE_OVERVIEW_PLAN.route, - }, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_OVERVIEW_PLAN]: DYNAMIC_ROUTES.WORKSPACE_OVERVIEW_PLAN.path, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_IMPORT]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CHART_OF_ACCOUNTS]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CHART_OF_ACCOUNTS.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CLASSES]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES.route}, diff --git a/src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx b/src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx similarity index 98% rename from src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx rename to src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx index 4fef9a6419de..8ad8ac82a280 100644 --- a/src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx +++ b/src/pages/workspace/DynamicWorkspaceOverviewPlanTypePage.tsx @@ -34,7 +34,7 @@ type WorkspacePlanTypeItem = { keyForList: ValueOf; isSelected: boolean; }; -function WorkspaceOverviewPlanTypePage({policy}: WithPolicyProps) { +function DynamicWorkspaceOverviewPlanTypePage({policy}: WithPolicyProps) { const [currentPlan, setCurrentPlan] = useState(policy?.type); const policyID = policy?.id; const {translate} = useLocalize(); @@ -164,4 +164,4 @@ function WorkspaceOverviewPlanTypePage({policy}: WithPolicyProps) { ); } -export default withPolicy(WorkspaceOverviewPlanTypePage); +export default withPolicy(DynamicWorkspaceOverviewPlanTypePage); diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index 166e563d5171..77666ebf076d 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -47,6 +47,7 @@ import { } from '@libs/actions/Policy/Policy'; import {filterInactiveCards, getCardSettings} from '@libs/CardUtils'; import {getLatestErrorField, getLatestErrorMessage} from '@libs/ErrorUtils'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types'; @@ -67,7 +68,7 @@ import StringUtils from '@libs/StringUtils'; import {isSubscriptionTypeOfInvoicing, shouldCalculateBillNewDot} from '@libs/SubscriptionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {ownerPoliciesSelector} from '@src/selectors/Policy'; import {reimbursementAccountErrorSelector} from '@src/selectors/ReimbursementAccount'; @@ -163,7 +164,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa if (!policyID) { return; } - Navigation.navigate(ROUTES.WORKSPACE_OVERVIEW_PLAN.getRoute(policyID)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.WORKSPACE_OVERVIEW_PLAN.path)); }; const policyName = policy?.name ?? ''; const policyDescription = policy?.description ?? translate('workspace.common.defaultDescription'); From aeb01eb162e81b5d36ed257bf2084f56635822b3 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Mon, 16 Mar 2026 14:59:42 +0700 Subject: [PATCH 2/6] migrate WORKSPACE_INVITE --- src/ROUTES.ts | 10 ++++------ src/SCREENS.ts | 2 +- .../AppNavigator/ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +--- src/libs/Navigation/types.ts | 4 +--- ...InvitePage.tsx => DynamicWorkspaceInvitePage.tsx} | 12 +++++++----- src/pages/workspace/WorkspaceMembersPage.tsx | 5 +++-- src/pages/workspace/WorkspaceOverviewPage.tsx | 2 +- src/pages/workspace/withPolicy.tsx | 2 +- 9 files changed, 20 insertions(+), 23 deletions(-) rename src/pages/workspace/{WorkspaceInvitePage.tsx => DynamicWorkspaceInvitePage.tsx} (96%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index f0c6e3c7842d..3b10d6e7e2b7 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -116,6 +116,10 @@ const DYNAMIC_ROUTES = { path: 'plan', entryScreens: [SCREENS.WORKSPACE.PROFILE], }, + WORKSPACE_INVITE: { + path: 'invite', + entryScreens: [SCREENS.WORKSPACE.PROFILE, SCREENS.WORKSPACE.MEMBERS], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -1563,12 +1567,6 @@ const ROUTES = { return `${getUrlWithBackToParam(`workspaces/${policyID}`, backTo)}` as const; }, }, - WORKSPACE_INVITE: { - route: 'workspaces/:policyID/invite', - - // eslint-disable-next-line no-restricted-syntax -- Legacy route generation - getRoute: (policyID: string, backTo?: string) => `${getUrlWithBackToParam(`workspaces/${policyID}/invite`, backTo)}` as const, - }, WORKSPACE_INVITE_MESSAGE: { route: 'workspaces/:policyID/invite-message', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 63c7bce128db..e5b4c4f44177 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -678,7 +678,7 @@ const SCREENS = { MEMBERS_IMPORT: 'Members_Import', MEMBERS_IMPORTED: 'Members_Imported', MEMBERS_IMPORTED_CONFIRMATION: 'Members_Imported_Confirmation', - INVITE: 'Workspace_Invite', + DYNAMIC_WORKSPACE_INVITE: 'Dynamic_Workspace_Invite', INVITE_MESSAGE: 'Workspace_Invite_Message', INVITE_MESSAGE_ROLE: 'Workspace_Invite_Message_Role', CATEGORIES: 'Workspace_Categories', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index c6e258110063..09863b745c88 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -485,7 +485,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/settings/Subscription/RequestEarlyCancellationPage').default, [SCREENS.SETTINGS.SUBSCRIPTION.SUBSCRIPTION_DOWNGRADE_BLOCKED]: () => require('../../../../pages/settings/Subscription/SubscriptionPlan/SubscriptionPlanDowngradeBlockedPage').default, - [SCREENS.WORKSPACE.INVITE]: () => require('../../../../pages/workspace/WorkspaceInvitePage').default, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE]: () => require('../../../../pages/workspace/DynamicWorkspaceInvitePage').default, [SCREENS.WORKSPACE.MEMBERS_IMPORT]: () => require('../../../../pages/workspace/members/ImportMembersPage').default, [SCREENS.WORKSPACE.MEMBERS_IMPORTED]: () => require('../../../../pages/workspace/members/ImportedMembersPage').default, [SCREENS.WORKSPACE.MEMBERS_IMPORTED_CONFIRMATION]: () => require('../../../../pages/workspace/members/ImportedMembersConfirmationPage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 5b930dd5cc4b..0d8b57d395c1 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -892,9 +892,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.COMPANY_CARDS_ASSIGN_CARD_INVITE_NEW_MEMBER]: { path: ROUTES.WORKSPACE_COMPANY_CARDS_ASSIGN_CARD_INVITE_NEW_MEMBER.route, }, - [SCREENS.WORKSPACE.INVITE]: { - path: ROUTES.WORKSPACE_INVITE.route, - }, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE]: DYNAMIC_ROUTES.WORKSPACE_INVITE.path, [SCREENS.WORKSPACE.MEMBERS_IMPORT]: { path: ROUTES.WORKSPACE_MEMBERS_IMPORT.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 072269fe167f..70683492f725 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -290,10 +290,8 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.DESCRIPTION]: undefined; [SCREENS.WORKSPACE.CLIENT_ID]: undefined; [SCREENS.WORKSPACE.SHARE]: undefined; - [SCREENS.WORKSPACE.INVITE]: { + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE]: { 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.WORKSPACE.MEMBERS_IMPORT]: { policyID: string; diff --git a/src/pages/workspace/WorkspaceInvitePage.tsx b/src/pages/workspace/DynamicWorkspaceInvitePage.tsx similarity index 96% rename from src/pages/workspace/WorkspaceInvitePage.tsx rename to src/pages/workspace/DynamicWorkspaceInvitePage.tsx index d018d0609cfc..0e53802c1a4b 100644 --- a/src/pages/workspace/WorkspaceInvitePage.tsx +++ b/src/pages/workspace/DynamicWorkspaceInvitePage.tsx @@ -7,6 +7,7 @@ import SelectionListWithSections from '@components/SelectionList/SelectionListWi import type {Section} from '@components/SelectionList/SelectionListWithSections/types'; import withNavigationTransitionEnd from '@components/withNavigationTransitionEnd'; import type {WithNavigationTransitionEndProps} from '@components/withNavigationTransitionEnd'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -28,7 +29,7 @@ import type {OptionData} from '@libs/ReportUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {InvitedEmailsToAccountIDs} from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; @@ -39,11 +40,12 @@ import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscree type WorkspaceInvitePageProps = WithPolicyAndFullscreenLoadingProps & WithNavigationTransitionEndProps & - PlatformStackScreenProps; + PlatformStackScreenProps; -function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) { +function DynamicWorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const dynamicBackPath = useDynamicBackPath(DYNAMIC_ROUTES.WORKSPACE_INVITE.path); const [didScreenTransitionEnd, setDidScreenTransitionEnd] = useState(false); const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false}); const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE); @@ -266,7 +268,7 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) { subtitle={policyName} onBackButtonPress={() => { clearErrors(route.params.policyID); - Navigation.goBack(route.params.backTo); + Navigation.goBack(dynamicBackPath); }} /> Date: Mon, 16 Mar 2026 15:13:56 +0700 Subject: [PATCH 3/6] migrate WORKSPACE_INVITE_MESSAGE --- src/ROUTES.ts | 10 ++++------ src/SCREENS.ts | 2 +- .../AppNavigator/ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +--- src/libs/Navigation/types.ts | 4 +--- ...e.tsx => DynamicWorkspaceInviteMessagePage.tsx} | 14 +++++++++----- src/pages/workspace/DynamicWorkspaceInvitePage.tsx | 5 +++-- src/pages/workspace/withPolicy.tsx | 2 +- 8 files changed, 21 insertions(+), 22 deletions(-) rename src/pages/workspace/{WorkspaceInviteMessagePage.tsx => DynamicWorkspaceInviteMessagePage.tsx} (66%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 3b10d6e7e2b7..8cb197864898 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -120,6 +120,10 @@ const DYNAMIC_ROUTES = { path: 'invite', entryScreens: [SCREENS.WORKSPACE.PROFILE, SCREENS.WORKSPACE.MEMBERS], }, + WORKSPACE_INVITE_MESSAGE: { + path: 'invite-message', + entryScreens: [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -1567,12 +1571,6 @@ const ROUTES = { return `${getUrlWithBackToParam(`workspaces/${policyID}`, backTo)}` as const; }, }, - WORKSPACE_INVITE_MESSAGE: { - route: 'workspaces/:policyID/invite-message', - - // eslint-disable-next-line no-restricted-syntax -- Legacy route generation - getRoute: (policyID: string, backTo?: string) => `${getUrlWithBackToParam(`workspaces/${policyID}/invite-message`, backTo)}` as const, - }, WORKSPACE_INVITE_MESSAGE_ROLE: { route: 'workspaces/:policyID/invite-message/role', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index e5b4c4f44177..0de8a12bc155 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -679,7 +679,7 @@ const SCREENS = { MEMBERS_IMPORTED: 'Members_Imported', MEMBERS_IMPORTED_CONFIRMATION: 'Members_Imported_Confirmation', DYNAMIC_WORKSPACE_INVITE: 'Dynamic_Workspace_Invite', - INVITE_MESSAGE: 'Workspace_Invite_Message', + DYNAMIC_WORKSPACE_INVITE_MESSAGE: 'Dynamic_Workspace_Invite_Message', INVITE_MESSAGE_ROLE: 'Workspace_Invite_Message_Role', CATEGORIES: 'Workspace_Categories', TAGS: 'Workspace_Tags', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 09863b745c88..6071dfa3e52c 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -500,7 +500,7 @@ const SettingsModalStackNavigator = createModalStackNavigator('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsApprovalLimitPage').default, [SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_OVER_LIMIT_APPROVER]: () => require('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsOverLimitApproverPage').default, - [SCREENS.WORKSPACE.INVITE_MESSAGE]: () => require('../../../../pages/workspace/WorkspaceInviteMessagePage').default, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE]: () => require('../../../../pages/workspace/DynamicWorkspaceInviteMessagePage').default, [SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE]: () => require('../../../../pages/workspace/WorkspaceInviteMessageRolePage').default, [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: () => require('../../../../pages/workspace/workflows/WorkspaceWorkflowsPayerPage').default, [SCREENS.WORKSPACE.NAME]: () => require('../../../../pages/workspace/WorkspaceNamePage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 0d8b57d395c1..227d5924f2da 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -923,9 +923,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_OVER_LIMIT_APPROVER]: { path: ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_OVER_LIMIT_APPROVER.route, }, - [SCREENS.WORKSPACE.INVITE_MESSAGE]: { - path: ROUTES.WORKSPACE_INVITE_MESSAGE.route, - }, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE]: DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE.path, [SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE]: { path: ROUTES.WORKSPACE_INVITE_MESSAGE_ROLE.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 70683492f725..f749ec47d6f9 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -302,10 +302,8 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.MEMBERS_IMPORTED_CONFIRMATION]: { policyID: string; }; - [SCREENS.WORKSPACE.INVITE_MESSAGE]: { + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE]: { 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.WORKSPACE.INVITE_MESSAGE_ROLE]: { policyID: string; diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/DynamicWorkspaceInviteMessagePage.tsx similarity index 66% rename from src/pages/workspace/WorkspaceInviteMessagePage.tsx rename to src/pages/workspace/DynamicWorkspaceInviteMessagePage.tsx index ad6af75835ae..a779f11182ed 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/DynamicWorkspaceInviteMessagePage.tsx @@ -1,26 +1,30 @@ import React from 'react'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {SettingsNavigatorParamList} from '@navigation/types'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import WorkspaceInviteMessageComponent from './members/WorkspaceInviteMessageComponent'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; -type WorkspaceInviteMessagePageProps = WithPolicyAndFullscreenLoadingProps & +type DynamicWorkspaceInviteMessagePageProps = WithPolicyAndFullscreenLoadingProps & WithCurrentUserPersonalDetailsProps & - PlatformStackScreenProps; + PlatformStackScreenProps; + +function DynamicWorkspaceInviteMessagePage({policy, route, currentUserPersonalDetails}: DynamicWorkspaceInviteMessagePageProps) { + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE.path); -function WorkspaceInviteMessagePage({policy, route, currentUserPersonalDetails}: WorkspaceInviteMessagePageProps) { return ( ); } -export default withPolicyAndFullscreenLoading(withCurrentUserPersonalDetails(WorkspaceInviteMessagePage)); +export default withPolicyAndFullscreenLoading(withCurrentUserPersonalDetails(DynamicWorkspaceInviteMessagePage)); diff --git a/src/pages/workspace/DynamicWorkspaceInvitePage.tsx b/src/pages/workspace/DynamicWorkspaceInvitePage.tsx index 0e53802c1a4b..292ea0b3e4a9 100644 --- a/src/pages/workspace/DynamicWorkspaceInvitePage.tsx +++ b/src/pages/workspace/DynamicWorkspaceInvitePage.tsx @@ -20,6 +20,7 @@ import {READ_COMMANDS} from '@libs/API/types'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import HttpUtils from '@libs/HttpUtils'; import {appendCountryCode} from '@libs/LoginUtils'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import {getHeaderMessage, getParticipantsOption} from '@libs/OptionsListUtils'; @@ -29,7 +30,7 @@ import type {OptionData} from '@libs/ReportUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {InvitedEmailsToAccountIDs} from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; @@ -189,7 +190,7 @@ function DynamicWorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) { invitedEmailsToAccountIDs[login] = Number(accountID); } setWorkspaceInviteMembersDraft(route.params.policyID, invitedEmailsToAccountIDs); - Navigation.navigate(ROUTES.WORKSPACE_INVITE_MESSAGE.getRoute(route.params.policyID, Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE.path)); }, [route.params.policyID, selectedOptions]); const [policyName, shouldShowAlertPrompt] = useMemo( diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index ae5fdfeb8102..f9044286494a 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -21,7 +21,7 @@ type PolicyRouteName = | typeof SCREENS.WORKSPACE.EXPENSIFY_CARD | typeof SCREENS.WORKSPACE.COMPANY_CARDS | typeof SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE - | typeof SCREENS.WORKSPACE.INVITE_MESSAGE + | typeof SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE | typeof SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE | typeof SCREENS.WORKSPACE.WORKFLOWS_PAYER | typeof SCREENS.WORKSPACE.WORKFLOWS From 2dcbcb46219d0cecc7ad1718dbd14fa8713ac0d2 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Mon, 16 Mar 2026 15:23:32 +0700 Subject: [PATCH 4/6] migrate WORKSPACE_INVITE_MESSAGE_ROLE --- src/ROUTES.ts | 10 ++++------ src/SCREENS.ts | 2 +- .../AppNavigator/ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +--- src/libs/Navigation/types.ts | 4 +--- ...x => DynamicWorkspaceInviteMessageRolePage.tsx} | 14 +++++++++----- .../members/WorkspaceInviteMessageComponent.tsx | 5 +++-- src/pages/workspace/withPolicy.tsx | 2 +- 8 files changed, 21 insertions(+), 22 deletions(-) rename src/pages/workspace/{WorkspaceInviteMessageRolePage.tsx => DynamicWorkspaceInviteMessageRolePage.tsx} (76%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 8cb197864898..8f90a965d9e0 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -124,6 +124,10 @@ const DYNAMIC_ROUTES = { path: 'invite-message', entryScreens: [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE], }, + WORKSPACE_INVITE_MESSAGE_ROLE: { + path: 'role', + entryScreens: [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -1571,12 +1575,6 @@ const ROUTES = { return `${getUrlWithBackToParam(`workspaces/${policyID}`, backTo)}` as const; }, }, - WORKSPACE_INVITE_MESSAGE_ROLE: { - route: 'workspaces/:policyID/invite-message/role', - - // eslint-disable-next-line no-restricted-syntax -- Legacy route generation - getRoute: (policyID: string, backTo?: string) => `${getUrlWithBackToParam(`workspaces/${policyID}/invite-message/role`, backTo)}` as const, - }, WORKSPACE_OVERVIEW: { route: 'workspaces/:policyID/overview', getRoute: (policyID: string | undefined, backTo?: string) => { diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 0de8a12bc155..0e155d3bf973 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -680,7 +680,7 @@ const SCREENS = { MEMBERS_IMPORTED_CONFIRMATION: 'Members_Imported_Confirmation', DYNAMIC_WORKSPACE_INVITE: 'Dynamic_Workspace_Invite', DYNAMIC_WORKSPACE_INVITE_MESSAGE: 'Dynamic_Workspace_Invite_Message', - INVITE_MESSAGE_ROLE: 'Workspace_Invite_Message_Role', + DYNAMIC_WORKSPACE_INVITE_MESSAGE_ROLE: 'Dynamic_Workspace_Invite_Message_Role', CATEGORIES: 'Workspace_Categories', TAGS: 'Workspace_Tags', TAGS_SETTINGS: 'Tags_Settings', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 6071dfa3e52c..671a0f05d38c 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -501,7 +501,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsOverLimitApproverPage').default, [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE]: () => require('../../../../pages/workspace/DynamicWorkspaceInviteMessagePage').default, - [SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE]: () => require('../../../../pages/workspace/WorkspaceInviteMessageRolePage').default, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE_ROLE]: () => require('../../../../pages/workspace/DynamicWorkspaceInviteMessageRolePage').default, [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: () => require('../../../../pages/workspace/workflows/WorkspaceWorkflowsPayerPage').default, [SCREENS.WORKSPACE.NAME]: () => require('../../../../pages/workspace/WorkspaceNamePage').default, [SCREENS.WORKSPACE.DESCRIPTION]: () => require('../../../../pages/workspace/WorkspaceOverviewDescriptionPage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 227d5924f2da..0ff54a7c1090 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -924,9 +924,7 @@ const config: LinkingOptions['config'] = { path: ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_OVER_LIMIT_APPROVER.route, }, [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE]: DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE.path, - [SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE]: { - path: ROUTES.WORKSPACE_INVITE_MESSAGE_ROLE.route, - }, + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE_ROLE]: DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE_ROLE.path, [SCREENS.WORKSPACE.RECEIPT_PARTNERS_INVITE]: { path: ROUTES.WORKSPACE_RECEIPT_PARTNERS_INVITE.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index f749ec47d6f9..d38844e18325 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -305,10 +305,8 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE]: { policyID: string; }; - [SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE]: { + [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE_ROLE]: { 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.WORKSPACE.CATEGORY_CREATE]: { policyID: string; diff --git a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx b/src/pages/workspace/DynamicWorkspaceInviteMessageRolePage.tsx similarity index 76% rename from src/pages/workspace/WorkspaceInviteMessageRolePage.tsx rename to src/pages/workspace/DynamicWorkspaceInviteMessageRolePage.tsx index bbcbf165dfb1..f689b5a08907 100644 --- a/src/pages/workspace/WorkspaceInviteMessageRolePage.tsx +++ b/src/pages/workspace/DynamicWorkspaceInviteMessageRolePage.tsx @@ -1,6 +1,7 @@ import React from 'react'; import ScreenWrapper from '@components/ScreenWrapper'; import WorkspaceMemberRoleList from '@components/WorkspaceMemberRoleList'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useOnyx from '@hooks/useOnyx'; import {setWorkspaceInviteRoleDraft} from '@libs/actions/Policy/Member'; import Navigation from '@libs/Navigation/Navigation'; @@ -9,6 +10,7 @@ import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import {goBackFromInvalidPolicy} from '@libs/PolicyUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; @@ -16,11 +18,13 @@ import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; -type WorkspaceInviteMessageRolePageProps = WithPolicyAndFullscreenLoadingProps & PlatformStackScreenProps; +type DynamicWorkspaceInviteMessageRolePageProps = WithPolicyAndFullscreenLoadingProps & + PlatformStackScreenProps; -function WorkspaceInviteMessageRolePage({policy, route}: WorkspaceInviteMessageRolePageProps) { +function DynamicWorkspaceInviteMessageRolePage({policy, route}: DynamicWorkspaceInviteMessageRolePageProps) { const [role = CONST.POLICY.ROLE.USER, roleResult] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_ROLE_DRAFT}${route.params.policyID}`); const isOnyxLoading = isLoadingOnyxValue(roleResult); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE_ROLE.path); return ( { setWorkspaceInviteRoleDraft(route.params.policyID, value); Navigation.setNavigationActionToMicrotaskQueue(() => { - Navigation.goBack(route.params.backTo); + Navigation.goBack(backPath); }); }} - navigateBackTo={route.params.backTo} + navigateBackTo={backPath} /> ); } -export default withPolicyAndFullscreenLoading(WorkspaceInviteMessageRolePage); +export default withPolicyAndFullscreenLoading(DynamicWorkspaceInviteMessageRolePage); diff --git a/src/pages/workspace/members/WorkspaceInviteMessageComponent.tsx b/src/pages/workspace/members/WorkspaceInviteMessageComponent.tsx index 4e95f50ca45d..7f517b20804c 100644 --- a/src/pages/workspace/members/WorkspaceInviteMessageComponent.tsx +++ b/src/pages/workspace/members/WorkspaceInviteMessageComponent.tsx @@ -23,6 +23,7 @@ import {openExternalLink} from '@libs/actions/Link'; import {addMembersToWorkspace, clearWorkspaceInviteRoleDraft} from '@libs/actions/Policy/Member'; import {setWorkspaceInviteMessageDraft} from '@libs/actions/Policy/Policy'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import {getPersonalDetailsForAccountIDs} from '@libs/OptionsListUtils'; import {getDisplayNameOrDefault, getPersonalDetailByEmail} from '@libs/PersonalDetailsUtils'; @@ -32,7 +33,7 @@ import variables from '@styles/variables'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import AccessOrNotFoundWrapper from '@src/pages/workspace/AccessOrNotFoundWrapper'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {Route as Routes} from '@src/ROUTES'; import INPUT_IDS from '@src/types/form/WorkspaceInviteMessageForm'; import type {PersonalDetails} from '@src/types/onyx'; @@ -250,7 +251,7 @@ function WorkspaceInviteMessageComponent({ description={translate('common.role')} shouldShowRightIcon onPress={() => { - Navigation.navigate(ROUTES.WORKSPACE_INVITE_MESSAGE_ROLE.getRoute(policyID, Navigation.getActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.WORKSPACE_INVITE_MESSAGE_ROLE.path)); }} /> diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index f9044286494a..33fc709fdb93 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -22,7 +22,7 @@ type PolicyRouteName = | typeof SCREENS.WORKSPACE.COMPANY_CARDS | typeof SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE | typeof SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE - | typeof SCREENS.WORKSPACE.INVITE_MESSAGE_ROLE + | typeof SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE_ROLE | typeof SCREENS.WORKSPACE.WORKFLOWS_PAYER | typeof SCREENS.WORKSPACE.WORKFLOWS | typeof SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_NEW From de5eb11d42d13593e2c867d5f3e5f9f4064bf2aa Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Mon, 16 Mar 2026 16:36:09 +0700 Subject: [PATCH 5/6] remove code unused --- src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts index 0e292fed8bfe..e5adbf69439a 100755 --- a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts @@ -8,7 +8,6 @@ const WORKSPACE_TO_RHP: Partial Date: Sat, 28 Mar 2026 09:33:02 +0700 Subject: [PATCH 6/6] update entry for member role --- src/ROUTES.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 799dbf6a9d85..9ef9f5349a44 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -134,7 +134,7 @@ const DYNAMIC_ROUTES = { }, WORKSPACE_INVITE_MESSAGE_ROLE: { path: 'role', - entryScreens: [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE], + entryScreens: [SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_INVITE_MESSAGE, SCREENS.WORKSPACE.COMPANY_CARDS_ASSIGN_CARD_INVITE_NEW_MEMBER, SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW], }, } as const satisfies DynamicRoutes;