From 43a729626bc2a3a252a83dadcc5c28e881e14fb1 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 14:55:28 -0700 Subject: [PATCH 001/135] add distance request consts --- src/CONST.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CONST.js b/src/CONST.js index c78268aacd8b..53a7f14c75b5 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1309,6 +1309,7 @@ const CONST = { DATE: 'date', DESCRIPTION: 'description', MERCHANT: 'merchant', + DISTANCE: 'distance', }, FOOTER: { EXPENSE_MANAGEMENT_URL: `${USE_EXPENSIFY_URL}/expense-management`, From 28c293e462f7d1b58d1bd5f1cdeb4d86955ccad5 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 16:03:53 -0700 Subject: [PATCH 002/135] add DISTANCE_REQUEST ONYXKEY --- src/ONYXKEYS.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index d4d2ab1f90a6..78430e0fdf33 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -41,6 +41,9 @@ const ONYXKEYS = { // Contains loading data for the IOU feature (MoneyRequestModal, IOUDetail, & MoneyRequestPreview Components) IOU: 'iou', + // Contains loading data for the DistanceRequest components (MoneyRequestEditWaypointPage) + DISTANCE_REQUEST: 'distanceRequest', + /** Keeps track if there is modal currently visible or not */ MODAL: 'modal', From 322504aafb2a51ac8ffa998db3b12f24935371f9 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 16:04:17 -0700 Subject: [PATCH 003/135] add routes for editdistancerequest and editrequestwaypoint --- src/ROUTES.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ROUTES.js b/src/ROUTES.js index bf1beaecb3c3..df36bf3e5069 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -97,6 +97,7 @@ export default { MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', MONEY_REQUEST_DISTANCE_TAB: ':iouType/new/:reportID?/distance', MONEY_REQUEST_WAYPOINT: ':iouType/new/waypoint/:waypointIndex', + MONEY_REQUEST_EDIT_WAYPOINT: 'r/:threadReportID/edit/distance/waypoint/:waypointIndex', IOU_SEND_ADD_BANK_ACCOUNT: `${IOU_SEND}/add-bank-account`, IOU_SEND_ADD_DEBIT_CARD: `${IOU_SEND}/add-debit-card`, IOU_SEND_ENABLE_PAYMENTS: `${IOU_SEND}/enable-payments`, @@ -111,6 +112,7 @@ export default { getMoneyRequestMerchantRoute: (iouType, reportID = '') => `${iouType}/new/merchant/${reportID}`, getMoneyRequestDistanceTabRoute: (iouType, reportID = '') => `${iouType}/new/${reportID}/distance`, getMoneyRequestWaypointRoute: (iouType, waypointIndex) => `${iouType}/new/waypoint/${waypointIndex}`, + getMoneyRequestEditWaypointRoute: (threadReportID, waypointIndex) => `r/${threadReportID}/edit/distance/waypoint/${waypointIndex}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID, reportActionID) => `r/${reportID}/split/${reportActionID}`, getNewTaskRoute: (reportID) => `${NEW_TASK}/${reportID}`, From c5c72a5bba9430de145a99ca1ae2e4eb81dc789c Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 16:04:33 -0700 Subject: [PATCH 004/135] add distance translations --- src/languages/en.js | 1 + src/languages/es.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.js b/src/languages/en.js index 5dcb84c4e487..cdc96834289b 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -158,6 +158,7 @@ export default { category: 'Category', receipt: 'Receipt', replace: 'Replace', + distance: 'Distance', }, anonymousReportFooter: { logoTagline: 'Join the discussion.', diff --git a/src/languages/es.js b/src/languages/es.js index 9cb91261cdd5..35ac0c2cc9d8 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -157,6 +157,7 @@ export default { category: 'Categoría', receipt: 'Recibo', replace: 'Sustituir', + distance: 'Distancia', }, anonymousReportFooter: { logoTagline: 'Únete a la discusión.', From 85ac77daa978300b79c7e4386cc0c07f05327e9e Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 16:04:50 -0700 Subject: [PATCH 005/135] add editDistanceRequest actions --- src/libs/actions/IOU.js | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 838214bbd98e..3f64c2c7c756 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -530,6 +530,61 @@ function createDistanceRequest(report, payeeEmail, payeeAccountID, participant, ); } +/** + * Edits an existing distance request + * + * @param {String} transactionID + * @param {Object} transactionChanges + * @param {String} [transactionChanges.created] + * @param {Number} [transactionChanges.amount] + * @param {String} [transactionChanges.comment] + * @param {String} [transactionChanges.waypoints] + * + */ +function editDistanceRequest(transactionID, transactionThreadReportID, transactionChanges) { + const pendingFields = _.mapObject(updatedProperties, () => CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE); + const clearedPendingFields = _.mapObject(updatedProperties, () => null); + const errorFields = _.mapObject(pendingFields, () => ({ + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.edit.genericError'), + })); + + const transactionThread = allReports[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`]; + const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; + const iouReport = allReports[`${ONYXKEYS.COLLECTION.REPORT}${transactionThread.parentReportID}`]; + const isFromExpenseReport = ReportUtils.isExpenseReport(iouReport); + const updatedTransaction = TransactionUtils.getUpdatedTransaction(transaction, transactionChanges, isFromExpenseReport); + API.write( + 'EditDistanceRequest', + {transactionID, ...ReportUtils.getTransactionDetails(updatedTransaction)}, + { + optimisticData: [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + value: {...updatedProperties, pendingFields}, + }, + ], + successData: [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + value: {pendingFields: clearedPendingFields}, + }, + ], + failureData: [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + value: { + pendingFields: clearedPendingFields, + errorFields, + }, + }, + ], + }, + ); +} + /** * Request money from another user * @@ -1767,6 +1822,13 @@ function createEmptyTransaction() { Onyx.merge(ONYXKEYS.IOU, {transactionID}); } +/** + * @param {String} transactionID + */ +function setDistanceRequestTransactionID(transactionID) { + Onyx.set(ONYXKEYS.DISTANCE_REQUEST, {transactionID}); +} + /** * Navigates to the next IOU page based on where the IOU request was started * @@ -1825,6 +1887,8 @@ export { setMoneyRequestMerchant, setMoneyRequestParticipants, setMoneyRequestReceipt, + setDistanceRequestTransactionID, createEmptyTransaction, navigateToNextPage, + editDistanceRequest, }; From 4cac0948a58821e3c9587b178eb82af91f657292 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 16:05:12 -0700 Subject: [PATCH 006/135] add new pages for editing distance requests --- src/pages/EditRequestDistancePage.js | 51 ++++++++++++++++++ src/pages/iou/MoneyRequestEditWaypointPage.js | 52 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/pages/EditRequestDistancePage.js create mode 100644 src/pages/iou/MoneyRequestEditWaypointPage.js diff --git a/src/pages/EditRequestDistancePage.js b/src/pages/EditRequestDistancePage.js new file mode 100644 index 000000000000..f2587db43a14 --- /dev/null +++ b/src/pages/EditRequestDistancePage.js @@ -0,0 +1,51 @@ +import React, {useEffect} from 'react'; +import PropTypes from 'prop-types'; +import ScreenWrapper from '../components/ScreenWrapper'; +import HeaderWithBackButton from '../components/HeaderWithBackButton'; +import Navigation from '../libs/Navigation/Navigation'; +import useLocalize from '../hooks/useLocalize'; +import DistanceRequest from '../components/DistanceRequest'; +import reportPropTypes from './reportPropTypes'; +import * as IOU from '../libs/actions/IOU'; + +const propTypes = { + /** The transactionID we're currently editing */ + transactionID: PropTypes.number, + + /** The report to with which the distance request is associated */ + report: reportPropTypes, +}; + +function EditRequestDistancePage({iou, report}) { + + useEffect(() => { + IOU.setDistanceRequestTransactionID(iou.transactionID); + }, []) + + const {translate} = useLocalize(); + return ( + + Navigation.goBack()} + /> + { + IOU.editDistanceRequest(iou.transactionID, report.reportID, {waypoints}); + Navigation.dismissModal(); + }} + /> + + ); +} + +EditRequestDistancePage.propTypes = propTypes; +EditRequestDistancePage.displayName = 'EditRequestDistancePage'; + +export default EditRequestDistancePage; diff --git a/src/pages/iou/MoneyRequestEditWaypointPage.js b/src/pages/iou/MoneyRequestEditWaypointPage.js new file mode 100644 index 000000000000..4a212cadd957 --- /dev/null +++ b/src/pages/iou/MoneyRequestEditWaypointPage.js @@ -0,0 +1,52 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import WaypointEditor from './WaypointEditor'; +import ONYXKEYS from '../../ONYXKEYS'; + +const propTypes = { + /** The transactionID of this request */ + transactionID: PropTypes.string, + + /** Route params */ + route: PropTypes.shape({ + params: PropTypes.shape({ + /** IOU type */ + iouType: PropTypes.string, + + /** Index of the waypoint being edited */ + waypointIndex: PropTypes.string, + }), + }), +}; + +const defaultProps = { + transactionID: '', + route: { + params: { + iouType: '', + waypointIndex: '', + }, + }, +}; + +// This component is responsible for grabbing the transactionID from the IOU key +// 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 WaypointEditor can subscribe to the transaction. +function MoneyRequestEditWaypointPage({transactionID, route}) { + console.log(">>>> transactionID", transactionID); + return ( + + ); +} + +MoneyRequestEditWaypointPage.displayName = 'MoneyRequestEditWaypointPage'; +MoneyRequestEditWaypointPage.propTypes = propTypes; +MoneyRequestEditWaypointPage.defaultProps = defaultProps; +export default withOnyx({ + // We must provide a default value for transactionID here, otherwise the component won't mount + // because withOnyx returns null until all the keys are defined + transactionID: {key: ONYXKEYS.DISTANCE_REQUEST, selector: (distanceRequest) => (distanceRequest && distanceRequest.transactionID) || ''}, +})(MoneyRequestEditWaypointPage); From ec140606b87805a5dc28f94e5ca816f3dc0f729c Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Mon, 28 Aug 2023 16:05:44 -0700 Subject: [PATCH 007/135] simplify DistanceRequest to just take a transactionID, modify to handle edits --- src/components/DistanceRequest.js | 47 ++++++++++++++----------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index c96342dd8965..55975022866a 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -22,7 +22,6 @@ import useNetwork from '../hooks/useNetwork'; import useLocalize from '../hooks/useLocalize'; import Navigation from '../libs/Navigation/Navigation'; import ROUTES from '../ROUTES'; -import * as IOU from '../libs/actions/IOU'; import participantPropTypes from './participantPropTypes'; import reportPropTypes from '../pages/reportPropTypes'; import transactionPropTypes from './transactionPropTypes'; @@ -38,17 +37,8 @@ const MAP_PADDING = 50; const DEFAULT_ZOOM_LEVEL = 10; const propTypes = { - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: PropTypes.shape({ - id: PropTypes.string, - amount: PropTypes.number, - currency: PropTypes.string, - participants: PropTypes.arrayOf(participantPropTypes), - transactionID: PropTypes.string, - }), - - /** Type of money request (i.e. IOU) */ - iouType: PropTypes.string, + /** The transactionID of the distance request we're currently looking at */ + transactionID: PropTypes.number, /** The report to with which the distance request is associated */ report: reportPropTypes, @@ -64,6 +54,12 @@ const propTypes = { /** Time when the token will expire in ISO 8601 */ expiration: PropTypes.string, }), + + /** Are we editing an existing distance request, or creating a new one? */ + isEditingRequest: PropTypes.bool, + + /** Called on submit of this page */ + onSubmit: PropTypes.func.isRequired, }; const defaultProps = { @@ -71,15 +67,13 @@ const defaultProps = { id: '', amount: 0, currency: CONST.CURRENCY.USD, - participants: [], }, - iouType: '', - report: {}, transaction: {}, mapboxAccessToken: {}, + isEditingRequest: false, }; -function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) { +function DistanceRequest({transactionID, report, transaction, mapboxAccessToken, isEditingRequest, onSubmit}) { const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); const [scrollContentHeight, setScrollContentHeight] = useState(0); @@ -136,12 +130,13 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) }, []); useEffect(() => { - if (!iou.transactionID || !_.isEmpty(waypoints)) { + console.log(">>>>", transactionID, waypoints); + if (!transactionID || !_.isEmpty(waypoints)) { return; } // Create the initial start and stop waypoints - Transaction.createInitialWaypoints(iou.transactionID); - }, [iou.transactionID, waypoints]); + Transaction.createInitialWaypoints(transactionID); + }, [transactionID, waypoints]); const updateGradientVisibility = (event = {}) => { // If a waypoint extends past the bottom of the visible area show the gradient, else hide it. @@ -155,8 +150,8 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) return; } - Transaction.getRoute(iou.transactionID, waypoints); - }, [shouldFetchRoute, iou.transactionID, waypoints]); + Transaction.getRoute(transactionID, waypoints); + }, [shouldFetchRoute, transactionID, waypoints]); useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight]); @@ -196,7 +191,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) secondaryIcon={waypointIcon} secondaryIconFill={theme.icon} shouldShowRightIcon - onPress={() => Navigation.navigate(ROUTES.getMoneyRequestWaypointRoute('request', index))} + onPress={() => Navigation.navigate(isEditingRequest ? ROUTES.getMoneyRequestEditWaypointRoute(report.reportID, index) : ROUTES.getMoneyRequestWaypointRoute('request', index))} key={key} /> ); @@ -220,7 +215,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken})