From 28469cb9dcb2dc146219184febd4c92f268834f5 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:13:36 +0700 Subject: [PATCH 01/12] migrate TRANSACTION_DUPLICATE_CONFIRMATION --- src/ROUTES.ts | 18 +++++-- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 5 +- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +- src/libs/Navigation/types.ts | 3 ++ src/libs/TransactionPreviewUtils.ts | 5 +- ...mation.tsx => DynamicConfirmationPage.tsx} | 50 ++++++++----------- 8 files changed, 46 insertions(+), 44 deletions(-) rename src/pages/TransactionDuplicate/{Confirmation.tsx => DynamicConfirmationPage.tsx} (85%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index fdafa4623ce1..658349d776b0 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1125,6 +1125,19 @@ const DYNAMIC_ROUTES = { path: 'initial-list-value', entryScreens: [SCREENS.WORKSPACE.REPORT_FIELDS_CREATE], }, + TRANSACTION_DUPLICATE_CONFIRMATION: { + path: 'transaction-duplicate-confirmation', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE, + SCREENS.TRANSACTION_DUPLICATE.BILLABLE, + ], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -3577,11 +3590,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/billable` as const, backTo), }, - TRANSACTION_DUPLICATE_CONFIRMATION_PAGE: { - route: 'r/:threadReportID/duplicates/confirm', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/confirm` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 8f58e99213a8..1c4323fd8c10 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -389,7 +389,7 @@ const SCREENS = { TAX_CODE: 'Transaction_Duplicate_Tax_Code', REIMBURSABLE: 'Transaction_Duplicate_Reimbursable', BILLABLE: 'Transaction_Duplicate_Billable', - CONFIRMATION: 'Transaction_Duplicate_Confirmation', + DYNAMIC_CONFIRMATION: 'Dynamic_Transaction_Duplicate_Confirmation', }, MERGE_TRANSACTION: { diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index 2a165dfe10d8..b749fdaff5c3 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -1,7 +1,8 @@ +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; import {useEffect, useMemo, useState} from 'react'; @@ -84,7 +85,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID, backTo)); break; default: - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path)); break; } }; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index e8574be05242..b8f5d287f9bf 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1176,7 +1176,7 @@ const TransactionDuplicateStackNavigator = createModalStackNavigator require('../../../../pages/TransactionDuplicate/ReviewTaxCode').default, [SCREENS.TRANSACTION_DUPLICATE.BILLABLE]: () => require('../../../../pages/TransactionDuplicate/ReviewBillable').default, [SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE]: () => require('../../../../pages/TransactionDuplicate/ReviewReimbursable').default, - [SCREENS.TRANSACTION_DUPLICATE.CONFIRMATION]: () => require('../../../../pages/TransactionDuplicate/Confirmation').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: () => require('../../../../pages/TransactionDuplicate/DynamicConfirmationPage').default, }); const MergeTransactionStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f4839edce363..2319311f5683 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1870,10 +1870,7 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.CONFIRMATION]: { - path: ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.route, - exact: true, - }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, }, }, [SCREENS.RIGHT_MODAL.MERGE_TRANSACTION]: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 8685eba094e9..521b7ed34f87 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2590,6 +2590,9 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: { + threadReportID: string; + }; }; type MergeTransactionNavigatorParamList = { diff --git a/src/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 2ccea5a90e62..1673c132cbec 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -3,7 +3,7 @@ import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -16,6 +16,7 @@ import type {ActionErrorsByTransaction, TransactionDetails} from './ReportUtils' import {setReviewDuplicatesKey} from './actions/Transaction'; import {isCategoryMissing} from './CategoryUtils'; import DateUtils from './DateUtils'; +import createDynamicRoute from './Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import {hasDynamicExternalWorkflow, isGroupPolicy as isGroupPolicyUtil} from './PolicyUtils'; import {getMostRecentActiveDEWSubmitFailedAction, getOriginalMessage, isDynamicExternalWorkflowSubmitFailedAction, isMessageDeleted, isMoneyRequestAction} from './ReportActionsUtils'; import {hasActionWithErrorsForTransaction, hasReceiptError, isExpenseReport, isReportApproved, isSettled} from './ReportUtils'; @@ -115,7 +116,7 @@ const getReviewNavigationRoute = ( return ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo); } - return ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, backTo); }; type TranslationPathOrText = { diff --git a/src/pages/TransactionDuplicate/Confirmation.tsx b/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx similarity index 85% rename from src/pages/TransactionDuplicate/Confirmation.tsx rename to src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx index 9f76bdfb8da9..37c30eb2a0bc 100644 --- a/src/pages/TransactionDuplicate/Confirmation.tsx +++ b/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx @@ -11,9 +11,9 @@ import Text from '@components/Text'; import {useWideRHPState} from '@components/WideRHPContextProvider'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; -import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; import useThemeStyles from '@hooks/useThemeStyles'; import useTransactionsByID from '@hooks/useTransactionsByID'; import useTransactionThreadReportIDs from '@hooks/useTransactionThreadReportIDs'; @@ -29,13 +29,12 @@ import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan import variables from '@styles/variables'; -import CONST from '@src/CONST'; import * as ReportActionsUtils from '@src/libs/ReportActionsUtils'; import * as ReportUtils from '@src/libs/ReportUtils'; import {generateReportID} from '@src/libs/ReportUtils'; import * as TransactionUtils from '@src/libs/TransactionUtils'; 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 {Transaction} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -47,39 +46,21 @@ import {useRoute} from '@react-navigation/native'; import React, {useCallback, useMemo, useRef} from 'react'; import {View} from 'react-native'; -function Confirmation() { +function DynamicConfirmationPage() { const styles = useThemeStyles(); const {translate} = useLocalize(); - const route = useRoute>(); + const route = useRoute>(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path); const [reviewDuplicates, reviewDuplicatesResult] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [duplicatedTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(reviewDuplicates?.transactionID)}`); const newTransaction = useMemo(() => TransactionUtils.buildNewTransactionAfterReviewingDuplicates(reviewDuplicates, duplicatedTransaction), [duplicatedTransaction, reviewDuplicates]); const [report, reportResult] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = TransactionUtils.getTransactionID(report); - const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); - const transactionViolations = allTransactionViolations?.[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${getNonEmptyStringOnyxID(transactionID)}`]; - const allDuplicateIDs = useMemo( - () => transactionViolations?.find((violation) => violation.name === CONST.VIOLATIONS.DUPLICATED_TRANSACTION)?.data?.duplicates ?? [], - [transactionViolations], - ); - const [allDuplicates] = useTransactionsByID(allDuplicateIDs); const [reviewDuplicatesReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reviewDuplicates?.reportID}`); - const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${getNonEmptyStringOnyxID(reviewDuplicatesReport?.policyID)}`); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); const [duplicatedTransactionPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${getNonEmptyStringOnyxID(reviewDuplicatesReport?.policyID)}`); - const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${getNonEmptyStringOnyxID(reviewDuplicatesReport?.policyID)}`); - const compareResult = TransactionUtils.compareDuplicateTransactionFields( - policyTags ?? {}, - transaction, - allDuplicates, - reviewDuplicatesReport, - reviewDuplicates?.transactionID, - policy, - policyCategories, - ); - const {goBack} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'confirmation', route.params.threadReportID, route.params.backTo); const [iouReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${newTransaction?.reportID}`); const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${newTransaction?.reportID}`); const reportAction = Object.values(reportActions ?? {}).find( @@ -123,7 +104,13 @@ function Confirmation() { // Suppress the NotFound guard for the discarded thread the server tears down on merge. const keptReportRoute = ROUTES.REPORT_WITH_ID.getRoute(mergeParams.reportID); setDeleteTransactionNavigateBackUrl(keptReportRoute); - mergeDuplicates({...mergeParams, ...taxData, currentUserAccountID, currentUserLogin: currentUserLogin ?? '', allTransactionViolations}); + mergeDuplicates({ + ...mergeParams, + ...taxData, + currentUserAccountID, + currentUserLogin: currentUserLogin ?? '', + allTransactionViolations, + }); if (isSuperWideRHPDisplayed) { Navigation.dismissToSuperWideRHP(); return; @@ -140,7 +127,12 @@ function Confirmation() { }, [childReportID, transactionsMergeParams, taxData, currentUserAccountID, currentUserLogin, isSuperWideRHPDisplayed, allTransactionViolations]); const handleResolveDuplicates = useCallback(() => { - resolveDuplicates({...transactionsMergeParams, ...taxData, transactionThreadReportIDMap, allTransactionViolations}); + resolveDuplicates({ + ...transactionsMergeParams, + ...taxData, + transactionThreadReportIDMap, + allTransactionViolations, + }); Navigation.dismissToSuperWideRHP(); }, [transactionsMergeParams, taxData, transactionThreadReportIDMap, allTransactionViolations]); @@ -185,14 +177,14 @@ function Confirmation() { return ( Navigation.goBack(backPath)} /> @@ -241,4 +233,4 @@ function Confirmation() { ); } -export default Confirmation; +export default DynamicConfirmationPage; From fa80bae9e6c0bd3bfdf67e4bdf45cf3d77523ae6 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:31:52 +0700 Subject: [PATCH 02/12] migrate TRANSACTION_DUPLICATE_REVIEW_BILLABLE --- src/ROUTES.ts | 21 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 ++-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +---- src/libs/Navigation/types.ts | 4 ++-- src/libs/TransactionPreviewUtils.ts | 2 +- ...able.tsx => DynamicReviewBillablePage.tsx} | 21 +++++++++---------- 8 files changed, 32 insertions(+), 29 deletions(-) rename src/pages/TransactionDuplicate/{ReviewBillable.tsx => DynamicReviewBillablePage.tsx} (83%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 658349d776b0..e5be5b6f0513 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1126,7 +1126,20 @@ const DYNAMIC_ROUTES = { entryScreens: [SCREENS.WORKSPACE.REPORT_FIELDS_CREATE], }, TRANSACTION_DUPLICATE_CONFIRMATION: { - path: 'transaction-duplicate-confirmation', + path: 'confirm', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, + ], + }, + TRANSACTION_DUPLICATE_REVIEW_BILLABLE: { + path: 'billable', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, @@ -1135,7 +1148,6 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE, - SCREENS.TRANSACTION_DUPLICATE.BILLABLE, ], }, } as const satisfies DynamicRoutes; @@ -3585,11 +3597,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/reimbursable` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE: { - route: 'r/:threadReportID/duplicates/review/billable', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/billable` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 1c4323fd8c10..c54c8839bde6 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -388,7 +388,7 @@ const SCREENS = { DESCRIPTION: 'Transaction_Duplicate_Description', TAX_CODE: 'Transaction_Duplicate_Tax_Code', REIMBURSABLE: 'Transaction_Duplicate_Reimbursable', - BILLABLE: 'Transaction_Duplicate_Billable', + DYNAMIC_BILLABLE: 'Dynamic_Transaction_Duplicate_Billable', DYNAMIC_CONFIRMATION: 'Dynamic_Transaction_Duplicate_Confirmation', }, diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index b749fdaff5c3..bbe6617bb3a3 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -49,7 +49,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo)); break; case 'billable': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path)); break; default: if (backTo) { @@ -82,7 +82,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo)); break; case 'billable': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path)); break; default: Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index b8f5d287f9bf..d8beb7bd1add 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1174,7 +1174,7 @@ const TransactionDuplicateStackNavigator = createModalStackNavigator require('../../../../pages/TransactionDuplicate/ReviewTag').default, [SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/ReviewDescription').default, [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/ReviewTaxCode').default, - [SCREENS.TRANSACTION_DUPLICATE.BILLABLE]: () => require('../../../../pages/TransactionDuplicate/ReviewBillable').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewBillablePage').default, [SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE]: () => require('../../../../pages/TransactionDuplicate/ReviewReimbursable').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: () => require('../../../../pages/TransactionDuplicate/DynamicConfirmationPage').default, }); diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 2319311f5683..490f32ee3df8 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1866,10 +1866,7 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.BILLABLE]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.route, - exact: true, - }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, }, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 521b7ed34f87..5f8ffd2dec64 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2580,12 +2580,12 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.BILLABLE]: { + [SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE]: { threadReportID: 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.TRANSACTION_DUPLICATE.REIMBURSABLE]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 1673c132cbec..193b1a4a43eb 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -110,7 +110,7 @@ const getReviewNavigationRoute = ( return ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo); } if (comparisonResult.change.billable) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, backTo); } if (comparisonResult.change.reimbursable) { return ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewBillable.tsx b/src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx similarity index 83% rename from src/pages/TransactionDuplicate/ReviewBillable.tsx rename to src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx index 472d75fbc802..c30fb17d142c 100644 --- a/src/pages/TransactionDuplicate/ReviewBillable.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx @@ -1,6 +1,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; @@ -8,12 +9,14 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import {compareDuplicateTransactionFields, getTransactionID} from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -23,9 +26,10 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewBillable() { - const route = useRoute>(); +function DynamicReviewBillablePage() { + const route = useRoute>(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); @@ -44,12 +48,7 @@ function ReviewBillable() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'billable', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'billable', route.params.threadReportID, route.params.backTo); const options = useMemo( () => compareResult.change.billable?.map((billable) => ({ @@ -67,10 +66,10 @@ function ReviewBillable() { }; return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -84,4 +83,4 @@ function ReviewBillable() { ); } -export default ReviewBillable; +export default DynamicReviewBillablePage; From b2ce5afb590040335f71b064fed386c4f7c20468 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:40:04 +0700 Subject: [PATCH 03/12] migrate TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE --- src/ROUTES.ts | 21 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 ++-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +---- src/libs/Navigation/types.ts | 4 ++-- src/libs/TransactionPreviewUtils.ts | 2 +- ....tsx => DynamicReviewReimbursablePage.tsx} | 16 ++++++++------ 8 files changed, 32 insertions(+), 24 deletions(-) rename src/pages/TransactionDuplicate/{ReviewReimbursable.tsx => DynamicReviewReimbursablePage.tsx} (85%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index e5be5b6f0513..4c0f133cdd9f 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1134,7 +1134,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.TAG, SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, ], }, @@ -1147,7 +1147,19 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.TAG, SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, + ], + }, + TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE: { + path: 'reimbursable', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, ], }, } as const satisfies DynamicRoutes; @@ -3592,11 +3604,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/description` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE: { - route: 'r/:threadReportID/duplicates/review/reimbursable', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/reimbursable` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index c54c8839bde6..04c95addde3b 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -387,8 +387,8 @@ const SCREENS = { TAG: 'Transaction_Duplicate_Tag', DESCRIPTION: 'Transaction_Duplicate_Description', TAX_CODE: 'Transaction_Duplicate_Tax_Code', - REIMBURSABLE: 'Transaction_Duplicate_Reimbursable', DYNAMIC_BILLABLE: 'Dynamic_Transaction_Duplicate_Billable', + DYNAMIC_REIMBURSABLE: 'Dynamic_Transaction_Duplicate_Reimbursable', DYNAMIC_CONFIRMATION: 'Dynamic_Transaction_Duplicate_Confirmation', }, diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index bbe6617bb3a3..6e4cf6626d35 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -46,7 +46,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo)); break; case 'reimbursable': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path)); break; case 'billable': Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path)); @@ -79,7 +79,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo)); break; case 'reimbursable': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path)); break; case 'billable': Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index d8beb7bd1add..df80fdab2518 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1175,7 +1175,7 @@ const TransactionDuplicateStackNavigator = createModalStackNavigator require('../../../../pages/TransactionDuplicate/ReviewDescription').default, [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/ReviewTaxCode').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewBillablePage').default, - [SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE]: () => require('../../../../pages/TransactionDuplicate/ReviewReimbursable').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewReimbursablePage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: () => require('../../../../pages/TransactionDuplicate/DynamicConfirmationPage').default, }); diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 490f32ee3df8..45638b17fb94 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1862,11 +1862,8 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.route, - exact: true, - }, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, }, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 5f8ffd2dec64..b0f0eef953e2 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2580,12 +2580,12 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.REIMBURSABLE]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: { threadReportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 193b1a4a43eb..8b92e5f4eb06 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -113,7 +113,7 @@ const getReviewNavigationRoute = ( return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, backTo); } if (comparisonResult.change.reimbursable) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path, backTo); } return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewReimbursable.tsx b/src/pages/TransactionDuplicate/DynamicReviewReimbursablePage.tsx similarity index 85% rename from src/pages/TransactionDuplicate/ReviewReimbursable.tsx rename to src/pages/TransactionDuplicate/DynamicReviewReimbursablePage.tsx index e21878191891..b301ee9b11f4 100644 --- a/src/pages/TransactionDuplicate/ReviewReimbursable.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewReimbursablePage.tsx @@ -1,6 +1,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; @@ -8,12 +9,14 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import {compareDuplicateTransactionFields, getTransactionID} from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -23,9 +26,10 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewReimbursable() { - const route = useRoute>(); +function DynamicReviewReimbursablePage() { + const route = useRoute>(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); @@ -43,7 +47,7 @@ function ReviewReimbursable() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation( Object.keys(compareResult.change ?? {}), 'reimbursable', route.params.threadReportID, @@ -66,10 +70,10 @@ function ReviewReimbursable() { }; return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -83,4 +87,4 @@ function ReviewReimbursable() { ); } -export default ReviewReimbursable; +export default DynamicReviewReimbursablePage; From ffe9d0dfe2b4c527ae78a8b899df063c063afeed Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:46:21 +0700 Subject: [PATCH 04/12] migrate TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION --- src/ROUTES.ts | 23 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 ++-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +--- src/libs/Navigation/types.ts | 4 ++-- src/libs/TransactionPreviewUtils.ts | 2 +- ...n.tsx => DynamicReviewDescriptionPage.tsx} | 16 ++++++++----- 8 files changed, 33 insertions(+), 25 deletions(-) rename src/pages/TransactionDuplicate/{ReviewDescription.tsx => DynamicReviewDescriptionPage.tsx} (87%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 4c0f133cdd9f..6116f5e54d91 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1132,7 +1132,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, - SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, @@ -1145,7 +1145,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, - SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, ], @@ -1157,11 +1157,23 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, - SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, ], }, + TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION: { + path: 'transaction-duplicate-description', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, + ], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -3599,11 +3611,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/tax-code` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE: { - route: 'r/:threadReportID/duplicates/review/description', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/description` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 04c95addde3b..3d03e4e60833 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -385,8 +385,8 @@ const SCREENS = { MERCHANT: 'Transaction_Duplicate_Merchant', CATEGORY: 'Transaction_Duplicate_Category', TAG: 'Transaction_Duplicate_Tag', - DESCRIPTION: 'Transaction_Duplicate_Description', TAX_CODE: 'Transaction_Duplicate_Tax_Code', + DYNAMIC_DESCRIPTION: 'Dynamic_Transaction_Duplicate_Description', DYNAMIC_BILLABLE: 'Dynamic_Transaction_Duplicate_Billable', DYNAMIC_REIMBURSABLE: 'Dynamic_Transaction_Duplicate_Reimbursable', DYNAMIC_CONFIRMATION: 'Dynamic_Transaction_Duplicate_Confirmation', diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index 6e4cf6626d35..daa67dc3fa74 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -40,7 +40,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo)); break; case 'description': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); break; case 'taxCode': Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo)); @@ -73,7 +73,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo)); break; case 'description': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); break; case 'taxCode': Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index df80fdab2518..826c00a07704 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1172,7 +1172,7 @@ const TransactionDuplicateStackNavigator = createModalStackNavigator require('../../../../pages/TransactionDuplicate/ReviewMerchant').default, [SCREENS.TRANSACTION_DUPLICATE.CATEGORY]: () => require('../../../../pages/TransactionDuplicate/ReviewCategory').default, [SCREENS.TRANSACTION_DUPLICATE.TAG]: () => require('../../../../pages/TransactionDuplicate/ReviewTag').default, - [SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/ReviewDescription').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewDescriptionPage').default, [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/ReviewTaxCode').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewBillablePage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewReimbursablePage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 45638b17fb94..fabb76984db9 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1854,14 +1854,11 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.route, - exact: true, - }, [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.route, exact: true, }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index b0f0eef953e2..a6eba8cea1b3 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2570,12 +2570,12 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.DESCRIPTION]: { + [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: { threadReportID: 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.TRANSACTION_DUPLICATE.TAX_CODE]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 8b92e5f4eb06..e4e1a6858074 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -104,7 +104,7 @@ const getReviewNavigationRoute = ( return ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo); } if (comparisonResult.change.description) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, backTo); } if (comparisonResult.change.taxCode) { return ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewDescription.tsx b/src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx similarity index 87% rename from src/pages/TransactionDuplicate/ReviewDescription.tsx rename to src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx index 7bb6e39e0aec..abe3f0eba7c2 100644 --- a/src/pages/TransactionDuplicate/ReviewDescription.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx @@ -1,6 +1,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; @@ -8,6 +9,7 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import Parser from '@libs/Parser'; @@ -16,6 +18,7 @@ import {compareDuplicateTransactionFields, getTransactionID} from '@libs/Transac import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -25,9 +28,10 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewDescription() { - const route = useRoute>(); +function DynamicReviewDescriptionPage() { + const route = useRoute>(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); @@ -45,7 +49,7 @@ function ReviewDescription() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation( Object.keys(compareResult.change ?? {}), 'description', route.params.threadReportID, @@ -71,10 +75,10 @@ function ReviewDescription() { }; return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -88,4 +92,4 @@ function ReviewDescription() { ); } -export default ReviewDescription; +export default DynamicReviewDescriptionPage; From d741c112e23e2d0ed1a1c9c0811c8806df4d92a7 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:52:56 +0700 Subject: [PATCH 05/12] migrate TRANSACTION_DUPLICATE_REVIEW_TAX_CODE --- src/ROUTES.ts | 25 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 +-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +--- src/libs/Navigation/types.ts | 4 +-- src/libs/TransactionPreviewUtils.ts | 2 +- ...xCode.tsx => DynamicReviewTaxCodePage.tsx} | 21 ++++++++-------- 8 files changed, 34 insertions(+), 31 deletions(-) rename src/pages/TransactionDuplicate/{ReviewTaxCode.tsx => DynamicReviewTaxCodePage.tsx} (86%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 6116f5e54d91..4bc9bfcb4c08 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1133,7 +1133,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, ], @@ -1146,7 +1146,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, ], }, @@ -1158,7 +1158,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, ], }, @@ -1169,7 +1169,19 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, SCREENS.TRANSACTION_DUPLICATE.TAG, - SCREENS.TRANSACTION_DUPLICATE.TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, + ], + }, + TRANSACTION_DUPLICATE_REVIEW_TAX_CODE: { + path: 'tax-code', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, ], @@ -3606,11 +3618,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/tag` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE: { - route: 'r/:threadReportID/duplicates/review/tax-code', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/tax-code` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 3d03e4e60833..245421c7275c 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -385,8 +385,8 @@ const SCREENS = { MERCHANT: 'Transaction_Duplicate_Merchant', CATEGORY: 'Transaction_Duplicate_Category', TAG: 'Transaction_Duplicate_Tag', - TAX_CODE: 'Transaction_Duplicate_Tax_Code', DYNAMIC_DESCRIPTION: 'Dynamic_Transaction_Duplicate_Description', + DYNAMIC_TAX_CODE: 'Dynamic_Transaction_Duplicate_Tax_Code', DYNAMIC_BILLABLE: 'Dynamic_Transaction_Duplicate_Billable', DYNAMIC_REIMBURSABLE: 'Dynamic_Transaction_Duplicate_Reimbursable', DYNAMIC_CONFIRMATION: 'Dynamic_Transaction_Duplicate_Confirmation', diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index daa67dc3fa74..89571dc5edd8 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -43,7 +43,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); break; case 'taxCode': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path)); break; case 'reimbursable': Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path)); @@ -76,7 +76,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); break; case 'taxCode': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path)); break; case 'reimbursable': Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 826c00a07704..a7fe7f76c586 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1173,7 +1173,7 @@ const TransactionDuplicateStackNavigator = createModalStackNavigator require('../../../../pages/TransactionDuplicate/ReviewCategory').default, [SCREENS.TRANSACTION_DUPLICATE.TAG]: () => require('../../../../pages/TransactionDuplicate/ReviewTag').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewDescriptionPage').default, - [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/ReviewTaxCode').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTaxCodePage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewBillablePage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewReimbursablePage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: () => require('../../../../pages/TransactionDuplicate/DynamicConfirmationPage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index fabb76984db9..e04fc04a21a9 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1854,11 +1854,8 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.route, - exact: true, - }, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index a6eba8cea1b3..12c9f7d537a4 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2570,12 +2570,12 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.TAX_CODE]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: { threadReportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index e4e1a6858074..88282288d909 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -107,7 +107,7 @@ const getReviewNavigationRoute = ( return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, backTo); } if (comparisonResult.change.taxCode) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path, backTo); } if (comparisonResult.change.billable) { return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewTaxCode.tsx b/src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx similarity index 86% rename from src/pages/TransactionDuplicate/ReviewTaxCode.tsx rename to src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx index 43c7e5d51ea8..cdce300ddc5c 100644 --- a/src/pages/TransactionDuplicate/ReviewTaxCode.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx @@ -2,6 +2,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import usePolicy from '@hooks/usePolicy'; @@ -11,6 +12,7 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import {convertToBackendAmount} from '@libs/CurrencyUtils'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import {getTaxByID} from '@libs/PolicyUtils'; @@ -18,6 +20,7 @@ import {calculateTaxAmount, compareDuplicateTransactionFields, getAmount, getDef import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -27,10 +30,11 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewTaxRate() { - const route = useRoute>(); +function DynamicReviewTaxCodePage() { + const route = useRoute>(); const {translate} = useLocalize(); const {getCurrencyDecimals} = useCurrencyListActions(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reviewDuplicates?.reportID}`); const policy = usePolicy(report?.policyID); @@ -49,12 +53,7 @@ function ReviewTaxRate() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'taxCode', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'taxCode', route.params.threadReportID, route.params.backTo); const options = useMemo( () => @@ -88,10 +87,10 @@ function ReviewTaxRate() { ); return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -105,4 +104,4 @@ function ReviewTaxRate() { ); } -export default ReviewTaxRate; +export default DynamicReviewTaxCodePage; From 0906f1ccdee2a73d1462712ef03227dccf38d451 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:59:27 +0700 Subject: [PATCH 06/12] migrate TRANSACTION_DUPLICATE_REVIEW_TAG --- src/ROUTES.ts | 27 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 +-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +--- src/libs/Navigation/types.ts | 2 +- src/libs/TransactionPreviewUtils.ts | 2 +- ...ReviewTag.tsx => DynamicReviewTagPage.tsx} | 21 +++++++-------- .../TransactionDuplicate/ReviewMerchant.tsx | 2 +- 9 files changed, 35 insertions(+), 32 deletions(-) rename src/pages/TransactionDuplicate/{ReviewTag.tsx => DynamicReviewTagPage.tsx} (84%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 4bc9bfcb4c08..10df348929d3 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1131,7 +1131,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, @@ -1144,7 +1144,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, @@ -1156,7 +1156,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, @@ -1168,7 +1168,7 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, @@ -1180,12 +1180,24 @@ const DYNAMIC_ROUTES = { SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, SCREENS.TRANSACTION_DUPLICATE.CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, ], }, + TRANSACTION_DUPLICATE_REVIEW_TAG: { + path: 'transaction-duplicate-tag', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, + ], + }, } as const satisfies DynamicRoutes; const ROUTES = { @@ -3613,11 +3625,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/category` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE: { - route: 'r/:threadReportID/duplicates/review/tag', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/tag` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 245421c7275c..30bcfbb022a0 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -384,7 +384,7 @@ const SCREENS = { REVIEW: 'Transaction_Duplicate_Review', MERCHANT: 'Transaction_Duplicate_Merchant', CATEGORY: 'Transaction_Duplicate_Category', - TAG: 'Transaction_Duplicate_Tag', + DYNAMIC_TAG: 'Dynamic_Transaction_Duplicate_Tag', DYNAMIC_DESCRIPTION: 'Dynamic_Transaction_Duplicate_Description', DYNAMIC_TAX_CODE: 'Dynamic_Transaction_Duplicate_Tax_Code', DYNAMIC_BILLABLE: 'Dynamic_Transaction_Duplicate_Billable', diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index 89571dc5edd8..a7bf2e6fd792 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -37,7 +37,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo)); break; case 'tag': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path)); break; case 'description': Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); @@ -70,7 +70,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo)); break; case 'tag': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path)); break; case 'description': Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index a7fe7f76c586..5a194b042eb0 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1171,7 +1171,7 @@ const TransactionDuplicateStackNavigator = createModalStackNavigator require('../../../../pages/TransactionDuplicate/Review').default, [SCREENS.TRANSACTION_DUPLICATE.MERCHANT]: () => require('../../../../pages/TransactionDuplicate/ReviewMerchant').default, [SCREENS.TRANSACTION_DUPLICATE.CATEGORY]: () => require('../../../../pages/TransactionDuplicate/ReviewCategory').default, - [SCREENS.TRANSACTION_DUPLICATE.TAG]: () => require('../../../../pages/TransactionDuplicate/ReviewTag').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTagPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewDescriptionPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTaxCodePage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewBillablePage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index e04fc04a21a9..372fa11e3dc0 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1850,10 +1850,7 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.TAG]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.route, - exact: true, - }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 12c9f7d537a4..07b995521b95 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2565,7 +2565,7 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.TAG]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 88282288d909..8142acd8b670 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -101,7 +101,7 @@ const getReviewNavigationRoute = ( return ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo); } if (comparisonResult.change.tag) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, backTo); } if (comparisonResult.change.description) { return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewTag.tsx b/src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx similarity index 84% rename from src/pages/TransactionDuplicate/ReviewTag.tsx rename to src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx index 4fbeb046af47..6587c8d3003c 100644 --- a/src/pages/TransactionDuplicate/ReviewTag.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx @@ -1,6 +1,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; @@ -8,6 +9,7 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import {getCleanedTagName} from '@libs/PolicyUtils'; @@ -15,6 +17,7 @@ import {compareDuplicateTransactionFields, getTransactionID} from '@libs/Transac import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -24,9 +27,10 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewTag() { - const route = useRoute>(); +function DynamicReviewTagPage() { + const route = useRoute>(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); @@ -44,12 +48,7 @@ function ReviewTag() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'tag', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'tag', route.params.threadReportID, route.params.backTo); const options = useMemo( () => compareResult.change.tag?.map((tag) => @@ -70,10 +69,10 @@ function ReviewTag() { }; return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -87,4 +86,4 @@ function ReviewTag() { ); } -export default ReviewTag; +export default DynamicReviewTagPage; diff --git a/src/pages/TransactionDuplicate/ReviewMerchant.tsx b/src/pages/TransactionDuplicate/ReviewMerchant.tsx index 08a28a7e4a16..536eae1b6e59 100644 --- a/src/pages/TransactionDuplicate/ReviewMerchant.tsx +++ b/src/pages/TransactionDuplicate/ReviewMerchant.tsx @@ -24,7 +24,7 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; function ReviewMerchant() { - const route = useRoute>(); + const route = useRoute>(); const {translate} = useLocalize(); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); From 415e0777f16262bfed91dea119e7fb2d445b597a Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:04:31 +0700 Subject: [PATCH 07/12] migrate TRANSACTION_DUPLICATE_REVIEW_CATEGORY --- src/ROUTES.ts | 29 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 +-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +--- src/libs/Navigation/types.ts | 2 +- src/libs/TransactionPreviewUtils.ts | 2 +- ...gory.tsx => DynamicReviewCategoryPage.tsx} | 21 +++++++------- 8 files changed, 35 insertions(+), 32 deletions(-) rename src/pages/TransactionDuplicate/{ReviewCategory.tsx => DynamicReviewCategoryPage.tsx} (84%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 10df348929d3..16f974a9d43d 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1130,7 +1130,7 @@ const DYNAMIC_ROUTES = { entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, @@ -1143,7 +1143,7 @@ const DYNAMIC_ROUTES = { entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, @@ -1155,7 +1155,7 @@ const DYNAMIC_ROUTES = { entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, @@ -1167,7 +1167,7 @@ const DYNAMIC_ROUTES = { entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, @@ -1179,7 +1179,7 @@ const DYNAMIC_ROUTES = { entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, @@ -1191,7 +1191,19 @@ const DYNAMIC_ROUTES = { entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, SCREENS.TRANSACTION_DUPLICATE.MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, + ], + }, + TRANSACTION_DUPLICATE_REVIEW_CATEGORY: { + path: 'category', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, @@ -3620,11 +3632,6 @@ const ROUTES = { getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/merchant` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE: { - route: 'r/:threadReportID/duplicates/review/category', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/category` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 30bcfbb022a0..1bf76eaab99b 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -383,7 +383,7 @@ const SCREENS = { TRANSACTION_DUPLICATE: { REVIEW: 'Transaction_Duplicate_Review', MERCHANT: 'Transaction_Duplicate_Merchant', - CATEGORY: 'Transaction_Duplicate_Category', + DYNAMIC_CATEGORY: 'Dynamic_Transaction_Duplicate_Category', DYNAMIC_TAG: 'Dynamic_Transaction_Duplicate_Tag', DYNAMIC_DESCRIPTION: 'Dynamic_Transaction_Duplicate_Description', DYNAMIC_TAX_CODE: 'Dynamic_Transaction_Duplicate_Tax_Code', diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index a7bf2e6fd792..dafffc7fd20e 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -34,7 +34,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo)); break; case 'category': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path)); break; case 'tag': Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path)); @@ -67,7 +67,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo)); break; case 'category': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path)); break; case 'tag': Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 5a194b042eb0..797851f8a023 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1170,7 +1170,7 @@ const ReferralModalStackNavigator = createModalStackNavigator({ [SCREENS.TRANSACTION_DUPLICATE.REVIEW]: () => require('../../../../pages/TransactionDuplicate/Review').default, [SCREENS.TRANSACTION_DUPLICATE.MERCHANT]: () => require('../../../../pages/TransactionDuplicate/ReviewMerchant').default, - [SCREENS.TRANSACTION_DUPLICATE.CATEGORY]: () => require('../../../../pages/TransactionDuplicate/ReviewCategory').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewCategoryPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTagPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewDescriptionPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTaxCodePage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 372fa11e3dc0..f8c45a3f8ba9 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1846,10 +1846,7 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.CATEGORY]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.route, - exact: true, - }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 07b995521b95..3cc9a8bc8b6d 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2560,7 +2560,7 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.CATEGORY]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 8142acd8b670..f0857e15d1bb 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -98,7 +98,7 @@ const getReviewNavigationRoute = ( return ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo); } if (comparisonResult.change.category) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path, backTo); } if (comparisonResult.change.tag) { return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewCategory.tsx b/src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx similarity index 84% rename from src/pages/TransactionDuplicate/ReviewCategory.tsx rename to src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx index d77d380864e4..e8f7546d9b13 100644 --- a/src/pages/TransactionDuplicate/ReviewCategory.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx @@ -1,6 +1,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; @@ -9,12 +10,14 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import {getDecodedCategoryName} from '@libs/CategoryUtils'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import {compareDuplicateTransactionFields, getTransactionID} from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -24,9 +27,10 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewCategory() { - const route = useRoute>(); +function DynamicReviewCategoryPage() { + const route = useRoute>(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); @@ -44,12 +48,7 @@ function ReviewCategory() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'category', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'category', route.params.threadReportID, route.params.backTo); const options = useMemo( () => compareResult.change.category?.map((category) => @@ -71,10 +70,10 @@ function ReviewCategory() { }; return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -88,4 +87,4 @@ function ReviewCategory() { ); } -export default ReviewCategory; +export default DynamicReviewCategoryPage; From 0569e8cef5e8b6c4157b65d796b675b42b4ad83e Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:09:30 +0700 Subject: [PATCH 08/12] migrate TRANSACTION_DUPLICATE_REVIEW_MERCHANT --- src/ROUTES.ts | 31 ++++++++++++------- src/SCREENS.ts | 2 +- src/hooks/useReviewDuplicatesNavigation.tsx | 4 +-- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +-- src/libs/Navigation/types.ts | 2 +- src/libs/TransactionPreviewUtils.ts | 2 +- ...hant.tsx => DynamicReviewMerchantPage.tsx} | 21 ++++++------- 8 files changed, 36 insertions(+), 33 deletions(-) rename src/pages/TransactionDuplicate/{ReviewMerchant.tsx => DynamicReviewMerchantPage.tsx} (83%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 16f974a9d43d..c0a39200af93 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1129,7 +1129,7 @@ const DYNAMIC_ROUTES = { path: 'confirm', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, @@ -1142,7 +1142,7 @@ const DYNAMIC_ROUTES = { path: 'billable', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, @@ -1154,7 +1154,7 @@ const DYNAMIC_ROUTES = { path: 'reimbursable', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, @@ -1166,7 +1166,7 @@ const DYNAMIC_ROUTES = { path: 'transaction-duplicate-description', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, @@ -1178,7 +1178,7 @@ const DYNAMIC_ROUTES = { path: 'tax-code', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, @@ -1190,7 +1190,7 @@ const DYNAMIC_ROUTES = { path: 'transaction-duplicate-tag', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, @@ -1202,7 +1202,19 @@ const DYNAMIC_ROUTES = { path: 'category', entryScreens: [ SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, + ], + }, + TRANSACTION_DUPLICATE_REVIEW_MERCHANT: { + path: 'merchant', + entryScreens: [ + SCREENS.TRANSACTION_DUPLICATE.REVIEW, + SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, @@ -3627,11 +3639,6 @@ const ROUTES = { getRoute: (threadReportID: string | undefined, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review` as const, backTo), }, - TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE: { - route: 'r/:threadReportID/duplicates/review/merchant', - - getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review/merchant` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 1bf76eaab99b..37ca1d15a932 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -382,7 +382,7 @@ const SCREENS = { TRANSACTION_DUPLICATE: { REVIEW: 'Transaction_Duplicate_Review', - MERCHANT: 'Transaction_Duplicate_Merchant', + DYNAMIC_MERCHANT: 'Dynamic_Transaction_Duplicate_Merchant', DYNAMIC_CATEGORY: 'Dynamic_Transaction_Duplicate_Category', DYNAMIC_TAG: 'Dynamic_Transaction_Duplicate_Tag', DYNAMIC_DESCRIPTION: 'Dynamic_Transaction_Duplicate_Description', diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index dafffc7fd20e..7149d93e42fa 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -31,7 +31,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S const goBack = () => { switch (prevScreen) { case 'merchant': - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path)); break; case 'category': Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path)); @@ -64,7 +64,7 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S const navigateToNextScreen = () => { switch (nextScreen) { case 'merchant': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path)); break; case 'category': Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path)); diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 797851f8a023..7ae11f644b60 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1169,7 +1169,7 @@ const ReferralModalStackNavigator = createModalStackNavigator({ [SCREENS.TRANSACTION_DUPLICATE.REVIEW]: () => require('../../../../pages/TransactionDuplicate/Review').default, - [SCREENS.TRANSACTION_DUPLICATE.MERCHANT]: () => require('../../../../pages/TransactionDuplicate/ReviewMerchant').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewMerchantPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewCategoryPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTagPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewDescriptionPage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f8c45a3f8ba9..f3b81596de4a 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1842,10 +1842,7 @@ const config: LinkingOptions['config'] = { path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.route, exact: true, }, - [SCREENS.TRANSACTION_DUPLICATE.MERCHANT]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.route, - exact: true, - }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 3cc9a8bc8b6d..6c0d618c5e2b 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2555,7 +2555,7 @@ type TransactionDuplicateNavigatorParamList = { // 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.TRANSACTION_DUPLICATE.MERCHANT]: { + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT]: { threadReportID: 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/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index f0857e15d1bb..0ae3f8bfd7b5 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -95,7 +95,7 @@ const getReviewNavigationRoute = ( ); if (comparisonResult.change.merchant) { - return ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path, backTo); } if (comparisonResult.change.category) { return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path, backTo); diff --git a/src/pages/TransactionDuplicate/ReviewMerchant.tsx b/src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx similarity index 83% rename from src/pages/TransactionDuplicate/ReviewMerchant.tsx rename to src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx index 536eae1b6e59..991ee359c5d4 100644 --- a/src/pages/TransactionDuplicate/ReviewMerchant.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx @@ -1,6 +1,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; @@ -8,12 +9,14 @@ import useTransactionsByID from '@hooks/useTransactionsByID'; import {setReviewDuplicatesKey} from '@libs/actions/Transaction'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; import {compareDuplicateTransactionFields, getTransactionID} from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -23,9 +26,10 @@ import type {FieldItemType} from './ReviewFields'; import ReviewFields from './ReviewFields'; -function ReviewMerchant() { - const route = useRoute>(); +function DynamicReviewMerchantPage() { + const route = useRoute>(); const {translate} = useLocalize(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); @@ -43,12 +47,7 @@ function ReviewMerchant() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, goBack, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'merchant', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'merchant', route.params.threadReportID, route.params.backTo); const options = useMemo( () => compareResult.change.merchant?.map((merchant) => @@ -70,10 +69,10 @@ function ReviewMerchant() { }; return ( - + Navigation.goBack(backPath)} /> stepNames={stepNames} @@ -87,4 +86,4 @@ function ReviewMerchant() { ); } -export default ReviewMerchant; +export default DynamicReviewMerchantPage; From b654ceb718c340f5d4bc29ad5ee82b869fec35e0 Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 20:23:54 +0700 Subject: [PATCH 09/12] update unit test --- tests/unit/TransactionPreviewUtils.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/TransactionPreviewUtils.test.ts b/tests/unit/TransactionPreviewUtils.test.ts index 732cd46d34b8..d1828d886ef0 100644 --- a/tests/unit/TransactionPreviewUtils.test.ts +++ b/tests/unit/TransactionPreviewUtils.test.ts @@ -698,7 +698,7 @@ describe('TransactionPreviewUtils', () => { }); const route = getReviewNavigationRoute(backTo, threadReportID, transaction1, [transaction2], undefined, undefined, {}, fakeReport); - expect(route).toContain('duplicates/confirm'); + expect(route).toContain('backRoute/confirm'); }); it('should navigate to merchant review page when merchants differ', () => { @@ -716,7 +716,7 @@ describe('TransactionPreviewUtils', () => { }; const route = getReviewNavigationRoute(backTo, threadReportID, transaction1, [transaction2], undefined, undefined, {}, fakeReport); - expect(route).toContain('duplicates/review/merchant'); + expect(route).toContain('backRoute/merchant'); }); it('should navigate to tag review page when tags differ with single-level policyTags', () => { @@ -747,7 +747,7 @@ describe('TransactionPreviewUtils', () => { const fakePolicy = {...createRandomPolicy(0), id: 'fakePolicyID', areTagsEnabled: true}; const route = getReviewNavigationRoute(backTo, threadReportID, transaction1, [transaction2], fakePolicy, undefined, policyTags, fakeReport); - expect(route).toContain('duplicates/review/tag'); + expect(route).toContain('backRoute/transaction-duplicate-tag'); }); it('should skip tag review when policyTags filters out disabled tags', () => { @@ -779,7 +779,7 @@ describe('TransactionPreviewUtils', () => { const fakePolicy = {...createRandomPolicy(0), id: 'fakePolicyID', areTagsEnabled: true}; const route = getReviewNavigationRoute(backTo, threadReportID, transaction1, [transaction2], fakePolicy, undefined, policyTags, fakeReport); // Since Marketing is disabled, only 1 enabled tag available, so tag review is skipped - expect(route).toContain('duplicates/confirm'); + expect(route).toContain('backRoute/confirm'); }); }); From b9ec4ff660fdb0cf38d2acf5fe299a4f3cb86eff Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Wed, 22 Jul 2026 20:48:12 +0700 Subject: [PATCH 10/12] update seatbelt --- config/eslint/eslint.seatbelt.tsv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/eslint/eslint.seatbelt.tsv b/config/eslint/eslint.seatbelt.tsv index 0f78ce026bcf..7853dc1e1810 100644 --- a/config/eslint/eslint.seatbelt.tsv +++ b/config/eslint/eslint.seatbelt.tsv @@ -1201,9 +1201,9 @@ "../../src/pages/ShareCodePage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 2 "../../src/pages/TeachersUnite/ImTeacherUpdateEmailPage.tsx" "no-restricted-imports" 1 "../../src/pages/TeachersUnite/SaveTheWorldPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 -"../../src/pages/TransactionDuplicate/Confirmation.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 -"../../src/pages/TransactionDuplicate/Confirmation.tsx" "no-restricted-imports" 2 -"../../src/pages/TransactionDuplicate/Confirmation.tsx" "react-hooks/refs" 12 +"../../src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 +"../../src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx" "no-restricted-imports" 2 +"../../src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx" "react-hooks/refs" 12 "../../src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx" "@typescript-eslint/no-unsafe-type-assertion" 2 "../../src/pages/TransactionDuplicate/Review.tsx" "no-restricted-imports" 1 "../../src/pages/TransactionMerge/ConfirmationPage.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1 From f2c8fb02b208fdfe9dcce604aa3c710aac9a9aae Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Thu, 23 Jul 2026 09:51:27 +0700 Subject: [PATCH 11/12] fix eslint --- src/libs/TransactionPreviewUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 0ae3f8bfd7b5..4293009b4cb0 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -3,7 +3,7 @@ import type {CurrencyListActionsContextType} from '@hooks/useCurrencyList'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; From 30364a9eb32a3032bad084c1ce59919662992d6f Mon Sep 17 00:00:00 2001 From: huutech <20178761+huult@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:04:07 +0700 Subject: [PATCH 12/12] migrate TRANSACTION_DUPLICATE_REVIEW --- src/ROUTES.ts | 129 ++++++------------ src/SCREENS.ts | 2 +- .../ReviewDuplicatesPrimaryAction.tsx | 5 +- src/components/MoneyRequestHeader.tsx | 2 +- .../MoneyRequestHeaderPrimaryAction.tsx | 14 +- ...neyRequestReportTransactionsNavigation.tsx | 2 +- .../TransactionPreview/index.tsx | 6 +- src/hooks/useReviewDuplicatesNavigation.tsx | 34 ++--- .../ModalStackNavigators/index.tsx | 2 +- src/libs/Navigation/linkingConfig/config.ts | 5 +- src/libs/Navigation/types.ts | 22 ++- src/libs/TransactionPreviewUtils.ts | 16 +-- .../DynamicConfirmationPage.tsx | 4 +- .../DynamicReviewBillablePage.tsx | 6 +- .../DynamicReviewCategoryPage.tsx | 6 +- .../DynamicReviewDescriptionPage.tsx | 11 +- .../DynamicReviewMerchantPage.tsx | 6 +- .../{Review.tsx => DynamicReviewPage.tsx} | 40 +++--- .../DynamicReviewReimbursablePage.tsx | 11 +- .../DynamicReviewTagPage.tsx | 6 +- .../DynamicReviewTaxCodePage.tsx | 6 +- .../MoneyRequestReportPreview.stories.tsx | 2 +- .../TransactionPreviewContent.stories.tsx | 2 +- 23 files changed, 145 insertions(+), 194 deletions(-) rename src/pages/TransactionDuplicate/{Review.tsx => DynamicReviewPage.tsx} (91%) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index c0b926bdc86a..15679801ca90 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1125,102 +1125,64 @@ const DYNAMIC_ROUTES = { path: 'initial-list-value', entryScreens: [SCREENS.WORKSPACE.REPORT_FIELDS_CREATE], }, + TRANSACTION_DUPLICATE_REVIEW: { + // `reportID` is carried as the dynamic route's own path param (not inherited from the entry + // screen) because this modal can be opened from within another already-open RHP (e.g. the + // Expense Report screen). In that case react-navigation pushes this route as a sibling inside + // the same shared RightModalNavigator stack instead of replacing the underlying full-screen + // route, so deriving reportID from "whatever screen is underneath" would pick up the wrong + // report (the Expense Report's reportID, not this transaction thread's). + path: 'duplicates/review/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `duplicates/review/${reportID}` as const, + }, + // These 7 sibling routes (and TRANSACTION_DUPLICATE_CONFIRMATION below) each carry their own + // `:reportID` path param for the same reason as TRANSACTION_DUPLICATE_REVIEW above: this wizard + // can be entered directly (skipping the review list) from a "Keep this one" quick-action on a + // duplicate preview, which is itself an already-open RHP. Deriving reportID from "whatever's + // beneath" would pick up that preview screen's own reportID instead of this transaction's. TRANSACTION_DUPLICATE_CONFIRMATION: { - path: 'confirm', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - ], + path: 'confirm/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `confirm/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_BILLABLE: { - path: 'billable', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - ], + path: 'billable/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `billable/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE: { - path: 'reimbursable', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - ], + path: 'reimbursable/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `reimbursable/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION: { - path: 'transaction-duplicate-description', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - ], + path: 'transaction-duplicate-description/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `transaction-duplicate-description/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_TAX_CODE: { - path: 'tax-code', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - ], + path: 'tax-code/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `tax-code/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_TAG: { - path: 'transaction-duplicate-tag', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - ], + path: 'transaction-duplicate-tag/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `transaction-duplicate-tag/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_CATEGORY: { - path: 'category', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - ], + // 'category/:reportID' would collide with WORKSPACE_CATEGORY_SETTINGS's 'category/:categoryName' + // (same segment shape) — the suffix matcher picks whichever is declared first, so this must use + // a disambiguated name, same as TAG/DESCRIPTION below. + path: 'transaction-duplicate-category/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `transaction-duplicate-category/${reportID}` as const, }, TRANSACTION_DUPLICATE_REVIEW_MERCHANT: { - path: 'merchant', - entryScreens: [ - SCREENS.TRANSACTION_DUPLICATE.REVIEW, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE, - SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE, - ], + path: 'merchant/:reportID', + entryScreens: ['*'], + getRoute: (reportID: string) => `merchant/${reportID}` as const, }, } as const satisfies DynamicRoutes; @@ -3634,11 +3596,6 @@ const ROUTES = { }, }, - TRANSACTION_DUPLICATE_REVIEW_PAGE: { - route: 'r/:threadReportID/duplicates/review', - - getRoute: (threadReportID: string | undefined, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review` as const, backTo), - }, MERGE_TRANSACTION_LIST_PAGE: { route: 'merge/:transactionID', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 37ca1d15a932..5c8e9fa72818 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -381,7 +381,7 @@ const SCREENS = { }, TRANSACTION_DUPLICATE: { - REVIEW: 'Transaction_Duplicate_Review', + DYNAMIC_REVIEW: 'Dynamic_Transaction_Duplicate_Review', DYNAMIC_MERCHANT: 'Dynamic_Transaction_Duplicate_Merchant', DYNAMIC_CATEGORY: 'Dynamic_Transaction_Duplicate_Category', DYNAMIC_TAG: 'Dynamic_Transaction_Duplicate_Tag', diff --git a/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx b/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx index 03cd0ed794a9..cacc56bb234d 100644 --- a/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx +++ b/src/components/MoneyReportHeaderPrimaryAction/ReviewDuplicatesPrimaryAction.tsx @@ -7,6 +7,7 @@ import useTransactionsAndViolationsForReport from '@hooks/useTransactionsAndViol import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; import {getThreadReportIDsForTransactions} from '@libs/MoneyRequestReportUtils'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import {getIOUActionForReportID} from '@libs/ReportActionsUtils'; import {isDuplicate} from '@libs/TransactionUtils'; @@ -14,7 +15,7 @@ import {isDuplicate} from '@libs/TransactionUtils'; import {createTransactionThreadReport} from '@userActions/Report'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import {personalDetailsLoginSelector} from '@src/selectors/PersonalDetails'; import React from 'react'; @@ -75,7 +76,7 @@ function ReviewDuplicatesPrimaryAction({reportID, chatReportID}: SimpleActionPro } } if (threadID) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(threadID)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW.getRoute(threadID))); } }} /> diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index def715741ef2..0dadca3f4edf 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -98,7 +98,7 @@ function MoneyRequestHeader({reportID: reportIDProp, onBackButtonPress}: MoneyRe const reportID = report?.reportID; const isReportInRHP = route.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT; - const isFromReviewDuplicates = !!route.params.backTo?.replaceAll(/\?.*/g, '').endsWith('/duplicates/review'); + const isFromReviewDuplicates = !!route.params.backTo && /\/duplicates\/review\/[^/]+$/.test(route.params.backTo.replaceAll(/\?.*/g, '')); const shouldDisplayTransactionNavigation = !!(reportID && isReportInRHP); const shouldOpenParentReportInCurrentTab = !isSelfDM(parentReport); const shouldDisplayButtonsInSeparateLine = useShouldDisplayButtonsInSeparateLine() && (wideRHPRouteKeys.length === 0 || isSmallScreenWidth); diff --git a/src/components/MoneyRequestHeaderPrimaryAction.tsx b/src/components/MoneyRequestHeaderPrimaryAction.tsx index f85b8dde6339..5759a9ea1739 100644 --- a/src/components/MoneyRequestHeaderPrimaryAction.tsx +++ b/src/components/MoneyRequestHeaderPrimaryAction.tsx @@ -10,6 +10,7 @@ import useTransactionViolations from '@hooks/useTransactionViolations'; import {markRejectViolationAsResolved} from '@libs/actions/IOU/RejectMoneyRequest'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; +import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; import type {ReportsSplitNavigatorParamList, RightModalNavigatorParamList} from '@libs/Navigation/types'; @@ -23,7 +24,7 @@ import {markAsCash as markAsCashAction} from '@userActions/Transaction'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import {useRoute} from '@react-navigation/native'; @@ -59,7 +60,7 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc const shouldUseDesktopLayout = !useShouldDisplayButtonsInSeparateLine(); const isNarrowButton = shouldUseDesktopLayout || (wideRHPRouteKeys.length > 0 && !isSmallScreenWidth); const {isOffline} = useNetwork(); - const isFromReviewDuplicates = !!route.params.backTo?.replaceAll(/\?.*/g, '').endsWith('/duplicates/review'); + const isFromReviewDuplicates = !!route.params.backTo && /\/duplicates\/review\/[^/]+$/.test(route.params.backTo.replaceAll(/\?.*/g, '')); // Per-key Onyx subscriptions const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); @@ -126,7 +127,7 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc if (!reportID) { return; } - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(reportID, Navigation.getReportRHPActiveRoute())); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW.getRoute(reportID))); }} /> ); @@ -143,7 +144,12 @@ function MoneyRequestHeaderPrimaryAction({reportID}: MoneyRequestHeaderPrimaryAc } Navigation.navigate( getReviewNavigationRoute( - Navigation.getActiveRoute(), + // `isFromReviewDuplicates` guarantees `route.params.backTo` is already the + // duplicates-review screen's own URL. We can't use `Navigation.getActiveRoute()` + // here because it would be *this* screen's URL (e.g. a duplicate preview opened + // via SEARCH_REPORT), which isn't a valid entry screen for the merchant/category/etc + // sibling routes below. + route.params.backTo ?? Navigation.getActiveRoute(), reportID, transaction, removeSettledAndApprovedTransactions( diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionsNavigation.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionsNavigation.tsx index 144546c0dc3f..3a784441ae65 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionsNavigation.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionsNavigation.tsx @@ -113,7 +113,7 @@ function MoneyRequestReportTransactionsNavigation({currentTransactionID, isFromR useEffect(() => { return () => { const focusedRoute = findFocusedRoute(navigationRef.getRootState()); - if (focusedRoute?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT || focusedRoute?.name === SCREENS.TRANSACTION_DUPLICATE.REVIEW) { + if (focusedRoute?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT || focusedRoute?.name === SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW) { return; } clearActiveTransactionIDs(); diff --git a/src/components/ReportActionItem/TransactionPreview/index.tsx b/src/components/ReportActionItem/TransactionPreview/index.tsx index 41c5f4c2e988..b1850100660e 100644 --- a/src/components/ReportActionItem/TransactionPreview/index.tsx +++ b/src/components/ReportActionItem/TransactionPreview/index.tsx @@ -46,7 +46,7 @@ function TransactionPreview(props: TransactionPreviewProps) { const {anchor: contextMenuAnchorRef, shouldDisplayContextMenu, originalReportID} = useShowContextMenuState(); const {checkIfContextMenuActive} = useShowContextMenuActions(); - const route = useRoute>(); + const route = useRoute>(); const isMoneyRequestAction = isMoneyRequestActionReportActionsUtils(action); const transactionID = transactionIDFromProps ?? (isMoneyRequestAction ? getOriginalMessage(action)?.IOUTransactionID : undefined); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -86,7 +86,7 @@ function TransactionPreview(props: TransactionPreviewProps) { }, [chatReportID]); const navigateToReviewFields = () => - Navigation.navigate(getReviewNavigationRoute(Navigation.getActiveRoute(), route.params?.threadReportID, transaction, duplicates, policy, policyCategories, policyTags ?? {}, report)); + Navigation.navigate(getReviewNavigationRoute(Navigation.getActiveRoute(), route.params?.reportID, transaction, duplicates, policy, policyCategories, policyTags ?? {}, report)); const transactionPreview = transaction; @@ -97,7 +97,7 @@ function TransactionPreview(props: TransactionPreviewProps) { const transactionRawAmount = (Number(transaction?.modifiedAmount) || transaction?.amount) ?? 0; const shouldDisableOnPress = isBillSplit && isEmptyObject(transaction); - const isReviewDuplicateTransactionPage = route.name === SCREENS.TRANSACTION_DUPLICATE.REVIEW; + const isReviewDuplicateTransactionPage = route.name === SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW; if (onPreviewPressed) { return ( diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index 7149d93e42fa..3d0adfd7cc13 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -2,7 +2,7 @@ import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/crea import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; -import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES'; +import {DYNAMIC_ROUTES} from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; import {useEffect, useMemo, useState} from 'react'; @@ -31,32 +31,32 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S const goBack = () => { switch (prevScreen) { case 'merchant': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.getRoute(threadReportID))); break; case 'category': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.getRoute(threadReportID))); break; case 'tag': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.getRoute(threadReportID))); break; case 'description': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.getRoute(threadReportID))); break; case 'taxCode': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.getRoute(threadReportID))); break; case 'reimbursable': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.getRoute(threadReportID))); break; case 'billable': - Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.getRoute(threadReportID))); break; default: if (backTo) { Navigation.goBack(backTo as Route); return; } - Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(threadReportID)); + Navigation.goBack(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW.getRoute(threadReportID))); break; } }; @@ -64,28 +64,28 @@ function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: S const navigateToNextScreen = () => { switch (nextScreen) { case 'merchant': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.getRoute(threadReportID))); break; case 'category': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.getRoute(threadReportID))); break; case 'tag': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.getRoute(threadReportID))); break; case 'description': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.getRoute(threadReportID))); break; case 'taxCode': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.getRoute(threadReportID))); break; case 'reimbursable': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.getRoute(threadReportID))); break; case 'billable': - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.getRoute(threadReportID))); break; default: - Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path)); + Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.getRoute(threadReportID))); break; } }; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 7ae11f644b60..870e685f0312 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -1168,7 +1168,7 @@ const ReferralModalStackNavigator = createModalStackNavigator({ - [SCREENS.TRANSACTION_DUPLICATE.REVIEW]: () => require('../../../../pages/TransactionDuplicate/Review').default, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewMerchantPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewCategoryPage').default, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: () => require('../../../../pages/TransactionDuplicate/DynamicReviewTagPage').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f3b81596de4a..2dd332fd2137 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1838,10 +1838,7 @@ const config: LinkingOptions['config'] = { }, [SCREENS.RIGHT_MODAL.TRANSACTION_DUPLICATE]: { screens: { - [SCREENS.TRANSACTION_DUPLICATE.REVIEW]: { - path: ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.route, - exact: true, - }, + [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path, [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 6c0d618c5e2b..225b1c9ca23c 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2550,48 +2550,46 @@ type PrivateNotesNavigatorParamList = { }; type TransactionDuplicateNavigatorParamList = { - [SCREENS.TRANSACTION_DUPLICATE.REVIEW]: { - threadReportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW]: { + reportID: string; }; [SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_MERCHANT]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_CATEGORY]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_TAG]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_DESCRIPTION]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_TAX_CODE]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_BILLABLE]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_REIMBURSABLE]: { - threadReportID: string; + reportID: 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.TRANSACTION_DUPLICATE.DYNAMIC_CONFIRMATION]: { - threadReportID: string; + reportID: string; }; }; diff --git a/src/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index 4293009b4cb0..fe22cfde1635 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -95,28 +95,28 @@ const getReviewNavigationRoute = ( ); if (comparisonResult.change.merchant) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.getRoute(threadReportID), backTo); } if (comparisonResult.change.category) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.getRoute(threadReportID), backTo); } if (comparisonResult.change.tag) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.getRoute(threadReportID), backTo); } if (comparisonResult.change.description) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.getRoute(threadReportID), backTo); } if (comparisonResult.change.taxCode) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE.getRoute(threadReportID), backTo); } if (comparisonResult.change.billable) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.getRoute(threadReportID), backTo); } if (comparisonResult.change.reimbursable) { - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.getRoute(threadReportID), backTo); } - return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.path, backTo); + return createDynamicRoute(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION.getRoute(threadReportID), backTo); }; type TranslationPathOrText = { diff --git a/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx b/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx index 37c30eb2a0bc..74413b680ef1 100644 --- a/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx +++ b/src/pages/TransactionDuplicate/DynamicConfirmationPage.tsx @@ -55,7 +55,7 @@ function DynamicConfirmationPage() { const [reviewDuplicates, reviewDuplicatesResult] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [duplicatedTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(reviewDuplicates?.transactionID)}`); const newTransaction = useMemo(() => TransactionUtils.buildNewTransactionAfterReviewingDuplicates(reviewDuplicates, duplicatedTransaction), [duplicatedTransaction, reviewDuplicates]); - const [report, reportResult] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report, reportResult] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = TransactionUtils.getTransactionID(report); const [allTransactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); const [reviewDuplicatesReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reviewDuplicates?.reportID}`); @@ -184,7 +184,7 @@ function DynamicConfirmationPage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> diff --git a/src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx b/src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx index c30fb17d142c..ff4a84651e20 100644 --- a/src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewBillablePage.tsx @@ -30,7 +30,7 @@ function DynamicReviewBillablePage() { const route = useRoute>(); const {translate} = useLocalize(); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE.path); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -48,7 +48,7 @@ function DynamicReviewBillablePage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'billable', route.params.threadReportID, route.params.backTo); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'billable', route.params.reportID, route.params.backTo); const options = useMemo( () => compareResult.change.billable?.map((billable) => ({ @@ -69,7 +69,7 @@ function DynamicReviewBillablePage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx b/src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx index e8f7546d9b13..0555df16db40 100644 --- a/src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewCategoryPage.tsx @@ -31,7 +31,7 @@ function DynamicReviewCategoryPage() { const route = useRoute>(); const {translate} = useLocalize(); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY.path); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -48,7 +48,7 @@ function DynamicReviewCategoryPage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'category', route.params.threadReportID, route.params.backTo); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'category', route.params.reportID, route.params.backTo); const options = useMemo( () => compareResult.change.category?.map((category) => @@ -73,7 +73,7 @@ function DynamicReviewCategoryPage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx b/src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx index abe3f0eba7c2..247626fbc318 100644 --- a/src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewDescriptionPage.tsx @@ -32,7 +32,7 @@ function DynamicReviewDescriptionPage() { const route = useRoute>(); const {translate} = useLocalize(); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION.path); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -49,12 +49,7 @@ function DynamicReviewDescriptionPage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'description', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'description', route.params.reportID, route.params.backTo); const options = useMemo( () => compareResult.change.description?.map((description) => @@ -78,7 +73,7 @@ function DynamicReviewDescriptionPage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx b/src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx index 991ee359c5d4..067495ea62a5 100644 --- a/src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewMerchantPage.tsx @@ -30,7 +30,7 @@ function DynamicReviewMerchantPage() { const route = useRoute>(); const {translate} = useLocalize(); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT.path); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -47,7 +47,7 @@ function DynamicReviewMerchantPage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'merchant', route.params.threadReportID, route.params.backTo); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'merchant', route.params.reportID, route.params.backTo); const options = useMemo( () => compareResult.change.merchant?.map((merchant) => @@ -72,7 +72,7 @@ function DynamicReviewMerchantPage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/pages/TransactionDuplicate/Review.tsx b/src/pages/TransactionDuplicate/DynamicReviewPage.tsx similarity index 91% rename from src/pages/TransactionDuplicate/Review.tsx rename to src/pages/TransactionDuplicate/DynamicReviewPage.tsx index 9a7c65cb889f..5e6ebc1d09fc 100644 --- a/src/pages/TransactionDuplicate/Review.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewPage.tsx @@ -10,6 +10,7 @@ import ScrollView from '@components/ScrollView'; import Text from '@components/Text'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -32,7 +33,7 @@ import {getReviewNavigationRoute} from '@libs/TransactionPreviewUtils'; 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 {Transaction} from '@src/types/onyx'; import getEmptyArray from '@src/types/utils/getEmptyArray'; @@ -43,8 +44,9 @@ import {View} from 'react-native'; import DuplicateTransactionsList from './DuplicateTransactionsList'; -function TransactionDuplicateReview() { - const route = useRoute>(); +function DynamicReviewPage() { + const route = useRoute>(); + const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW.path); const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -52,11 +54,11 @@ function TransactionDuplicateReview() { const {isBetaEnabled} = usePermissions(); const {isOffline} = useNetwork(); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); - const [hasReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${route.params.threadReportID}`, {selector: Boolean}); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); + const [hasReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${route.params.reportID}`, {selector: Boolean}); const [parentReportLoadingState] = useOnyx(`${ONYXKEYS.COLLECTION.RAM_ONLY_REPORT_LOADING_STATE}${report?.parentReportID}`); const [deleteTransactionNavigateBackUrl] = useOnyx(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL); - const [reportLoadingState] = useOnyx(`${ONYXKEYS.COLLECTION.RAM_ONLY_REPORT_LOADING_STATE}${route.params.threadReportID}`); + const [reportLoadingState] = useOnyx(`${ONYXKEYS.COLLECTION.RAM_ONLY_REPORT_LOADING_STATE}${route.params.reportID}`); const [expenseReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`); const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); const [allTransactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION); @@ -108,23 +110,23 @@ function TransactionDuplicateReview() { const isLoadingPage = (!report?.reportID && !hasLoadedThreadReportActions && !isThreadReportDeletedForReview) || (!reportAction?.reportActionID && !hasLoadedParentReportActions && !wasParentActionDeleted && !isThreadReportDeletedForReview); - const isDeleteNavigateBackToThisReview = doesDeleteNavigateBackUrlIncludeSpecificDuplicatesReview(deleteTransactionNavigateBackUrl, route.params.threadReportID); + const isDeleteNavigateBackToThisReview = doesDeleteNavigateBackUrlIncludeSpecificDuplicatesReview(deleteTransactionNavigateBackUrl, route.params.reportID); const isNavigatingBackToDeletedReview = !!deleteTransactionNavigateBackUrl && !(isDeleteNavigateBackToThisReview && wasTransactionDeleted); const shouldShowNotFound = !isNavigatingBackToDeletedReview && (wasTransactionDeleted || (!isLoadingPage && !transactionID)); const reasonAttributes: SkeletonSpanReasonAttributes = { - context: 'TransactionDuplicateReview', + context: 'DynamicReviewPage', hasLoadedThreadReportActions, hasLoadedParentReportActions, }; useEffect(() => { - if (!route.params.threadReportID || report?.reportID) { + if (!route.params.reportID || report?.reportID) { return; } - openReport({reportID: route.params.threadReportID, introSelected, betas, hasReportActions}); - }, [report?.reportID, route.params.threadReportID, introSelected, betas, hasReportActions]); + openReport({reportID: route.params.reportID, introSelected, betas, hasReportActions}); + }, [report?.reportID, route.params.reportID, introSelected, betas, hasReportActions]); useEffect(() => { if (!transactionID) { @@ -199,7 +201,7 @@ function TransactionDuplicateReview() { Navigation.navigate( getReviewNavigationRoute( Navigation.getActiveRoute(), - route.params.threadReportID, + route.params.reportID, selectedTransaction, transactions.filter((transaction) => transaction.transactionID !== selectedTransaction.transactionID), selectedTransactionPolicy, @@ -212,7 +214,7 @@ function TransactionDuplicateReview() { if (isLoadingPage) { return ( - + + Navigation.goBack(route.params.backTo)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> Navigation.goBack(route.params.backTo)} + onButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> ); @@ -246,14 +248,14 @@ function TransactionDuplicateReview() { return ( Navigation.goBack(route.params.backTo)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> >(); const {translate} = useLocalize(); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE.path); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -47,12 +47,7 @@ function DynamicReviewReimbursablePage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation( - Object.keys(compareResult.change ?? {}), - 'reimbursable', - route.params.threadReportID, - route.params.backTo, - ); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'reimbursable', route.params.reportID, route.params.backTo); const options = useMemo( () => compareResult.change.reimbursable?.map((reimbursable) => ({ @@ -73,7 +68,7 @@ function DynamicReviewReimbursablePage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx b/src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx index 6587c8d3003c..ae44438a43b6 100644 --- a/src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewTagPage.tsx @@ -31,7 +31,7 @@ function DynamicReviewTagPage() { const route = useRoute>(); const {translate} = useLocalize(); const backPath = useDynamicBackPath(DYNAMIC_ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG.path); - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(report); const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); @@ -48,7 +48,7 @@ function DynamicReviewTagPage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'tag', route.params.threadReportID, route.params.backTo); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'tag', route.params.reportID, route.params.backTo); const options = useMemo( () => compareResult.change.tag?.map((tag) => @@ -72,7 +72,7 @@ function DynamicReviewTagPage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx b/src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx index cdce300ddc5c..4e2f0763bf61 100644 --- a/src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx +++ b/src/pages/TransactionDuplicate/DynamicReviewTaxCodePage.tsx @@ -38,7 +38,7 @@ function DynamicReviewTaxCodePage() { const [reviewDuplicates] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reviewDuplicates?.reportID}`); const policy = usePolicy(report?.policyID); - const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); + const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`); const transactionID = getTransactionID(transactionThreadReport); const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); const [transactionViolations] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`); @@ -53,7 +53,7 @@ function DynamicReviewTaxCodePage() { const compareResult = compareDuplicateTransactionFields(policyTags ?? {}, transaction, allDuplicates, reviewDuplicatesReport, reviewDuplicates?.transactionID, policy, policyCategories); const stepNames = Object.keys(compareResult.change ?? {}).map((key, index) => (index + 1).toString()); - const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'taxCode', route.params.threadReportID, route.params.backTo); + const {currentScreenIndex, navigateToNextScreen} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'taxCode', route.params.reportID, route.params.backTo); const options = useMemo( () => @@ -90,7 +90,7 @@ function DynamicReviewTaxCodePage() { Navigation.goBack(backPath)} + onBackButtonPress={() => Navigation.goBack(backPath, {compareParams: false})} /> stepNames={stepNames} diff --git a/src/stories/MoneyRequestReportPreview.stories.tsx b/src/stories/MoneyRequestReportPreview.stories.tsx index 42ee5313a4a3..512d635f9034 100755 --- a/src/stories/MoneyRequestReportPreview.stories.tsx +++ b/src/stories/MoneyRequestReportPreview.stories.tsx @@ -153,7 +153,7 @@ function Template(props: MoneyRequestReportPreviewContentProps, {parameters}: {p areThereDuplicates={false} sessionAccountID={11111111} walletTermsErrors={undefined} - routeName={SCREENS.TRANSACTION_DUPLICATE.REVIEW} + routeName={SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW} shouldHideOnDelete={false} transactionPreviewWidth={reportPreviewStyles.transactionPreviewCarouselStyle.width} containerStyles={transactionPreviewContainerStyles} diff --git a/src/stories/TransactionPreviewContent.stories.tsx b/src/stories/TransactionPreviewContent.stories.tsx index ebe292f4fc29..fce7bd86897e 100644 --- a/src/stories/TransactionPreviewContent.stories.tsx +++ b/src/stories/TransactionPreviewContent.stories.tsx @@ -118,7 +118,7 @@ const story: Meta = { areThereDuplicates: false, sessionAccountID: 11111111, walletTermsErrors: undefined, - routeName: SCREENS.TRANSACTION_DUPLICATE.REVIEW, + routeName: SCREENS.TRANSACTION_DUPLICATE.DYNAMIC_REVIEW, shouldHideOnDelete: false, transactionPreviewWidth: 303, },