Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c335d31
Migrate DistanceRequest/index.js component to TypeScript
rayane-d Jan 11, 2024
f58a6a1
Fix lint errors
rayane-d Jan 11, 2024
96e13af
Migrate DistanceRequest/DistanceRequestRenderItem.js component to Typ…
rayane-d Jan 11, 2024
851ec79
Migrate DistanceRequest/DistanceRequestFooter.js component to TypeScript
rayane-d Jan 11, 2024
35599c6
fix lint error
rayane-d Jan 11, 2024
90915d6
use lodashIsEqual instead of _.Equal, and replace _.isEmpty with nati…
rayane-d Jan 11, 2024
0d1de90
address review comments
rayane-d Jan 12, 2024
8044355
use existing WayPoint type
rayane-d Jan 12, 2024
170d8ae
fix lint error
rayane-d Jan 12, 2024
dc7a5ac
Merge branch 'Expensify:main' into Migrate-DistanceRequest-component-…
rayane-d Jan 12, 2024
8dc1afe
run prettier
rayane-d Jan 12, 2024
9cfce3f
run prettier
rayane-d Jan 12, 2024
d612971
address review comment
rayane-d Jan 19, 2024
4d7c976
Merge branch 'main' into 'Migrate-DistanceRequest-component-to-TypeSc…
rayane-d Jan 24, 2024
3c17075
run prettier
rayane-d Jan 24, 2024
5ad6b46
Merge branch 'Expensify:main' into Migrate-DistanceRequest-component-…
rayane-d Jan 25, 2024
13504e6
Merge branch 'main' into Migrate-DistanceRequest-component-to-TypeScript
rayane-d Feb 2, 2024
095231f
Merge branch 'main' into Migrate-DistanceRequest-component-to-TypeScript
rayane-d Feb 6, 2024
4ad2c85
fix lint error
rayane-d Feb 6, 2024
8d39a54
Merge branch 'Expensify:main' into Migrate-DistanceRequest-component-…
rayane-d Feb 6, 2024
a1cc402
Merge branch 'Expensify:main' into Migrate-DistanceRequest-component-…
rayane-d Feb 7, 2024
b517b7b
Merge branch 'main' into Migrate-DistanceRequest-component-to-TypeScript
rayane-d Feb 10, 2024
c9d74fc
fix lint error
rayane-d Feb 10, 2024
c2d2808
Merge branch 'main' into Migrate-DistanceRequest-component-to-TypeScript
rayane-d Feb 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions src/components/ConfirmedRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,9 @@ import type IconAsset from '@src/types/utils/IconAsset';
import DistanceMapView from './DistanceMapView';
import * as Expensicons from './Icon/Expensicons';
import ImageSVG from './ImageSVG';
import type {WayPoint} from './MapView/MapViewTypes';
import PendingMapView from './MapView/PendingMapView';

type WayPoint = {
id: string;
coordinate: [number, number];
markerComponent: () => ReactNode;
};

