Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add option to delete stop #25984

Merged
2 changes: 2 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
105 changes: 64 additions & 41 deletions src/pages/iou/WaypointEditor.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -11,14 +11,15 @@
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 = {
Expand All @@ -38,11 +39,6 @@

/** The optimistic transaction for this request */
transaction: transactionPropTypes,

/** Information about the network */
network: networkPropTypes.isRequired,

...withLocalizePropTypes,
};

const defaultProps = {
Expand All @@ -54,21 +50,28 @@
transaction: {},
};

function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, network, translate, transaction, recentWaypoints}) {
function WaypointEditor({transactionID, route: {params: {iouType = '', waypointIndex = ''} = {}} = {}, transaction, recentWaypoints}) {

Check failure on line 53 in src/pages/iou/WaypointEditor.js

View workflow job for this annotation

GitHub Actions / lint

'recentWaypoints' is missing in props validation
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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This caused a regression in #35644 , The delete option should not be displayed for empty waypoints.


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';
}

Expand All @@ -85,7 +88,7 @@

// 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,
};
Expand All @@ -97,6 +100,12 @@
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,
Expand All @@ -120,6 +129,25 @@
onBackButtonPress={() => {
Navigation.goBack(ROUTES.getMoneyRequestDistanceTabRoute(iouType));
}}
shouldShowThreeDotsButton={shouldShowThreeDotsButton}
threeDotsAnchorPosition={styles.threeDotsPopoverOffset(windowWidth)}
hayata-suenaga marked this conversation as resolved.
Show resolved Hide resolved
threeDotsMenuItems={[
{
icon: Expensicons.Trashcan,
text: translate('distance.deleteWaypoint'),
onSelected: () => setIsDeleteStopModalOpen(true),
},
]}
/>
<ConfirmModal
title={translate('distance.deleteWaypoint')}
isVisible={isDeleteStopModalOpen}
onConfirm={deleteStopAndHideModal}
onCancel={() => setIsDeleteStopModalOpen(false)}
prompt={translate('distance.deleteWaypointConfirmation')}
confirmText={translate('common.delete')}
cancelText={translate('common.cancel')}
danger
/>
<Form
style={[styles.flexGrow1, styles.mh5]}
Expand All @@ -135,7 +163,7 @@
<AddressSearch
inputID={`waypoint${waypointIndex}`}
ref={(e) => (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}
Expand Down Expand Up @@ -163,30 +191,25 @@
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);
Loading