diff --git a/src/ROUTES.ts b/src/ROUTES.ts index f72744607f0f..0568272691c5 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -299,7 +299,7 @@ const ROUTES = { }, REPORT_WITH_ID_DETAILS_EXPORT: { route: 'r/:reportID/details/export/:connectionName', - getRoute: (reportID: string, connectionName: ConnectionName) => `r/${reportID}/details/export/${connectionName}` as const, + getRoute: (reportID: string, connectionName: ConnectionName, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/details/export/${connectionName}` as const, backTo), }, REPORT_SETTINGS: { route: 'r/:reportID/settings', @@ -1045,39 +1045,39 @@ const ROUTES = { }, TRANSACTION_DUPLICATE_REVIEW_PAGE: { route: 'r/:threadReportID/duplicates/review', - getRoute: (threadReportID: string) => `r/${threadReportID}/duplicates/review` as const, + getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/review` as const, backTo), }, TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE: { route: 'r/:threadReportID/duplicates/review/merchant', - getRoute: (threadReportID: string) => `r/${threadReportID}/duplicates/review/merchant` as const, + 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) => `r/${threadReportID}/duplicates/review/category` as const, + 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) => `r/${threadReportID}/duplicates/review/tag` as const, + 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) => `r/${threadReportID}/duplicates/review/tax-code` as const, + 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) => `r/${threadReportID}/duplicates/review/description` as const, + 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) => `r/${threadReportID}/duplicates/review/reimbursable` as const, + 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) => `r/${threadReportID}/duplicates/review/billable` as const, + 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) => `r/${threadReportID}/duplicates/confirm` as const, + getRoute: (threadReportID: string, backTo?: string) => getUrlWithBackToParam(`r/${threadReportID}/duplicates/confirm` as const, backTo), }, POLICY_ACCOUNTING_XERO_IMPORT: { route: 'settings/workspaces/:policyID/accounting/xero/import', diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 3d06deea9627..4a789d3e5df9 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -153,7 +153,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, shouldUseNarrow text={translate('iou.reviewDuplicates')} style={[styles.p0, styles.ml2]} onPress={() => { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(report.reportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(report.reportID, Navigation.getReportRHPActiveRoute())); }} /> )} @@ -177,7 +177,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, shouldUseNarrow text={translate('iou.reviewDuplicates')} style={[styles.w100, styles.pr0]} onPress={() => { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(report.reportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(report.reportID, Navigation.getReportRHPActiveRoute())); }} /> diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 6ab1c0937278..eda2bfa85de0 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -283,24 +283,25 @@ function MoneyRequestPreviewContent({ ); const navigateToReviewFields = () => { + const backTo = route.params.backTo; const comparisonResult = TransactionUtils.compareDuplicateTransactionFields(reviewingTransactionID); Transaction.setReviewDuplicatesKey({...comparisonResult.keep, duplicates, transactionID: transaction?.transactionID ?? ''}); if ('merchant' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(route.params?.threadReportID, backTo)); } else if ('category' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(route.params?.threadReportID, backTo)); } else if ('tag' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(route.params?.threadReportID, backTo)); } else if ('description' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(route.params?.threadReportID, backTo)); } else if ('taxCode' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(route.params?.threadReportID, backTo)); } else if ('billable' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(route.params?.threadReportID, backTo)); } else if ('reimbursable' in comparisonResult.change) { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(route.params?.threadReportID, backTo)); } else { - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.getRoute(route.params?.threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.getRoute(route.params?.threadReportID, backTo)); } }; diff --git a/src/hooks/useReviewDuplicatesNavigation.tsx b/src/hooks/useReviewDuplicatesNavigation.tsx index e14731024c17..de905647e440 100644 --- a/src/hooks/useReviewDuplicatesNavigation.tsx +++ b/src/hooks/useReviewDuplicatesNavigation.tsx @@ -3,50 +3,86 @@ import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; -type StepName = 'description' | 'merchant' | 'category' | 'billable' | 'tag' | 'taxCode' | 'reimbursable'; +type StepName = 'description' | 'merchant' | 'category' | 'billable' | 'tag' | 'taxCode' | 'reimbursable' | 'confirmation'; -function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: StepName, threadReportID: string) { - const [nextScreen, setNextScreen] = useState(currentScreenName); +function useReviewDuplicatesNavigation(stepNames: string[], currentScreenName: StepName, threadReportID: string, backTo?: string) { + const [nextScreen, setNextScreen] = useState(); + const [prevScreen, setPrevScreen] = useState(); const [currentScreenIndex, setCurrentScreenIndex] = useState(0); const intersection = useMemo(() => CONST.REVIEW_DUPLICATES_ORDER.filter((element) => stepNames.includes(element)), [stepNames]); useEffect(() => { + if (currentScreenName === 'confirmation') { + setPrevScreen(intersection[intersection.length - 1] ?? ''); + return; + } const currentIndex = intersection.indexOf(currentScreenName); const nextScreenIndex = currentIndex + 1; + const prevScreenIndex = currentIndex - 1; setCurrentScreenIndex(currentIndex); setNextScreen(intersection[nextScreenIndex] ?? ''); + setPrevScreen(intersection[prevScreenIndex] ?? ''); }, [currentScreenName, intersection]); + const goBack = () => { + switch (prevScreen) { + case 'merchant': + 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)); + break; + case 'tag': + 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)); + break; + case 'taxCode': + 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)); + break; + case 'billable': + Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID, backTo)); + break; + default: + Navigation.goBack(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(threadReportID, backTo)); + break; + } + }; + const navigateToNextScreen = () => { switch (nextScreen) { case 'merchant': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_MERCHANT_PAGE.getRoute(threadReportID, backTo)); break; case 'category': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_CATEGORY_PAGE.getRoute(threadReportID, backTo)); break; case 'tag': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAG_PAGE.getRoute(threadReportID, backTo)); break; case 'description': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_DESCRIPTION_PAGE.getRoute(threadReportID, backTo)); break; case 'taxCode': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_TAX_CODE_PAGE.getRoute(threadReportID)); + 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)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_REIMBURSABLE_PAGE.getRoute(threadReportID, backTo)); break; case 'billable': - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_BILLABLE_PAGE.getRoute(threadReportID, backTo)); break; default: - Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.getRoute(threadReportID)); + Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_CONFIRMATION_PAGE.getRoute(threadReportID, backTo)); break; } }; - return {navigateToNextScreen, currentScreenIndex}; + return {navigateToNextScreen, goBack, currentScreenIndex}; } export default useReviewDuplicatesNavigation; diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 4b5d9299e40a..4736364b86e2 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -761,6 +761,7 @@ type ReportDetailsNavigatorParamList = { reportID: string; policyID: string; connectionName: ConnectionName; + backTo?: Routes; }; }; @@ -1086,27 +1087,35 @@ type PrivateNotesNavigatorParamList = { type TransactionDuplicateNavigatorParamList = { [SCREENS.TRANSACTION_DUPLICATE.REVIEW]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.MERCHANT]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.CATEGORY]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.TAG]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.DESCRIPTION]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.TAX_CODE]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.BILLABLE]: { threadReportID: string; + backTo?: Routes; }; [SCREENS.TRANSACTION_DUPLICATE.REIMBURSABLE]: { threadReportID: string; + backTo?: Routes; }; }; diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 82a6a28c30f1..29ead7a7fef3 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -409,7 +409,7 @@ function ReportDetailsPage({policies, report, session, personalDetails, route}: icon: Expensicons.Upload, isAnonymousAction: false, action: () => { - Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS_EXPORT.getRoute(report?.reportID ?? '', connectedIntegration)); + Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS_EXPORT.getRoute(report?.reportID ?? '', connectedIntegration, backTo)); }, }); } diff --git a/src/pages/TransactionDuplicate/Confirmation.tsx b/src/pages/TransactionDuplicate/Confirmation.tsx index 96b32006675e..fa96190530fe 100644 --- a/src/pages/TransactionDuplicate/Confirmation.tsx +++ b/src/pages/TransactionDuplicate/Confirmation.tsx @@ -15,6 +15,7 @@ import ScrollView from '@components/ScrollView'; import {ShowContextMenuContext} from '@components/ShowContextMenuContext'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; +import useReviewDuplicatesNavigation from '@hooks/useReviewDuplicatesNavigation'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import type {TransactionDuplicateNavigatorParamList} from '@libs/Navigation/types'; @@ -36,6 +37,9 @@ function Confirmation() { const route = useRoute>(); const [reviewDuplicates, reviewDuplicatesResult] = useOnyx(ONYXKEYS.REVIEW_DUPLICATES); const transaction = useMemo(() => TransactionUtils.buildNewTransactionAfterReviewingDuplicates(reviewDuplicates), [reviewDuplicates]); + const transactionID = TransactionUtils.getTransactionID(route.params.threadReportID ?? ''); + const compareResult = TransactionUtils.compareDuplicateTransactionFields(transactionID); + const {goBack} = useReviewDuplicatesNavigation(Object.keys(compareResult.change ?? {}), 'confirmation', route.params.threadReportID, route.params.backTo); const [report, reportResult] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${route.params.threadReportID}`); const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transaction?.reportID}`); const reportAction = Object.values(reportActions ?? {}).find( @@ -82,7 +86,10 @@ function Confirmation() { {({safeAreaPaddingBottomStyle}) => ( - + - + Navigation.goBack(route.params.backTo)} + />