From 7d69e6634b3ac8b61303f1c3ecf06a768a81f4be Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sun, 6 Oct 2024 01:29:38 +0700 Subject: [PATCH 01/37] Change behavior, navigate before transaction delete to resolve [delete..] briefly appeared --- src/libs/actions/IOU.ts | 50 +++++++++++++++++++++++ src/libs/actions/Task.ts | 1 + src/pages/ReportDetailsPage.tsx | 72 +++++++++++++++++++++------------ 3 files changed, 98 insertions(+), 25 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 8d8e25a3ffb..4b2c4dcd199 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -73,6 +73,7 @@ import * as Category from './Policy/Category'; import * as Policy from './Policy/Policy'; import * as Tag from './Policy/Tag'; import * as Report from './Report'; +import * as Task from '@userActions/Task'; type IOURequestType = ValueOf; @@ -5684,6 +5685,51 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT }; } +function getUrlToNavigateBackForTask(report: OnyxEntry): string | undefined { + const parentReport = Task.getParentReport(report); + const shouldDeleteTaskReport = !ReportActionsUtils.doesReportHaveVisibleActions(report.reportID ?? '-1'); + if (shouldDeleteTaskReport) { + return ROUTES.REPORT_WITH_ID.getRoute(parentReport?.reportID ?? ''); + } + return undefined; +} +function getUrlToNavigateBackForMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView: boolean): string | undefined { + const { + shouldDeleteTransactionThread, + shouldDeleteIOUReport, + iouReport, + chatReport, + } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + + let reportIDToNavigateBack: string | undefined; + if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { + reportIDToNavigateBack = iouReport.chatReportID; + } + + if (iouReport?.chatReportID && shouldDeleteIOUReport) { + reportIDToNavigateBack = iouReport.chatReportID; + } + + return reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; +} +function getUrlToNavigateBackForTrackExpense(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView: boolean): string | undefined { + const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; + if (!ReportUtils.isSelfDM(chatReport)) { + return getUrlToNavigateBackForMoneyRequest(transactionID, reportAction, isSingleTransactionView); + } + + const { shouldDeleteTransactionThread } = getDeleteTrackExpenseInformation( + chatReportID, + transactionID, + reportAction, + ); + + if (shouldDeleteTransactionThread) { + return ROUTES.REPORT_WITH_ID.getRoute(chatReportID); + } + + return undefined; +} /** * * @param transactionID - The transactionID of IOU @@ -8476,5 +8522,9 @@ export { updateMoneyRequestTaxRate, mergeDuplicates, resolveDuplicates, + getUrlToNavigateBackForTask, + getUrlToNavigateBackForMoneyRequest, + getUrlToNavigateBackForTrackExpense, + }; export type {GPSPoint as GpsPoint, IOURequestType}; diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 2f9ec060c1e..ae3c2b596a7 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1207,6 +1207,7 @@ export { canModifyTask, canActionTask, setNewOptimisticAssignee, + getParentReport, }; export type {PolicyValue, Assignee, ShareDestination}; diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index e51b8e36704..03c911305fe 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -718,24 +718,46 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { const deleteTransaction = useCallback(() => { setIsDeleteModalVisible(false); - + + let urlToNavigateBack: string | undefined; + if (caseID === CASES.DEFAULT) { - navigateBackToAfterDelete.current = Task.deleteTask(report); + urlToNavigateBack = IOU.getUrlToNavigateBackForTask(report); + if (urlToNavigateBack) { + Navigation.goBack(urlToNavigateBack as Route); + } else { + Navigation.dismissModal(); + } + Task.deleteTask(report); return; } - + if (!requestParentReportAction) { return; } - - if (ReportActionsUtils.isTrackExpenseAction(requestParentReportAction)) { - navigateBackToAfterDelete.current = IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + if (isTrackExpense) { + urlToNavigateBack = IOU.getUrlToNavigateBackForTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); } else { - navigateBackToAfterDelete.current = IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); + urlToNavigateBack = IOU.getUrlToNavigateBackForMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); } - + + if (!urlToNavigateBack) { + Navigation.dismissModal(); + } else { + ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); + } + + if (isTrackExpense) { + IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + } else { + IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); + } + isTransactionDeleted.current = true; }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView]); + return ( @@ -826,23 +848,23 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { onConfirm={deleteTransaction} onCancel={() => setIsDeleteModalVisible(false)} onModalHide={() => { - // We use isTransactionDeleted to know if the modal hides because the user deletes the transaction. - if (!isTransactionDeleted.current) { - if (caseID === CASES.DEFAULT) { - if (navigateBackToAfterDelete.current) { - Navigation.goBack(navigateBackToAfterDelete.current); - } else { - Navigation.dismissModal(); - } - } - return; - } - - if (!navigateBackToAfterDelete.current) { - Navigation.dismissModal(); - } else { - ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); - } + // // We use isTransactionDeleted to know if the modal hides because the user deletes the transaction. + // if (!isTransactionDeleted.current) { + // if (caseID === CASES.DEFAULT) { + // if (navigateBackToAfterDelete.current) { + // Navigation.goBack(navigateBackToAfterDelete.current); + // } else { + // Navigation.dismissModal(); + // } + // } + // return; + // } + + // if (!navigateBackToAfterDelete.current) { + // Navigation.dismissModal(); + // } else { + // ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); + // } }} prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} From bc8f8edbd608afeb42020a776c2886b55c18fae4 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sun, 6 Oct 2024 23:46:32 +0700 Subject: [PATCH 02/37] fix incorrect reportIDToNavigateBack --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 4b2c4dcd199..9304b3a4c08 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5703,7 +5703,7 @@ function getUrlToNavigateBackForMoneyRequest(transactionID: string, reportAction let reportIDToNavigateBack: string | undefined; if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { - reportIDToNavigateBack = iouReport.chatReportID; + reportIDToNavigateBack = iouReport.reportID; } if (iouReport?.chatReportID && shouldDeleteIOUReport) { From f6781e6e0f0cd6325759f3c6eb64ab8f8790495c Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 7 Oct 2024 00:08:15 +0700 Subject: [PATCH 03/37] actually delete the transaction after ReportDetailsPage unmounted --- src/pages/ReportDetailsPage.tsx | 34 +++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 03c911305fe..600b1411729 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -715,9 +715,35 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { const isTransactionDeleted = useRef(false); // Where to go back after deleting the transaction and its report. It's empty if the transaction report isn't deleted. const navigateBackToAfterDelete = useRef(); + useEffect(() => { + return () => { + if(!isTransactionDeleted.current) + { + return; + } + + if (caseID === CASES.DEFAULT) { + Task.deleteTask(report); + return; + } + + if (!requestParentReportAction) { + return; + } + + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + + if (isTrackExpense) { + IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + } else { + IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); + } + }; + }, [isTransactionDeleted]); const deleteTransaction = useCallback(() => { setIsDeleteModalVisible(false); + isTransactionDeleted.current = true; let urlToNavigateBack: string | undefined; @@ -728,7 +754,6 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { } else { Navigation.dismissModal(); } - Task.deleteTask(report); return; } @@ -749,13 +774,6 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); } - if (isTrackExpense) { - IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); - } else { - IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); - } - - isTransactionDeleted.current = true; }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView]); return ( From 0bd45cc23e6c040a86e249353ab4da429efbfddb Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 7 Oct 2024 13:46:53 +0700 Subject: [PATCH 04/37] Refactor, remove unnecessary code --- src/pages/ReportDetailsPage.tsx | 75 +++++++++++++-------------------- 1 file changed, 29 insertions(+), 46 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 600b1411729..533709ff50d 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -3,7 +3,7 @@ import {Str} from 'expensify-common'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import {useOnyx} from 'react-native-onyx'; +import Onyx, {useOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; @@ -713,35 +713,37 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { // A flag to indicate whether the user choose to delete the transaction or not const isTransactionDeleted = useRef(false); - // Where to go back after deleting the transaction and its report. It's empty if the transaction report isn't deleted. - const navigateBackToAfterDelete = useRef(); useEffect(() => { return () => { - if(!isTransactionDeleted.current) - { - return; - } - - if (caseID === CASES.DEFAULT) { - Task.deleteTask(report); - return; - } - - if (!requestParentReportAction) { - return; - } - - const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); - - if (isTrackExpense) { - IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); - } else { - IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); - } + deleteTransaction(); }; - }, [isTransactionDeleted]); + }, []); const deleteTransaction = useCallback(() => { + if (!isTransactionDeleted.current) { + return; + } + + if (caseID === CASES.DEFAULT) { + Task.deleteTask(report); + return; + } + + if (!requestParentReportAction) { + return; + } + + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + + if (isTrackExpense) { + IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + } else { + IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); + } + }, [caseID, iouTransactionID, isSingleTransactionView, moneyRequestReport?.reportID, report, requestParentReportAction]); + + // Where to go back after deleting the transaction and its report. + const navigateAfterTransactionDeletion = useCallback(() => { setIsDeleteModalVisible(false); isTransactionDeleted.current = true; @@ -774,7 +776,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); } - }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView]); + }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, setIsDeleteModalVisible, isTransactionDeleted]); return ( @@ -863,27 +865,8 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { setIsDeleteModalVisible(false)} - onModalHide={() => { - // // We use isTransactionDeleted to know if the modal hides because the user deletes the transaction. - // if (!isTransactionDeleted.current) { - // if (caseID === CASES.DEFAULT) { - // if (navigateBackToAfterDelete.current) { - // Navigation.goBack(navigateBackToAfterDelete.current); - // } else { - // Navigation.dismissModal(); - // } - // } - // return; - // } - - // if (!navigateBackToAfterDelete.current) { - // Navigation.dismissModal(); - // } else { - // ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); - // } - }} prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} From eb051bb80bce29294ea1552eb62163bd01fda5c1 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 7 Oct 2024 14:23:17 +0700 Subject: [PATCH 05/37] Add NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL to show loading transaction during delete process --- src/ONYXKEYS.ts | 4 ++++ src/libs/actions/IOU.ts | 16 ++++++++++++++++ src/libs/actions/Task.ts | 5 +++++ src/pages/ReportDetailsPage.tsx | 2 ++ src/pages/home/ReportScreen.tsx | 4 +++- 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index df1413620c2..ecc3d865c9e 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -208,6 +208,9 @@ const ONYXKEYS = { /** The NVP containing all information related to educational tooltip in workspace chat */ NVP_WORKSPACE_TOOLTIP: 'workspaceTooltip', + /** The NVP contain url to back after deleting transaction */ + NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL: 'nvp_deleteTransactionNavigateBackURL', + /** Whether to show save search rename tooltip */ SHOULD_SHOW_SAVED_SEARCH_RENAME_TOOLTIP: 'shouldShowSavedSearchRenameTooltip', @@ -990,6 +993,7 @@ type OnyxValuesMapping = { [ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED]: number; [ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END]: number; [ONYXKEYS.NVP_WORKSPACE_TOOLTIP]: OnyxTypes.WorkspaceTooltip; + [ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL]: string | undefined; [ONYXKEYS.NVP_SHOULD_HIDE_GBR_TOOLTIP]: boolean; [ONYXKEYS.NVP_PRIVATE_CANCELLATION_DETAILS]: OnyxTypes.CancellationDetails[]; [ONYXKEYS.ROOM_MEMBERS_USER_SEARCH_PHRASE]: string; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 9304b3a4c08..afaf4b3143b 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5977,6 +5977,12 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor }); } + optimisticData.push({ + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, + value: null, + }); + const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -6260,6 +6266,15 @@ function getSendMoneyParams( [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: optimisticCreatedActionForTransactionThread, }, }; + const optimisticDeleteTransactionNavigateBackUrl: OnyxUpdate = { + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, + value: null, +}; + + + + const successData: OnyxUpdate[] = []; @@ -6430,6 +6445,7 @@ function getSendMoneyParams( optimisticTransactionData, optimisticTransactionThreadData, optimisticTransactionThreadReportActionsData, + optimisticDeleteTransactionNavigateBackUrl, ]; if (!isEmptyObject(optimisticPersonalDetailListData)) { diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index ae3c2b596a7..b8edbaa8b24 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1005,6 +1005,11 @@ function deleteTask(report: OnyxEntry) { key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport?.reportID}`, value: optimisticReportActions as OnyxTypes.ReportActions, }, + { + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, + value: null, + }, ]; // Update optimistic data for parent report action if the report is a child report and the task report has no visible child diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 533709ff50d..3e098e20b27 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -751,6 +751,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { if (caseID === CASES.DEFAULT) { urlToNavigateBack = IOU.getUrlToNavigateBackForTask(report); + Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); if (urlToNavigateBack) { Navigation.goBack(urlToNavigateBack as Route); } else { @@ -769,6 +770,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { } else { urlToNavigateBack = IOU.getUrlToNavigateBackForMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); } + Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); if (!urlToNavigateBack) { Navigation.dismissModal(); diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index dd38a071637..ac7418062de 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -343,13 +343,15 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro [currentUserAccountID, linkedAction], ); + const [deleteTransactionNavigateBackUrl] = useOnyx(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL); + /** * Using logical OR operator because with nullish coalescing operator, when `isLoadingApp` is false, the right hand side of the operator * is not evaluated. This causes issues where we have `isLoading` set to false and later set to true and then set to false again. * Ideally, `isLoading` should be set initially to true and then set to false. We can achieve this by using logical OR operator. */ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const isLoading = isLoadingApp || !reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty(); + const isLoading = isLoadingApp || !reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty() || (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID); const shouldShowSkeleton = (isLinkingToMessage && !isLinkedMessagePageReady) || From c2cecdc0da807aed28640c29fa411e37a3da8ab1 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 7 Oct 2024 14:33:52 +0700 Subject: [PATCH 06/37] prettier --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index afaf4b3143b..f8c10e21b00 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6270,7 +6270,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, value: null, -}; + }; From 7e8d4f45dc89f0000da7969d918fce0251a1a8a9 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 7 Oct 2024 15:46:26 +0700 Subject: [PATCH 07/37] Refactor --- src/pages/ReportDetailsPage.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 3e098e20b27..e82fdf97c1a 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -715,15 +715,15 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { const isTransactionDeleted = useRef(false); useEffect(() => { return () => { + if (!isTransactionDeleted.current) { + return; + } + deleteTransaction(); }; }, []); const deleteTransaction = useCallback(() => { - if (!isTransactionDeleted.current) { - return; - } - if (caseID === CASES.DEFAULT) { Task.deleteTask(report); return; @@ -743,7 +743,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { }, [caseID, iouTransactionID, isSingleTransactionView, moneyRequestReport?.reportID, report, requestParentReportAction]); // Where to go back after deleting the transaction and its report. - const navigateAfterTransactionDeletion = useCallback(() => { + const navigateToTargetUrl = useCallback(() => { setIsDeleteModalVisible(false); isTransactionDeleted.current = true; @@ -867,7 +867,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { setIsDeleteModalVisible(false)} prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} From 66e3de8f4bff7c7b1f0990e9efec698dfcea9f7e Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 7 Oct 2024 16:35:27 +0700 Subject: [PATCH 08/37] Partially DeleteTransactionThread to prevent not found page briefly appear --- src/libs/actions/IOU.ts | 46 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f8c10e21b00..ef2cc894c82 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1744,7 +1744,16 @@ function getDeleteTrackExpenseInformation( { onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, - value: null, + value: { + reportID: null, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + participants: { + [userAccountID]: { + notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + }, + }, + }, }, { onyxMethod: Onyx.METHOD.SET, @@ -1784,6 +1793,17 @@ function getDeleteTrackExpenseInformation( }, ]; + if (shouldDeleteTransactionThread && transactionThread) { + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, + value: Object.keys(transactionThread).reduce>((acc, key) => { + acc[key] = null; + return acc; + }, {}), + }); + } + const failureData: OnyxUpdate[] = []; if (shouldDeleteTransactionFromOnyx) { @@ -5908,9 +5928,18 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor if (shouldDeleteTransactionThread) { optimisticData.push( { - onyxMethod: Onyx.METHOD.SET, + onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, - value: null, + value: { + reportID: null, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + participants: { + [userAccountID]: { + notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + }, + }, + }, }, { onyxMethod: Onyx.METHOD.SET, @@ -6007,6 +6036,17 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor }, ]; + if (shouldDeleteTransactionThread && transactionThread) { + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, + value: Object.keys(transactionThread).reduce>((acc, key) => { + acc[key] = null; + return acc; + }, {}), + }); + } + if (shouldDeleteIOUReport) { successData.push({ onyxMethod: Onyx.METHOD.SET, From 9bce4f03bb5c00cd93be04f841a23d7e54c9dc35 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Wed, 23 Oct 2024 21:54:54 +0700 Subject: [PATCH 09/37] decouple urlToNavigateBack functions --- src/libs/actions/IOU.ts | 116 ++++++++++++++++++++++++++++++++++----- src/libs/actions/Task.ts | 53 +++++++++++++++--- 2 files changed, 148 insertions(+), 21 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 497f43f9331..01a86eef2b2 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5713,16 +5713,17 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT // STEP 5: Calculate the url that the user will be navigated back to // This depends on which page they are on and which resources were deleted - let reportIDToNavigateBack: string | undefined; - if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { - reportIDToNavigateBack = iouReport.reportID; - } + // let reportIDToNavigateBack: string | undefined; + // if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { + // reportIDToNavigateBack = iouReport.reportID; + // } - if (iouReport?.chatReportID && shouldDeleteIOUReport) { - reportIDToNavigateBack = iouReport.chatReportID; - } + // if (iouReport?.chatReportID && shouldDeleteIOUReport) { + // reportIDToNavigateBack = iouReport.chatReportID; + // } - const urlToNavigateBack = reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; + // const urlToNavigateBack = reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; + const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); return { shouldDeleteTransactionThread, @@ -5741,6 +5742,84 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT }; } +/** + * Calculate the URL to navigate to after a money request deletion + * @param transactionID - The ID of the money request being deleted + * @param reportAction - The report action associated with the money request + * @param isSingleTransactionView - Whether we're in single transaction view + * @returns The URL to navigate to + */ +function getNavigationUrlAfterMoneyRequestDelete( + transactionID: string, + reportAction: OnyxTypes.ReportAction, + isSingleTransactionView = false +): string | undefined { + // Get all collections we need for navigation + const allReports = ReportConnection.getAllReports(); + const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) + ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID + : '-1'; + const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; + const transactionThreadID = reportAction.childReportID; + + // Calculate if resources would be deleted + const shouldDeleteTransactionThread = transactionThreadID + ? (reportAction?.childVisibleActionCount ?? 0) === 0 + : false; + + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1'); + const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1').lastMessageText; + const shouldDeleteIOUReport = iouReportLastMessageText.length === 0 + && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) + && (!transactionThreadID || shouldDeleteTransactionThread); + + // Determine which report to navigate back to + if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { + return ROUTES.REPORT_WITH_ID.getRoute(iouReport.reportID); + } + + if (iouReport?.chatReportID && shouldDeleteIOUReport) { + return ROUTES.REPORT_WITH_ID.getRoute(iouReport.chatReportID); + } + + return undefined; +} + +/** + * Calculate the URL to navigate to after a track expense deletion + * @param chatReportID - The ID of the chat report containing the track expense + * @param transactionID - The ID of the track expense being deleted + * @param reportAction - The report action associated with the track expense + * @param isSingleTransactionView - Whether we're in single transaction view + * @returns The URL to navigate to + */ +function getNavigationUrlAfterTrackExpenseDelete( + chatReportID: string, + transactionID: string, + reportAction: OnyxTypes.ReportAction, + isSingleTransactionView = false +): string | undefined { + const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; + + // If not a self DM, handle it as a regular money request + if (!ReportUtils.isSelfDM(chatReport)) { + return getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); + } + + const transactionThreadID = reportAction.childReportID; + const shouldDeleteTransactionThread = transactionThreadID + ? (reportAction?.childVisibleActionCount ?? 0) === 0 + : false; + + // Only navigate if in single transaction view and the thread will be deleted + if (isSingleTransactionView && shouldDeleteTransactionThread && chatReport?.reportID) { + // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. + return ROUTES.REPORT_WITH_ID.getRoute(chatReport.reportID); + } + + return undefined; +} + /** * * @param transactionID - The transactionID of IOU @@ -6115,10 +6194,18 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor } function deleteTrackExpense(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { + const urlToNavigateBack = getNavigationUrlAfterTrackExpenseDelete( + chatReportID, + transactionID, + reportAction, + isSingleTransactionView + ); + // STEP 1: Get all collections we're updating const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; if (!ReportUtils.isSelfDM(chatReport)) { - return deleteMoneyRequest(transactionID, reportAction, isSingleTransactionView); + deleteMoneyRequest(transactionID, reportAction, isSingleTransactionView); + return urlToNavigateBack; } const whisperAction = ReportActionsUtils.getTrackExpenseActionableWhisper(transactionID, chatReportID); @@ -6138,10 +6225,11 @@ function deleteTrackExpense(chatReportID: string, transactionID: string, reportA CachedPDFPaths.clearByKey(transactionID); // STEP 7: Navigate the user depending on which page they are on and which resources were deleted - if (isSingleTransactionView && shouldDeleteTransactionThread) { - // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. - return ROUTES.REPORT_WITH_ID.getRoute(chatReport?.reportID ?? '-1'); - } + return urlToNavigateBack; + // if (isSingleTransactionView && shouldDeleteTransactionThread) { + // // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. + // return ROUTES.REPORT_WITH_ID.getRoute(chatReport?.reportID ?? '-1'); + // } } /** @@ -8565,5 +8653,7 @@ export { updateLastLocationPermissionPrompt, resolveDuplicates, getIOUReportActionToApproveOrPay, + getNavigationUrlAfterMoneyRequestDelete, + getNavigationUrlAfterTrackExpenseDelete, }; export type {GPSPoint as GpsPoint, IOURequestType}; diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index b159e391f94..2031d5a4225 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -955,6 +955,36 @@ function getParentReport(report: OnyxEntry): OnyxEntry): string | undefined { + if (!report) { + return undefined; + } + + const shouldDeleteTaskReport = !ReportActionsUtils.doesReportHaveVisibleActions(report.reportID ?? '-1'); + if (!shouldDeleteTaskReport) { + return undefined; + } + + // First try to navigate to parent report + const parentReport = getParentReport(report); + if (parentReport?.reportID) { + return ROUTES.REPORT_WITH_ID.getRoute(parentReport.reportID); + } + + // If no parent report, try to navigate to most recent report + const mostRecentReportID = Report.getMostRecentReportID(report); + if (mostRecentReportID) { + return ROUTES.REPORT_WITH_ID.getRoute(mostRecentReportID); + } + + return undefined; +} + /** * Cancels a task by setting the report state to SUBMITTED and status to CLOSED */ @@ -1109,15 +1139,21 @@ function deleteTask(report: OnyxEntry) { API.write(WRITE_COMMANDS.CANCEL_TASK, parameters, {optimisticData, successData, failureData}); Report.notifyNewAction(report.reportID, currentUserAccountID); - if (shouldDeleteTaskReport) { + // if (shouldDeleteTaskReport) { + // Navigation.goBack(); + // if (parentReport?.reportID) { + // return ROUTES.REPORT_WITH_ID.getRoute(parentReport.reportID); + // } + // const mostRecentReportID = Report.getMostRecentReportID(report); + // if (mostRecentReportID) { + // return ROUTES.REPORT_WITH_ID.getRoute(mostRecentReportID); + // } + // } + + const urlToNavigateBack = getNavigationUrlAfterTaskDelete(report); + if (urlToNavigateBack) { Navigation.goBack(); - if (parentReport?.reportID) { - return ROUTES.REPORT_WITH_ID.getRoute(parentReport.reportID); - } - const mostRecentReportID = Report.getMostRecentReportID(report); - if (mostRecentReportID) { - return ROUTES.REPORT_WITH_ID.getRoute(mostRecentReportID); - } + return urlToNavigateBack; } } @@ -1232,6 +1268,7 @@ export { canActionTask, setNewOptimisticAssignee, getParentReport, + getNavigationUrlAfterTaskDelete, }; export type {PolicyValue, Assignee, ShareDestination}; From e2cd64213c51a03b9d0a0836257d82430899e4b4 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Wed, 23 Oct 2024 22:06:39 +0700 Subject: [PATCH 10/37] actually delete transaction after reportdetailspage unmounted --- src/pages/ReportDetailsPage.tsx | 107 +++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 29 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 7de12eeda89..fcaa696d526 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -3,7 +3,7 @@ import {Str} from 'expensify-common'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import {useOnyx} from 'react-native-onyx'; +import Onyx, {useOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; @@ -225,6 +225,18 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { const canUnapproveRequest = ReportUtils.isExpenseReport(report) && (ReportUtils.isReportManager(report) || isPolicyAdmin) && ReportUtils.isReportApproved(report) && !PolicyUtils.isSubmitAndClose(policy); + + useEffect(() => { + return () => { + if (!isTransactionDeleted.current) { + return; + } + + deleteTransaction(); + }; + }, []); + + useEffect(() => { if (canDeleteRequest) { return; @@ -759,11 +771,48 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { // Where to go back after deleting the transaction and its report. It's empty if the transaction report isn't deleted. const navigateBackToAfterDelete = useRef(); - const deleteTransaction = useCallback(() => { + + // Where to go back after deleting the transaction and its report. + const navigateToTargetUrl = useCallback(() => { setIsDeleteModalVisible(false); + isTransactionDeleted.current = true; + + let urlToNavigateBack: string | undefined; + + if (caseID === CASES.DEFAULT) { + urlToNavigateBack = Task.getNavigationUrlAfterTaskDelete(report); + Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); + if (urlToNavigateBack) { + Navigation.goBack(urlToNavigateBack as Route); + } else { + Navigation.dismissModal(); + } + return; + } + + if (!requestParentReportAction) { + return; + } + + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + if (isTrackExpense) { + urlToNavigateBack = IOU.getNavigationUrlAfterTrackExpenseDelete(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + } else { + urlToNavigateBack = IOU.getNavigationUrlAfterMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); + } + Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); + + if (!urlToNavigateBack) { + Navigation.dismissModal(); + } else { + ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); + } + + }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, setIsDeleteModalVisible, isTransactionDeleted]); + const deleteTransaction = useCallback(() => { if (caseID === CASES.DEFAULT) { - navigateBackToAfterDelete.current = Task.deleteTask(report); + Task.deleteTask(report); return; } @@ -771,14 +820,14 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { return; } - if (ReportActionsUtils.isTrackExpenseAction(requestParentReportAction)) { - navigateBackToAfterDelete.current = IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + + if (isTrackExpense) { + IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); } else { - navigateBackToAfterDelete.current = IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); + IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); } - - isTransactionDeleted.current = true; - }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView]); + }, [caseID, iouTransactionID, isSingleTransactionView, moneyRequestReport?.reportID, report, requestParentReportAction]); const mentionReportContextValue = useMemo(() => ({currentReportID: report.reportID, exactlyMatch: true}), [report.reportID]); @@ -871,27 +920,27 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { setIsDeleteModalVisible(false)} - onModalHide={() => { - // We use isTransactionDeleted to know if the modal hides because the user deletes the transaction. - if (!isTransactionDeleted.current) { - if (caseID === CASES.DEFAULT) { - if (navigateBackToAfterDelete.current) { - Navigation.goBack(navigateBackToAfterDelete.current); - } else { - Navigation.dismissModal(); - } - } - return; - } - - if (!navigateBackToAfterDelete.current) { - Navigation.dismissModal(); - } else { - ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); - } - }} + // onModalHide={() => { + // // We use isTransactionDeleted to know if the modal hides because the user deletes the transaction. + // if (!isTransactionDeleted.current) { + // if (caseID === CASES.DEFAULT) { + // if (navigateBackToAfterDelete.current) { + // Navigation.goBack(navigateBackToAfterDelete.current); + // } else { + // Navigation.dismissModal(); + // } + // } + // return; + // } + + // if (!navigateBackToAfterDelete.current) { + // Navigation.dismissModal(); + // } else { + // ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); + // } + // }} prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} From 980e8e5dc810f1e2e511228e2dfc817b89a3034c Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 24 Oct 2024 04:40:53 +0700 Subject: [PATCH 11/37] Resolve cyclic dependency --- src/libs/actions/IOU.ts | 42 ++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 01a86eef2b2..53a0b4f47e9 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5723,7 +5723,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT // } // const urlToNavigateBack = reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; - const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); + const urlToNavigateBack = undefined; return { shouldDeleteTransactionThread, @@ -5754,24 +5754,32 @@ function getNavigationUrlAfterMoneyRequestDelete( reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false ): string | undefined { - // Get all collections we need for navigation - const allReports = ReportConnection.getAllReports(); - const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) - ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID - : '-1'; - const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; - const transactionThreadID = reportAction.childReportID; + // // Get all collections we need for navigation + // const allReports = ReportConnection.getAllReports(); + // const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) + // ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID + // : '-1'; + // const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; + // const transactionThreadID = reportAction.childReportID; + + // // Calculate if resources would be deleted + // const shouldDeleteTransactionThread = transactionThreadID + // ? (reportAction?.childVisibleActionCount ?? 0) === 0 + // : false; + + // const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1'); + // const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1').lastMessageText; + // const shouldDeleteIOUReport = iouReportLastMessageText.length === 0 + // && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) + // && (!transactionThreadID || shouldDeleteTransactionThread); - // Calculate if resources would be deleted - const shouldDeleteTransactionThread = transactionThreadID - ? (reportAction?.childVisibleActionCount ?? 0) === 0 - : false; + const { + shouldDeleteTransactionThread, + shouldDeleteIOUReport, + iouReport, + chatReport, + } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); - const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1'); - const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1').lastMessageText; - const shouldDeleteIOUReport = iouReportLastMessageText.length === 0 - && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) - && (!transactionThreadID || shouldDeleteTransactionThread); // Determine which report to navigate back to if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { From 0288efb572cf441b44066069362f6a1cc5c880f9 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 24 Oct 2024 08:58:00 +0700 Subject: [PATCH 12/37] extract navagateUrl from prepareToCleanUpMoneyRequest --- src/libs/actions/IOU.ts | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 53a0b4f47e9..64dca4fd851 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5723,7 +5723,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT // } // const urlToNavigateBack = reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; - const urlToNavigateBack = undefined; + // const urlToNavigateBack = undefined; return { shouldDeleteTransactionThread, @@ -5738,7 +5738,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT transactionViolations, reportPreviewAction, iouReport, - urlToNavigateBack, + // urlToNavigateBack, }; } @@ -5754,30 +5754,10 @@ function getNavigationUrlAfterMoneyRequestDelete( reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false ): string | undefined { - // // Get all collections we need for navigation - // const allReports = ReportConnection.getAllReports(); - // const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) - // ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID - // : '-1'; - // const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; - // const transactionThreadID = reportAction.childReportID; - - // // Calculate if resources would be deleted - // const shouldDeleteTransactionThread = transactionThreadID - // ? (reportAction?.childVisibleActionCount ?? 0) === 0 - // : false; - - // const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(iouReport?.reportID ?? '-1'); - // const iouReportLastMessageText = ReportActionsUtils.getLastVisibleMessage(iouReport?.reportID ?? '-1').lastMessageText; - // const shouldDeleteIOUReport = iouReportLastMessageText.length === 0 - // && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) - // && (!transactionThreadID || shouldDeleteTransactionThread); - const { shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport, - chatReport, } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); @@ -5846,9 +5826,10 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo chatReport, iouReport, reportPreviewAction, - urlToNavigateBack, } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + + const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); // build Onyx data // Onyx operations to delete the transaction, update the IOU report action and chat report action @@ -5984,9 +5965,10 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor transactionViolations, iouReport, reportPreviewAction, - urlToNavigateBack, } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); + // STEP 2: Build Onyx data // The logic mostly resembles the cleanUpMoneyRequest function const optimisticData: OnyxUpdate[] = [ From 5d982cc62be7074302d153b1d575c6ec63946d15 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 24 Oct 2024 09:45:21 +0700 Subject: [PATCH 13/37] Implement NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL --- src/libs/actions/IOU.ts | 10 ++++++++++ src/pages/home/ReportScreen.tsx | 11 +++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index c125e083056..b271baf9388 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1779,6 +1779,11 @@ function getDeleteTrackExpenseInformation( lastMessageHtml: !lastMessageHtml ? lastMessageText : lastMessageHtml, }, }, + { + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, + value: null, + } ); const successData: OnyxUpdate[] = [ @@ -6020,6 +6025,11 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, value: ReportUtils.getOutstandingChildRequest(updatedIOUReport), }, + { + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, + value: null, + } ); if (!shouldDeleteIOUReport && updatedReportPreviewAction?.childMoneyRequestCount === 0) { diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index baf3d02d7af..d17ee485498 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -342,8 +342,15 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro () => !!linkedAction && ReportActionsUtils.isWhisperAction(linkedAction) && !(linkedAction?.whisperedToAccountIDs ?? []).includes(currentUserAccountID), [currentUserAccountID, linkedAction], ); - - const isLoading = isLoadingApp ?? (!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty()); + const [deleteTransactionNavigateBackUrl] = useOnyx(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL); + console.log("[wildebug] ~ file: ReportScreen.tsx:346 ~ ReportScreen ~ deleteTransactionNavigateBackUrl:", deleteTransactionNavigateBackUrl) + console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ report?.reportID:", report?.reportID) + console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl):", ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl)) + console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID):", (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID)) + + const isLoading = isLoadingApp || ((!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty()) || (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID)); + // const isLoading = isLoadingApp || ((!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty())); + console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ isLoading:", isLoading) const shouldShowSkeleton = (isLinkingToMessage && !isLinkedMessagePageReady) || (!isLinkingToMessage && !isInitialPageReady) || From 44473445ee83fc22b70910ca11eb0a147776d03e Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 24 Oct 2024 10:07:01 +0700 Subject: [PATCH 14/37] change delete money request and track expense to merge instead of fast, to resolve not found page briefly appeared --- src/libs/actions/IOU.ts | 48 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index b271baf9388..45f0a95e424 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1752,9 +1752,18 @@ function getDeleteTrackExpenseInformation( if (shouldDeleteTransactionThread) { optimisticData.push( { - onyxMethod: Onyx.METHOD.SET, + onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, - value: null, + value: { + reportID: null, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + participants: { + [userAccountID]: { + notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + }, + }, + }, }, { onyxMethod: Onyx.METHOD.SET, @@ -1799,6 +1808,17 @@ function getDeleteTrackExpenseInformation( }, ]; + if (shouldDeleteTransactionThread && transactionThread) { + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, + value: Object.keys(transactionThread).reduce>((acc, key) => { + acc[key] = null; + return acc; + }, {}), + }); + } + const failureData: OnyxUpdate[] = []; if (shouldDeleteTransactionFromOnyx) { @@ -5990,9 +6010,18 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor if (shouldDeleteTransactionThread) { optimisticData.push( { - onyxMethod: Onyx.METHOD.SET, + onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, - value: null, + value: { + reportID: null, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + participants: { + [userAccountID]: { + notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + }, + }, + }, }, { onyxMethod: Onyx.METHOD.SET, @@ -6088,6 +6117,17 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor }, ]; + if (shouldDeleteTransactionThread && transactionThread) { + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, + value: Object.keys(transactionThread).reduce>((acc, key) => { + acc[key] = null; + return acc; + }, {}), + }); + } + if (shouldDeleteIOUReport) { successData.push({ onyxMethod: Onyx.METHOD.SET, From 71c3d417ef110eee161f8c51e5789d77a1ba5762 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 24 Oct 2024 11:04:06 +0700 Subject: [PATCH 15/37] show skeleton when deleting processed --- src/libs/actions/IOU.ts | 10 ---------- src/libs/actions/Task.ts | 5 ----- src/pages/home/ReportScreen.tsx | 25 +++++++++++++++++-------- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 45f0a95e424..39692bc10fe 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1788,11 +1788,6 @@ function getDeleteTrackExpenseInformation( lastMessageHtml: !lastMessageHtml ? lastMessageText : lastMessageHtml, }, }, - { - onyxMethod: Onyx.METHOD.SET, - key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, - value: null, - } ); const successData: OnyxUpdate[] = [ @@ -6054,11 +6049,6 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, value: ReportUtils.getOutstandingChildRequest(updatedIOUReport), }, - { - onyxMethod: Onyx.METHOD.SET, - key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, - value: null, - } ); if (!shouldDeleteIOUReport && updatedReportPreviewAction?.childMoneyRequestCount === 0) { diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 2031d5a4225..b2fc07bd868 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1053,11 +1053,6 @@ function deleteTask(report: OnyxEntry) { key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport?.reportID}`, value: optimisticReportActions as OnyxTypes.ReportActions, }, - { - onyxMethod: Onyx.METHOD.SET, - key: ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, - value: null, - }, ]; // Update optimistic data for parent report action if the report is a child report and the task report has no visible child diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index d17ee485498..15c5e9b3487 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -55,6 +55,9 @@ import ReportActionsView from './report/ReportActionsView'; import ReportFooter from './report/ReportFooter'; import type {ActionListContextType, ReactionListRef, ScrollPosition} from './ReportScreenContext'; import {ActionListContext, ReactionListContext} from './ReportScreenContext'; +import Onyx from 'react-native-onyx'; +import lodashDefer from 'lodash/defer'; + type ReportScreenNavigationProps = StackScreenProps; @@ -343,20 +346,26 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro [currentUserAccountID, linkedAction], ); const [deleteTransactionNavigateBackUrl] = useOnyx(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL); - console.log("[wildebug] ~ file: ReportScreen.tsx:346 ~ ReportScreen ~ deleteTransactionNavigateBackUrl:", deleteTransactionNavigateBackUrl) - console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ report?.reportID:", report?.reportID) - console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl):", ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl)) - console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID):", (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID)) - - const isLoading = isLoadingApp || ((!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty()) || (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID)); - // const isLoading = isLoadingApp || ((!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty())); - console.log("[wildebug] ~ file: ReportScreen.tsx:348 ~ ReportScreen ~ isLoading:", isLoading) + + useEffect(() => { + if (!isFocused || !deleteTransactionNavigateBackUrl) { + return; + } + // Schedule the code to run after the current call stack is cleared, + // ensuring all updates are processed before hide the skeleton + lodashDefer(() => { + Onyx.merge(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, null); + }); + }, [isFocused]); + + const isLoading = isLoadingApp ?? ((!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty())); const shouldShowSkeleton = (isLinkingToMessage && !isLinkedMessagePageReady) || (!isLinkingToMessage && !isInitialPageReady) || isEmptyObject(reportOnyx) || isLoadingReportOnyx || !isCurrentReportLoadedFromOnyx || + (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID) || isLoading; const isLinkedActionBecomesDeleted = prevIsLinkedActionDeleted !== undefined && !prevIsLinkedActionDeleted && isLinkedActionDeleted; From 390d35791eefee063aaa0a923de5ec4981034954 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 14 Nov 2024 13:15:42 +0700 Subject: [PATCH 16/37] remove unnecessary code --- src/libs/actions/IOU.ts | 15 --------------- src/pages/ReportDetailsPage.tsx | 19 ------------------- 2 files changed, 34 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index cf2ab1dda20..9302ed0b0db 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5487,20 +5487,6 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT updatedReportPreviewAction.childMoneyRequestCount = reportPreviewAction.childMoneyRequestCount - 1; } - // STEP 5: Calculate the url that the user will be navigated back to - // This depends on which page they are on and which resources were deleted - // let reportIDToNavigateBack: string | undefined; - // if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { - // reportIDToNavigateBack = iouReport.reportID; - // } - - // if (iouReport?.chatReportID && shouldDeleteIOUReport) { - // reportIDToNavigateBack = iouReport.chatReportID; - // } - - // const urlToNavigateBack = reportIDToNavigateBack ? ROUTES.REPORT_WITH_ID.getRoute(reportIDToNavigateBack) : undefined; - // const urlToNavigateBack = undefined; - return { shouldDeleteTransactionThread, shouldDeleteIOUReport, @@ -5514,7 +5500,6 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT transactionViolations, reportPreviewAction, iouReport, - // urlToNavigateBack, }; } diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 53815b88bde..027fa278cca 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -962,25 +962,6 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { isVisible={isDeleteModalVisible} onConfirm={navigateToTargetUrl} onCancel={() => setIsDeleteModalVisible(false)} - // onModalHide={() => { - // // We use isTransactionDeleted to know if the modal hides because the user deletes the transaction. - // if (!isTransactionDeleted.current) { - // if (caseID === CASES.DEFAULT) { - // if (navigateBackToAfterDelete.current) { - // Navigation.goBack(navigateBackToAfterDelete.current); - // } else { - // Navigation.dismissModal(); - // } - // } - // return; - // } - - // if (!navigateBackToAfterDelete.current) { - // Navigation.dismissModal(); - // } else { - // ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current, true); - // } - // }} prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} From 576e19456c9b3ee6172d5113197d5a66c97f5e3a Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 14 Nov 2024 13:17:12 +0700 Subject: [PATCH 17/37] prettier --- src/libs/actions/IOU.ts | 36 +++++++-------------------------- src/pages/ReportDetailsPage.tsx | 14 +++++-------- 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 9302ed0b0db..b6d6544ba5f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5510,17 +5510,8 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT * @param isSingleTransactionView - Whether we're in single transaction view * @returns The URL to navigate to */ -function getNavigationUrlAfterMoneyRequestDelete( - transactionID: string, - reportAction: OnyxTypes.ReportAction, - isSingleTransactionView = false -): string | undefined { - const { - shouldDeleteTransactionThread, - shouldDeleteIOUReport, - iouReport, - } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); - +function getNavigationUrlAfterMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { + const {shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport} = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); // Determine which report to navigate back to if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { @@ -5542,23 +5533,16 @@ function getNavigationUrlAfterMoneyRequestDelete( * @param isSingleTransactionView - Whether we're in single transaction view * @returns The URL to navigate to */ -function getNavigationUrlAfterTrackExpenseDelete( - chatReportID: string, - transactionID: string, - reportAction: OnyxTypes.ReportAction, - isSingleTransactionView = false -): string | undefined { +function getNavigationUrlAfterTrackExpenseDelete(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; - + // If not a self DM, handle it as a regular money request if (!ReportUtils.isSelfDM(chatReport)) { return getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); } const transactionThreadID = reportAction.childReportID; - const shouldDeleteTransactionThread = transactionThreadID - ? (reportAction?.childVisibleActionCount ?? 0) === 0 - : false; + const shouldDeleteTransactionThread = transactionThreadID ? (reportAction?.childVisibleActionCount ?? 0) === 0 : false; // Only navigate if in single transaction view and the thread will be deleted if (isSingleTransactionView && shouldDeleteTransactionThread && chatReport?.reportID) { @@ -5589,7 +5573,6 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo reportPreviewAction, } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); - const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); // build Onyx data @@ -5965,13 +5948,8 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor } function deleteTrackExpense(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { - const urlToNavigateBack = getNavigationUrlAfterTrackExpenseDelete( - chatReportID, - transactionID, - reportAction, - isSingleTransactionView - ); - + const urlToNavigateBack = getNavigationUrlAfterTrackExpenseDelete(chatReportID, transactionID, reportAction, isSingleTransactionView); + // STEP 1: Get all collections we're updating const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; if (!ReportUtils.isSelfDM(chatReport)) { diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 027fa278cca..4bfc053131d 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -225,7 +225,6 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { const canUnapproveRequest = ReportUtils.isExpenseReport(report) && (ReportUtils.isReportManager(report) || isPolicyAdmin) && ReportUtils.isReportApproved(report) && !PolicyUtils.isSubmitAndClose(policy); - useEffect(() => { return () => { if (!isTransactionDeleted.current) { @@ -236,7 +235,6 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { }; }, []); - useEffect(() => { if (canDeleteRequest) { return; @@ -811,14 +809,13 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { // Where to go back after deleting the transaction and its report. It's empty if the transaction report isn't deleted. const navigateBackToAfterDelete = useRef(); - // Where to go back after deleting the transaction and its report. const navigateToTargetUrl = useCallback(() => { setIsDeleteModalVisible(false); isTransactionDeleted.current = true; - + let urlToNavigateBack: string | undefined; - + if (caseID === CASES.DEFAULT) { urlToNavigateBack = Task.getNavigationUrlAfterTaskDelete(report); Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); @@ -829,11 +826,11 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { } return; } - + if (!requestParentReportAction) { return; } - + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); if (isTrackExpense) { urlToNavigateBack = IOU.getNavigationUrlAfterTrackExpenseDelete(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); @@ -841,13 +838,12 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { urlToNavigateBack = IOU.getNavigationUrlAfterMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); } Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); - + if (!urlToNavigateBack) { Navigation.dismissModal(); } else { ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); } - }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, setIsDeleteModalVisible, isTransactionDeleted]); const deleteTransaction = useCallback(() => { From 7145f31c185f71a15ada45acfc5733fbd1f6cc7e Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 14 Nov 2024 14:00:43 +0700 Subject: [PATCH 18/37] lint & prettier --- src/libs/actions/IOU.ts | 11 +++--- src/libs/actions/Report.ts | 10 +++++ src/pages/ReportDetailsPage.tsx | 67 ++++++++++++++++----------------- src/pages/home/ReportScreen.tsx | 12 +++--- 4 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index b6d6544ba5f..6eaec2c751f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5387,10 +5387,9 @@ function updateMoneyRequestAmountAndCurrency({ * * @param transactionID - The transactionID of IOU * @param reportAction - The reportAction of the transaction in the IOU report - * @param isSingleTransactionView - whether we are in the transaction thread report * @return the url to navigate back once the money request is deleted */ -function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false) { +function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction) { // STEP 1: Get all collections we're updating const allReports = ReportConnection.getAllReports(); const iouReportID = ReportActionsUtils.isMoneyRequestAction(reportAction) ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUReportID : '-1'; @@ -5507,11 +5506,11 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT * Calculate the URL to navigate to after a money request deletion * @param transactionID - The ID of the money request being deleted * @param reportAction - The report action associated with the money request - * @param isSingleTransactionView - Whether we're in single transaction view + * @param isSingleTransactionView - whether we are in the transaction thread report * @returns The URL to navigate to */ function getNavigationUrlAfterMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { - const {shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport} = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + const {shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport} = prepareToCleanUpMoneyRequest(transactionID, reportAction); // Determine which report to navigate back to if (iouReport && isSingleTransactionView && shouldDeleteTransactionThread && !shouldDeleteIOUReport) { @@ -5571,7 +5570,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo chatReport, iouReport, reportPreviewAction, - } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + } = prepareToCleanUpMoneyRequest(transactionID, reportAction); const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); // build Onyx data @@ -5959,7 +5958,7 @@ function deleteTrackExpense(chatReportID: string, transactionID: string, reportA const whisperAction = ReportActionsUtils.getTrackExpenseActionableWhisper(transactionID, chatReportID); const actionableWhisperReportActionID = whisperAction?.reportActionID; - const {parameters, optimisticData, successData, failureData, shouldDeleteTransactionThread} = getDeleteTrackExpenseInformation( + const {parameters, optimisticData, successData, failureData} = getDeleteTrackExpenseInformation( chatReportID, transactionID, reportAction, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index f2b4186fa56..cc28e22b15d 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -4337,6 +4337,14 @@ function exportReportToCSV({reportID, transactionIDList}: ExportReportCSVParams, fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_REPORT_TO_CSV}), 'Expensify.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } +function setDeleteTransactionNavigateBackUrl(url: string) { + Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, url); +} + +function clearDeleteTransactionNavigateBackUrl() { + Onyx.merge(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, null); +} + export type {Video}; export { @@ -4426,4 +4434,6 @@ export { updateReportName, updateRoomVisibility, updateWriteCapability, + setDeleteTransactionNavigateBackUrl, + clearDeleteTransactionNavigateBackUrl, }; diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 4bfc053131d..be4e79916c3 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -3,7 +3,7 @@ import {Str} from 'expensify-common'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import Onyx, {useOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; @@ -225,16 +225,6 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { const canUnapproveRequest = ReportUtils.isExpenseReport(report) && (ReportUtils.isReportManager(report) || isPolicyAdmin) && ReportUtils.isReportApproved(report) && !PolicyUtils.isSubmitAndClose(policy); - useEffect(() => { - return () => { - if (!isTransactionDeleted.current) { - return; - } - - deleteTransaction(); - }; - }, []); - useEffect(() => { if (canDeleteRequest) { return; @@ -804,10 +794,38 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { ); + const deleteTransaction = useCallback(() => { + if (caseID === CASES.DEFAULT) { + Task.deleteTask(report); + return; + } + + if (!requestParentReportAction) { + return; + } + + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + + if (isTrackExpense) { + IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + } else { + IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); + } + }, [caseID, iouTransactionID, isSingleTransactionView, moneyRequestReport?.reportID, report, requestParentReportAction]); + // A flag to indicate whether the user choose to delete the transaction or not const isTransactionDeleted = useRef(false); - // Where to go back after deleting the transaction and its report. It's empty if the transaction report isn't deleted. - const navigateBackToAfterDelete = useRef(); + + useEffect(() => { + return () => { + // Perform the actual deletion after the details page is unmounted. This prevents the [Deleted ...] text from briefly appearing when dismissing the modal. + if (!isTransactionDeleted.current) { + return; + } + + deleteTransaction(); + }; + }, [deleteTransaction]); // Where to go back after deleting the transaction and its report. const navigateToTargetUrl = useCallback(() => { @@ -818,8 +836,8 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { if (caseID === CASES.DEFAULT) { urlToNavigateBack = Task.getNavigationUrlAfterTaskDelete(report); - Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); if (urlToNavigateBack) { + Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); Navigation.goBack(urlToNavigateBack as Route); } else { Navigation.dismissModal(); @@ -837,34 +855,15 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { } else { urlToNavigateBack = IOU.getNavigationUrlAfterMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); } - Onyx.set(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, urlToNavigateBack); if (!urlToNavigateBack) { Navigation.dismissModal(); } else { + Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); } }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, setIsDeleteModalVisible, isTransactionDeleted]); - const deleteTransaction = useCallback(() => { - if (caseID === CASES.DEFAULT) { - Task.deleteTask(report); - return; - } - - if (!requestParentReportAction) { - return; - } - - const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); - - if (isTrackExpense) { - IOU.deleteTrackExpense(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); - } else { - IOU.deleteMoneyRequest(iouTransactionID, requestParentReportAction, isSingleTransactionView); - } - }, [caseID, iouTransactionID, isSingleTransactionView, moneyRequestReport?.reportID, report, requestParentReportAction]); - const mentionReportContextValue = useMemo(() => ({currentReportID: report.reportID, exactlyMatch: true}), [report.reportID]); return ( diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 3d1490df03d..7157d9d5afa 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -1,6 +1,7 @@ import {PortalHost} from '@gorhom/portal'; import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; +import lodashDefer from 'lodash/defer'; import lodashIsEqual from 'lodash/isEqual'; import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import type {FlatList, ViewStyle} from 'react-native'; @@ -53,9 +54,6 @@ import ReportActionsView from './report/ReportActionsView'; import ReportFooter from './report/ReportFooter'; import type {ActionListContextType, ReactionListRef, ScrollPosition} from './ReportScreenContext'; import {ActionListContext, ReactionListContext} from './ReportScreenContext'; -import Onyx from 'react-native-onyx'; -import lodashDefer from 'lodash/defer'; - type ReportScreenNavigationProps = StackScreenProps; @@ -351,17 +349,19 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro // Schedule the code to run after the current call stack is cleared, // ensuring all updates are processed before hide the skeleton lodashDefer(() => { - Onyx.merge(ONYXKEYS.NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL, null); + Report.clearDeleteTransactionNavigateBackUrl(); }); - }, [isFocused]); + }, [isFocused, deleteTransactionNavigateBackUrl]); + + const isLoading = isLoadingApp ?? (!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty()); - const isLoading = isLoadingApp ?? ((!reportIDFromRoute || (!isSidebarLoaded && !isInNarrowPaneModal) || PersonalDetailsUtils.isPersonalDetailsEmpty())); const shouldShowSkeleton = (isLinkingToMessage && !isLinkedMessagePageReady) || (!isLinkingToMessage && !isInitialPageReady) || isEmptyObject(reportOnyx) || isLoadingReportOnyx || !isCurrentReportLoadedFromOnyx || + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing (deleteTransactionNavigateBackUrl && ReportUtils.getReportIDFromLink(deleteTransactionNavigateBackUrl) === report?.reportID) || isLoading; From a343297798fa9425fc4e2767f4a3985043939422 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 15 Nov 2024 09:38:11 +0700 Subject: [PATCH 19/37] Ensure report skeleton hide after interaction and update completed --- src/pages/home/ReportScreen.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 7157d9d5afa..bf2ca0488f6 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -346,10 +346,11 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro if (!isFocused || !deleteTransactionNavigateBackUrl) { return; } - // Schedule the code to run after the current call stack is cleared, - // ensuring all updates are processed before hide the skeleton - lodashDefer(() => { - Report.clearDeleteTransactionNavigateBackUrl(); + // Clear the URL after all interactions are processed to ensure all updates are completed before hiding the skeleton + InteractionManager.runAfterInteractions(() => { + requestAnimationFrame(() => { + Report.clearDeleteTransactionNavigateBackUrl(); + }); }); }, [isFocused, deleteTransactionNavigateBackUrl]); From e41e18212dd320b54b4c9a42993fd6e505b7de72 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 15 Nov 2024 09:46:00 +0700 Subject: [PATCH 20/37] Remove unused import --- src/pages/home/ReportScreen.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index bf2ca0488f6..e0e9286b3a5 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -1,7 +1,6 @@ import {PortalHost} from '@gorhom/portal'; import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import lodashDefer from 'lodash/defer'; import lodashIsEqual from 'lodash/isEqual'; import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import type {FlatList, ViewStyle} from 'react-native'; From 7123b2ff987945f2abf46be661ad1b7d1cbb1397 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 15 Nov 2024 11:06:37 +0700 Subject: [PATCH 21/37] Move navigateToTargetUrl to onModalHide, fix potential bug, remove unnecessary code --- src/libs/actions/IOU.ts | 2 +- src/pages/ReportDetailsPage.tsx | 42 +++++++++++++++++---------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d81b3f0b48f..18f849b3c6e 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5694,7 +5694,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor transactionViolations, iouReport, reportPreviewAction, - } = prepareToCleanUpMoneyRequest(transactionID, reportAction, isSingleTransactionView); + } = prepareToCleanUpMoneyRequest(transactionID, reportAction); const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index be4e79916c3..9a09df29f78 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -829,31 +829,29 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { // Where to go back after deleting the transaction and its report. const navigateToTargetUrl = useCallback(() => { - setIsDeleteModalVisible(false); - isTransactionDeleted.current = true; - let urlToNavigateBack: string | undefined; - if (caseID === CASES.DEFAULT) { - urlToNavigateBack = Task.getNavigationUrlAfterTaskDelete(report); - if (urlToNavigateBack) { - Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); - Navigation.goBack(urlToNavigateBack as Route); - } else { - Navigation.dismissModal(); + if (!isTransactionDeleted.current) { + if (caseID === CASES.DEFAULT) { + urlToNavigateBack = Task.getNavigationUrlAfterTaskDelete(report); + if (urlToNavigateBack) { + Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); + Navigation.goBack(urlToNavigateBack as Route); + } else { + Navigation.dismissModal(); + } + return; } return; } - if (!requestParentReportAction) { - return; - } - - const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); - if (isTrackExpense) { - urlToNavigateBack = IOU.getNavigationUrlAfterTrackExpenseDelete(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); - } else { - urlToNavigateBack = IOU.getNavigationUrlAfterMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); + if (!isEmptyObject(requestParentReportAction)) { + const isTrackExpense = ReportActionsUtils.isTrackExpenseAction(requestParentReportAction); + if (isTrackExpense) { + urlToNavigateBack = IOU.getNavigationUrlAfterTrackExpenseDelete(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); + } else { + urlToNavigateBack = IOU.getNavigationUrlAfterMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); + } } if (!urlToNavigateBack) { @@ -955,13 +953,17 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { { + setIsDeleteModalVisible(false); + isTransactionDeleted.current = true; + }} onCancel={() => setIsDeleteModalVisible(false)} prompt={caseID === CASES.DEFAULT ? translate('task.deleteConfirmation') : translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} danger shouldEnableNewFocusManagement + onModalHide={navigateToTargetUrl} /> Date: Fri, 15 Nov 2024 12:58:21 +0700 Subject: [PATCH 22/37] lint --- src/pages/ReportDetailsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 9a09df29f78..9515ba58375 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -860,7 +860,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); } - }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, setIsDeleteModalVisible, isTransactionDeleted]); + }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, isTransactionDeleted]); const mentionReportContextValue = useMemo(() => ({currentReportID: report.reportID, exactlyMatch: true}), [report.reportID]); @@ -953,7 +953,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { { + onConfirm={() => { setIsDeleteModalVisible(false); isTransactionDeleted.current = true; }} From 6c96672536bbce89a642620b85ad1416b6ad34c8 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 15 Nov 2024 13:06:07 +0700 Subject: [PATCH 23/37] Refactor for more accurate function name --- src/components/MoneyReportHeader.tsx | 2 +- src/libs/ReportUtils.ts | 4 ++-- src/pages/ReportDetailsPage.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 2dc809f9ce6..2c1b1150149 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -500,7 +500,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea isVisible={isDeleteRequestModalVisible} onConfirm={deleteTransaction} onCancel={() => setIsDeleteRequestModalVisible(false)} - onModalHide={() => ReportUtils.navigateBackAfterDeleteTransaction(navigateBackToAfterDelete.current)} + onModalHide={() => ReportUtils.navigateBackOnDeleteTransaction(navigateBackToAfterDelete.current)} prompt={translate('iou.deleteConfirmation', {count: 1})} confirmText={translate('common.delete')} cancelText={translate('common.cancel')} diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ee9b303cb7d..e993f5096c1 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4198,7 +4198,7 @@ function goBackToDetailsPage(report: OnyxEntry, backTo?: string) { Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(report?.reportID ?? '-1', backTo)); } -function navigateBackAfterDeleteTransaction(backRoute: Route | undefined, isFromRHP?: boolean) { +function navigateBackOnDeleteTransaction(backRoute: Route | undefined, isFromRHP?: boolean) { if (!backRoute) { return; } @@ -8675,7 +8675,7 @@ export { canWriteInReport, navigateToDetailsPage, navigateToPrivateNotes, - navigateBackAfterDeleteTransaction, + navigateBackOnDeleteTransaction as navigateBackOnDeleteTransaction, parseReportRouteParams, parseReportActionHtmlToText, requiresAttentionFromCurrentUser, diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 9515ba58375..0d9b6dc626b 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -858,7 +858,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { Navigation.dismissModal(); } else { Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); - ReportUtils.navigateBackAfterDeleteTransaction(urlToNavigateBack as Route, true); + ReportUtils.navigateBackOnDeleteTransaction(urlToNavigateBack as Route, true); } }, [caseID, iouTransactionID, moneyRequestReport?.reportID, report, requestParentReportAction, isSingleTransactionView, isTransactionDeleted]); From 964626bb2bd862fe415c56276fbe3e8265895fc6 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 19 Nov 2024 11:07:59 +0700 Subject: [PATCH 24/37] fix lint --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index c0450dca283..2a76e3cd1dd 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -8694,7 +8694,7 @@ export { canWriteInReport, navigateToDetailsPage, navigateToPrivateNotes, - navigateBackOnDeleteTransaction as navigateBackOnDeleteTransaction, + navigateBackOnDeleteTransaction, parseReportRouteParams, parseReportActionHtmlToText, requiresAttentionFromCurrentUser, From 67eb8271724369aaa02800d51eb04e0d9d5e7558 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 19 Nov 2024 13:20:22 +0700 Subject: [PATCH 25/37] Remove unnecessary code --- src/libs/actions/Task.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 75e00365572..749918724d4 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1138,17 +1138,6 @@ function deleteTask(report: OnyxEntry) { API.write(WRITE_COMMANDS.CANCEL_TASK, parameters, {optimisticData, successData, failureData}); Report.notifyNewAction(report.reportID, currentUserAccountID); - // if (shouldDeleteTaskReport) { - // Navigation.goBack(); - // if (parentReport?.reportID) { - // return ROUTES.REPORT_WITH_ID.getRoute(parentReport.reportID); - // } - // const mostRecentReportID = Report.getMostRecentReportID(report); - // if (mostRecentReportID) { - // return ROUTES.REPORT_WITH_ID.getRoute(mostRecentReportID); - // } - // } - const urlToNavigateBack = getNavigationUrlAfterTaskDelete(report); if (urlToNavigateBack) { Navigation.goBack(); From 62aaa285fed1116ac798ffddccdaa85f90e5d830 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 19 Nov 2024 14:07:45 +0700 Subject: [PATCH 26/37] remove unnecessary export --- src/libs/actions/Task.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 749918724d4..5f892aeff32 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -1255,7 +1255,6 @@ export { canModifyTask, canActionTask, setNewOptimisticAssignee, - getParentReport, getNavigationUrlAfterTaskDelete, }; From 051d3cca74b8a0fbfd75dbe62811f05b7cbd4d3b Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 19 Nov 2024 14:16:16 +0700 Subject: [PATCH 27/37] Adjust tests after change deleting approach from set to merge --- tests/actions/IOUTest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 1c26390f7b0..85cf2b81c01 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -2217,7 +2217,7 @@ describe('actions/IOU', () => { }); }); - expect(report).toBeFalsy(); + expect(report?.reportID).toBeFalsy(); mockFetch?.resume?.(); // Then After resuming fetch, the report for the given thread ID still does not exist @@ -2232,7 +2232,7 @@ describe('actions/IOU', () => { }); }); - expect(report).toBeFalsy(); + expect(report?.reportID).toBeFalsy(); }); it('delete the transaction thread if there are only changelogs (i.e. MODIFIED_EXPENSE actions) in the thread', async () => { From 088777930cfeb8a4cc0fba447a91e57a26f1f582 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 19 Nov 2024 14:20:38 +0700 Subject: [PATCH 28/37] Adjust more test --- tests/actions/IOUTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 85cf2b81c01..1ac0e85beca 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -2339,7 +2339,7 @@ describe('actions/IOU', () => { }); }); - expect(report).toBeFalsy(); + expect(report?.reportID).toBeFalsy(); }); it('does not delete the transaction thread if there are visible comments in the thread', async () => { From 78f8f71a22fbb6c12d0bb7d366bacee842a3e737 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 22 Nov 2024 13:15:43 +0700 Subject: [PATCH 29/37] Update src/ONYXKEYS.ts Co-authored-by: Carlos Martins --- src/ONYXKEYS.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 9f39c7adef1..7310f4ab734 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -219,7 +219,7 @@ const ONYXKEYS = { /** The NVP containing all information related to educational tooltip in workspace chat */ NVP_WORKSPACE_TOOLTIP: 'workspaceTooltip', - /** The NVP contain url to back after deleting transaction */ + /** The NVP containing the target url to navigate to when deleting a transaction */ NVP_DELETE_TRANSACTION_NAVIGATE_BACK_URL: 'nvp_deleteTransactionNavigateBackURL', /** Whether to show save search rename tooltip */ From df0100f4a6e0cb5b1feed3d18cb88c8d150f3f7c Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 22 Nov 2024 13:18:01 +0700 Subject: [PATCH 30/37] Refactor name --- src/libs/actions/IOU.ts | 10 +++++----- src/pages/ReportDetailsPage.tsx | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 210d9f54468..4706578c16e 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5513,7 +5513,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT * @param isSingleTransactionView - whether we are in the transaction thread report * @returns The URL to navigate to */ -function getNavigationUrlAfterMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { +function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { const {shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport} = prepareToCleanUpMoneyRequest(transactionID, reportAction); // Determine which report to navigate back to @@ -5541,7 +5541,7 @@ function getNavigationUrlAfterTrackExpenseDelete(chatReportID: string, transacti // If not a self DM, handle it as a regular money request if (!ReportUtils.isSelfDM(chatReport)) { - return getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); + return getNavigationUrlOnMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); } const transactionThreadID = reportAction.childReportID; @@ -5576,7 +5576,7 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo reportPreviewAction, } = prepareToCleanUpMoneyRequest(transactionID, reportAction); - const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); + const urlToNavigateBack = getNavigationUrlOnMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); // build Onyx data // Onyx operations to delete the transaction, update the IOU report action and chat report action @@ -5714,7 +5714,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor reportPreviewAction, } = prepareToCleanUpMoneyRequest(transactionID, reportAction); - const urlToNavigateBack = getNavigationUrlAfterMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); + const urlToNavigateBack = getNavigationUrlOnMoneyRequestDelete(transactionID, reportAction, isSingleTransactionView); // STEP 2: Build Onyx data // The logic mostly resembles the cleanUpMoneyRequest function @@ -8443,7 +8443,7 @@ export { updateLastLocationPermissionPrompt, resolveDuplicates, getIOUReportActionToApproveOrPay, - getNavigationUrlAfterMoneyRequestDelete, + getNavigationUrlOnMoneyRequestDelete, getNavigationUrlAfterTrackExpenseDelete, }; export type {GPSPoint as GpsPoint, IOURequestType}; diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 0d9b6dc626b..5893ef4a76e 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -850,7 +850,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { if (isTrackExpense) { urlToNavigateBack = IOU.getNavigationUrlAfterTrackExpenseDelete(moneyRequestReport?.reportID ?? '', iouTransactionID, requestParentReportAction, isSingleTransactionView); } else { - urlToNavigateBack = IOU.getNavigationUrlAfterMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); + urlToNavigateBack = IOU.getNavigationUrlOnMoneyRequestDelete(iouTransactionID, requestParentReportAction, isSingleTransactionView); } } From 0ea2bbaf70cbe165a3068c928bebf40ff0e8ff3c Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 22 Nov 2024 13:18:44 +0700 Subject: [PATCH 31/37] remove unnecessary code --- src/libs/actions/IOU.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 4706578c16e..d566fc2e5a5 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5978,10 +5978,6 @@ function deleteTrackExpense(chatReportID: string, transactionID: string, reportA // STEP 7: Navigate the user depending on which page they are on and which resources were deleted return urlToNavigateBack; - // if (isSingleTransactionView && shouldDeleteTransactionThread) { - // // Pop the deleted report screen before navigating. This prevents navigating to the Concierge chat due to the missing report. - // return ROUTES.REPORT_WITH_ID.getRoute(chatReport?.reportID ?? '-1'); - // } } /** From 9cedf925aec661738bf33ef2affd94f9ce575422 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 22 Nov 2024 13:19:34 +0700 Subject: [PATCH 32/37] Update src/pages/ReportDetailsPage.tsx Co-authored-by: Carlos Martins --- src/pages/ReportDetailsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 5893ef4a76e..19362fb312e 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -813,7 +813,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { } }, [caseID, iouTransactionID, isSingleTransactionView, moneyRequestReport?.reportID, report, requestParentReportAction]); - // A flag to indicate whether the user choose to delete the transaction or not + // A flag to indicate whether the user chose to delete the transaction or not const isTransactionDeleted = useRef(false); useEffect(() => { From 65199e2fb326c2dd920904aad0e21db4e1b08e1e Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 22 Nov 2024 13:19:42 +0700 Subject: [PATCH 33/37] Update src/pages/ReportDetailsPage.tsx Co-authored-by: Carlos Martins --- src/pages/ReportDetailsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 19362fb312e..71ca9470998 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -827,7 +827,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { }; }, [deleteTransaction]); - // Where to go back after deleting the transaction and its report. + // Where to navigate back to after deleting the transaction and its report. const navigateToTargetUrl = useCallback(() => { let urlToNavigateBack: string | undefined; From 213fe69f82330b5db8f22bba6e785af14ffe14cf Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 22 Nov 2024 13:21:15 +0700 Subject: [PATCH 34/37] Refactor --- src/libs/actions/Task.ts | 6 +++--- src/pages/ReportDetailsPage.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 5f892aeff32..20ea7b2b141 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -964,7 +964,7 @@ function getParentReport(report: OnyxEntry): OnyxEntry): string | undefined { +function getNavigationUrlOnTaskDelete(report: OnyxEntry): string | undefined { if (!report) { return undefined; } @@ -1138,7 +1138,7 @@ function deleteTask(report: OnyxEntry) { API.write(WRITE_COMMANDS.CANCEL_TASK, parameters, {optimisticData, successData, failureData}); Report.notifyNewAction(report.reportID, currentUserAccountID); - const urlToNavigateBack = getNavigationUrlAfterTaskDelete(report); + const urlToNavigateBack = getNavigationUrlOnTaskDelete(report); if (urlToNavigateBack) { Navigation.goBack(); return urlToNavigateBack; @@ -1255,7 +1255,7 @@ export { canModifyTask, canActionTask, setNewOptimisticAssignee, - getNavigationUrlAfterTaskDelete, + getNavigationUrlOnTaskDelete, }; export type {PolicyValue, Assignee, ShareDestination}; diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 5893ef4a76e..a2af7a71928 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -833,7 +833,7 @@ function ReportDetailsPage({policies, report, route}: ReportDetailsPageProps) { if (!isTransactionDeleted.current) { if (caseID === CASES.DEFAULT) { - urlToNavigateBack = Task.getNavigationUrlAfterTaskDelete(report); + urlToNavigateBack = Task.getNavigationUrlOnTaskDelete(report); if (urlToNavigateBack) { Report.setDeleteTransactionNavigateBackUrl(urlToNavigateBack); Navigation.goBack(urlToNavigateBack as Route); From 51daaa0a6f7b46b26f55adda2ca1c23dd00588bc Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 22 Nov 2024 13:56:16 +0700 Subject: [PATCH 35/37] resolve typecheck error --- 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 7d1d7623ff5..1e042cb2d37 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -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 type {Route} from '@src/ROUTES'; 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'; @@ -5503,7 +5504,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT * @param isSingleTransactionView - whether we are in the transaction thread report * @returns The URL to navigate to */ -function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { +function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): Route | undefined { const {shouldDeleteTransactionThread, shouldDeleteIOUReport, iouReport} = prepareToCleanUpMoneyRequest(transactionID, reportAction); // Determine which report to navigate back to @@ -5526,7 +5527,7 @@ function getNavigationUrlOnMoneyRequestDelete(transactionID: string, reportActio * @param isSingleTransactionView - Whether we're in single transaction view * @returns The URL to navigate to */ -function getNavigationUrlAfterTrackExpenseDelete(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): string | undefined { +function getNavigationUrlAfterTrackExpenseDelete(chatReportID: string, transactionID: string, reportAction: OnyxTypes.ReportAction, isSingleTransactionView = false): Route | undefined { const chatReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`] ?? null; // If not a self DM, handle it as a regular money request From 5e5026d0f9b6bb7ad0e4e78007278d39f2ec27b1 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 23 Nov 2024 08:51:18 +0700 Subject: [PATCH 36/37] Add comment why use merge instead of set when deleting report --- src/libs/actions/IOU.ts | 8 ++++++++ src/libs/actions/Report.ts | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 82666e12fce..a25a5d3032b 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1784,6 +1784,8 @@ function getDeleteTrackExpenseInformation( if (shouldDeleteTransactionThread) { optimisticData.push( + // Use merge instead of set to avoid deleting the report too quickly, which could cause a brief "not found" page to appear. + // The remaining parts of the report object will be removed after the API call is successful. { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, @@ -1836,6 +1838,8 @@ function getDeleteTrackExpenseInformation( }, ]; + // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. + // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. if (shouldDeleteTransactionThread && transactionThread) { successData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -5768,6 +5772,8 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor if (shouldDeleteTransactionThread) { optimisticData.push( + // Use merge instead of set to avoid deleting the report too quickly, which could cause a brief "not found" page to appear. + // The remaining parts of the report object will be removed after the API call is successful. { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadID}`, @@ -5878,6 +5884,8 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor }, ]; + // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. + // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. if (shouldDeleteTransactionThread && transactionThread) { successData.push({ onyxMethod: Onyx.METHOD.MERGE, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index ef21096cb80..4fcfb0dde13 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -2915,6 +2915,8 @@ function leaveGroupChat(reportID: string) { }); } + // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. + // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, From 5ddba66c78d1c8a39b75a2bb30b0d454fb54fad1 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 23 Nov 2024 08:53:30 +0700 Subject: [PATCH 37/37] prettier --- src/libs/actions/IOU.ts | 4 ++-- src/libs/actions/Report.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a25a5d3032b..d4b6595600c 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1839,7 +1839,7 @@ function getDeleteTrackExpenseInformation( ]; // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. - // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. + // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. if (shouldDeleteTransactionThread && transactionThread) { successData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -5885,7 +5885,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor ]; // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. - // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. + // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. if (shouldDeleteTransactionThread && transactionThread) { successData.push({ onyxMethod: Onyx.METHOD.MERGE, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 4fcfb0dde13..5ce3245aa82 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -2916,7 +2916,7 @@ function leaveGroupChat(reportID: string) { } // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. - // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. + // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE,