diff --git a/src/components/DistanceRequest/index.js b/src/components/DistanceRequest/index.js index 995785bdebd5..be34a42ead5e 100644 --- a/src/components/DistanceRequest/index.js +++ b/src/components/DistanceRequest/index.js @@ -23,6 +23,7 @@ import useThemeStyles from '@styles/useThemeStyles'; import variables from '@styles/variables'; import * as MapboxToken from '@userActions/MapboxToken'; import * as Transaction from '@userActions/Transaction'; +import * as TransactionEdit from '@userActions/TransactionEdit'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import DistanceRequestFooter from './DistanceRequestFooter'; @@ -38,6 +39,9 @@ const propTypes = { /** Are we editing an existing distance request, or creating a new one? */ isEditingRequest: PropTypes.bool, + /** Are we editing the distance while creating a new distance request */ + isEditingNewRequest: PropTypes.bool, + /** Called on submit of this page */ onSubmit: PropTypes.func.isRequired, @@ -61,17 +65,17 @@ const defaultProps = { transactionID: '', report: {}, isEditingRequest: false, + isEditingNewRequest: false, transaction: {}, }; -function DistanceRequest({transactionID, report, transaction, route, isEditingRequest, onSubmit}) { +function DistanceRequest({transactionID, report, transaction, route, isEditingRequest, isEditingNewRequest, onSubmit}) { const styles = useThemeStyles(); const {isOffline} = useNetwork(); const {translate} = useLocalize(); const [optimisticWaypoints, setOptimisticWaypoints] = useState(null); const [hasError, setHasError] = useState(false); - const isEditing = Navigation.getActiveRoute().includes('address'); const reportID = lodashGet(report, 'reportID', ''); const waypoints = useMemo(() => optimisticWaypoints || lodashGet(transaction, 'comment.waypoints', {waypoint0: {}, waypoint1: {}}), [optimisticWaypoints, transaction]); const waypointsList = _.keys(waypoints); @@ -90,12 +94,36 @@ function DistanceRequest({transactionID, report, transaction, route, isEditingRe const haveValidatedWaypointsChanged = !_.isEqual(previousValidatedWaypoints, validatedWaypoints); const isRouteAbsentWithoutErrors = !hasRoute && !hasRouteError; const shouldFetchRoute = (isRouteAbsentWithoutErrors || haveValidatedWaypointsChanged) && !isLoadingRoute && _.size(validatedWaypoints) > 1; + const transactionWasSaved = useRef(false); useEffect(() => { MapboxToken.init(); return MapboxToken.stop; }, []); + useEffect(() => { + if (!isEditingNewRequest && !isEditingRequest) { + 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(transaction.transactionID); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + useEffect(() => { const transactionWaypoints = lodashGet(transaction, 'comment.waypoints', {}); if (!lodashGet(transaction, 'transactionID') || !_.isEmpty(transactionWaypoints)) { @@ -134,7 +162,7 @@ function DistanceRequest({transactionID, report, transaction, route, isEditingRe }, [waypoints, previousWaypoints]); const navigateBack = () => { - Navigation.goBack(isEditing ? ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID) : ROUTES.HOME); + Navigation.goBack(isEditingNewRequest ? ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, reportID) : ROUTES.HOME); }; /** @@ -182,8 +210,13 @@ function DistanceRequest({transactionID, report, transaction, route, isEditingRe setHasError(true); return; } + + if (isEditingNewRequest || isEditingRequest) { + transactionWasSaved.current = true; + } + onSubmit(waypoints); - }, [onSubmit, setHasError, hasRouteError, isLoadingRoute, isLoading, validatedWaypoints, waypoints]); + }, [onSubmit, setHasError, hasRouteError, isLoadingRoute, isLoading, validatedWaypoints, waypoints, isEditingNewRequest, isEditingRequest]); const content = ( <> @@ -238,7 +271,7 @@ function DistanceRequest({transactionID, report, transaction, route, isEditingRe ); - if (!isEditing) { + if (!isEditingNewRequest) { return content; } diff --git a/src/pages/EditRequestDistancePage.js b/src/pages/EditRequestDistancePage.js index 48b80890dc49..0ea295c0780b 100644 --- a/src/pages/EditRequestDistancePage.js +++ b/src/pages/EditRequestDistancePage.js @@ -12,7 +12,6 @@ import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; import Navigation from '@libs/Navigation/Navigation'; import * as IOU from '@userActions/IOU'; -import * as TransactionEdit from '@userActions/TransactionEdit'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import reportPropTypes from './reportPropTypes'; @@ -52,7 +51,6 @@ const defaultProps = { function EditRequestDistancePage({report, route, transaction, transactionBackup}) { const {isOffline} = useNetwork(); const {translate} = useLocalize(); - const transactionWasSaved = useRef(false); const hasWaypointError = useRef(false); const prevIsLoading = usePrevious(transaction.isLoading); @@ -66,26 +64,6 @@ function EditRequestDistancePage({report, route, transaction, transactionBackup} } }, [transaction, prevIsLoading, report]); - useEffect(() => { - // 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(transaction.transactionID); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - /** * Save the changes to the original transaction object * @param {Object} waypoints @@ -101,7 +79,6 @@ function EditRequestDistancePage({report, route, transaction, transactionBackup} return; } - transactionWasSaved.current = true; IOU.editMoneyRequest(transaction, report.reportID, {waypoints}); // If the client is offline, then the modal can be closed as well (because there are no errors or other feedback to show them diff --git a/src/pages/iou/NewDistanceRequestPage.js b/src/pages/iou/NewDistanceRequestPage.js index fc4549be3b33..750ac5d0141e 100644 --- a/src/pages/iou/NewDistanceRequestPage.js +++ b/src/pages/iou/NewDistanceRequestPage.js @@ -1,13 +1,15 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useEffect} from 'react'; +import React, {useCallback, useEffect} from 'react'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import DistanceRequest from '@components/DistanceRequest'; +import Navigation from '@libs/Navigation/Navigation'; import reportPropTypes from '@pages/reportPropTypes'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import {iouPropTypes} from './propTypes'; const propTypes = { @@ -44,6 +46,7 @@ const defaultProps = { // You can't use Onyx props in the withOnyx mapping, so we need to set up and access the transactionID here, and then pass it down so that DistanceRequest can subscribe to the transaction. function NewDistanceRequestPage({iou, report, route}) { const iouType = lodashGet(route, 'params.iouType', 'request'); + const isEditingNewRequest = Navigation.getActiveRoute().includes('address'); useEffect(() => { if (iou.transactionID) { @@ -52,12 +55,21 @@ function NewDistanceRequestPage({iou, report, route}) { IOU.setUpDistanceTransaction(); }, [iou.transactionID]); + const onSubmit = useCallback(() => { + if (isEditingNewRequest) { + Navigation.goBack(ROUTES.MONEY_REQUEST_CONFIRMATION.getRoute(iouType, report.reportID)); + return; + } + IOU.navigateToNextPage(iou, iouType, report); + }, [iou, iouType, isEditingNewRequest, report]); + return ( IOU.navigateToNextPage(iou, iouType, report)} + onSubmit={onSubmit} /> ); }