From 32ca0ed72713911fb9444bafa992089dccbd9963 Mon Sep 17 00:00:00 2001 From: MelvinBot Date: Fri, 27 Feb 2026 19:43:35 +0000 Subject: [PATCH] Fix duplicate expense navigation arrows showing inverted state on first open When opening a duplicate expense from the Review Duplicates screen, MoneyRequestReportTransactionList's useEffect was racing with Review.tsx's onPreviewPressed, overwriting the active transaction IDs with the parent report's visual order. This caused the left/right navigation arrows to show inverted state on the first open. Skip setting active transaction IDs when the SEARCH_REPORT was opened from the duplicate review context (backTo ends with /duplicates/review), matching the existing isFromReviewDuplicates pattern in MoneyRequestHeader. Co-authored-by: Chavda Sachin --- .../MoneyRequestReportTransactionList.tsx | 6 +++ ...ransactionListActiveTransactionIDsTest.tsx | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx index 690931ac19f80..a941184f214e7 100644 --- a/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx +++ b/src/components/MoneyRequestReportView/MoneyRequestReportTransactionList.tsx @@ -288,6 +288,12 @@ function MoneyRequestReportTransactionList({ if (focusedRoute?.name !== SCREENS.RIGHT_MODAL.SEARCH_REPORT) { return; } + // Don't overwrite active transaction IDs when navigating from the duplicate review, + // as Review.tsx sets its own order via onPreviewPressed. + const backTo = (focusedRoute.params as Record | undefined)?.backTo; + if (backTo?.replaceAll(/\?.*/g, '').endsWith('/duplicates/review')) { + return; + } setActiveTransactionIDs(visualOrderTransactionIDs); }, [visualOrderTransactionIDs]); diff --git a/tests/unit/MoneyRequestReportTransactionListActiveTransactionIDsTest.tsx b/tests/unit/MoneyRequestReportTransactionListActiveTransactionIDsTest.tsx index cc41316738195..0ae287dfb67a2 100644 --- a/tests/unit/MoneyRequestReportTransactionListActiveTransactionIDsTest.tsx +++ b/tests/unit/MoneyRequestReportTransactionListActiveTransactionIDsTest.tsx @@ -34,6 +34,10 @@ function useActiveTransactionIDsEffect(visualOrderTransactionIDs: string[]) { if (focusedRoute?.name !== SCREENS.RIGHT_MODAL.SEARCH_REPORT) { return; } + const backTo = (focusedRoute.params as Record | undefined)?.backTo; + if (backTo?.replaceAll(/\?.*/g, '').endsWith('/duplicates/review')) { + return; + } setActiveTransactionIDs(visualOrderTransactionIDs); }, [visualOrderTransactionIDs]); @@ -173,6 +177,40 @@ describe('MoneyRequestReportTransactionList - Active Transaction IDs Effect', () expect(mockClearActiveTransactionIDs).not.toHaveBeenCalled(); }); + it('should NOT call setActiveTransactionIDs when backTo includes duplicates review', () => { + // Given the focused route is SEARCH_REPORT with backTo pointing to a duplicate review + mockFindFocusedRoute.mockReturnValue({ + name: SCREENS.RIGHT_MODAL.SEARCH_REPORT, + key: 'test-key', + params: {backTo: '/r/123/duplicates/review'}, + }); + + const transactionIDs = ['trans1', 'trans2']; + + // When the hook is rendered + renderHook(() => useActiveTransactionIDsEffect(transactionIDs)); + + // Then setActiveTransactionIDs should NOT be called because the IDs were already set by Review.tsx + expect(mockSetActiveTransactionIDs).not.toHaveBeenCalled(); + }); + + it('should NOT call setActiveTransactionIDs when backTo includes duplicates review with query params', () => { + // Given the focused route is SEARCH_REPORT with backTo including query params after duplicates/review + mockFindFocusedRoute.mockReturnValue({ + name: SCREENS.RIGHT_MODAL.SEARCH_REPORT, + key: 'test-key', + params: {backTo: '/r/456/duplicates/review?someParam=value'}, + }); + + const transactionIDs = ['trans1', 'trans2']; + + // When the hook is rendered + renderHook(() => useActiveTransactionIDsEffect(transactionIDs)); + + // Then setActiveTransactionIDs should NOT be called + expect(mockSetActiveTransactionIDs).not.toHaveBeenCalled(); + }); + it('should handle empty transaction IDs array', () => { // Given the focused route is SEARCH_REPORT mockFindFocusedRoute.mockReturnValue({name: SCREENS.RIGHT_MODAL.SEARCH_REPORT, key: 'test-key'});