type ConfirmedRoutePropsOnyxProps = {
/** Data about Mapbox token for calling Mapbox API */
mapboxAccessToken: OnyxEntry<MapboxAccessToken>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,77 +1,61 @@
import lodashGet from 'lodash/get';
import lodashIsNil from 'lodash/isNil';
import PropTypes from 'prop-types';
import React, {useMemo} from 'react';
import type {ReactNode} from 'react';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import type {OnyxEntry} from 'react-native-onyx';
import Button from '@components/Button';
import DistanceMapView from '@components/DistanceMapView';
import * as Expensicons from '@components/Icon/Expensicons';
import ImageSVG from '@components/ImageSVG';
import transactionPropTypes from '@components/transactionPropTypes';
import type {WayPoint} from '@components/MapView/MapViewTypes';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import * as TransactionUtils from '@libs/TransactionUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {MapboxAccessToken} from '@src/types/onyx';
import type {WaypointCollection} from '@src/types/onyx/Transaction';
import type Transaction from '@src/types/onyx/Transaction';
import type IconAsset from '@src/types/utils/IconAsset';

const MAX_WAYPOINTS = 25;

const propTypes = {
type DistanceRequestFooterOnyxProps = {
/** Data about Mapbox token for calling Mapbox API */
mapboxAccessToken: OnyxEntry<MapboxAccessToken>;
};

type DistanceRequestFooterProps = DistanceRequestFooterOnyxProps & {
Comment thread
rayane-d marked this conversation as resolved.
Resolved
/** The waypoints for the distance request */
waypoints: PropTypes.objectOf(
PropTypes.shape({
lat: PropTypes.number,
lng: PropTypes.number,
address: PropTypes.string,
name: PropTypes.string,
}),
),
waypoints?: WaypointCollection;

/** Function to call when the user wants to add a new waypoint */
navigateToWaypointEditPage: PropTypes.func.isRequired,

/** Data about Mapbox token for calling Mapbox API */
mapboxAccessToken: PropTypes.shape({
/** Temporary token for Mapbox API */
token: PropTypes.string,

/** Time when the token will expire in ISO 8601 */
expiration: PropTypes.string,
}),
navigateToWaypointEditPage: (index: number) => void;

/** The transaction being interacted with */
transaction: transactionPropTypes,
transaction: OnyxEntry<Transaction>;
};

const defaultProps = {
waypoints: {},
mapboxAccessToken: {
token: '',
},
transaction: {},
};
function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navigateToWaypointEditPage}) {
function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navigateToWaypointEditPage}: DistanceRequestFooterProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();

const numberOfWaypoints = _.size(waypoints);
const numberOfFilledWaypoints = _.size(_.filter(waypoints, (waypoint) => !_.isEmpty(waypoint)));
const numberOfWaypoints = Object.keys(waypoints ?? {}).length;
const numberOfFilledWaypoints = Object.values(waypoints ?? {}).filter((waypoint) => Object.keys(waypoint).length).length;
const lastWaypointIndex = numberOfWaypoints - 1;

