From 6a2007f158971dbc5357b809cef47e309b7d24df Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:45:56 +0700 Subject: [PATCH 1/8] migrate SETTINGS_CATEGORY_EDIT --- src/ROUTES.ts | 10 +++----- src/SCREENS.ts | 2 +- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +-- src/libs/Navigation/types.ts | 4 +-- .../categories/CategorySettingsPage.tsx | 7 +++--- .../workspace/categories/EditCategoryPage.tsx | 25 +++++++------------ 7 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 28d2b18b6a0f..4de4ad350f9d 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -124,6 +124,10 @@ const DYNAMIC_ROUTES = { getRoute: (country = '') => `country?country=${country}`, queryParams: ['country'], }, + SETTINGS_CATEGORY_EDIT: { + path: 'edit', + entryScreens: [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_SETTINGS], + }, WORKSPACE_OVERVIEW_PLAN: { path: 'plan', entryScreens: [SCREENS.WORKSPACE.PROFILE], @@ -1350,12 +1354,6 @@ const ROUTES = { // eslint-disable-next-line no-restricted-syntax -- Legacy route generation getRoute: (policyID: string, backTo = '') => getUrlWithBackToParam(`settings/${policyID}/categories/new`, backTo), }, - SETTINGS_CATEGORY_EDIT: { - route: 'settings/:policyID/category/:categoryName/edit', - - // eslint-disable-next-line no-restricted-syntax -- Legacy route generation - getRoute: (policyID: string, categoryName: string, backTo = '') => getUrlWithBackToParam(`settings/${policyID}/category/${encodeURIComponent(categoryName)}/edit`, backTo), - }, SETTINGS_CATEGORIES_IMPORT: { route: 'settings/:policyID/categories/import', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 0b34df90b022..2861ec7aa2b9 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -425,7 +425,7 @@ const SCREENS = { SETTINGS_CATEGORY_SETTINGS: 'Settings_Category_Settings', SETTINGS_CATEGORIES_SETTINGS: 'Settings_Categories_Settings', SETTINGS_CATEGORY_CREATE: 'Settings_Category_Create', - SETTINGS_CATEGORY_EDIT: 'Settings_Category_Edit', + DYNAMIC_SETTINGS_CATEGORY_EDIT: 'Dynamic_Settings_Category_Edit', SETTINGS_CATEGORIES_ROOT: 'Settings_Categories', SETTINGS_CATEGORIES_IMPORT: 'Settings_Categories_Import', SETTINGS_CATEGORIES_IMPORTED: 'Settings_Categories_Imported', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index e7a413775309..de303b4cb086 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -306,7 +306,7 @@ const ReportDescriptionModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/categories/WorkspaceCategoriesSettingsPage').default, [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_CREATE]: () => require('../../../../pages/workspace/categories/CreateCategoryPage').default, - [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_EDIT]: () => require('../../../../pages/workspace/categories/EditCategoryPage').default, + [SCREENS.SETTINGS_CATEGORIES.DYNAMIC_SETTINGS_CATEGORY_EDIT]: () => require('../../../../pages/workspace/categories/EditCategoryPage').default, [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_SETTINGS]: () => require('../../../../pages/workspace/categories/CategorySettingsPage').default, [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORIES_IMPORT]: () => require('../../../../pages/workspace/categories/ImportCategoriesPage').default, [SCREENS.SETTINGS_CATEGORIES.SETTINGS_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 78a95d9bb1ac..fd064b7565a3 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1456,9 +1456,7 @@ const config: LinkingOptions['config'] = { [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_CREATE]: { path: ROUTES.SETTINGS_CATEGORY_CREATE.route, }, - [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_EDIT]: { - path: ROUTES.SETTINGS_CATEGORY_EDIT.route, - }, + [SCREENS.SETTINGS_CATEGORIES.DYNAMIC_SETTINGS_CATEGORY_EDIT]: DYNAMIC_ROUTES.SETTINGS_CATEGORY_EDIT.path, [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORIES_IMPORT]: { path: ROUTES.SETTINGS_CATEGORIES_IMPORT.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 8c66f0f224b3..82b3c1caef08 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -341,11 +341,9 @@ type SettingsNavigatorParamList = { // 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.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_EDIT]: { + [SCREENS.SETTINGS_CATEGORIES.DYNAMIC_SETTINGS_CATEGORY_EDIT]: { policyID: string; categoryName: 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_PAYROLL_CODE]: { policyID: string; diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 1fa0df3deac8..041979402f53 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -30,6 +30,7 @@ import { } from '@libs/CategoryUtils'; import {convertToDisplayString} from '@libs/CurrencyUtils'; import {getLatestErrorMessageField} 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 {isDisablingOrDeletingLastEnabledCategory} from '@libs/OptionsListUtils'; @@ -41,7 +42,7 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import {clearCategoryErrors, deleteWorkspaceCategories, setWorkspaceCategoryEnabled} from '@userActions/Policy/Category'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; type CategorySettingsPageProps = @@ -221,9 +222,7 @@ function CategorySettingsPage({ ); const navigateToEditCategory = () => { - Navigation.navigate( - isQuickSettingsFlow ? ROUTES.SETTINGS_CATEGORY_EDIT.getRoute(policyID, policyCategory.name, backTo) : ROUTES.WORKSPACE_CATEGORY_EDIT.getRoute(policyID, policyCategory.name), - ); + Navigation.navigate(isQuickSettingsFlow ? createDynamicRoute(DYNAMIC_ROUTES.SETTINGS_CATEGORY_EDIT.path) : ROUTES.WORKSPACE_CATEGORY_EDIT.getRoute(policyID, policyCategory.name)); }; const deleteCategory = () => { diff --git a/src/pages/workspace/categories/EditCategoryPage.tsx b/src/pages/workspace/categories/EditCategoryPage.tsx index 87ed21e723e1..76e36302e7b1 100644 --- a/src/pages/workspace/categories/EditCategoryPage.tsx +++ b/src/pages/workspace/categories/EditCategoryPage.tsx @@ -2,6 +2,7 @@ import React, {useCallback} from 'react'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import usePolicyData from '@hooks/usePolicyData'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -12,21 +13,22 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import {renamePolicyCategory} from '@userActions/Policy/Category'; import CONST from '@src/CONST'; import type ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import CategoryForm from './CategoryForm'; type EditCategoryPageProps = | PlatformStackScreenProps - | PlatformStackScreenProps; + | PlatformStackScreenProps; function EditCategoryPage({route}: EditCategoryPageProps) { - const {backTo, policyID, categoryName: currentCategoryName} = route.params; + const {policyID, categoryName: currentCategoryName} = route.params; const policyData = usePolicyData(policyID); const {categories: policyCategories} = policyData; const styles = useThemeStyles(); const {translate} = useLocalize(); - const isQuickSettingsFlow = route.name === SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_EDIT; + const isQuickSettingsFlow = route.name === SCREENS.SETTINGS_CATEGORIES.DYNAMIC_SETTINGS_CATEGORY_EDIT; + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.SETTINGS_CATEGORY_EDIT.path); const validate = useCallback( (values: FormOnyxValues) => { @@ -56,15 +58,10 @@ function EditCategoryPage({route}: EditCategoryPageProps) { // Ensure Onyx.update is executed before navigation to prevent UI blinking issues, affecting the category name and rate. Navigation.setNavigationActionToMicrotaskQueue(() => { - Navigation.goBack( - isQuickSettingsFlow - ? ROUTES.SETTINGS_CATEGORY_SETTINGS.getRoute(policyID, currentCategoryName, backTo) - : ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, currentCategoryName), - {compareParams: false}, - ); + Navigation.goBack(isQuickSettingsFlow ? backPath : ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, currentCategoryName), {compareParams: false}); }); }, - [isQuickSettingsFlow, currentCategoryName, policyData, policyID, backTo], + [currentCategoryName, policyData, isQuickSettingsFlow, backPath, policyID], ); return ( @@ -82,11 +79,7 @@ function EditCategoryPage({route}: EditCategoryPageProps) { - Navigation.goBack( - isQuickSettingsFlow - ? ROUTES.SETTINGS_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName, backTo) - : ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName), - ) + Navigation.goBack(isQuickSettingsFlow ? backPath : ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName)) } /> Date: Thu, 2 Apr 2026 15:32:24 +0700 Subject: [PATCH 2/8] migrate WORKSPACE_TAG_CREATE --- src/ROUTES.ts | 8 ++++---- src/SCREENS.ts | 2 +- .../AppNavigator/ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +--- src/libs/Navigation/types.ts | 2 +- src/pages/workspace/tags/WorkspaceCreateTagPage.tsx | 10 ++++++---- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 4de4ad350f9d..ac59d8caad4a 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -171,6 +171,10 @@ const DYNAMIC_ROUTES = { }), queryParams: ['fieldName', 'fieldValue', 'policyID'], }, + WORKSPACE_TAG_CREATE: { + path: 'workspace-tag-create', + entryScreens: [SCREENS.WORKSPACE.TAGS, SCREENS.WORKSPACE.TAG_SETTINGS], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -2297,10 +2301,6 @@ const ROUTES = { return `workspaces/${policyID}/tags` as const; }, }, - WORKSPACE_TAG_CREATE: { - route: 'workspaces/:policyID/tags/new', - getRoute: (policyID: string) => `workspaces/${policyID}/tags/new` as const, - }, WORKSPACE_TAGS_SETTINGS: { route: 'workspaces/:policyID/tags/settings', getRoute: (policyID: string) => `workspaces/${policyID}/tags/settings` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 2861ec7aa2b9..6589b207eada 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -737,7 +737,7 @@ const SCREENS = { TAXES_SETTINGS_WORKSPACE_CURRENCY_DEFAULT: 'Workspace_Taxes_Settings_WorkspaceCurrency', TAXES_SETTINGS_FOREIGN_CURRENCY_DEFAULT: 'Workspace_Taxes_Settings_ForeignCurrency', TAX_CREATE: 'Workspace_Tax_Create', - TAG_CREATE: 'Tag_Create', + DYNAMIC_TAG_CREATE: 'Dynamic_Tag_Create', TAG_SETTINGS: 'Tag_Settings', TAG_APPROVER: 'Tag_Approver', TAG_LIST_VIEW: 'Tag_List_View', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index de303b4cb086..009725e7f8f1 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -552,7 +552,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/tags/TagSettingsPage').default, [SCREENS.WORKSPACE.TAG_LIST_VIEW]: () => require('../../../../pages/workspace/tags/WorkspaceViewTagsPage').default, [SCREENS.WORKSPACE.TAGS_EDIT]: () => require('../../../../pages/workspace/tags/WorkspaceEditTagsPage').default, - [SCREENS.WORKSPACE.TAG_CREATE]: () => require('../../../../pages/workspace/tags/WorkspaceCreateTagPage').default, + [SCREENS.WORKSPACE.DYNAMIC_TAG_CREATE]: () => require('../../../../pages/workspace/tags/WorkspaceCreateTagPage').default, [SCREENS.WORKSPACE.TAG_EDIT]: () => require('../../../../pages/workspace/tags/EditTagPage').default, [SCREENS.WORKSPACE.TAG_APPROVER]: () => require('../../../../pages/workspace/tags/TagApproverPage').default, [SCREENS.WORKSPACE.TAG_GL_CODE]: () => require('../../../../pages/workspace/tags/TagGLCodePage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index fd064b7565a3..74669569ef82 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1104,9 +1104,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.TAGS_IMPORTED_MULTI_LEVEL]: { path: ROUTES.WORKSPACE_TAGS_IMPORTED_MULTI_LEVEL.route, }, - [SCREENS.WORKSPACE.TAG_CREATE]: { - path: ROUTES.WORKSPACE_TAG_CREATE.route, - }, + [SCREENS.WORKSPACE.DYNAMIC_TAG_CREATE]: DYNAMIC_ROUTES.WORKSPACE_TAG_CREATE.path, [SCREENS.WORKSPACE.TAG_EDIT]: { path: ROUTES.WORKSPACE_TAG_EDIT.route, parse: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 82b3c1caef08..e8a6eee5138b 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -454,7 +454,7 @@ type SettingsNavigatorParamList = { // 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.TAG_CREATE]: { + [SCREENS.WORKSPACE.DYNAMIC_TAG_CREATE]: { 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; diff --git a/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx b/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx index 100b1c42d5c1..cc739c5300e2 100644 --- a/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx +++ b/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx @@ -8,6 +8,7 @@ import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnboardingTaskInformation from '@hooks/useOnboardingTaskInformation'; import usePolicyData from '@hooks/usePolicyData'; @@ -22,12 +23,12 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import {createPolicyTag} from '@userActions/Policy/Tag'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/WorkspaceTagForm'; type WorkspaceCreateTagPageProps = - | PlatformStackScreenProps + | PlatformStackScreenProps | PlatformStackScreenProps; function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { @@ -38,6 +39,7 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { const {translate} = useLocalize(); const {inputCallbackRef} = useAutoFocusInput(); const isQuickSettingsFlow = route.name === SCREENS.SETTINGS_TAGS.SETTINGS_TAG_CREATE; + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.WORKSPACE_TAG_CREATE.path); const policyHasCustomCategories = hasCustomCategories(policyCategories); @@ -96,7 +98,7 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { policyHasCustomCategories, }); Keyboard.dismiss(); - Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : undefined); + Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : backPath); }; return ( @@ -113,7 +115,7 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { > Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : undefined)} + onBackButtonPress={() => Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : backPath)} /> { - Navigation.navigate(isQuickSettingsFlow ? ROUTES.SETTINGS_TAG_CREATE.getRoute(policyID, backTo) : ROUTES.WORKSPACE_TAG_CREATE.getRoute(policyID)); + Navigation.navigate(isQuickSettingsFlow ? ROUTES.SETTINGS_TAG_CREATE.getRoute(policyID, backTo) : createDynamicRoute(DYNAMIC_ROUTES.WORKSPACE_TAG_CREATE.path)); }; const navigateToTagSettings = (tag: TagListItem) => { From b9bcef6a452e44bba440404fc28d3fec853f611f Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:43:19 +0700 Subject: [PATCH 3/8] update lints --- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index a27f1a35a52c..c355b3fa49c6 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -51,6 +51,7 @@ import { } from '@libs/actions/Policy/Tag'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; +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'; @@ -76,7 +77,7 @@ import variables from '@styles/variables'; import {close} from '@userActions/Modal'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import type {PendingAction} from '@src/types/onyx/OnyxCommon'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; From ade816eaef410e34ff1160f29862b95dd33c6d9e Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:50:33 +0700 Subject: [PATCH 4/8] update type error --- src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts | 2 +- 1 file changed, 1 insertion(+), 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 97d78694d881..fca3465b4194 100755 --- a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts @@ -190,7 +190,7 @@ const WORKSPACE_TO_RHP: Partial Date: Mon, 6 Apr 2026 09:42:43 +0700 Subject: [PATCH 5/8] remove migrate WORKSPACE_TAG_CREATE --- src/ROUTES.ts | 10 +++++----- src/SCREENS.ts | 2 +- .../AppNavigator/ModalStackNavigators/index.tsx | 2 +- .../linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts | 2 +- src/libs/Navigation/linkingConfig/config.ts | 4 +++- src/libs/Navigation/types.ts | 4 +--- src/pages/workspace/tags/WorkspaceTagsPage.tsx | 5 ++--- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index abf438a2185a..eff07220376c 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -125,7 +125,7 @@ const DYNAMIC_ROUTES = { queryParams: ['country'], }, SETTINGS_CATEGORY_EDIT: { - path: 'edit', + path: 'category-edit', entryScreens: [SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_SETTINGS], }, WORKSPACE_OVERVIEW_PLAN: { @@ -171,10 +171,6 @@ const DYNAMIC_ROUTES = { }), queryParams: ['fieldName', 'fieldValue', 'policyID'], }, - WORKSPACE_TAG_CREATE: { - path: 'workspace-tag-create', - entryScreens: [SCREENS.WORKSPACE.TAGS, SCREENS.WORKSPACE.TAG_SETTINGS], - }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -2313,6 +2309,10 @@ const ROUTES = { // eslint-disable-next-line no-restricted-syntax -- Legacy route generation getRoute: (policyID: string, orderWeight: number, backTo?: string) => getUrlWithBackToParam(`workspaces/${policyID}/tags/${orderWeight}/edit` as const, backTo), }, + WORKSPACE_TAG_CREATE: { + route: 'workspaces/:policyID/tags/new', + getRoute: (policyID: string) => `workspaces/${policyID}/tags/new` as const, + }, WORKSPACE_TAG_EDIT: { route: 'workspaces/:policyID/tag/:orderWeight/:tagName/edit', getRoute: (policyID: string, orderWeight: number, tagName: string) => `workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}/edit` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 690123535b01..bd7f77eea206 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -741,7 +741,7 @@ const SCREENS = { TAXES_SETTINGS_WORKSPACE_CURRENCY_DEFAULT: 'Workspace_Taxes_Settings_WorkspaceCurrency', TAXES_SETTINGS_FOREIGN_CURRENCY_DEFAULT: 'Workspace_Taxes_Settings_ForeignCurrency', TAX_CREATE: 'Workspace_Tax_Create', - DYNAMIC_TAG_CREATE: 'Dynamic_Tag_Create', + TAG_CREATE: 'Tag_Create', TAG_SETTINGS: 'Tag_Settings', TAG_APPROVER: 'Tag_Approver', TAG_LIST_VIEW: 'Tag_List_View', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 25231f26e1d7..0679a131123b 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -552,7 +552,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/tags/TagSettingsPage').default, [SCREENS.WORKSPACE.TAG_LIST_VIEW]: () => require('../../../../pages/workspace/tags/WorkspaceViewTagsPage').default, [SCREENS.WORKSPACE.TAGS_EDIT]: () => require('../../../../pages/workspace/tags/WorkspaceEditTagsPage').default, - [SCREENS.WORKSPACE.DYNAMIC_TAG_CREATE]: () => require('../../../../pages/workspace/tags/WorkspaceCreateTagPage').default, + [SCREENS.WORKSPACE.TAG_CREATE]: () => require('../../../../pages/workspace/tags/WorkspaceCreateTagPage').default, [SCREENS.WORKSPACE.TAG_EDIT]: () => require('../../../../pages/workspace/tags/EditTagPage').default, [SCREENS.WORKSPACE.TAG_APPROVER]: () => require('../../../../pages/workspace/tags/TagApproverPage').default, [SCREENS.WORKSPACE.TAG_GL_CODE]: () => require('../../../../pages/workspace/tags/TagGLCodePage').default, diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts index fca3465b4194..97d78694d881 100755 --- a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts @@ -190,7 +190,7 @@ const WORKSPACE_TO_RHP: Partial['config'] = { [SCREENS.WORKSPACE.TAGS_IMPORTED_MULTI_LEVEL]: { path: ROUTES.WORKSPACE_TAGS_IMPORTED_MULTI_LEVEL.route, }, - [SCREENS.WORKSPACE.DYNAMIC_TAG_CREATE]: DYNAMIC_ROUTES.WORKSPACE_TAG_CREATE.path, + [SCREENS.WORKSPACE.TAG_CREATE]: { + path: ROUTES.WORKSPACE_TAG_CREATE.route, + }, [SCREENS.WORKSPACE.TAG_EDIT]: { path: ROUTES.WORKSPACE_TAG_EDIT.route, parse: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index b9548fe75ac3..73869c259116 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -454,10 +454,8 @@ type SettingsNavigatorParamList = { // 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.DYNAMIC_TAG_CREATE]: { + [SCREENS.WORKSPACE.TAG_CREATE]: { 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.SETTINGS_TAGS.SETTINGS_TAG_CREATE]: { policyID: string; diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index c355b3fa49c6..774ac47a4c2e 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -51,7 +51,6 @@ import { } from '@libs/actions/Policy/Tag'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; -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'; @@ -77,7 +76,7 @@ import variables from '@styles/variables'; import {close} from '@userActions/Modal'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import type {PendingAction} from '@src/types/onyx/OnyxCommon'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; @@ -475,7 +474,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { }, [isQuickSettingsFlow, policyID, backTo]); const navigateToCreateTagPage = () => { - Navigation.navigate(isQuickSettingsFlow ? ROUTES.SETTINGS_TAG_CREATE.getRoute(policyID, backTo) : createDynamicRoute(DYNAMIC_ROUTES.WORKSPACE_TAG_CREATE.path)); + Navigation.navigate(isQuickSettingsFlow ? ROUTES.SETTINGS_TAG_CREATE.getRoute(policyID, backTo) : ROUTES.WORKSPACE_TAG_CREATE.getRoute(policyID)); }; const navigateToTagSettings = (tag: TagListItem) => { From f4d8ca93cde9616d94b8211779902ce431521194 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Mon, 6 Apr 2026 09:44:29 +0700 Subject: [PATCH 6/8] update position --- src/ROUTES.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index eff07220376c..9e3221c38f97 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -2299,6 +2299,10 @@ const ROUTES = { return `workspaces/${policyID}/tags` as const; }, }, + WORKSPACE_TAG_CREATE: { + route: 'workspaces/:policyID/tags/new', + getRoute: (policyID: string) => `workspaces/${policyID}/tags/new` as const, + }, WORKSPACE_TAGS_SETTINGS: { route: 'workspaces/:policyID/tags/settings', getRoute: (policyID: string) => `workspaces/${policyID}/tags/settings` as const, @@ -2309,10 +2313,6 @@ const ROUTES = { // eslint-disable-next-line no-restricted-syntax -- Legacy route generation getRoute: (policyID: string, orderWeight: number, backTo?: string) => getUrlWithBackToParam(`workspaces/${policyID}/tags/${orderWeight}/edit` as const, backTo), }, - WORKSPACE_TAG_CREATE: { - route: 'workspaces/:policyID/tags/new', - getRoute: (policyID: string) => `workspaces/${policyID}/tags/new` as const, - }, WORKSPACE_TAG_EDIT: { route: 'workspaces/:policyID/tag/:orderWeight/:tagName/edit', getRoute: (policyID: string, orderWeight: number, tagName: string) => `workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}/edit` as const, From e259f0278519433dc8baa53ea7781befb6b0fbbd Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Mon, 6 Apr 2026 09:51:43 +0700 Subject: [PATCH 7/8] update type errors --- src/libs/Navigation/types.ts | 2 ++ src/pages/workspace/tags/WorkspaceCreateTagPage.tsx | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 73869c259116..9ff7746838dd 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -456,6 +456,8 @@ type SettingsNavigatorParamList = { }; [SCREENS.WORKSPACE.TAG_CREATE]: { 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.SETTINGS_TAGS.SETTINGS_TAG_CREATE]: { policyID: string; diff --git a/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx b/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx index cc739c5300e2..100b1c42d5c1 100644 --- a/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx +++ b/src/pages/workspace/tags/WorkspaceCreateTagPage.tsx @@ -8,7 +8,6 @@ import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; -import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnboardingTaskInformation from '@hooks/useOnboardingTaskInformation'; import usePolicyData from '@hooks/usePolicyData'; @@ -23,12 +22,12 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import {createPolicyTag} from '@userActions/Policy/Tag'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/WorkspaceTagForm'; type WorkspaceCreateTagPageProps = - | PlatformStackScreenProps + | PlatformStackScreenProps | PlatformStackScreenProps; function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { @@ -39,7 +38,6 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { const {translate} = useLocalize(); const {inputCallbackRef} = useAutoFocusInput(); const isQuickSettingsFlow = route.name === SCREENS.SETTINGS_TAGS.SETTINGS_TAG_CREATE; - const backPath = useDynamicBackPath(DYNAMIC_ROUTES.WORKSPACE_TAG_CREATE.path); const policyHasCustomCategories = hasCustomCategories(policyCategories); @@ -98,7 +96,7 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { policyHasCustomCategories, }); Keyboard.dismiss(); - Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : backPath); + Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : undefined); }; return ( @@ -115,7 +113,7 @@ function WorkspaceCreateTagPage({route}: WorkspaceCreateTagPageProps) { > Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : backPath)} + onBackButtonPress={() => Navigation.goBack(isQuickSettingsFlow ? ROUTES.SETTINGS_TAGS_ROOT.getRoute(policyID, backTo) : undefined)} /> Date: Mon, 20 Apr 2026 11:11:44 +0700 Subject: [PATCH 8/8] update old route --- src/libs/Navigation/linkingConfig/OldRoutes.ts | 1 + tests/navigation/getMatchingNewRouteTest.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/libs/Navigation/linkingConfig/OldRoutes.ts b/src/libs/Navigation/linkingConfig/OldRoutes.ts index b234737e4058..f5defb53967d 100644 --- a/src/libs/Navigation/linkingConfig/OldRoutes.ts +++ b/src/libs/Navigation/linkingConfig/OldRoutes.ts @@ -1,5 +1,6 @@ const oldRoutes: Record = { /* eslint-disable @typescript-eslint/naming-convention */ + '/settings/*/category/*/edit': '/settings/$1/category/$2/category-edit', '/settings/workspaces/*': '/workspaces/$1', '/settings/workspaces': '/workspaces', '/r/*/settings/name': '/r/$1/details/settings/name', diff --git a/tests/navigation/getMatchingNewRouteTest.ts b/tests/navigation/getMatchingNewRouteTest.ts index ef98dc803e4b..32d3df2e949b 100644 --- a/tests/navigation/getMatchingNewRouteTest.ts +++ b/tests/navigation/getMatchingNewRouteTest.ts @@ -44,6 +44,14 @@ describe('getBestMatchingPath', () => { ); }); + it('redirects old settings category edit path to the new dynamic suffix shape', () => { + expect(getMatchingNewRoute('/settings/abc/category/Meals/edit')).toBe('/settings/abc/category/Meals/category-edit'); + }); + + it('preserves query params when redirecting old settings category edit path', () => { + expect(getMatchingNewRoute('/settings/abc/category/Meals/edit?backTo=/home')).toBe('/settings/abc/category/Meals/category-edit?backTo=/home'); + }); + it('redirects old flag comment path to report-based dynamic route', () => { expect(getMatchingNewRoute('/flag/123/456')).toBe('/r/123/flag/123/456'); });