diff --git a/src/languages/en.js b/src/languages/en.js index 093dec9ce64a..08d508bd1dd6 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1612,6 +1612,8 @@ export default { }, distance: { addStop: 'Add stop', + deleteWaypoint: 'Delete waypoint', + deleteWaypointConfirmation: 'Are you sure you want to delete this waypoint?', address: 'Address', waypointEditor: 'Waypoint Editor', waypointDescription: { diff --git a/src/languages/es.js b/src/languages/es.js index e5e5cb8894f7..f6c93e344d5e 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -2099,6 +2099,8 @@ export default { }, distance: { addStop: 'Agregar parada', + deleteWaypoint: 'Eliminar punto de ruta', + deleteWaypointConfirmation: '¿Estás seguro de que quieres eliminar este punto de ruta?', address: 'Dirección', waypointEditor: 'Editor de puntos de ruta', waypointDescription: { diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js index c0c621e353cb..7be73144f0fb 100644 --- a/src/pages/iou/WaypointEditor.js +++ b/src/pages/iou/WaypointEditor.js @@ -1,5 +1,5 @@ -import React, {useRef} from 'react'; import _ from 'underscore'; +import React, {useRef, useState} from 'react'; import lodashGet from 'lodash/get'; import {View} from 'react-native'; import PropTypes from 'prop-types'; @@ -11,14 +11,15 @@ 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 useWindowDimensions from '../../hooks/useWindowDimensions'; +import useLocalize from '../../hooks/useLocalize'; +import useNetwork from '../../hooks/useNetwork'; import CONST from '../../CONST'; -import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import * as Expensicons from '../../components/Icon/Expensicons'; +import ConfirmModal from '../../components/ConfirmModal'; import * as Transaction from '../../libs/actions/Transaction'; import * as ValidationUtils from '../../libs/ValidationUtils'; import ROUTES from '../../ROUTES'; -import {withNetwork} from '../../components/OnyxProvider'; -import networkPropTypes from '../../components/networkPropTypes'; import transactionPropTypes from '../../components/transactionPropTypes'; const propTypes = { @@ -38,11 +39,6 @@ const propTypes = { /** The optimistic transaction for this request */ transaction: transactionPropTypes, - - /** Information about the network */ - network: networkPropTypes.isRequired, - - ...withLocalizePropTypes, }; const defaultProps = { @@ -54,21 +50,28 @@ const defaultProps = { transaction: {}, }; -function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate, transaction, recentWaypoints}) { +function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, transaction, recentWaypoints}) { + const {windowWidth} = useWindowDimensions(); + const {translate} = useLocalize(); + const {isOffline} = useNetwork(); const textInput = useRef(null); + const [isDeleteStopModalOpen, setIsDeleteStopModalOpen] = useState(false); const currentWaypoint = lodashGet(transaction, `comment.waypoints.waypoint${waypointIndex}`, {}); const waypointAddress = lodashGet(currentWaypoint, 'address', ''); + const totalWaypoints = _.size(lodashGet(transaction, 'comment.waypoints', {})); + // Hide the menu when there is only start and finish waypoint + const shouldShowThreeDotsButton = totalWaypoints > 2; const validate = (values) => { const errors = {}; const waypointValue = values[`waypoint${waypointIndex}`] || ''; - if (network.isOffline && waypointValue !== '' && !ValidationUtils.isValidAddress(waypointValue)) { + if (isOffline && waypointValue !== '' && !ValidationUtils.isValidAddress(waypointValue)) { errors[`waypoint${waypointIndex}`] = 'bankAccount.error.address'; } // If the user is online and they are trying to save a value without using the autocomplete, show an error message instructing them to use a selected address instead. // That enables us to save the address with coordinates when it is selected - if (!network.isOffline && waypointValue !== '') { + if (!isOffline && waypointValue !== '') { errors[`waypoint${waypointIndex}`] = 'distance.errors.selectSuggestedAddress'; } @@ -85,7 +88,7 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI // 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 && waypointValue) { + if (isOffline && waypointValue) { const waypoint = { address: waypointValue, }; @@ -97,6 +100,12 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI Navigation.goBack(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); }; + const deleteStopAndHideModal = () => { + Transaction.removeWaypoint(transactionID, waypointIndex); + setIsDeleteStopModalOpen(false); + Navigation.goBack(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); + }; + const selectWaypoint = (values) => { const waypoint = { lat: values.lat, @@ -120,6 +129,25 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI onBackButtonPress={() => { Navigation.goBack(ROUTES.getMoneyRequestDistanceTabRoute(iouType)); }} + shouldShowThreeDotsButton={shouldShowThreeDotsButton} + threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)} + threeDotsMenuItems={[ + { + icon: Expensicons.Trashcan, + text: translate('distance.deleteWaypoint'), + onSelected: () => setIsDeleteStopModalOpen(true), + }, + ]} + /> + setIsDeleteStopModalOpen(false)} + prompt={translate('distance.deleteWaypointConfirmation')} + confirmText={translate('common.delete')} + cancelText={translate('common.cancel')} + danger />
(textInput.current = e)} - hint={!network.isOffline ? translate('distance.errors.selectSuggestedAddress') : ''} + hint={!isOffline ? translate('distance.errors.selectSuggestedAddress') : ''} containerStyles={[styles.mt4]} label={translate('distance.address')} defaultValue={waypointAddress} @@ -163,30 +191,25 @@ function WaypointEditor({transactionID, route: {params: {iouType = '', waypointI WaypointEditor.displayName = 'WaypointEditor'; WaypointEditor.propTypes = propTypes; WaypointEditor.defaultProps = defaultProps; -export default compose( - withLocalize, - withNetwork(), - withOnyx({ - transaction: { - key: (props) => `${ONYXKEYS.COLLECTION.TRANSACTION}${props.transactionID}`, - selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), - }, - - recentWaypoints: { - key: ONYXKEYS.NVP_RECENT_WAYPOINTS, - - // Only grab the most recent 5 waypoints because that's all that is shown in the UI. This also puts them into the format of data - // that the google autocomplete component expects for it's "predefined places" feature. - selector: (waypoints) => - _.map(waypoints ? waypoints.slice(0, 5) : [], (waypoint) => ({ - description: waypoint.address, - geometry: { - location: { - lat: waypoint.lat, - lng: waypoint.lng, - }, +export default withOnyx({ + transaction: { + key: ({transactionID}) => `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + selector: (transaction) => (transaction ? {transactionID: transaction.transactionID, comment: {waypoints: lodashGet(transaction, 'comment.waypoints')}} : null), + }, + recentWaypoints: { + key: ONYXKEYS.NVP_RECENT_WAYPOINTS, + + // Only grab the most recent 5 waypoints because that's all that is shown in the UI. This also puts them into the format of data + // that the google autocomplete component expects for it's "predefined places" feature. + selector: (waypoints) => + _.map(waypoints ? waypoints.slice(0, 5) : [], (waypoint) => ({ + description: waypoint.address, + geometry: { + location: { + lat: waypoint.lat, + lng: waypoint.lng, }, - })), - }, - }), -)(WaypointEditor); + }, + })), + }, +})(WaypointEditor);