From 208f430029b055a2ba4ea8d8c7058f430c3f5428 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 8 Aug 2023 14:14:00 -0700 Subject: [PATCH 01/51] Create WaypointEditor bones --- src/pages/WaypointEditor.js | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/pages/WaypointEditor.js diff --git a/src/pages/WaypointEditor.js b/src/pages/WaypointEditor.js new file mode 100644 index 000000000000..07f4a2edf0a8 --- /dev/null +++ b/src/pages/WaypointEditor.js @@ -0,0 +1,47 @@ +import React from 'react'; +import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import AddressSearch from '../components/AddressSearch'; +import ScreenWrapper from '../components/ScreenWrapper'; +import HeaderWithBackButton from '../components/HeaderWithBackButton'; +import {withOnyx} from 'react-native-onyx'; +import Navigation from '../../libs/Navigation/Navigation'; +import ONYXKEYS from '../ONYXKEYS'; +import Form from '../components/Form'; + +function WaypointEditor(props) { + + function selectWaypoint(details) { + const lat = details.geometry.location.lat; + const long = details.geometry.location.lng; + } + + return ( + + { + Navigation.goBack(); + }} + /> +
+ + + +
+
+ ) + +} + +export default WaypointEditor; \ No newline at end of file From cc0352a39de64a54df4a12ce1ef38347495e3b0f Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 8 Aug 2023 14:14:07 -0700 Subject: [PATCH 02/51] Start DistanceRequest actions --- src/libs/actions/DistanceRequest.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/libs/actions/DistanceRequest.js diff --git a/src/libs/actions/DistanceRequest.js b/src/libs/actions/DistanceRequest.js new file mode 100644 index 000000000000..b3a220b5ba81 --- /dev/null +++ b/src/libs/actions/DistanceRequest.js @@ -0,0 +1,14 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '../../ONYXKEYS'; +import CONST from '../../CONST'; + + +function saveWaypoint(transactionID, index, waypoint) +{ + +} + + +export { + +}; \ No newline at end of file From 8dd750bcb7e13f9cfbc2ebc0a67b4dba4a3d2ae0 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 8 Aug 2023 14:51:06 -0700 Subject: [PATCH 03/51] Add route navigation --- src/ROUTES.js | 1 + .../Navigation/AppNavigator/ModalStackNavigators.js | 7 +++++++ src/pages/{ => iou}/WaypointEditor.js | 12 +++++------- 3 files changed, 13 insertions(+), 7 deletions(-) rename src/pages/{ => iou}/WaypointEditor.js (78%) diff --git a/src/ROUTES.js b/src/ROUTES.js index 88db46a60113..8450ab04fe4e 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -88,6 +88,7 @@ export default { MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', MONEY_REQUEST_DISTANCE_TAB: ':iouType/new/:reportID?/distance', + MONEY_REQUEST_WAYPOINT: ':iouType/new/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`, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 31d2057ddd5a..056ccd8be95e 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -97,6 +97,13 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator([ }, name: 'IOU_Send_Enable_Payments', }, + { + getComponent: () => { + const WaypointEditor = require('../../../pages/iou/WaypointEditor').default; + return WaypointEditor; + }, + name: 'Money_Request_Waypoint', + } ]); const SplitDetailsModalStackNavigator = createModalStackNavigator([ diff --git a/src/pages/WaypointEditor.js b/src/pages/iou/WaypointEditor.js similarity index 78% rename from src/pages/WaypointEditor.js rename to src/pages/iou/WaypointEditor.js index 07f4a2edf0a8..79b357095830 100644 --- a/src/pages/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,13 +1,13 @@ import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; -import AddressSearch from '../components/AddressSearch'; -import ScreenWrapper from '../components/ScreenWrapper'; -import HeaderWithBackButton from '../components/HeaderWithBackButton'; +import AddressSearch from '../../components/AddressSearch'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import {withOnyx} from 'react-native-onyx'; import Navigation from '../../libs/Navigation/Navigation'; -import ONYXKEYS from '../ONYXKEYS'; -import Form from '../components/Form'; +import ONYXKEYS from '../../ONYXKEYS'; +import Form from '../../components/Form'; function WaypointEditor(props) { @@ -28,8 +28,6 @@ function WaypointEditor(props) {
From 4192bcb817daae356f670e904d7a84dd2a4ff485 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 8 Aug 2023 14:52:02 -0700 Subject: [PATCH 04/51] Update linkingConfig.js --- src/libs/Navigation/linkingConfig.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 6c4d58a4c585..ef54121e445a 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -313,6 +313,7 @@ export default { Money_Request_Confirmation: ROUTES.MONEY_REQUEST_CONFIRMATION, Money_Request_Currency: ROUTES.MONEY_REQUEST_CURRENCY, Money_Request_Description: ROUTES.MONEY_REQUEST_DESCRIPTION, + Money_Request_Waypoint: ROUTES.MONEY_REQUEST_WAYPOINT, IOU_Send_Enable_Payments: ROUTES.IOU_SEND_ENABLE_PAYMENTS, IOU_Send_Add_Bank_Account: ROUTES.IOU_SEND_ADD_BANK_ACCOUNT, IOU_Send_Add_Debit_Card: ROUTES.IOU_SEND_ADD_DEBIT_CARD, From b63cdbb7dc06cf8b7bc9262e29c6119e8c1e933d Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 8 Aug 2023 15:14:26 -0700 Subject: [PATCH 05/51] Update passed in props --- src/components/DistanceRequest.js | 2 ++ src/pages/iou/WaypointEditor.js | 55 ++++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 45b831f083f5..9f9b64322421 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -14,6 +14,8 @@ import theme from '../styles/themes/default'; import Button from './Button'; import styles from '../styles/styles'; import LinearGradient from './LinearGradient'; +import Navigation from '../libs/Navigation/Navigation'; +import ROUTES from '../ROUTES'; const MAX_WAYPOINTS = 25; const MAX_WAYPOINTS_TO_DISPLAY = 4; diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 79b357095830..540bbe785391 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,17 +1,48 @@ import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; import AddressSearch from '../../components/AddressSearch'; +import lodashGet from 'lodash/get'; import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; -import {withOnyx} from 'react-native-onyx'; import Navigation from '../../libs/Navigation/Navigation'; import ONYXKEYS from '../../ONYXKEYS'; import Form from '../../components/Form'; +import styles from '../../styles/styles'; +import compose from '../../libs/compose'; +import CONST from '../../CONST'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; + + +const propTypes = { + /** The transactionID of this request */ + transactionID: PropTypes.string, + + /** The optimistic transaction for this request */ + transaction: PropTypes.shape({ + transactionID: PropTypes.string, + comment: PropTypes.shape({ + waypoints: PropTypes.shape({ + lat: PropTypes.number, + lng: PropTypes.number, + address: PropTypes.string, + }), + }), + }), + + ...withLocalizePropTypes, +}; + +const defaultProps = { + transactionID: '', + transaction: {}, +}; function WaypointEditor(props) { function selectWaypoint(details) { + console.log('What are details', details); const lat = details.geometry.location.lat; const long = details.geometry.location.lng; } @@ -28,12 +59,17 @@ function WaypointEditor(props) { selectWaypoint(details)} + shouldSaveDraft + containerStyles={[styles.mt4]} + label="Address" + maxInputLength={CONST.FORM_CHARACTER_LIMIT} /> @@ -42,4 +78,15 @@ function WaypointEditor(props) { } -export default WaypointEditor; \ No newline at end of file +WaypointEditor.displayName = 'WaypointEditor'; +WaypointEditor.propTypes = propTypes; +WaypointEditor.defaultProps = defaultProps; +export default compose( + withLocalize, + withOnyx({ + transaction: { + key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, + selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), + }, + }), +)(WaypointEditor); \ No newline at end of file From 975863c4f47c99a1a6e23fe29bf165aa30960e14 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 11:10:52 -0700 Subject: [PATCH 06/51] Add navigation and form draft --- src/ONYXKEYS.js | 2 + src/ROUTES.js | 3 +- src/components/DistanceRequest.js | 1 + src/pages/iou/WaypointEditor.js | 85 +++++++++++++++++++++++-------- 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 0d27ba64dedf..6d3d2686ce6d 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -215,6 +215,8 @@ export default { MONEY_REQUEST_DESCRIPTION_FORM: 'moneyRequestDescriptionForm', NEW_CONTACT_METHOD_FORM: 'newContactMethodForm', PAYPAL_FORM: 'payPalForm', + WAYPOINT_FORM: 'waypointForm', + WAYPOINT_FORM_DRAFT: 'waypointFormDraft', }, // Whether we should show the compose input or not diff --git a/src/ROUTES.js b/src/ROUTES.js index 8450ab04fe4e..e572aa00f0d1 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -88,7 +88,7 @@ export default { MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', 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_WAYPOINT: ':iouType/new/waypoint/:transactionID/: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`, @@ -98,6 +98,7 @@ export default { getMoneyRequestConfirmationRoute: (iouType, reportID = '') => `${iouType}/new/confirmation/${reportID}`, getMoneyRequestCurrencyRoute: (iouType, reportID = '', currency, backTo) => `${iouType}/new/currency/${reportID}?currency=${currency}&backTo=${backTo}`, getMoneyRequestDescriptionRoute: (iouType, reportID = '') => `${iouType}/new/description/${reportID}`, + getMoneyRequestWaypointRoute: (iouType, transactionID, waypointIndex) => `${iouType}/new/waypoint/${transactionID}/${waypointIndex}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID, reportActionID) => `r/${reportID}/split/${reportActionID}`, getNewTaskRoute: (reportID) => `${NEW_TASK}/${reportID}`, diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 9f9b64322421..1105808c06fb 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -107,6 +107,7 @@ function DistanceRequest({transactionID, transaction, translate}) { secondaryIcon={waypointIcon} secondaryIconFill={theme.icon} shouldShowRightIcon + onPress={() => Navigation.navigate(ROUTES.getMoneyRequestWaypointRoute('request', transactionID, index))} key={key} /> ); diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 540bbe785391..7c105f57b3ec 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -12,6 +12,7 @@ import Form from '../../components/Form'; import styles from '../../styles/styles'; import compose from '../../libs/compose'; import CONST from '../../CONST'; +import * as ValidationUtils from '../../libs/ValidationUtils'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; @@ -19,34 +20,75 @@ const propTypes = { /** The transactionID of this request */ transactionID: PropTypes.string, - /** The optimistic transaction for this request */ - transaction: PropTypes.shape({ - transactionID: PropTypes.string, - comment: PropTypes.shape({ - waypoints: PropTypes.shape({ - lat: PropTypes.number, - lng: PropTypes.number, - address: PropTypes.string, - }), - }), + + /** Form values */ + values: PropTypes.shape({ + /** Address street field */ + street: PropTypes.string, + + /** Address city field */ + city: PropTypes.string, + + /** Address state field */ + state: PropTypes.string, + + /** Address zip code field */ + zipCode: PropTypes.string, }), + + + formData: PropTypes.shape({}), ...withLocalizePropTypes, }; const defaultProps = { + values: { + street: undefined, + city: undefined, + state: undefined, + zipCode: undefined, + }, transactionID: '', - transaction: {}, + formData: {}, }; function WaypointEditor(props) { - - function selectWaypoint(details) { + const waypointIndex = lodashGet(props.route.params, 'waypointIndex', ''); + console.log(props); + const selectWaypoint = (details) => { console.log('What are details', details); const lat = details.geometry.location.lat; const long = details.geometry.location.lng; } + const [address, setAddressValue] = React.useState(''); + + const validate = (values) => { + const errors = {}; + if (!values.addressStreet || !ValidationUtils.isValidAddress(values.addressStreet)) { + errors.addressStreet = 'addDebitCardPage.error.addressStreet'; + } + + if (!values.addressZipCode || !ValidationUtils.isValidZipCode(values.addressZipCode)) { + errors.addressZipCode = 'addDebitCardPage.error.addressZipCode'; + } + + if (!values.addressState || !values.addressState) { + errors.addressState = 'addDebitCardPage.error.addressState'; + } + + return errors; + } + + const onSubmit = (params) => { + console.log('What are params', params); + } + + const onAddressUpdate = (value) => { + console.log('value', value); + } + return (
selectWaypoint(details)} - shouldSaveDraft + inputID={`waypoint${waypointIndex}`} containerStyles={[styles.mt4]} label="Address" + shouldSaveDraft maxInputLength={CONST.FORM_CHARACTER_LIMIT} + onInputChange={(value) => console.log(value)} />
@@ -84,9 +128,8 @@ WaypointEditor.defaultProps = defaultProps; export default compose( withLocalize, withOnyx({ - transaction: { - key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, - selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), + formData: { + key: ONYXKEYS.FORMS.WAYPOINT_FORM, }, }), )(WaypointEditor); \ No newline at end of file From 3aa122c20cc99900a31cb75a945a2cdfeaa67ea2 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 11:35:11 -0700 Subject: [PATCH 07/51] Have draft keys shown --- src/components/DistanceRequest.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 1105808c06fb..ffcf05f33ad1 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -36,15 +36,18 @@ const propTypes = { }), }), + formData: PropTypes.shape({}), + ...withLocalizePropTypes, }; const defaultProps = { transactionID: '', transaction: {}, + formData: {}, }; -function DistanceRequest({transactionID, transaction, translate}) { +function DistanceRequest({transactionID, transaction, translate, formData}) { const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); const [scrollContentHeight, setScrollContentHeight] = useState(0); @@ -103,6 +106,7 @@ function DistanceRequest({transactionID, transaction, translate}) { return ( `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), From 98fbf354e73c3bb8c8e2419eb310ca8b44b3c7f7 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 15:49:43 -0700 Subject: [PATCH 08/51] return the lat/long/address! --- src/components/AddressSearch/index.js | 3 +++ src/languages/en.js | 3 +++ src/pages/iou/WaypointEditor.js | 19 +++++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index e8a41ec35435..ce3ce2d8f702 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -166,6 +166,9 @@ function AddressSearch(props) { zipCode, country: '', state: state || stateAutoCompleteFallback, + lat: details.geometry.location.lat, + lng: details.geometry.location.lng, + address: details.formatted_address, }; // If the address is not in the US, use the full length state name since we're displaying the address's diff --git a/src/languages/en.js b/src/languages/en.js index 5573e924a93a..8c1eb69886b4 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1571,6 +1571,9 @@ export default { finish: 'Finish', stop: 'Stop', }, + errors: { + invalidAddress: 'Please select a suggested address', + } }, countrySelectorModal: { placeholderText: 'Search to see options', diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 7c105f57b3ec..42351019223f 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -55,7 +55,8 @@ const defaultProps = { function WaypointEditor(props) { const waypointIndex = lodashGet(props.route.params, 'waypointIndex', ''); - console.log(props); + const waypoint = `waypoint${waypointIndex}`; + const selectWaypoint = (details) => { console.log('What are details', details); const lat = details.geometry.location.lat; @@ -78,15 +79,17 @@ function WaypointEditor(props) { errors.addressState = 'addDebitCardPage.error.addressState'; } + const waypointValue = values[`waypoint${waypointIndex}`]; + if (!waypointValue || !ValidationUtils.isValidAddress(waypointValue)) { + errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; + } + return errors; } const onSubmit = (params) => { - console.log('What are params', params); - } - const onAddressUpdate = (value) => { - console.log('value', value); + } return ( @@ -104,6 +107,7 @@ function WaypointEditor(props) { enabledWhenOffline validate={validate} onSubmit={onSubmit} + submitButtonText='' isSubmitButtonVisible={false} > @@ -111,9 +115,12 @@ function WaypointEditor(props) { inputID={`waypoint${waypointIndex}`} containerStyles={[styles.mt4]} label="Address" + onPress={onSubmit} shouldSaveDraft maxInputLength={CONST.FORM_CHARACTER_LIMIT} - onInputChange={(value) => console.log(value)} + renamedInputKeys={{ + address: `waypoint${waypointIndex}`, + }} /> From e8b0c98a2764515d58b877356bc1e3e6c44c9b60 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 16:28:02 -0700 Subject: [PATCH 09/51] Make it so waypoint form only updates the waypoint index --- src/components/AddressSearch/index.js | 5 +++ src/pages/iou/WaypointEditor.js | 56 ++++++++++++--------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index ce3ce2d8f702..1207684afd5a 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -48,6 +48,8 @@ const propTypes = { /** A callback function when the value of this field has changed */ onInputChange: PropTypes.func.isRequired, + onSubmit: PropTypes.func, + /** Customize the TextInput container */ // eslint-disable-next-line react/forbid-prop-types containerStyles: PropTypes.arrayOf(PropTypes.object), @@ -73,6 +75,7 @@ const defaultProps = { inputID: undefined, shouldSaveDraft: false, onBlur: () => {}, + onSubmit: () => {}, errorText: '', hint: '', value: undefined, @@ -202,6 +205,8 @@ function AddressSearch(props) { } else { props.onInputChange(values); } + + props.onSubmit(values); }; return ( diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 42351019223f..dce2ee611d2c 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -14,13 +14,10 @@ import compose from '../../libs/compose'; import CONST from '../../CONST'; import * as ValidationUtils from '../../libs/ValidationUtils'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import * as FormActions from '../../libs/actions/FormActions'; const propTypes = { - /** The transactionID of this request */ - transactionID: PropTypes.string, - - /** Form values */ values: PropTypes.shape({ /** Address street field */ @@ -35,9 +32,6 @@ const propTypes = { /** Address zip code field */ zipCode: PropTypes.string, }), - - - formData: PropTypes.shape({}), ...withLocalizePropTypes, }; @@ -50,45 +44,37 @@ const defaultProps = { zipCode: undefined, }, transactionID: '', - formData: {}, }; function WaypointEditor(props) { const waypointIndex = lodashGet(props.route.params, 'waypointIndex', ''); - const waypoint = `waypoint${waypointIndex}`; + const transactionID = lodashGet(props.route.params, 'transactionID', 0); const selectWaypoint = (details) => { - console.log('What are details', details); - const lat = details.geometry.location.lat; - const long = details.geometry.location.lng; - } - const [address, setAddressValue] = React.useState(''); + } const validate = (values) => { const errors = {}; - if (!values.addressStreet || !ValidationUtils.isValidAddress(values.addressStreet)) { - errors.addressStreet = 'addDebitCardPage.error.addressStreet'; - } - - if (!values.addressZipCode || !ValidationUtils.isValidZipCode(values.addressZipCode)) { - errors.addressZipCode = 'addDebitCardPage.error.addressZipCode'; - } - - if (!values.addressState || !values.addressState) { - errors.addressState = 'addDebitCardPage.error.addressState'; - } const waypointValue = values[`waypoint${waypointIndex}`]; if (!waypointValue || !ValidationUtils.isValidAddress(waypointValue)) { errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; } + // We only want you to be able to select an address from the dropdown + // When an address is selected, we set a bunch of other values in the form + // We're going to use those to determine whether an address has been selected or not + if (!values.street && !values.city && !values.state && !values.zipCode) { + errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; + } + + return errors; } - const onSubmit = (params) => { - + const onSubmit = (values) => { + console.log('what are my values'); } @@ -103,7 +89,7 @@ function WaypointEditor(props) { />
@@ -135,8 +129,6 @@ WaypointEditor.defaultProps = defaultProps; export default compose( withLocalize, withOnyx({ - formData: { - key: ONYXKEYS.FORMS.WAYPOINT_FORM, - }, + }), -)(WaypointEditor); \ No newline at end of file +)(WaypointEditor); From fdcdc4662d963c4eeeea47280444bd301cadccc8 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 16:42:00 -0700 Subject: [PATCH 10/51] Prevent you from inputting null keys --- src/components/AddressSearch/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 1207684afd5a..a3ef799270f3 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -200,6 +200,9 @@ function AddressSearch(props) { if (props.inputID) { _.each(values, (value, key) => { const inputKey = lodashGet(props.renamedInputKeys, key, key); + if (!inputKey) { + return; + } props.onInputChange(value, inputKey); }); } else { From f3296cd50432016163492b0742352b304f387b55 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 17:29:18 -0700 Subject: [PATCH 11/51] Save waypoint to transaction --- src/ROUTES.js | 1 + src/components/AddressSearch/index.js | 6 ++- src/libs/actions/DistanceRequest.js | 20 +++++++-- src/pages/iou/WaypointEditor.js | 62 +++++++++++---------------- 4 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/ROUTES.js b/src/ROUTES.js index e572aa00f0d1..10dbd5eecfda 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -98,6 +98,7 @@ export default { getMoneyRequestConfirmationRoute: (iouType, reportID = '') => `${iouType}/new/confirmation/${reportID}`, getMoneyRequestCurrencyRoute: (iouType, reportID = '', currency, backTo) => `${iouType}/new/currency/${reportID}?currency=${currency}&backTo=${backTo}`, getMoneyRequestDescriptionRoute: (iouType, reportID = '') => `${iouType}/new/description/${reportID}`, + getMoneyRequestDistanceTabRoute: (iouType, reportID = '') => `${iouType}/new/${reportID}/distance`, getMoneyRequestWaypointRoute: (iouType, transactionID, waypointIndex) => `${iouType}/new/waypoint/${transactionID}/${waypointIndex}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID, reportActionID) => `r/${reportID}/split/${reportActionID}`, diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index a3ef799270f3..1fe4f335eee8 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -48,6 +48,9 @@ const propTypes = { /** A callback function when the value of this field has changed */ onInputChange: PropTypes.func.isRequired, + /** A callback function when an address has been auto-selected */ + onPress: PropTypes.func, + onSubmit: PropTypes.func, /** Customize the TextInput container */ @@ -75,6 +78,7 @@ const defaultProps = { inputID: undefined, shouldSaveDraft: false, onBlur: () => {}, + onPress: () => {}, onSubmit: () => {}, errorText: '', hint: '', @@ -209,7 +213,7 @@ function AddressSearch(props) { props.onInputChange(values); } - props.onSubmit(values); + props.onPress(values); }; return ( diff --git a/src/libs/actions/DistanceRequest.js b/src/libs/actions/DistanceRequest.js index b3a220b5ba81..33125bd62e1e 100644 --- a/src/libs/actions/DistanceRequest.js +++ b/src/libs/actions/DistanceRequest.js @@ -3,12 +3,24 @@ import ONYXKEYS from '../../ONYXKEYS'; import CONST from '../../CONST'; +/** + * Saves the selected waypoint to the transaction + * @param {String} transactionID + * @param {String} index + * @param {Object} waypoint + */ function saveWaypoint(transactionID, index, waypoint) { - + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { + comment: { + waypoints: { + [`waypoint${index}`]: waypoint, + }, + } + }); } -export { - -}; \ No newline at end of file +export default { + saveWaypoint, +}; diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index dce2ee611d2c..d52cc9865a35 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -2,8 +2,8 @@ import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; -import AddressSearch from '../../components/AddressSearch'; import lodashGet from 'lodash/get'; +import AddressSearch from '../../components/AddressSearch'; import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import Navigation from '../../libs/Navigation/Navigation'; @@ -14,45 +14,33 @@ import compose from '../../libs/compose'; import CONST from '../../CONST'; import * as ValidationUtils from '../../libs/ValidationUtils'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; -import * as FormActions from '../../libs/actions/FormActions'; +import * as DistanceRequest from '../../libs/actions/DistanceRequest'; +import ROUTES from '../../ROUTES'; const propTypes = { - /** Form values */ - values: PropTypes.shape({ - /** Address street field */ - street: PropTypes.string, - - /** Address city field */ - city: PropTypes.string, - - /** Address state field */ - state: PropTypes.string, - - /** Address zip code field */ - zipCode: PropTypes.string, + route: PropTypes.shape({ + params: PropTypes.shape({ + waypointIndex: PropTypes.string, + transactionID: PropTypes.string, + }), }), - ...withLocalizePropTypes, }; const defaultProps = { - values: { - street: undefined, - city: undefined, - state: undefined, - zipCode: undefined, + route: { + params: { + waypointIndex: '', + transactionID: '', + }, }, - transactionID: '', }; function WaypointEditor(props) { const waypointIndex = lodashGet(props.route.params, 'waypointIndex', ''); - const transactionID = lodashGet(props.route.params, 'transactionID', 0); + const transactionID = lodashGet(props.route.params, 'transactionID', ''); - const selectWaypoint = (details) => { - - } const validate = (values) => { const errors = {}; @@ -62,22 +50,24 @@ function WaypointEditor(props) { errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; } - // We only want you to be able to select an address from the dropdown - // When an address is selected, we set a bunch of other values in the form - // We're going to use those to determine whether an address has been selected or not - if (!values.street && !values.city && !values.state && !values.zipCode) { - errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; - } - - return errors; } const onSubmit = (values) => { - console.log('what are my values'); } + const onPress = (values) => { + const waypoint = { + lat: values.lat, + lng: values.lng, + address: values.address, + } + + DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); + Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute('request')); + } + return ( Date: Wed, 9 Aug 2023 17:37:48 -0700 Subject: [PATCH 12/51] Handle saving an empty waypoint --- src/pages/iou/WaypointEditor.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index d52cc9865a35..fe9ac25a10d0 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -12,9 +12,8 @@ import Form from '../../components/Form'; import styles from '../../styles/styles'; import compose from '../../libs/compose'; import CONST from '../../CONST'; -import * as ValidationUtils from '../../libs/ValidationUtils'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; -import * as DistanceRequest from '../../libs/actions/DistanceRequest'; +import DistanceRequest from '../../libs/actions/DistanceRequest'; import ROUTES from '../../ROUTES'; @@ -45,16 +44,24 @@ function WaypointEditor(props) { const validate = (values) => { const errors = {}; - const waypointValue = values[`waypoint${waypointIndex}`]; - if (!waypointValue || !ValidationUtils.isValidAddress(waypointValue)) { + // The address can only be empty (removes the value), or auto-selected which goes through the onPress method + // This basically only allows empty values to be saved + if (values[`waypoint${waypointIndex}`]) { errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; } return errors; } - const onSubmit = (values) => { + const onSubmit = (values) => { + // Allows letting you set a waypoint to an empty value + if (!values[`waypoint${waypointIndex}`]) { + DistanceRequest.saveWaypoint(transactionID, waypointIndex, null); + } else { + return; + } + Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute('request')); } const onPress = (values) => { From 6ac918344877560ce01b7a2c61dca4f2c486c20c Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 9 Aug 2023 18:07:09 -0700 Subject: [PATCH 13/51] Add offline functionality --- src/languages/en.js | 3 ++- src/pages/iou/WaypointEditor.js | 45 +++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 8c1eb69886b4..e364522c6992 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1572,7 +1572,8 @@ export default { stop: 'Stop', }, errors: { - invalidAddress: 'Please select a suggested address', + enterValidAddress: 'Please enter a valid address', + selectSuggestedAddress: 'Please select a suggested address', } }, countrySelectorModal: { diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index fe9ac25a10d0..b80775f2e9c9 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -14,22 +14,32 @@ import compose from '../../libs/compose'; import CONST from '../../CONST'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; import DistanceRequest from '../../libs/actions/DistanceRequest'; +import * as ValidationUtils from '../libs/ValidationUtils'; import ROUTES from '../../ROUTES'; +import {withNetwork} from '../../components/OnyxProvider'; +import networkPropTypes from '../../components/networkPropTypes'; const propTypes = { route: PropTypes.shape({ params: PropTypes.shape({ + iouType: PropTypes.string, waypointIndex: PropTypes.string, transactionID: PropTypes.string, }), }), + + /** Information about the network */ + network: networkPropTypes.isRequired, + ...withLocalizePropTypes, + }; const defaultProps = { route: { params: { + iouType: '', waypointIndex: '', transactionID: '', }, @@ -37,17 +47,23 @@ const defaultProps = { }; function WaypointEditor(props) { - const waypointIndex = lodashGet(props.route.params, 'waypointIndex', ''); - const transactionID = lodashGet(props.route.params, 'transactionID', ''); - + const waypointIndex = lodashGet(props.route.params, 'waypointIndex'); + const transactionID = lodashGet(props.route.params, 'transactionID'); + const iouType = lodashGet(props.route.params, 'iouType'); const validate = (values) => { const errors = {}; // The address can only be empty (removes the value), or auto-selected which goes through the onPress method - // This basically only allows empty values to be saved - if (values[`waypoint${waypointIndex}`]) { - errors[`waypoint${waypointIndex}`] = 'distance.errors.invalidAddress'; + const waypointValue = values[`waypoint${waypointIndex}`]; + if (!props.network.isOffline && waypointValue) { + errors[`waypoint${waypointIndex}`] = 'distance.errors.selectSuggestedAddress'; + } + + // When the user is offline, we can't use auto-complete to validate the address + // So we're going to save the waypoint as just the address, and the lat/long will be filled in on the backend + if (props.network.isOffline && waypointValue && ValidationUtils.isValidAddress(waypointValue)) { + errors[`waypoint${waypointIndex}`] = 'distance.errors.enterValidAddress'; } return errors; @@ -57,11 +73,19 @@ function WaypointEditor(props) { // Allows letting you set a waypoint to an empty value if (!values[`waypoint${waypointIndex}`]) { DistanceRequest.saveWaypoint(transactionID, waypointIndex, null); - } else { - return; } - Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute('request')); + // While the user is offline, the auto-complete address search will not work + // Therefore, we're going to save the waypoint as just the address, and the lat/long will be filled in on the backend + if (props.network.isOffline && values[`waypoint${waypointIndex}`]) { + const waypoint = { + address: values[`waypoint${waypointIndex}`], + } + + DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); + } + + Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); } const onPress = (values) => { @@ -72,7 +96,7 @@ function WaypointEditor(props) { } DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); - Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute('request')); + Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); } return ( @@ -125,6 +149,7 @@ WaypointEditor.propTypes = propTypes; WaypointEditor.defaultProps = defaultProps; export default compose( withLocalize, + withNetwork(), withOnyx({ }), From 5b5fc38dd28503a55264061665455851a9bb1ed8 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Thu, 10 Aug 2023 11:49:23 -0700 Subject: [PATCH 14/51] comments & translations --- src/languages/en.js | 2 +- src/languages/es.js | 4 ++++ src/pages/iou/WaypointEditor.js | 14 +++++++------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index e364522c6992..d7b0c35f3c39 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1566,13 +1566,13 @@ export default { }, distance: { addStop: 'Add stop', + address: 'Address', waypointDescription: { start: 'Start', finish: 'Finish', stop: 'Stop', }, errors: { - enterValidAddress: 'Please enter a valid address', selectSuggestedAddress: 'Please select a suggested address', } }, diff --git a/src/languages/es.js b/src/languages/es.js index 3882ed74c03e..aab34de42610 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -2037,11 +2037,15 @@ export default { }, distance: { addStop: 'Agregar parada', + address: 'Dirección', waypointDescription: { start: 'Comienzo', finish: 'Final', stop: 'Parada', }, + errors: { + selectSuggestedAddress: 'Por favor, selecciona una dirección sugerida', + } }, countrySelectorModal: { placeholderText: 'Buscar para ver opciones', diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index b80775f2e9c9..5b0ec2592592 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -14,7 +14,7 @@ import compose from '../../libs/compose'; import CONST from '../../CONST'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; import DistanceRequest from '../../libs/actions/DistanceRequest'; -import * as ValidationUtils from '../libs/ValidationUtils'; +import * as ValidationUtils from '../../libs/ValidationUtils'; import ROUTES from '../../ROUTES'; import {withNetwork} from '../../components/OnyxProvider'; import networkPropTypes from '../../components/networkPropTypes'; @@ -60,16 +60,16 @@ function WaypointEditor(props) { errors[`waypoint${waypointIndex}`] = 'distance.errors.selectSuggestedAddress'; } - // When the user is offline, we can't use auto-complete to validate the address - // So we're going to save the waypoint as just the address, and the lat/long will be filled in on the backend + // When the user is offline, we can't use auto-complete to validate the address so we will just save the address + // Otherwise, we require the user to select an address from the auto-complete if (props.network.isOffline && waypointValue && ValidationUtils.isValidAddress(waypointValue)) { - errors[`waypoint${waypointIndex}`] = 'distance.errors.enterValidAddress'; + errors[`waypoint${waypointIndex}`] = 'bankAccount.error.address'; } return errors; } - const onSubmit = (values) => { + const onSubmit = (values) => { // Allows letting you set a waypoint to an empty value if (!values[`waypoint${waypointIndex}`]) { DistanceRequest.saveWaypoint(transactionID, waypointIndex, null); @@ -105,7 +105,7 @@ function WaypointEditor(props) { title="Waypoint Editor" shouldShowBackButton onBackButtonPress={() => { - Navigation.goBack(); + Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); }} /> Date: Thu, 10 Aug 2023 12:42:48 -0700 Subject: [PATCH 15/51] prettier --- src/languages/en.js | 2 +- src/languages/es.js | 2 +- .../AppNavigator/ModalStackNavigators.js | 2 +- src/libs/actions/DistanceRequest.js | 13 ++++----- src/pages/iou/WaypointEditor.js | 27 +++++++------------ 5 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 5aa87a218713..2737a0f9d98b 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1587,7 +1587,7 @@ export default { }, errors: { selectSuggestedAddress: 'Please select a suggested address', - } + }, }, countrySelectorModal: { placeholderText: 'Search to see options', diff --git a/src/languages/es.js b/src/languages/es.js index 761c5c95d171..778307ed0d3a 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -2059,7 +2059,7 @@ export default { }, errors: { selectSuggestedAddress: 'Por favor, selecciona una dirección sugerida', - } + }, }, countrySelectorModal: { placeholderText: 'Buscar para ver opciones', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index c3209cff7e69..c1d7143f92b2 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -103,7 +103,7 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator([ return WaypointEditor; }, name: 'Money_Request_Waypoint', - } + }, ]); const SplitDetailsModalStackNavigator = createModalStackNavigator([ diff --git a/src/libs/actions/DistanceRequest.js b/src/libs/actions/DistanceRequest.js index 33125bd62e1e..d4e3ac3da42c 100644 --- a/src/libs/actions/DistanceRequest.js +++ b/src/libs/actions/DistanceRequest.js @@ -2,25 +2,22 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '../../ONYXKEYS'; import CONST from '../../CONST'; - /** * Saves the selected waypoint to the transaction - * @param {String} transactionID - * @param {String} index - * @param {Object} waypoint + * @param {String} transactionID + * @param {String} index + * @param {Object} waypoint */ -function saveWaypoint(transactionID, index, waypoint) -{ +function saveWaypoint(transactionID, index, waypoint) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { comment: { waypoints: { [`waypoint${index}`]: waypoint, }, - } + }, }); } - export default { saveWaypoint, }; diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 5b0ec2592592..90b0e280a5ed 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -19,7 +19,6 @@ import ROUTES from '../../ROUTES'; import {withNetwork} from '../../components/OnyxProvider'; import networkPropTypes from '../../components/networkPropTypes'; - const propTypes = { route: PropTypes.shape({ params: PropTypes.shape({ @@ -28,12 +27,11 @@ const propTypes = { transactionID: PropTypes.string, }), }), - + /** Information about the network */ network: networkPropTypes.isRequired, ...withLocalizePropTypes, - }; const defaultProps = { @@ -67,7 +65,7 @@ function WaypointEditor(props) { } return errors; - } + }; const onSubmit = (values) => { // Allows letting you set a waypoint to an empty value @@ -80,24 +78,24 @@ function WaypointEditor(props) { if (props.network.isOffline && values[`waypoint${waypointIndex}`]) { const waypoint = { address: values[`waypoint${waypointIndex}`], - } + }; DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); } Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); - } + }; const onPress = (values) => { const waypoint = { lat: values.lat, lng: values.lng, address: values.address, - } + }; DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); - } + }; return ( @@ -114,7 +112,7 @@ function WaypointEditor(props) { enabledWhenOffline validate={validate} onSubmit={onSubmit} - submitButtonText='' + submitButtonText="" isSubmitButtonVisible={false} > @@ -140,17 +138,10 @@ function WaypointEditor(props) { - ) - + ); } WaypointEditor.displayName = 'WaypointEditor'; WaypointEditor.propTypes = propTypes; WaypointEditor.defaultProps = defaultProps; -export default compose( - withLocalize, - withNetwork(), - withOnyx({ - - }), -)(WaypointEditor); +export default compose(withLocalize, withNetwork(), withOnyx({}))(WaypointEditor); From 948b91cdafb27ab56b04255c1cd4a48e6470acb1 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 11 Aug 2023 11:11:29 -0700 Subject: [PATCH 16/51] Remove the onSubmit --- src/components/AddressSearch/index.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 1fe4f335eee8..0108a7740f7f 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -51,8 +51,6 @@ const propTypes = { /** A callback function when an address has been auto-selected */ onPress: PropTypes.func, - onSubmit: PropTypes.func, - /** Customize the TextInput container */ // eslint-disable-next-line react/forbid-prop-types containerStyles: PropTypes.arrayOf(PropTypes.object), @@ -79,7 +77,6 @@ const defaultProps = { shouldSaveDraft: false, onBlur: () => {}, onPress: () => {}, - onSubmit: () => {}, errorText: '', hint: '', value: undefined, From 702d2166a0ecf8e84e0e042613b07fe2da971432 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 11 Aug 2023 11:28:03 -0700 Subject: [PATCH 17/51] icon color update / remove const --- src/components/DistanceRequest.js | 1 + src/libs/actions/DistanceRequest.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index f4c34d1a4beb..2be52e39843b 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -118,6 +118,7 @@ function DistanceRequest({transactionID, transaction, translate, formData}) { description={translate(descriptionKey)} title={formData[`waypoint${index}`] || ''} icon={Expensicons.DragHandles} + iconFill={theme.icon} secondaryIcon={waypointIcon} secondaryIconFill={theme.icon} shouldShowRightIcon diff --git a/src/libs/actions/DistanceRequest.js b/src/libs/actions/DistanceRequest.js index d4e3ac3da42c..2aadd4ff0365 100644 --- a/src/libs/actions/DistanceRequest.js +++ b/src/libs/actions/DistanceRequest.js @@ -1,6 +1,5 @@ import Onyx from 'react-native-onyx'; import ONYXKEYS from '../../ONYXKEYS'; -import CONST from '../../CONST'; /** * Saves the selected waypoint to the transaction From 83bdef20de2a83b512f1bb8836fc836230bac5c8 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 11 Aug 2023 11:56:36 -0700 Subject: [PATCH 18/51] Add save button --- src/pages/iou/WaypointEditor.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 90b0e280a5ed..6a35f473c1d6 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -112,8 +112,7 @@ function WaypointEditor(props) { enabledWhenOffline validate={validate} onSubmit={onSubmit} - submitButtonText="" - isSubmitButtonVisible={false} + submitButtonText={props.translate('common.save')} > Date: Fri, 11 Aug 2023 17:16:18 -0700 Subject: [PATCH 19/51] Move DistanceRequest action to Transaction actions --- src/libs/actions/DistanceRequest.js | 22 ---------------------- src/libs/actions/Transaction.js | 19 ++++++++++++++++++- src/pages/iou/WaypointEditor.js | 8 ++++---- 3 files changed, 22 insertions(+), 27 deletions(-) delete mode 100644 src/libs/actions/DistanceRequest.js diff --git a/src/libs/actions/DistanceRequest.js b/src/libs/actions/DistanceRequest.js deleted file mode 100644 index 2aadd4ff0365..000000000000 --- a/src/libs/actions/DistanceRequest.js +++ /dev/null @@ -1,22 +0,0 @@ -import Onyx from 'react-native-onyx'; -import ONYXKEYS from '../../ONYXKEYS'; - -/** - * Saves the selected waypoint to the transaction - * @param {String} transactionID - * @param {String} index - * @param {Object} waypoint - */ -function saveWaypoint(transactionID, index, waypoint) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { - comment: { - waypoints: { - [`waypoint${index}`]: waypoint, - }, - }, - }); -} - -export default { - saveWaypoint, -}; diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 98e0328fa160..0773af1ea5f9 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -31,4 +31,21 @@ function addStop(transactionID, newLastIndex) { }); } -export {addStop, createInitialWaypoints}; +/** + * Saves the selected waypoint to the transaction + * @param {String} transactionID + * @param {String} index + * @param {Object} waypoint + */ +function saveWaypoint(transactionID, index, waypoint) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, { + comment: { + waypoints: { + [`waypoint${index}`]: waypoint, + }, + }, + }); +} + + +export {addStop, createInitialWaypoints, saveWaypoint}; diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 6a35f473c1d6..b2735deb3f24 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -13,7 +13,7 @@ import styles from '../../styles/styles'; import compose from '../../libs/compose'; import CONST from '../../CONST'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; -import DistanceRequest from '../../libs/actions/DistanceRequest'; +import * as Transaction from '../../libs/actions/Transaction'; import * as ValidationUtils from '../../libs/ValidationUtils'; import ROUTES from '../../ROUTES'; import {withNetwork} from '../../components/OnyxProvider'; @@ -70,7 +70,7 @@ function WaypointEditor(props) { const onSubmit = (values) => { // Allows letting you set a waypoint to an empty value if (!values[`waypoint${waypointIndex}`]) { - DistanceRequest.saveWaypoint(transactionID, waypointIndex, null); + Transaction.saveWaypoint(transactionID, waypointIndex, null); } // While the user is offline, the auto-complete address search will not work @@ -80,7 +80,7 @@ function WaypointEditor(props) { address: values[`waypoint${waypointIndex}`], }; - DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); + Transaction.saveWaypoint(transactionID, waypointIndex, waypoint); } Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); @@ -93,7 +93,7 @@ function WaypointEditor(props) { address: values.address, }; - DistanceRequest.saveWaypoint(transactionID, waypointIndex, waypoint); + Transaction.saveWaypoint(transactionID, waypointIndex, waypoint); Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); }; From 3357bf1b95d5ec4b887a446b0a31769f23740113 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 11 Aug 2023 17:25:09 -0700 Subject: [PATCH 20/51] Use destructuring --- src/libs/actions/Transaction.js | 1 - src/pages/iou/WaypointEditor.js | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 0773af1ea5f9..52876b7acaf0 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -47,5 +47,4 @@ function saveWaypoint(transactionID, index, waypoint) { }); } - export {addStop, createInitialWaypoints, saveWaypoint}; diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index b2735deb3f24..b3fabf8c381a 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -22,8 +22,13 @@ import networkPropTypes from '../../components/networkPropTypes'; const propTypes = { route: PropTypes.shape({ params: PropTypes.shape({ + /** IOU type */ iouType: PropTypes.string, + + /** Index of the waypoint being edited */ waypointIndex: PropTypes.string, + + /** The transactionID of this request */ transactionID: PropTypes.string, }), }), @@ -44,23 +49,19 @@ const defaultProps = { }, }; -function WaypointEditor(props) { - const waypointIndex = lodashGet(props.route.params, 'waypointIndex'); - const transactionID = lodashGet(props.route.params, 'transactionID'); - const iouType = lodashGet(props.route.params, 'iouType'); - +function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', transactionID = ''} = {}} = {}, network, translate}) { const validate = (values) => { const errors = {}; // The address can only be empty (removes the value), or auto-selected which goes through the onPress method const waypointValue = values[`waypoint${waypointIndex}`]; - if (!props.network.isOffline && waypointValue) { + if (!network.isOffline && waypointValue) { errors[`waypoint${waypointIndex}`] = 'distance.errors.selectSuggestedAddress'; } // When the user is offline, we can't use auto-complete to validate the address so we will just save the address // Otherwise, we require the user to select an address from the auto-complete - if (props.network.isOffline && waypointValue && ValidationUtils.isValidAddress(waypointValue)) { + if (network.isOffline && waypointValue && ValidationUtils.isValidAddress(waypointValue)) { errors[`waypoint${waypointIndex}`] = 'bankAccount.error.address'; } @@ -75,7 +76,7 @@ function WaypointEditor(props) { // While the user is offline, the auto-complete address search will not work // Therefore, we're going to save the waypoint as just the address, and the lat/long will be filled in on the backend - if (props.network.isOffline && values[`waypoint${waypointIndex}`]) { + if (network.isOffline && values[`waypoint${waypointIndex}`]) { const waypoint = { address: values[`waypoint${waypointIndex}`], }; @@ -112,13 +113,13 @@ function WaypointEditor(props) { enabledWhenOffline validate={validate} onSubmit={onSubmit} - submitButtonText={props.translate('common.save')} + submitButtonText={translate('common.save')} > Date: Fri, 11 Aug 2023 17:27:38 -0700 Subject: [PATCH 21/51] Use lodashGet for safer access --- src/components/AddressSearch/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 0108a7740f7f..0005110199c4 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -170,9 +170,9 @@ function AddressSearch(props) { zipCode, country: '', state: state || stateAutoCompleteFallback, - lat: details.geometry.location.lat, - lng: details.geometry.location.lng, - address: details.formatted_address, + lat: lodashGet(details, 'geometry.location.lat', 0), + lng: lodashGet(details, 'geometry.location.lng', 0), + address: lodashGet(details, 'formatted_address', ''), }; // If the address is not in the US, use the full length state name since we're displaying the address's From 5f5746eba8239c18995727828ff7d1c10e85a62e Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Fri, 11 Aug 2023 17:30:34 -0700 Subject: [PATCH 22/51] Add missing renamedInputKeys --- src/components/AddressSearch/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 0005110199c4..a106df62974f 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -61,8 +61,11 @@ const propTypes = { /** A map of inputID key names */ renamedInputKeys: PropTypes.shape({ street: PropTypes.string, + street2: PropTypes.string, city: PropTypes.string, state: PropTypes.string, + lat: PropTypes.string, + lng: PropTypes.string, zipCode: PropTypes.string, }), @@ -85,9 +88,12 @@ const defaultProps = { isLimitedToUSA: true, renamedInputKeys: { street: 'addressStreet', + street2: 'addressStreet2', city: 'addressCity', state: 'addressState', zipCode: 'addressZipCode', + lat: 'addressLat', + lng: 'addressLng', }, maxInputLength: undefined, }; From c2dc39674a2ea2d67af2d581abf9dd06513361b6 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 12:41:36 -0500 Subject: [PATCH 23/51] prevent empty spaces / showing error on failure --- src/pages/iou/WaypointEditor.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index b3fabf8c381a..b882ad5a0030 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,3 +1,4 @@ +import _ from 'underscore'; import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; @@ -52,16 +53,10 @@ const defaultProps = { function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', transactionID = ''} = {}} = {}, network, translate}) { const validate = (values) => { const errors = {}; + const waypointValue = values[`waypoint${waypointIndex}`] || ''; - // The address can only be empty (removes the value), or auto-selected which goes through the onPress method - const waypointValue = values[`waypoint${waypointIndex}`]; - if (!network.isOffline && waypointValue) { - errors[`waypoint${waypointIndex}`] = 'distance.errors.selectSuggestedAddress'; - } - - // When the user is offline, we can't use auto-complete to validate the address so we will just save the address - // Otherwise, we require the user to select an address from the auto-complete - if (network.isOffline && waypointValue && ValidationUtils.isValidAddress(waypointValue)) { + // If the user is offline, they can enter any address they want, so we validate it this way + if (network.isOffline && !ValidationUtils.isValidAddress(waypointValue)) { errors[`waypoint${waypointIndex}`] = 'bankAccount.error.address'; } @@ -69,16 +64,24 @@ function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', tran }; const onSubmit = (values) => { + const waypointValue = values[`waypoint${waypointIndex}`] || ''; + + // Prevent the user from submitting the form if they are online + // The only way is to select an address from the auto-complete + if (!network.isOffline && waypointValue !== '') { + return; + } + // Allows letting you set a waypoint to an empty value - if (!values[`waypoint${waypointIndex}`]) { + if (waypointValue === '') { Transaction.saveWaypoint(transactionID, waypointIndex, null); } // While the user is offline, the auto-complete address search will not work // Therefore, we're going to save the waypoint as just the address, and the lat/long will be filled in on the backend - if (network.isOffline && values[`waypoint${waypointIndex}`]) { + if (network.isOffline && waypointValue) { const waypoint = { - address: values[`waypoint${waypointIndex}`], + address: waypointValue, }; Transaction.saveWaypoint(transactionID, waypointIndex, waypoint); @@ -118,6 +121,7 @@ function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', tran Date: Mon, 14 Aug 2023 12:57:51 -0500 Subject: [PATCH 24/51] Add no results to AddressSearch component --- src/components/AddressSearch/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index a106df62974f..05a256597c97 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -1,7 +1,7 @@ import _ from 'underscore'; import React, {useMemo, useRef, useState} from 'react'; import PropTypes from 'prop-types'; -import {LogBox, ScrollView, View} from 'react-native'; +import {LogBox, ScrollView, View, Text} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; import lodashGet from 'lodash/get'; import withLocalize, {withLocalizePropTypes} from '../withLocalize'; @@ -244,6 +244,7 @@ function AddressSearch(props) { fetchDetails suppressDefaultStyles enablePoweredByContainer={false} + ListEmptyComponent={{props.translate('common.noResultsFound')}} onPress={(data, details) => { saveLocationDetails(data, details); From f0e1c4afe26ccd5d10a662730cabaf0b1a73c5e1 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 13:03:52 -0500 Subject: [PATCH 25/51] Lint --- src/pages/iou/WaypointEditor.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index b882ad5a0030..998da29ada9a 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,9 +1,7 @@ -import _ from 'underscore'; import React from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; -import lodashGet from 'lodash/get'; import AddressSearch from '../../components/AddressSearch'; import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; From 194ec270d36b3747489c97d45e0078ddcd132222 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 16:10:00 -0500 Subject: [PATCH 26/51] remove the transactionID from the route --- src/ROUTES.js | 4 ++-- src/pages/iou/WaypointEditor.js | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ROUTES.js b/src/ROUTES.js index 1b065ba6678b..d5c1a3d6bf9c 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -92,7 +92,7 @@ export default { MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', MONEY_REQUEST_DISTANCE_TAB: ':iouType/new/:reportID?/distance', - MONEY_REQUEST_WAYPOINT: ':iouType/new/waypoint/:transactionID/:waypointIndex', + MONEY_REQUEST_WAYPOINT: ':iouType/new/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`, @@ -103,7 +103,7 @@ export default { getMoneyRequestCurrencyRoute: (iouType, reportID = '', currency, backTo) => `${iouType}/new/currency/${reportID}?currency=${currency}&backTo=${backTo}`, getMoneyRequestDescriptionRoute: (iouType, reportID = '') => `${iouType}/new/description/${reportID}`, getMoneyRequestDistanceTabRoute: (iouType, reportID = '') => `${iouType}/new/${reportID}/distance`, - getMoneyRequestWaypointRoute: (iouType, transactionID, waypointIndex) => `${iouType}/new/waypoint/${transactionID}/${waypointIndex}`, + getMoneyRequestWaypointRoute: (iouType, waypointIndex) => `${iouType}/new/waypoint/${waypointIndex}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID, reportActionID) => `r/${reportID}/split/${reportActionID}`, getNewTaskRoute: (reportID) => `${NEW_TASK}/${reportID}`, diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 998da29ada9a..f3adc57ac1a7 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -19,6 +19,9 @@ import {withNetwork} from '../../components/OnyxProvider'; import networkPropTypes from '../../components/networkPropTypes'; const propTypes = { + /** The transactionID of the IOU */ + transactionID: PropTypes.string.isRequired, + route: PropTypes.shape({ params: PropTypes.shape({ /** IOU type */ @@ -26,9 +29,6 @@ const propTypes = { /** Index of the waypoint being edited */ waypointIndex: PropTypes.string, - - /** The transactionID of this request */ - transactionID: PropTypes.string, }), }), @@ -43,12 +43,11 @@ const defaultProps = { params: { iouType: '', waypointIndex: '', - transactionID: '', }, }, }; -function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', transactionID = ''} = {}} = {}, network, translate}) { +function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate}) { const validate = (values) => { const errors = {}; const waypointValue = values[`waypoint${waypointIndex}`] || ''; @@ -88,7 +87,7 @@ function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', tran Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); }; - const onPress = (values) => { + const selectWaypoint = (values) => { const waypoint = { lat: values.lat, lng: values.lng, @@ -123,7 +122,7 @@ function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', tran containerStyles={[styles.mt4]} label={translate('distance.address')} shouldSaveDraft - onPress={onPress} + onPress={selectWaypoint} maxInputLength={CONST.FORM_CHARACTER_LIMIT} renamedInputKeys={{ address: `waypoint${waypointIndex}`, @@ -146,4 +145,6 @@ function WaypointEditor({route: {params: {iouType = '', waypointIndex = '', tran WaypointEditor.displayName = 'WaypointEditor'; WaypointEditor.propTypes = propTypes; WaypointEditor.defaultProps = defaultProps; -export default compose(withLocalize, withNetwork(), withOnyx({}))(WaypointEditor); +export default compose(withLocalize, withNetwork(), withOnyx({ + transactionID: {key: ONYXKEYS.IOU, selector: (iou) => (iou && iou.transactionID) || ''}, +}))(WaypointEditor); From 1b8cea9c7bb75467ab36f3ee17b82be00ed5f7ad Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 16:21:58 -0500 Subject: [PATCH 27/51] Add network to google places --- src/components/AddressSearch/index.js | 12 +++++++++--- src/pages/iou/WaypointEditor.js | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 05a256597c97..6a130e9f88cb 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import {LogBox, ScrollView, View, Text} from 'react-native'; import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete'; import lodashGet from 'lodash/get'; +import compose from '../../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../withLocalize'; import styles from '../../styles/styles'; import themeColors from '../../styles/themes/default'; @@ -14,6 +15,8 @@ import CONST from '../../CONST'; import * as StyleUtils from '../../styles/StyleUtils'; import resetDisplayListViewBorderOnBlur from './resetDisplayListViewBorderOnBlur'; import variables from '../../styles/variables'; +import {withNetwork} from '../OnyxProvider'; +import networkPropTypes from '../networkPropTypes'; // The error that's being thrown below will be ignored until we fork the // react-native-google-places-autocomplete repo and replace the @@ -72,6 +75,9 @@ const propTypes = { /** Maximum number of characters allowed in search input */ maxInputLength: PropTypes.number, + /** Information about the network */ + network: networkPropTypes.isRequired, + ...withLocalizePropTypes, }; @@ -244,7 +250,7 @@ function AddressSearch(props) { fetchDetails suppressDefaultStyles enablePoweredByContainer={false} - ListEmptyComponent={{props.translate('common.noResultsFound')}} + ListEmptyComponent={props.network.isOffline ? null : {props.translate('common.noResultsFound')}} onPress={(data, details) => { saveLocationDetails(data, details); @@ -325,12 +331,12 @@ AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; AddressSearch.displayName = 'AddressSearch'; -export default withLocalize( +export default compose(withNetwork(), withLocalize)( React.forwardRef((props, ref) => ( - )), + )) ); diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index f3adc57ac1a7..7c04a09967dd 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -22,6 +22,7 @@ const propTypes = { /** The transactionID of the IOU */ transactionID: PropTypes.string.isRequired, + /** Route params */ route: PropTypes.shape({ params: PropTypes.shape({ /** IOU type */ From d2965479312d928ff106ecc054d131f6c7c10c4b Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 16:22:42 -0500 Subject: [PATCH 28/51] Add network to WaypointEditor --- src/components/AddressSearch/index.js | 13 ++++++++++--- src/pages/iou/WaypointEditor.js | 10 +++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 6a130e9f88cb..204333474849 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -250,7 +250,11 @@ function AddressSearch(props) { fetchDetails suppressDefaultStyles enablePoweredByContainer={false} - ListEmptyComponent={props.network.isOffline ? null : {props.translate('common.noResultsFound')}} + ListEmptyComponent={ + props.network.isOffline ? null : ( + {props.translate('common.noResultsFound')} + ) + } onPress={(data, details) => { saveLocationDetails(data, details); @@ -331,12 +335,15 @@ AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; AddressSearch.displayName = 'AddressSearch'; -export default compose(withNetwork(), withLocalize)( +export default compose( + withNetwork(), + withLocalize, +)( React.forwardRef((props, ref) => ( - )) + )), ); diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 7c04a09967dd..2ec3b9da4651 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -146,6 +146,10 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI WaypointEditor.displayName = 'WaypointEditor'; WaypointEditor.propTypes = propTypes; WaypointEditor.defaultProps = defaultProps; -export default compose(withLocalize, withNetwork(), withOnyx({ - transactionID: {key: ONYXKEYS.IOU, selector: (iou) => (iou && iou.transactionID) || ''}, -}))(WaypointEditor); +export default compose( + withLocalize, + withNetwork(), + withOnyx({ + transactionID: {key: ONYXKEYS.IOU, selector: (iou) => (iou && iou.transactionID) || ''}, + }), +)(WaypointEditor); From 072c408ca7ccf370ade965e4790d31299427c2e8 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 16:23:53 -0500 Subject: [PATCH 29/51] Fix values not aligning --- src/components/DistanceRequest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 2be52e39843b..56becd2cac6e 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -122,7 +122,7 @@ function DistanceRequest({transactionID, transaction, translate, formData}) { secondaryIcon={waypointIcon} secondaryIconFill={theme.icon} shouldShowRightIcon - onPress={() => Navigation.navigate(ROUTES.getMoneyRequestWaypointRoute('request', transactionID, index))} + onPress={() => Navigation.navigate(ROUTES.getMoneyRequestWaypointRoute('request', index))} key={key} /> ); From 396934448901d9d388289af5a4e17c44660e5cb2 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 16:29:37 -0500 Subject: [PATCH 30/51] Update WaypointEditor.js --- src/pages/iou/WaypointEditor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 2ec3b9da4651..7f9696dee5d0 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -54,7 +54,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI const waypointValue = values[`waypoint${waypointIndex}`] || ''; // If the user is offline, they can enter any address they want, so we validate it this way - if (network.isOffline && !ValidationUtils.isValidAddress(waypointValue)) { + if (network.isOffline && waypointValue !== '' && !ValidationUtils.isValidAddress(waypointValue)) { errors[`waypoint${waypointIndex}`] = 'bankAccount.error.address'; } From 05a3c4198310d32ccedd098582d38f77ec0726d3 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Mon, 14 Aug 2023 17:21:02 -0500 Subject: [PATCH 31/51] add props to validate on change and on blur --- src/components/Form.js | 17 +++++++++++++++-- src/pages/iou/WaypointEditor.js | 17 ++++++++--------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index d4db912d975a..55b863fb0214 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -62,6 +62,12 @@ const propTypes = { /** Whether the form submit action is dangerous */ isSubmitActionDangerous: PropTypes.bool, + /** Whether the validate() method should run on input changes */ + shouldValidateOnChange: PropTypes.bool, + + /** Whether the validate() method should run on blur */ + shouldValidateOnBlur: PropTypes.bool, + /** Whether ScrollWithContext should be used instead of regular ScrollView. * Set to true when there's a nested Picker component in Form. */ @@ -89,6 +95,8 @@ const defaultProps = { enabledWhenOffline: false, isSubmitActionDangerous: false, scrollContextEnabled: false, + shouldValidateOnChange: true, + shouldValidateOnBlur: true, footerContent: null, style: [], validate: () => ({}), @@ -306,7 +314,9 @@ function Form(props) { // web and mobile web platforms. setTimeout(() => { setTouchedInput(inputID); - onValidate(inputValues); + if (props.shouldValidateOnBlur) { + onValidate(inputValues); + } }, 200); } @@ -324,7 +334,10 @@ function Form(props) { ...prevState, [inputKey]: value, }; - onValidate(newState); + + if (props.shouldValidateOnChange) { + onValidate(newState); + } return newState; }); diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 7f9696dee5d0..54371c043e3a 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -52,23 +52,20 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI const validate = (values) => { const errors = {}; const waypointValue = values[`waypoint${waypointIndex}`] || ''; - - // If the user is offline, they can enter any address they want, so we validate it this way if (network.isOffline && waypointValue !== '' && !ValidationUtils.isValidAddress(waypointValue)) { errors[`waypoint${waypointIndex}`] = 'bankAccount.error.address'; } + // Require the user to select a suggested address if they are online + if (!network.isOffline && waypointValue !== '') { + errors[`waypoint${waypointIndex}`] = 'distance.errors.selectSuggestedAddress'; + } + return errors; }; const onSubmit = (values) => { - const waypointValue = values[`waypoint${waypointIndex}`] || ''; - - // Prevent the user from submitting the form if they are online - // The only way is to select an address from the auto-complete - if (!network.isOffline && waypointValue !== '') { - return; - } + const waypointValue = (values[`waypoint${waypointIndex}`]) || ''; // Allows letting you set a waypoint to an empty value if (waypointValue === '') { @@ -114,6 +111,8 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI enabledWhenOffline validate={validate} onSubmit={onSubmit} + shouldValidateOnChange={false} + shouldValidateOnBlur={false} submitButtonText={translate('common.save')} > From 92e11a7b91e6d2347547ffe23c22b62858beb50d Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 15 Aug 2023 10:01:19 -0500 Subject: [PATCH 32/51] Add auto-focus --- src/pages/iou/WaypointEditor.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 54371c043e3a..de5256772171 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useRef} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; @@ -49,6 +49,8 @@ const defaultProps = { }; function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate}) { + const textInput = useRef(null); + const validate = (values) => { const errors = {}; const waypointValue = values[`waypoint${waypointIndex}`] || ''; @@ -97,7 +99,10 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI }; return ( - + textInput.current && textInput.current.focus()} + > (textInput.current = e)} hint={!network.isOffline ? translate('distance.errors.selectSuggestedAddress') : ''} containerStyles={[styles.mt4]} label={translate('distance.address')} From 4a1490c4726a4dca34787b6044646e1a113d190d Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 15 Aug 2023 10:12:29 -0500 Subject: [PATCH 33/51] prettier --- src/pages/iou/WaypointEditor.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index de5256772171..247342d26ec0 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -50,7 +50,7 @@ const defaultProps = { function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate}) { const textInput = useRef(null); - + const validate = (values) => { const errors = {}; const waypointValue = values[`waypoint${waypointIndex}`] || ''; @@ -67,7 +67,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI }; const onSubmit = (values) => { - const waypointValue = (values[`waypoint${waypointIndex}`]) || ''; + const waypointValue = values[`waypoint${waypointIndex}`] || ''; // Allows letting you set a waypoint to an empty value if (waypointValue === '') { @@ -99,7 +99,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI }; return ( - textInput.current && textInput.current.focus()} > From b14be0bda13525fda40e11f249a6381f9c3c9c0b Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 15 Aug 2023 10:30:18 -0500 Subject: [PATCH 34/51] Have it pull the transaction data --- src/components/DistanceRequest.js | 10 ++-------- src/pages/iou/WaypointEditor.js | 1 + 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 56becd2cac6e..31778c5918e7 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -46,18 +46,15 @@ const propTypes = { }), }), - formData: PropTypes.shape({}), - ...withLocalizePropTypes, }; const defaultProps = { transactionID: '', transaction: {}, - formData: {}, }; -function DistanceRequest({transactionID, transaction, translate, formData}) { +function DistanceRequest({transactionID, transaction, translate}) { const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); const [scrollContentHeight, setScrollContentHeight] = useState(0); @@ -116,7 +113,7 @@ function DistanceRequest({transactionID, transaction, translate, formData}) { return ( `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 247342d26ec0..41876687ffa1 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -84,6 +84,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI Transaction.saveWaypoint(transactionID, waypointIndex, waypoint); } + // Other flows will be handled by selecting a waypoint with selectWaypoint as this is mainly for the offline flow Navigation.navigate(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); }; From 378c4a57e3cfeed3ab1d3a41d0c01c75e04da5cb Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 15 Aug 2023 15:19:58 -0500 Subject: [PATCH 35/51] Add handling to remove waypoints and reindex them --- src/libs/actions/Transaction.js | 46 ++++++++++++++++++++++++++++++++- src/pages/iou/WaypointEditor.js | 2 +- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 52876b7acaf0..77e80255ea95 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -1,5 +1,20 @@ +import _ from 'underscore'; import Onyx from 'react-native-onyx'; import ONYXKEYS from '../../ONYXKEYS'; +import lodashGet from 'lodash/get'; +import * as CollectionUtils from '../CollectionUtils'; + +const allTransactions = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.TRANSACTION, + callback: (transactions, key) => { + if (!key || !transactions) { + return; + } + const transactionID = CollectionUtils.extractCollectionItemID(key); + allTransactions[transactionID] = transactions; + }, +}); /** * @param {String} transactionID @@ -47,4 +62,33 @@ function saveWaypoint(transactionID, index, waypoint) { }); } -export {addStop, createInitialWaypoints, saveWaypoint}; + +function removeWaypoint(transactionID, index) { + const transaction = lodashGet(allTransactions, transactionID, {}); + const existingWaypoints = lodashGet(transaction, 'comment.waypoints', {}); + const totalWaypoints = _.size(existingWaypoints); + + // Prevents removing the starting or ending waypoint + if (index === 0 || index === totalWaypoints - 1) { + saveWaypoint(transactionID, index, null); + return; + } + + const waypointValues = _.values(existingWaypoints); + waypointValues.splice(index, 1); + + const reIndexedWaypoints = {}; + waypointValues.forEach((waypoint, idx) => { + reIndexedWaypoints[`waypoint${idx}`] = waypoint; + }); + + // Onyx.merge won't remove the null nested object values, this is a workaround + // to remove nested keys while also preserving other object keys + transaction.comment.waypoints = reIndexedWaypoints; + + console.log(transaction); + + Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {...transaction}); +} + +export {addStop, createInitialWaypoints, saveWaypoint, removeWaypoint}; diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 41876687ffa1..646b0030f126 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -71,7 +71,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI // Allows letting you set a waypoint to an empty value if (waypointValue === '') { - Transaction.saveWaypoint(transactionID, waypointIndex, null); + Transaction.removeWaypoint(transactionID, waypointIndex); } // While the user is offline, the auto-complete address search will not work From 602d87ac116643b7d39c9bce21481a4567453374 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 15 Aug 2023 15:23:59 -0500 Subject: [PATCH 36/51] fix lint issue --- src/components/Form.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Form.js b/src/components/Form.js index 55b863fb0214..c77412b01254 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -354,7 +354,7 @@ function Form(props) { return childrenElements; }, - [errors, inputRefs, inputValues, onValidate, props.draftValues, props.formID, props.formState, setTouchedInput], + [errors, inputRefs, inputValues, onValidate, props.draftValues, props.formID, props.formState, setTouchedInput, props.shouldValidateOnBlur, props.shouldValidateOnChange], ); const scrollViewContent = useCallback( From 868ea3d38036121ae35c75fc95faf3e286345d60 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Tue, 15 Aug 2023 15:31:44 -0500 Subject: [PATCH 37/51] Prettier --- src/libs/actions/Transaction.js | 4 ---- src/pages/iou/WaypointEditor.js | 1 - 2 files changed, 5 deletions(-) diff --git a/src/libs/actions/Transaction.js b/src/libs/actions/Transaction.js index 77e80255ea95..3266e16a33e6 100644 --- a/src/libs/actions/Transaction.js +++ b/src/libs/actions/Transaction.js @@ -62,7 +62,6 @@ function saveWaypoint(transactionID, index, waypoint) { }); } - function removeWaypoint(transactionID, index) { const transaction = lodashGet(allTransactions, transactionID, {}); const existingWaypoints = lodashGet(transaction, 'comment.waypoints', {}); @@ -85,9 +84,6 @@ function removeWaypoint(transactionID, index) { // Onyx.merge won't remove the null nested object values, this is a workaround // to remove nested keys while also preserving other object keys transaction.comment.waypoints = reIndexedWaypoints; - - console.log(transaction); - Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {...transaction}); } diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 646b0030f126..9db66cd64807 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -128,7 +128,6 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI hint={!network.isOffline ? translate('distance.errors.selectSuggestedAddress') : ''} containerStyles={[styles.mt4]} label={translate('distance.address')} - shouldSaveDraft onPress={selectWaypoint} maxInputLength={CONST.FORM_CHARACTER_LIMIT} renamedInputKeys={{ From 72887b1695db715ea2037e8075653b742e130309 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 16 Aug 2023 10:22:51 -0500 Subject: [PATCH 38/51] Add new page so WaypointEditor can use transactionID as a prop --- .../AppNavigator/ModalStackNavigators.js | 4 +- src/pages/iou/WaypointEditor.js | 33 +++++++++++- src/pages/iou/WaypointEditorPage.js | 52 +++++++++++++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/pages/iou/WaypointEditorPage.js diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index c1d7143f92b2..5a857da6dafe 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -99,8 +99,8 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator([ }, { getComponent: () => { - const WaypointEditor = require('../../../pages/iou/WaypointEditor').default; - return WaypointEditor; + const WaypointEditorPage = require('../../../pages/iou/WaypointEditorPage').default; + return WaypointEditorPage; }, name: 'Money_Request_Waypoint', }, diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 9db66cd64807..7cb90f49c36a 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,4 +1,5 @@ import React, {useRef} from 'react'; +import lodashGet from 'lodash/get'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; @@ -33,6 +34,27 @@ const propTypes = { }), }), + /** The optimistic transaction for this request */ + transaction: PropTypes.shape({ + /** The transactionID of this request */ + transactionID: PropTypes.string, + + /** The comment object on the transaction */ + comment: PropTypes.shape({ + /** The waypoints defining the distance request */ + waypoints: PropTypes.shape({ + /** The latitude of the waypoint */ + lat: PropTypes.number, + + /** The longitude of the waypoint */ + lng: PropTypes.number, + + /** The address of the waypoint */ + address: PropTypes.string, + }), + }), + }), + /** Information about the network */ network: networkPropTypes.isRequired, @@ -46,10 +68,13 @@ const defaultProps = { waypointIndex: '', }, }, + transaction: {}, }; -function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate}) { +function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate, transaction}) { const textInput = useRef(null); + const waypoint = lodashGet(transaction, `comment.waypoints.waypoint${waypointIndex}`, {}); + const waypointAddress = lodashGet(waypoint, 'address', ''); const validate = (values) => { const errors = {}; @@ -128,6 +153,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI hint={!network.isOffline ? translate('distance.errors.selectSuggestedAddress') : ''} containerStyles={[styles.mt4]} label={translate('distance.address')} + initialValue={waypointAddress} onPress={selectWaypoint} maxInputLength={CONST.FORM_CHARACTER_LIMIT} renamedInputKeys={{ @@ -155,6 +181,9 @@ export default compose( withLocalize, withNetwork(), withOnyx({ - transactionID: {key: ONYXKEYS.IOU, selector: (iou) => (iou && iou.transactionID) || ''}, + transaction: { + key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, + selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), + }, }), )(WaypointEditor); diff --git a/src/pages/iou/WaypointEditorPage.js b/src/pages/iou/WaypointEditorPage.js new file mode 100644 index 000000000000..943d2cfda1aa --- /dev/null +++ b/src/pages/iou/WaypointEditorPage.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 WaypointEditorPage({transactionID, route}) { + return ( + + ) +} + + +WaypointEditorPage.displayName = 'WaypointEditorPage'; +WaypointEditorPage.propTypes = propTypes; +WaypointEditorPage.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.IOU, selector: (iou) => (iou && iou.transactionID) || ''}, +})(WaypointEditorPage); From d52aa161e7d2e32d8ec0309407f487ec4699001f Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 16 Aug 2023 10:23:14 -0500 Subject: [PATCH 39/51] Update WaypointEditor.js --- src/pages/iou/WaypointEditor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index 7cb90f49c36a..f347a2d56992 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -73,8 +73,8 @@ const defaultProps = { function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate, transaction}) { const textInput = useRef(null); - const waypoint = lodashGet(transaction, `comment.waypoints.waypoint${waypointIndex}`, {}); - const waypointAddress = lodashGet(waypoint, 'address', ''); + const currentWaypoint = lodashGet(transaction, `comment.waypoints.waypoint${waypointIndex}`, {}); + const waypointAddress = lodashGet(currentWaypoint, 'address', ''); const validate = (values) => { const errors = {}; From 1bdc6aa71ff3f0a6cb2ec40c9a107146854047c8 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 16 Aug 2023 10:40:23 -0500 Subject: [PATCH 40/51] Fix issue with initial waypoints not showing up --- src/components/DistanceRequest.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index 31778c5918e7..fef04d6f1280 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -68,12 +68,12 @@ function DistanceRequest({transactionID, transaction, translate}) { const scrollContainerMaxHeight = variables.baseMenuItemHeight * MAX_WAYPOINTS_TO_DISPLAY + halfMenuItemHeight; useEffect(() => { - if (!transaction.transactionID || !_.isEmpty(waypoints)) { + if (!transactionID || !_.isEmpty(waypoints)) { return; } // Create the initial start and stop waypoints - Transaction.createInitialWaypoints(transaction.transactionID); - }, [transaction.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. From dda94c5c164627db85d3039fa4161f6892c643c5 Mon Sep 17 00:00:00 2001 From: Jack Nam Date: Wed, 16 Aug 2023 11:17:15 -0500 Subject: [PATCH 41/51] fix numbering --- src/components/DistanceRequest.js | 2 +- src/libs/actions/Transaction.js | 15 +++++++++++---- src/pages/iou/WaypointEditor.js | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index fef04d6f1280..a42d5f7f230a 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -136,7 +136,7 @@ function DistanceRequest({transactionID, transaction, translate}) {