Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add backup transaction again #39144

Merged
merged 9 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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_',
Expand Down Expand Up @@ -539,6 +540,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;
Expand Down
10 changes: 5 additions & 5 deletions src/libs/actions/TransactionEdit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ function createBackupTransaction(transaction: OnyxEntry<Transaction>) {
};

// 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);
Beamanator marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* 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) {
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);

// 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);
},
});
Expand Down
34 changes: 33 additions & 1 deletion src/pages/iou/request/step/IOURequestStepDistance.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,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';
Expand Down Expand Up @@ -84,6 +85,7 @@ function IOURequestStepDistance({
const duplicateWaypointsError = useMemo(() => nonEmptyWaypointsCount >= 2 && _.size(validatedWaypoints) !== nonEmptyWaypointsCount, [nonEmptyWaypointsCount, validatedWaypoints]);
const atLeastTwoDifferentWaypointsError = useMemo(() => _.size(validatedWaypoints) < 2, [validatedWaypoints]);
const isEditing = action === CONST.IOU.ACTION.EDIT;
const transactionWasSaved = useRef(false);
const isCreatingNewRequest = !(backTo || isEditing);

useEffect(() => {
Expand Down Expand Up @@ -112,6 +114,29 @@ 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 () => {};
}

// 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', ''), action === CONST.IOU.ACTION.CREATE);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const navigateBack = () => {
Navigation.goBack(backTo);
};
Expand Down Expand Up @@ -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
Expand All @@ -213,6 +241,7 @@ function IOURequestStepDistance({
hasRouteError,
isLoadingRoute,
isLoading,
isCreatingNewRequest,
isEditing,
navigateToNextStep,
transactionBackup,
Expand Down Expand Up @@ -292,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);
Loading