From 6379d9db4261d906227e17cb5bab03a45bef35dc Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Wed, 27 Mar 2024 16:54:25 +0700 Subject: [PATCH 1/5] add backup transaction again --- .../request/step/IOURequestStepDistance.js | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.js b/src/pages/iou/request/step/IOURequestStepDistance.js index dad610cbc636..a86c4146a685 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.js +++ b/src/pages/iou/request/step/IOURequestStepDistance.js @@ -15,6 +15,7 @@ import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; +import * as TransactionEdit from '@userActions/TransactionEdit'; import Navigation from '@libs/Navigation/Navigation'; import * as TransactionUtils from '@libs/TransactionUtils'; import reportPropTypes from '@pages/reportPropTypes'; @@ -85,6 +86,7 @@ function IOURequestStepDistance({ const atLeastTwoDifferentWaypointsError = useMemo(() => _.size(validatedWaypoints) < 2, [validatedWaypoints]); const isEditing = action === CONST.IOU.ACTION.EDIT; const isCreatingNewRequest = Navigation.getActiveRoute().includes('start'); + const transactionWasSaved = useRef(false); useEffect(() => { MapboxToken.init(); @@ -112,6 +114,29 @@ function IOURequestStepDistance({ setShouldShowAtLeastTwoDifferentWaypointsError(false); }, [atLeastTwoDifferentWaypointsError, duplicateWaypointsError, hasRouteError, isLoading, isLoadingRoute, nonEmptyWaypointsCount, transaction]); + useEffect(() => { + if (isCreatingNewRequest) { + return () => {}; + } + // This effect runs when the component is mounted and unmounted. It's purpose is to be able to properly + // discard changes if the user cancels out of making any changes. This is accomplished by backing up the + // original transaction, letting the user modify the current transaction, and then if the user ever + // cancels out of the modal without saving changes, the original transaction is restored from the backup. + + // On mount, create the backup transaction. + TransactionEdit.createBackupTransaction(transaction); + + return () => { + // If the user cancels out of the modal without without saving changes, then the original transaction + // needs to be restored from the backup so that all changes are removed. + if (transactionWasSaved.current) { + return; + } + TransactionEdit.restoreOriginalTransactionFromBackup(lodashGet(transaction, 'transactionID', '')); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const navigateBack = () => { Navigation.goBack(backTo); }; @@ -191,6 +216,9 @@ function IOURequestStepDistance({ setShouldShowAtLeastTwoDifferentWaypointsError(true); return; } + if (!isCreatingNewRequest) { + transactionWasSaved.current = true; + } if (isEditing) { // If nothing was changed, simply go to transaction thread // We compare only addresses because numbers are rounded while backup @@ -207,19 +235,7 @@ function IOURequestStepDistance({ } navigateToNextStep(); - }, [ - duplicateWaypointsError, - atLeastTwoDifferentWaypointsError, - hasRouteError, - isLoadingRoute, - isLoading, - isEditing, - navigateToNextStep, - transactionBackup, - waypoints, - transaction.transactionID, - report.reportID, - ]); + }, [duplicateWaypointsError, atLeastTwoDifferentWaypointsError, hasRouteError, isLoadingRoute, isLoading, isCreatingNewRequest, isEditing, navigateToNextStep, transactionBackup, waypoints, transaction.transactionID, report.reportID]); return ( Date: Thu, 28 Mar 2024 16:04:35 +0700 Subject: [PATCH 2/5] add isDraft param --- src/libs/actions/TransactionEdit.ts | 4 ++-- src/pages/iou/request/step/IOURequestStepDistance.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/TransactionEdit.ts b/src/libs/actions/TransactionEdit.ts index b1710aa72cbb..eed0485a7b56 100644 --- a/src/libs/actions/TransactionEdit.ts +++ b/src/libs/actions/TransactionEdit.ts @@ -26,14 +26,14 @@ function removeBackupTransaction(transactionID: string) { Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, null); } -function restoreOriginalTransactionFromBackup(transactionID: string) { +function restoreOriginalTransactionFromBackup(transactionID: string, isDraft: boolean) { const connectionID = Onyx.connect({ key: `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, callback: (backupTransaction) => { Onyx.disconnect(connectionID); // Use set to completely overwrite the original transaction - Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, backupTransaction); + Onyx.set(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, backupTransaction); removeBackupTransaction(transactionID); }, }); diff --git a/src/pages/iou/request/step/IOURequestStepDistance.js b/src/pages/iou/request/step/IOURequestStepDistance.js index a86c4146a685..1dea27b2293f 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.js +++ b/src/pages/iou/request/step/IOURequestStepDistance.js @@ -132,7 +132,7 @@ function IOURequestStepDistance({ if (transactionWasSaved.current) { return; } - TransactionEdit.restoreOriginalTransactionFromBackup(lodashGet(transaction, 'transactionID', '')); + TransactionEdit.restoreOriginalTransactionFromBackup(lodashGet(transaction, 'transactionID', ''), action === CONST.IOU.ACTION.CREATE); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); From 752d5786b7c42fc8b8d757409704b6a70b913112 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Thu, 28 Mar 2024 16:21:43 +0700 Subject: [PATCH 3/5] lint fix --- .../iou/request/step/IOURequestStepDistance.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.js b/src/pages/iou/request/step/IOURequestStepDistance.js index 1dea27b2293f..d4e82e7918b2 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.js +++ b/src/pages/iou/request/step/IOURequestStepDistance.js @@ -15,7 +15,6 @@ import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; import * as ErrorUtils from '@libs/ErrorUtils'; -import * as TransactionEdit from '@userActions/TransactionEdit'; import Navigation from '@libs/Navigation/Navigation'; import * as TransactionUtils from '@libs/TransactionUtils'; import reportPropTypes from '@pages/reportPropTypes'; @@ -23,6 +22,7 @@ import variables from '@styles/variables'; import * as IOU from '@userActions/IOU'; import * as MapboxToken from '@userActions/MapboxToken'; import * as Transaction from '@userActions/Transaction'; +import * as TransactionEdit from '@userActions/TransactionEdit'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -235,7 +235,20 @@ function IOURequestStepDistance({ } navigateToNextStep(); - }, [duplicateWaypointsError, atLeastTwoDifferentWaypointsError, hasRouteError, isLoadingRoute, isLoading, isCreatingNewRequest, isEditing, navigateToNextStep, transactionBackup, waypoints, transaction.transactionID, report.reportID]); + }, [ + duplicateWaypointsError, + atLeastTwoDifferentWaypointsError, + hasRouteError, + isLoadingRoute, + isLoading, + isCreatingNewRequest, + isEditing, + navigateToNextStep, + transactionBackup, + waypoints, + transaction.transactionID, + report.reportID, + ]); return ( Date: Mon, 8 Apr 2024 16:15:07 +0700 Subject: [PATCH 4/5] add new field and get correct transactionID --- src/ONYXKEYS.ts | 4 +++- src/libs/actions/TransactionEdit.ts | 6 +++--- src/pages/iou/request/step/IOURequestStepDistance.js | 5 ++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 0a21cb17df7e..f47d9e554414 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -337,9 +337,10 @@ const ONYXKEYS = { SECURITY_GROUP: 'securityGroup_', TRANSACTION: 'transactions_', TRANSACTION_VIOLATIONS: 'transactionViolations_', + TRANSACTION_DRAFT: 'transactionsDraft_', // Holds temporary transactions used during the creation and edit flow - TRANSACTION_DRAFT: 'transactionsDraft_', + TRANSACTION_BACKUP: 'transactionsBackup_', SPLIT_TRANSACTION_DRAFT: 'splitTransactionDraft_', PRIVATE_NOTES_DRAFT: 'privateNotesDraft_', NEXT_STEP: 'reportNextStep_', @@ -537,6 +538,7 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup; [ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction; [ONYXKEYS.COLLECTION.TRANSACTION_DRAFT]: OnyxTypes.Transaction; + [ONYXKEYS.COLLECTION.TRANSACTION_BACKUP]: OnyxTypes.Transaction; [ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS]: OnyxTypes.TransactionViolations; [ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT]: OnyxTypes.Transaction; [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags; diff --git a/src/libs/actions/TransactionEdit.ts b/src/libs/actions/TransactionEdit.ts index eed0485a7b56..26219d72920e 100644 --- a/src/libs/actions/TransactionEdit.ts +++ b/src/libs/actions/TransactionEdit.ts @@ -16,19 +16,19 @@ function createBackupTransaction(transaction: OnyxEntry) { }; // Use set so that it will always fully overwrite any backup transaction that could have existed before - Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`, newTransaction); + Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transaction.transactionID}`, newTransaction); } /** * Removes a transaction from Onyx that was only used temporary in the edit flow */ function removeBackupTransaction(transactionID: string) { - Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, null); + Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transactionID}`, null); } function restoreOriginalTransactionFromBackup(transactionID: string, isDraft: boolean) { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, + key: `${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transactionID}`, callback: (backupTransaction) => { Onyx.disconnect(connectionID); diff --git a/src/pages/iou/request/step/IOURequestStepDistance.js b/src/pages/iou/request/step/IOURequestStepDistance.js index ddfd01e49379..0c1c362f93fa 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.js +++ b/src/pages/iou/request/step/IOURequestStepDistance.js @@ -321,7 +321,10 @@ export default compose( withFullTransactionOrNotFound, withOnyx({ transactionBackup: { - key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${props.transactionID}`, + key: ({route}) => { + const transactionID = lodashGet(route, 'params.transactionID', 0); + return `${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transactionID}`; + }, }, }), )(IOURequestStepDistance); From db75ccd6f667c1bfc99fc11821fefbf8e9c86f78 Mon Sep 17 00:00:00 2001 From: DylanDylann Date: Thu, 11 Apr 2024 13:32:32 +0700 Subject: [PATCH 5/5] update comment --- src/pages/iou/request/step/IOURequestStepDistance.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.js b/src/pages/iou/request/step/IOURequestStepDistance.js index 3eae0de1e665..398b2f83712b 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.js +++ b/src/pages/iou/request/step/IOURequestStepDistance.js @@ -114,14 +114,14 @@ function IOURequestStepDistance({ setShouldShowAtLeastTwoDifferentWaypointsError(false); }, [atLeastTwoDifferentWaypointsError, duplicateWaypointsError, hasRouteError, isLoading, isLoadingRoute, nonEmptyWaypointsCount, transaction]); + // This effect runs when the component is mounted and unmounted. It's purpose is to be able to properly + // discard changes if the user cancels out of making any changes. This is accomplished by backing up the + // original transaction, letting the user modify the current transaction, and then if the user ever + // cancels out of the modal without saving changes, the original transaction is restored from the backup. useEffect(() => { if (isCreatingNewRequest) { return () => {}; } - // This effect runs when the component is mounted and unmounted. It's purpose is to be able to properly - // discard changes if the user cancels out of making any changes. This is accomplished by backing up the - // original transaction, letting the user modify the current transaction, and then if the user ever - // cancels out of the modal without saving changes, the original transaction is restored from the backup. // On mount, create the backup transaction. TransactionEdit.createBackupTransaction(transaction);