const waypointMarkers = useMemo(
() =>
_.filter(
_.map(waypoints, (waypoint, key) => {
if (!waypoint || lodashIsNil(waypoint.lat) || lodashIsNil(waypoint.lng)) {
Object.entries(waypoints ?? {})
.map(([key, waypoint]) => {
if (!waypoint?.lat || !waypoint?.lng) {
return;
}

const index = TransactionUtils.getWaypointIndex(key);
let MarkerComponent;
let MarkerComponent: IconAsset;
if (index === 0) {
MarkerComponent = Expensicons.DotIndicatorUnfilled;
} else if (index === lastWaypointIndex) {
Expand All @@ -82,8 +66,8 @@ function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navig

return {
id: `${waypoint.lng},${waypoint.lat},${index}`,
coordinate: [waypoint.lng, waypoint.lat],
markerComponent: () => (
coordinate: [waypoint.lng, waypoint.lat] as const,
markerComponent: (): ReactNode => (
<ImageSVG
src={MarkerComponent}
width={CONST.MAP_MARKER_SIZE}
Expand All @@ -92,9 +76,8 @@ function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navig
/>
),
};
}),
(waypoint) => waypoint,
),
})
.filter((waypoint): waypoint is WayPoint => !!waypoint),
[waypoints, lastWaypointIndex, theme.icon],
);

Expand All @@ -105,7 +88,7 @@ function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navig
<Button
small
icon={Expensicons.Plus}
onPress={() => navigateToWaypointEditPage(_.size(lodashGet(transaction, 'comment.waypoints', {})))}
onPress={() => navigateToWaypointEditPage(Object.keys(transaction?.comment?.waypoints ?? {}).length)}
text={translate('distance.addStop')}
isDisabled={numberOfWaypoints === MAX_WAYPOINTS}
innerStyles={[styles.ph10]}
Expand All @@ -114,14 +97,14 @@ function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navig
)}
<View style={styles.mapViewContainer}>
<DistanceMapView
accessToken={mapboxAccessToken.token}
accessToken={mapboxAccessToken?.token ?? ''}
mapPadding={CONST.MAPBOX.PADDING}
pitchEnabled={false}
initialState={{
zoom: CONST.MAPBOX.DEFAULT_ZOOM,
location: lodashGet(waypointMarkers, [0, 'coordinate'], CONST.MAPBOX.DEFAULT_COORDINATE),
location: waypointMarkers?.[0]?.coordinate ?? (CONST.MAPBOX.DEFAULT_COORDINATE as [number, number]),
}}
directionCoordinates={lodashGet(transaction, 'routes.route0.geometry.coordinates', [])}
directionCoordinates={(transaction?.routes?.route0?.geometry?.coordinates as Array<[number, number]>) ?? []}
style={[styles.mapView, styles.mapEditView]}
waypoints={waypointMarkers}
styleURL={CONST.MAPBOX.STYLE_URL}
Expand All @@ -133,10 +116,8 @@ function DistanceRequestFooter({waypoints, transaction, mapboxAccessToken, navig
}

DistanceRequestFooter.displayName = 'DistanceRequestFooter';
DistanceRequestFooter.propTypes = propTypes;
DistanceRequestFooter.defaultProps = defaultProps;

export default withOnyx({
export default withOnyx<DistanceRequestFooterProps, DistanceRequestFooterOnyxProps>({
mapboxAccessToken: {
key: ONYXKEYS.MAPBOX_ACCESS_TOKEN,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,41 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React from 'react';
import _ from 'underscore';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import type {TranslationPaths} from '@src/languages/types';
import type {WaypointCollection} from '@src/types/onyx/Transaction';

const propTypes = {
type DistanceRequestProps = {
/** The waypoints for the distance request */
waypoints: PropTypes.objectOf(
PropTypes.shape({
lat: PropTypes.number,
lng: PropTypes.number,
address: PropTypes.string,
name: PropTypes.string,
}),
),
waypoints?: WaypointCollection;

/** The index of the item */
item: PropTypes.string,
item?: string;

/** Function to call when the secondary interaction is triggered */
onSecondaryInteraction: PropTypes.func,
onSecondaryInteraction?: () => void;

/** Function to get the index of the item */
getIndex: PropTypes.func,
getIndex?: () => number;

/** Whether the item is active */
isActive: PropTypes.bool,
isActive?: boolean;

/** Function to call when the user clicks the item */
onPress: PropTypes.func,
onPress?: (index: number) => void;

/** Whether the item is disabled */
disabled: PropTypes.bool,
disabled?: boolean;
};

const defaultProps = {
waypoints: {},
item: '',
onSecondaryInteraction: () => {},
getIndex: () => {},
isActive: false,
onPress: () => {},
disabled: false,
};

function DistanceRequestRenderItem({waypoints, item, onSecondaryInteraction, getIndex, isActive, onPress, disabled}) {
function DistanceRequestRenderItem({waypoints, item = '', onSecondaryInteraction, getIndex, isActive = false, onPress = () => {}, disabled = false}: DistanceRequestProps) {
const theme = useTheme();
const {translate} = useLocalize();
const numberOfWaypoints = _.size(waypoints);
const numberOfWaypoints = Object.keys(waypoints ?? {}).length;
const lastWaypointIndex = numberOfWaypoints - 1;

const index = getIndex();
const index = getIndex?.() ?? -1;
let descriptionKey = 'distance.waypointDescription.';
let waypointIcon;
if (index === 0) {
Expand All @@ -67,12 +49,13 @@ function DistanceRequestRenderItem({waypoints, item, onSecondaryInteraction, get
waypointIcon = Expensicons.DotIndicator;
}

const waypoint = lodashGet(waypoints, [`waypoint${index}`], {});
const waypoint = waypoints?.[`waypoint${index}`] ?? {};
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const title = waypoint.name || waypoint.address;

return (
<MenuItemWithTopDescription
description={translate(descriptionKey)}
description={translate(descriptionKey as TranslationPaths)}
title={title}
icon={Expensicons.DragHandles}
iconFill={theme.icon}
Expand All @@ -89,7 +72,5 @@ function DistanceRequestRenderItem({waypoints, item, onSecondaryInteraction, get
}

DistanceRequestRenderItem.displayName = 'DistanceRequestRenderItem';
DistanceRequestRenderItem.propTypes = propTypes;
DistanceRequestRenderItem.defaultProps = defaultProps;

export default DistanceRequestRenderItem;
Loading