From 24fcb4a86a7bf2cc923ee250678c5ce41d827a57 Mon Sep 17 00:00:00 2001 From: daledah Date: Mon, 25 Nov 2024 21:07:35 +0700 Subject: [PATCH 01/10] fix: back button returns to expense report after submitting track expense --- src/libs/Navigation/Navigation.ts | 15 +++++++++++++++ src/libs/actions/IOU.ts | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index d54668bf3f69..ae2026a8bf79 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -433,6 +433,20 @@ function removeScreenFromNavigationState(screen: Screen) { }); } +function removeScreenByKey(key: string) { + isNavigationReady().then(() => { + navigationRef.dispatch((state) => { + const routes = state.routes?.filter((item) => item.key !== key); + + return CommonActions.reset({ + ...state, + routes, + index: routes.length < state.routes.length ? state.index - 1 : state.index, + }); + }); + }); +} + export default { setShouldPopAllStateOnUP, navigate, @@ -458,6 +472,7 @@ export default { setNavigationActionToMicrotaskQueue, getTopMostCentralPaneRouteFromRootState, removeScreenFromNavigationState, + removeScreenByKey, }; export {navigationRef}; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 10eee66428e8..96830bac09f3 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -40,7 +40,7 @@ import * as IOUUtils from '@libs/IOUUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import * as Localize from '@libs/Localize'; import isSearchTopmostCentralPane from '@libs/Navigation/isSearchTopmostCentralPane'; -import Navigation from '@libs/Navigation/Navigation'; +import Navigation, {navigationRef} from '@libs/Navigation/Navigation'; import * as NextStepUtils from '@libs/NextStepUtils'; import {rand64} from '@libs/NumberUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -60,6 +60,7 @@ import type {IOUAction, IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type {Attendee, Participant, Split} from '@src/types/onyx/IOU'; import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; @@ -3700,6 +3701,14 @@ function requestMoney(requestMoneyInformation: RequestMoneyInformation) { } InteractionManager.runAfterInteractions(() => TransactionEdit.removeDraftTransaction(CONST.IOU.OPTIMISTIC_TRANSACTION_ID)); + + const trackReport = navigationRef + .getRootState() + .routes.find((r) => r.name === SCREENS.REPORT && !!r.params && 'reportID' in r.params && r.params.reportID === linkedTrackedExpenseReportAction?.childReportID); + if (trackReport?.key) { + Navigation.removeScreenByKey(trackReport.key); + } + Navigation.dismissModal(isSearchTopmostCentralPane() ? undefined : activeReportID); if (activeReportID) { Report.notifyNewAction(activeReportID, payeeAccountID); From 9a9ed9a03a5f37fe6313ed460cee7720b78c7828 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 4 Dec 2024 11:54:44 +0700 Subject: [PATCH 02/10] fix: handle back button on chrome --- src/libs/actions/IOU.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 96830bac09f3..f5032ebfe5da 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3702,14 +3702,15 @@ function requestMoney(requestMoneyInformation: RequestMoneyInformation) { InteractionManager.runAfterInteractions(() => TransactionEdit.removeDraftTransaction(CONST.IOU.OPTIMISTIC_TRANSACTION_ID)); + Navigation.dismissModal(isSearchTopmostCentralPane() ? undefined : activeReportID); + const trackReport = navigationRef .getRootState() .routes.find((r) => r.name === SCREENS.REPORT && !!r.params && 'reportID' in r.params && r.params.reportID === linkedTrackedExpenseReportAction?.childReportID); if (trackReport?.key) { - Navigation.removeScreenByKey(trackReport.key); + Navigation.isNavigationReady().then(() => Navigation.removeScreenByKey(trackReport.key)); } - Navigation.dismissModal(isSearchTopmostCentralPane() ? undefined : activeReportID); if (activeReportID) { Report.notifyNewAction(activeReportID, payeeAccountID); } From 430609a848f113c9d598de747017106cc54a44b8 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 4 Dec 2024 11:56:07 +0700 Subject: [PATCH 03/10] fix: IOUTest --- tests/actions/IOUTest.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 4430ec0ce052..b363de583f69 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -32,8 +32,17 @@ jest.mock('@src/libs/Navigation/Navigation', () => ({ dismissModal: jest.fn(), dismissModalWithReport: jest.fn(), goBack: jest.fn(), + removeScreenByKey: jest.fn(), })); +jest.mock('@src/libs/Navigation/navigationRef', () => ({ + getRootState: () => ({ + routes: [], + }), +})); + +jest.mock('@react-navigation/native'); + jest.mock('@src/libs/Navigation/isSearchTopmostCentralPane', () => jest.fn()); const CARLOS_EMAIL = 'cmartins@expensifail.com'; From e67221c770d765e5c4dce255c948f7c174eb882e Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 4 Dec 2024 15:07:41 +0700 Subject: [PATCH 04/10] fix: IOUTest --- src/libs/Navigation/Navigation.ts | 10 +++++++++- src/libs/actions/IOU.ts | 4 +--- tests/actions/IOUTest.ts | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index ae2026a8bf79..7e2bff9c5500 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -11,7 +11,7 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; import ROUTES, {HYBRID_APP_ROUTES} from '@src/ROUTES'; -import {PROTECTED_SCREENS} from '@src/SCREENS'; +import SCREENS, {PROTECTED_SCREENS} from '@src/SCREENS'; import type {Screen} from '@src/SCREENS'; import type {Report} from '@src/types/onyx'; import originalCloseRHPFlow from './closeRHPFlow'; @@ -419,6 +419,13 @@ function getTopMostCentralPaneRouteFromRootState() { return getTopmostCentralPaneRoute(navigationRef.getRootState() as State); } +function getPreviousTrackReport(reportID?: string) { + if (!reportID) { + return null; + } + return navigationRef.getRootState().routes.find((r) => r.name === SCREENS.REPORT && !!r.params && 'reportID' in r.params && r.params.reportID === reportID); +} + function removeScreenFromNavigationState(screen: Screen) { isNavigationReady().then(() => { navigationRef.dispatch((state) => { @@ -473,6 +480,7 @@ export default { getTopMostCentralPaneRouteFromRootState, removeScreenFromNavigationState, removeScreenByKey, + getPreviousTrackReport, }; export {navigationRef}; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f5032ebfe5da..e209eb517a05 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3704,9 +3704,7 @@ function requestMoney(requestMoneyInformation: RequestMoneyInformation) { Navigation.dismissModal(isSearchTopmostCentralPane() ? undefined : activeReportID); - const trackReport = navigationRef - .getRootState() - .routes.find((r) => r.name === SCREENS.REPORT && !!r.params && 'reportID' in r.params && r.params.reportID === linkedTrackedExpenseReportAction?.childReportID); + const trackReport = Navigation.getPreviousTrackReport(linkedTrackedExpenseReportAction?.childReportID); if (trackReport?.key) { Navigation.isNavigationReady().then(() => Navigation.removeScreenByKey(trackReport.key)); } diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index b363de583f69..427c3dac59e7 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -33,6 +33,8 @@ jest.mock('@src/libs/Navigation/Navigation', () => ({ dismissModalWithReport: jest.fn(), goBack: jest.fn(), removeScreenByKey: jest.fn(), + isNavigationReady: jest.fn(() => Promise.resolve()), + getPreviousTrackReport: jest.fn(), })); jest.mock('@src/libs/Navigation/navigationRef', () => ({ From 14f77f91190ac8c737f95745044e541ecc5ee039 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 4 Dec 2024 15:21:28 +0700 Subject: [PATCH 05/10] fix: lint --- src/libs/actions/IOU.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index e209eb517a05..31c464260ea4 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -40,7 +40,7 @@ import * as IOUUtils from '@libs/IOUUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import * as Localize from '@libs/Localize'; import isSearchTopmostCentralPane from '@libs/Navigation/isSearchTopmostCentralPane'; -import Navigation, {navigationRef} from '@libs/Navigation/Navigation'; +import Navigation from '@libs/Navigation/Navigation'; import * as NextStepUtils from '@libs/NextStepUtils'; import {rand64} from '@libs/NumberUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; @@ -60,7 +60,6 @@ import type {IOUAction, IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type {Attendee, Participant, Split} from '@src/types/onyx/IOU'; import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; From 1f8b4c6f4bf558d649d5e0e06c337a2c678d4503 Mon Sep 17 00:00:00 2001 From: daledah Date: Mon, 13 Jan 2025 17:37:27 +0700 Subject: [PATCH 06/10] fix: update removeScreenByKey --- src/libs/Navigation/Navigation.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index ef30c207e5c2..2d94e8635d82 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -450,15 +450,14 @@ function removeScreenFromNavigationState(screen: Screen) { } function removeScreenByKey(key: string) { - isNavigationReady().then(() => { - navigationRef.dispatch((state) => { - const routes = state.routes?.filter((item) => item.key !== key); - - return CommonActions.reset({ - ...state, - routes, - index: routes.length < state.routes.length ? state.index - 1 : state.index, - }); + const state = navigationRef.getRootState(); + const routes = state.routes.filter((item) => item.key !== key); + + navigationRef.current?.dispatch(() => { + return CommonActions.reset({ + ...state, + routes, + index: routes.length < state.routes.length ? state.index - 1 : state.index, }); }); } From 21c9f014995a3495d265ad891eb8df69484913a9 Mon Sep 17 00:00:00 2001 From: daledah Date: Fri, 31 Jan 2025 11:29:27 +0700 Subject: [PATCH 07/10] refactor: change functions names --- src/libs/Navigation/Navigation.ts | 6 +++--- src/libs/actions/IOU.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index d4c8b1631700..747313f6574a 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -428,11 +428,11 @@ function getTopMostCentralPaneRouteFromRootState() { return getTopmostCentralPaneRoute(navigationRef.getRootState() as State); } -function getPreviousTrackReport(reportID?: string) { +function getReportRouteByID(reportID?: string) { if (!reportID) { return null; } - return navigationRef.getRootState().routes.find((r) => r.name === SCREENS.REPORT && !!r.params && 'reportID' in r.params && r.params.reportID === reportID); + return navigationRef.getRootState().routes.find((route) => route.name === SCREENS.REPORT && !!route.params && 'reportID' in route.params && route.params.reportID === reportID); } function removeScreenFromNavigationState(screen: Screen) { @@ -488,7 +488,7 @@ export default { getTopMostCentralPaneRouteFromRootState, removeScreenFromNavigationState, removeScreenByKey, - getPreviousTrackReport, + getReportRouteByID, }; export {navigationRef}; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 32453220e8ff..5bd4698ac82e 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -4415,7 +4415,7 @@ function requestMoney(requestMoneyInformation: RequestMoneyInformation) { InteractionManager.runAfterInteractions(() => removeDraftTransaction(CONST.IOU.OPTIMISTIC_TRANSACTION_ID)); Navigation.dismissModal(isSearchTopmostCentralPane() ? undefined : activeReportID); - const trackReport = Navigation.getPreviousTrackReport(linkedTrackedExpenseReportAction?.childReportID); + const trackReport = Navigation.getReportRouteByID(linkedTrackedExpenseReportAction?.childReportID); if (trackReport?.key) { Navigation.isNavigationReady().then(() => Navigation.removeScreenByKey(trackReport.key)); } From 77ed6beb240151397e5f6fac0db6a1042f1fb070 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 12 Feb 2025 08:53:42 +0700 Subject: [PATCH 08/10] refactor: move isNavigationReady to inside removeScreenByKey --- src/libs/Navigation/Navigation.ts | 12 +++++++----- src/libs/actions/IOU.ts | 2 +- tests/actions/IOUTest.ts | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 747313f6574a..a896a18d6d72 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -453,11 +453,13 @@ function removeScreenByKey(key: string) { const state = navigationRef.getRootState(); const routes = state.routes.filter((item) => item.key !== key); - navigationRef.current?.dispatch(() => { - return CommonActions.reset({ - ...state, - routes, - index: routes.length < state.routes.length ? state.index - 1 : state.index, + isNavigationReady().then(() => { + navigationRef.current?.dispatch(() => { + return CommonActions.reset({ + ...state, + routes, + index: routes.length < state.routes.length ? state.index - 1 : state.index, + }); }); }); } diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 2f9e27b8f95f..567999a89172 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -4585,7 +4585,7 @@ function requestMoney(requestMoneyInformation: RequestMoneyInformation) { const trackReport = Navigation.getReportRouteByID(linkedTrackedExpenseReportAction?.childReportID); if (trackReport?.key) { - Navigation.isNavigationReady().then(() => Navigation.removeScreenByKey(trackReport.key)); + Navigation.removeScreenByKey(trackReport.key); } if (activeReportID) { diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 7a0ec281d9dd..955c8eb720cc 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -79,7 +79,7 @@ jest.mock('@src/libs/Navigation/Navigation', () => ({ setNavigationActionToMicrotaskQueue: jest.fn(), removeScreenByKey: jest.fn(), isNavigationReady: jest.fn(() => Promise.resolve()), - getPreviousTrackReport: jest.fn(), + getReportRouteByID: jest.fn(), })); jest.mock('@src/libs/Navigation/navigationRef', () => ({ From 02373acb4de9c976ff84151f2dad2f5f58181ab7 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 19 Feb 2025 10:18:22 +0700 Subject: [PATCH 09/10] fix: refactor logics to match new navigation state --- src/libs/Navigation/Navigation.ts | 25 +++++++++++++++++-------- src/libs/Navigation/types.ts | 2 ++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index fe15a640e851..804adf605c01 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -33,7 +33,7 @@ import setNavigationActionToMicrotaskQueue from './helpers/setNavigationActionTo import switchPolicyID from './helpers/switchPolicyID'; import {linkingConfig} from './linkingConfig'; import navigationRef from './navigationRef'; -import type {NavigationPartialRoute, NavigationStateRoute, RootNavigatorParamList, State} from './types'; +import type {NavigationPartialRoute, NavigationRoute, NavigationStateRoute, RootNavigatorParamList, State} from './types'; let allReports: OnyxCollection; Onyx.connect({ @@ -506,11 +506,22 @@ function navigateToReportWithPolicyCheck({report, reportID, reportActionID, refe ); } -function getReportRouteByID(reportID?: string) { - if (!reportID) { +function getReportRouteByID(reportID?: string, routes: NavigationRoute[] = navigationRef.getRootState().routes): NavigationRoute | null { + if (!reportID || !routes?.length) { return null; } - return navigationRef.getRootState().routes.find((route) => route.name === SCREENS.REPORT && !!route.params && 'reportID' in route.params && route.params.reportID === reportID); + for (const route of routes) { + if (route.name === SCREENS.REPORT && !!route.params && 'reportID' in route.params && route.params.reportID === reportID) { + return route; + } + if (route.state?.routes) { + const partialRoute = getReportRouteByID(reportID, route.state.routes); + if (partialRoute) { + return partialRoute; + } + } + } + return null; } /** @@ -563,11 +574,9 @@ function removeScreenFromNavigationState(screen: string) { } function removeScreenByKey(key: string) { - const state = navigationRef.getRootState(); - const routes = state.routes.filter((item) => item.key !== key); - isNavigationReady().then(() => { - navigationRef.current?.dispatch(() => { + navigationRef.current?.dispatch((state) => { + const routes = state.routes?.filter((item) => item.key !== key); return CommonActions.reset({ ...state, routes, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index fa274d1ecf7e..3ff21efc6968 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -53,6 +53,7 @@ type NavigationStateRoute = NavigationState['routes'][number]; type NavigationPartialRoute = PartialRoute>; type StateOrRoute = NavigationState | NavigationStateRoute | NavigationPartialRoute; type State = NavigationState | PartialState>; +type NavigationRoute = NavigationStateRoute | NavigationPartialRoute; type SplitNavigatorSidebarScreen = keyof typeof SIDEBAR_TO_SPLIT; @@ -1912,6 +1913,7 @@ export type { NavigationRef, NavigationRoot, NavigationStateRoute, + NavigationRoute, NewChatNavigatorParamList, NewTaskNavigatorParamList, OnboardingFlowName, From 61df97e79d0e13bd077ab35a16f2d9fc8dbea979 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 19 Feb 2025 16:08:04 +0700 Subject: [PATCH 10/10] fix: lint --- src/libs/Navigation/Navigation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 804adf605c01..26399ca62664 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -481,12 +481,12 @@ function navigateToReportWithPolicyCheck({report, reportID, reportActionID, refe const shouldOpenAllWorkspace = isEmptyObject(targetReport) ? true : !doesReportBelongToWorkspace(targetReport, policyMemberAccountIDs, policyID); if ((shouldOpenAllWorkspace && !policyID) || !shouldOpenAllWorkspace) { - linkTo(ref.current, ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID ?? '-1', reportActionID, referrer)); + linkTo(ref.current, ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID, reportActionID, referrer)); return; } const params: Record = { - reportID: targetReport?.reportID ?? '-1', + reportID: targetReport?.reportID ?? String(CONST.DEFAULT_NUMBER_ID), }; if (reportActionID) {