From b22583ed53a39a21a50715bddaf70cf918f72cf6 Mon Sep 17 00:00:00 2001 From: MelvinBot Date: Thu, 19 Feb 2026 02:13:15 +0000 Subject: [PATCH 1/3] Add missing warning modals for re-exporting and retracting exported reports Set isExportedToIntegration optimistically in both exportToIntegration and markAsManuallyExported so the isExported check returns true immediately. Add isExported guard to the RETRACT action matching the existing REOPEN pattern. Co-authored-by: parasharrajat --- src/components/MoneyReportHeader.tsx | 17 ++++++++++++- src/libs/actions/Report/index.ts | 36 ++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 71d989ba1dadc..f699d2d0a351c 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -1533,7 +1533,22 @@ function MoneyReportHeader({ icon: expensifyIcons.CircularArrowBackwards, value: CONST.REPORT.SECONDARY_ACTIONS.RETRACT, sentryLabel: CONST.SENTRY_LABEL.MORE_MENU.RETRACT, - onSelected: () => { + onSelected: async () => { + if (isExported) { + const result = await showConfirmModal({ + title: translate('iou.reopenReport'), + prompt: reopenExportedReportWarningText, + confirmText: translate('iou.reopenReport'), + cancelText: translate('common.cancel'), + danger: true, + }); + + if (result.action !== ModalActions.CONFIRM) { + return; + } + retractReport(moneyRequestReport, chatReport, policy, accountID, email ?? '', hasViolations, isASAPSubmitBetaEnabled, nextStep); + return; + } retractReport(moneyRequestReport, chatReport, policy, accountID, email ?? '', hasViolations, isASAPSubmitBetaEnabled, nextStep); }, }, diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index f0cf692c349c6..35c665412a0f1 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -4899,7 +4899,7 @@ function exportToIntegration(reportID: string, connectionName: ConnectionName) { const action = buildOptimisticExportIntegrationAction(connectionName); const optimisticReportActionID = action.reportActionID; - const optimisticData: Array> = [ + const optimisticData: Array> = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, @@ -4907,9 +4907,16 @@ function exportToIntegration(reportID: string, connectionName: ConnectionName) { [optimisticReportActionID]: action, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + isExportedToIntegration: true, + }, + }, ]; - const failureData: Array> = [ + const failureData: Array> = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, @@ -4919,6 +4926,13 @@ function exportToIntegration(reportID: string, connectionName: ConnectionName) { }, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + isExportedToIntegration: false, + }, + }, ]; const params = { @@ -4938,7 +4952,7 @@ function markAsManuallyExported(reportID: string, connectionName: ConnectionName const label = CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]; const optimisticReportActionID = action.reportActionID; - const optimisticData: Array> = [ + const optimisticData: Array> = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, @@ -4946,6 +4960,13 @@ function markAsManuallyExported(reportID: string, connectionName: ConnectionName [optimisticReportActionID]: action, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + isExportedToIntegration: true, + }, + }, ]; const successData: Array> = [ @@ -4960,7 +4981,7 @@ function markAsManuallyExported(reportID: string, connectionName: ConnectionName }, ]; - const failureData: Array> = [ + const failureData: Array> = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, @@ -4970,6 +4991,13 @@ function markAsManuallyExported(reportID: string, connectionName: ConnectionName }, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, + value: { + isExportedToIntegration: false, + }, + }, ]; const params = { From d8f9130efb18caf3e11d3bf316a9e18bd7e3c86b Mon Sep 17 00:00:00 2001 From: MelvinBot Date: Thu, 26 Feb 2026 19:16:42 +0000 Subject: [PATCH 2/3] Fix: Sort imports in getClipboardTextTest.ts to match Prettier configuration Co-authored-by: parasharrajat --- tests/unit/libs/getClipboardTextTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/libs/getClipboardTextTest.ts b/tests/unit/libs/getClipboardTextTest.ts index 042120d6357b8..15c2480f9aed1 100644 --- a/tests/unit/libs/getClipboardTextTest.ts +++ b/tests/unit/libs/getClipboardTextTest.ts @@ -1,5 +1,5 @@ -import Parser from '@libs/Parser'; import getClipboardText from '@libs/Clipboard/getClipboardText'; +import Parser from '@libs/Parser'; jest.mock('@libs/Parser', () => ({ // eslint-disable-next-line @typescript-eslint/naming-convention From 638147a45f9cf6367bdb26e705717e133c6ae74d Mon Sep 17 00:00:00 2001 From: "parasharrajat (via MelvinBot)" Date: Mon, 16 Mar 2026 10:28:41 +0000 Subject: [PATCH 3/3] Fix: Restore prior export state on exportToIntegration failure Instead of hardcoding isExportedToIntegration: false in failure data, capture the previous value before the optimistic update and restore it on failure. This matches the pattern in markAsManuallyExported and prevents clearing the exported flag when re-exporting a report fails. Co-authored-by: parasharrajat --- src/libs/actions/Report/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report/index.ts b/src/libs/actions/Report/index.ts index b3a34f6d1caf3..1eb18f3ec3c41 100644 --- a/src/libs/actions/Report/index.ts +++ b/src/libs/actions/Report/index.ts @@ -5299,6 +5299,7 @@ function setGroupDraft(newGroupDraft: Partial) { function exportToIntegration(reportID: string, connectionName: ConnectionName) { const action = buildOptimisticExportIntegrationAction(connectionName); const optimisticReportActionID = action.reportActionID; + const previousExportedValue = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.isExportedToIntegration; const optimisticData: Array> = [ { @@ -5331,7 +5332,7 @@ function exportToIntegration(reportID: string, connectionName: ConnectionName) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { - isExportedToIntegration: false, + isExportedToIntegration: previousExportedValue, }, }, ];