From e8bf7eee21f46d1151d28860fe67ed82f5e57eb3 Mon Sep 17 00:00:00 2001 From: rayane-djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:09:39 +0100 Subject: [PATCH 1/6] Migrate ConfirmedRoute.js component to TypeScript --- .../{ConfirmedRoute.js => ConfirmedRoute.tsx} | 72 ++++++++----------- .../distanceMapViewPropTypes.js | 2 +- 2 files changed, 32 insertions(+), 42 deletions(-) rename src/components/{ConfirmedRoute.js => ConfirmedRoute.tsx} (64%) diff --git a/src/components/ConfirmedRoute.js b/src/components/ConfirmedRoute.tsx similarity index 64% rename from src/components/ConfirmedRoute.js rename to src/components/ConfirmedRoute.tsx index 3abec6d0d1f4..069235282de9 100644 --- a/src/components/ConfirmedRoute.js +++ b/src/components/ConfirmedRoute.tsx @@ -1,9 +1,7 @@ -import lodashGet from 'lodash/get'; -import lodashIsNil from 'lodash/isNil'; -import PropTypes from 'prop-types'; import React, {useCallback, useEffect} from 'react'; import {withOnyx} from 'react-native-onyx'; -import _ from 'underscore'; +import {OnyxEntry} from 'react-native-onyx/lib/types'; +import {SvgProps} from 'react-native-svg'; import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -11,53 +9,46 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import * as MapboxToken from '@userActions/MapboxToken'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import {MapboxAccessToken, Transaction} from '@src/types/onyx'; +import {WaypointCollection} from '@src/types/onyx/Transaction'; import DistanceMapView from './DistanceMapView'; import * as Expensicons from './Icon/Expensicons'; +import {WayPoint} from './MapView/MapViewTypes'; import PendingMapView from './MapView/PendingMapView'; -import transactionPropTypes from './transactionPropTypes'; - -const propTypes = { - /** Transaction that stores the distance request data */ - transaction: transactionPropTypes, +type ConfirmedRoutePropsOnyxProps = { /** 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, - }), + mapboxAccessToken: OnyxEntry; }; -const defaultProps = { - transaction: {}, - mapboxAccessToken: { - token: '', - }, +type ConfirmedRouteProps = { + /** Transaction that stores the distance request data */ + transaction: Transaction; + /** Data about Mapbox token for calling Mapbox API */ + mapboxAccessToken: MapboxAccessToken; }; -function ConfirmedRoute({mapboxAccessToken, transaction}) { +function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { const {isOffline} = useNetwork(); - const {route0: route} = transaction.routes || {}; - const waypoints = lodashGet(transaction, 'comment.waypoints', {}); - const coordinates = lodashGet(route, 'geometry.coordinates', []); + const route = transaction.routes?.route0 ?? {geometry: {coordinates: []}}; + const waypoints = transaction.comment?.waypoints ?? {}; + const coordinates = route.geometry?.coordinates ?? []; const theme = useTheme(); const styles = useThemeStyles(); const getWaypointMarkers = useCallback( - (waypointsData) => { - const numberOfWaypoints = _.size(waypointsData); + (waypointsData: WaypointCollection): Array => { + const numberOfWaypoints = Object.keys(waypointsData).length; const lastWaypointIndex = numberOfWaypoints - 1; - return _.filter( - _.map(waypointsData, (waypoint, key) => { - if (!waypoint || lodashIsNil(waypoint.lat) || lodashIsNil(waypoint.lng)) { + return Object.entries(waypointsData) + .map(([key, waypoint]) => { + if (!waypoint?.lat || !waypoint?.lng) { return; } const index = TransactionUtils.getWaypointIndex(key); - let MarkerComponent; + let MarkerComponent: React.FC; if (index === 0) { MarkerComponent = Expensicons.DotIndicatorUnfilled; } else if (index === lastWaypointIndex) { @@ -68,7 +59,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}) { return { id: `${waypoint.lng},${waypoint.lat},${index}`, - coordinate: [waypoint.lng, waypoint.lat], + coordinate: [waypoint.lng, waypoint.lat] as [number, number], markerComponent: () => ( ), }; - }), - (waypoint) => waypoint, - ); + }) + .filter((waypoint) => !!waypoint); }, [theme], ); @@ -88,19 +78,21 @@ function ConfirmedRoute({mapboxAccessToken, transaction}) { useEffect(() => { MapboxToken.init(); - return MapboxToken.stop; + return () => { + MapboxToken.stop(); + }; }, []); return ( <> - {!isOffline && Boolean(mapboxAccessToken.token) ? ( + {!isOffline && mapboxAccessToken.token ? ( ({ mapboxAccessToken: { key: ONYXKEYS.MAPBOX_ACCESS_TOKEN, }, })(ConfirmedRoute); ConfirmedRoute.displayName = 'ConfirmedRoute'; -ConfirmedRoute.propTypes = propTypes; -ConfirmedRoute.defaultProps = defaultProps; diff --git a/src/components/DistanceMapView/distanceMapViewPropTypes.js b/src/components/DistanceMapView/distanceMapViewPropTypes.js index 05068cbc9b34..d2904b2048ff 100644 --- a/src/components/DistanceMapView/distanceMapViewPropTypes.js +++ b/src/components/DistanceMapView/distanceMapViewPropTypes.js @@ -27,7 +27,7 @@ const propTypes = { PropTypes.shape({ id: PropTypes.string, coordinate: PropTypes.arrayOf(PropTypes.number), - markerComponent: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), + markerComponent: PropTypes.elementType, }), ), From 5d67fb4da5eef503ea099ee3b0a456d7f0c43c65 Mon Sep 17 00:00:00 2001 From: rayane-djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:54:36 +0100 Subject: [PATCH 2/6] use ConfirmedRoutePropsOnyxProps in ConfirmedRouteProps --- src/components/ConfirmedRoute.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index a7152f0cc0c0..80486cf4f350 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -23,11 +23,9 @@ type ConfirmedRoutePropsOnyxProps = { mapboxAccessToken: OnyxEntry; }; -type ConfirmedRouteProps = { +type ConfirmedRouteProps = ConfirmedRoutePropsOnyxProps & { /** Transaction that stores the distance request data */ transaction: Transaction; - /** Data about Mapbox token for calling Mapbox API */ - mapboxAccessToken: MapboxAccessToken; }; function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { @@ -88,7 +86,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { return ( <> - {!isOffline && mapboxAccessToken.token ? ( + {!isOffline && mapboxAccessToken?.token ? ( Date: Sat, 23 Dec 2023 00:23:10 +0100 Subject: [PATCH 3/6] correct conditional rendering --- src/components/ConfirmedRoute.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index 80486cf4f350..77f8560479e3 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -86,9 +86,9 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { return ( <> - {!isOffline && mapboxAccessToken?.token ? ( + {!isOffline && Boolean(mapboxAccessToken?.token) ? ( Date: Fri, 29 Dec 2023 16:48:34 +0100 Subject: [PATCH 4/6] Address review comments --- src/components/ConfirmedRoute.tsx | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index 77f8560479e3..82ba490b135a 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -1,8 +1,6 @@ -import React, {useCallback, useEffect} from 'react'; -import {ImageSourcePropType} from 'react-native'; +import React, {ReactNode, useCallback, useEffect} from 'react'; import {withOnyx} from 'react-native-onyx'; import {OnyxEntry} from 'react-native-onyx/lib/types'; -import {SvgProps} from 'react-native-svg'; import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -12,12 +10,18 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {MapboxAccessToken, Transaction} from '@src/types/onyx'; import {WaypointCollection} from '@src/types/onyx/Transaction'; +import IconAsset from '@src/types/utils/IconAsset'; import DistanceMapView from './DistanceMapView'; import * as Expensicons from './Icon/Expensicons'; import ImageSVG from './ImageSVG'; -import {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; @@ -30,14 +34,14 @@ type ConfirmedRouteProps = ConfirmedRoutePropsOnyxProps & { function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { const {isOffline} = useNetwork(); - const route = transaction.routes?.route0 ?? {geometry: {coordinates: []}}; + const {route0: route} = transaction.routes ?? {}; const waypoints = transaction.comment?.waypoints ?? {}; const coordinates = route.geometry?.coordinates ?? []; const theme = useTheme(); const styles = useThemeStyles(); const getWaypointMarkers = useCallback( - (waypointsData: WaypointCollection): Array => { + (waypointsData: WaypointCollection): WayPoint[] => { const numberOfWaypoints = Object.keys(waypointsData).length; const lastWaypointIndex = numberOfWaypoints - 1; @@ -48,7 +52,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { } const index = TransactionUtils.getWaypointIndex(key); - let MarkerComponent: React.FC | ImageSourcePropType; + let MarkerComponent: IconAsset; if (index === 0) { MarkerComponent = Expensicons.DotIndicatorUnfilled; } else if (index === lastWaypointIndex) { @@ -59,8 +63,8 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { return { id: `${waypoint.lng},${waypoint.lat},${index}`, - coordinate: [waypoint.lng, waypoint.lat] as [number, number], - markerComponent: () => ( + coordinate: [waypoint.lng, waypoint.lat] as const, + markerComponent: (): ReactNode => ( !!waypoint); + .filter((waypoint): waypoint is WayPoint => !!waypoint); }, [theme], ); @@ -79,9 +83,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { useEffect(() => { MapboxToken.init(); - return () => { - MapboxToken.stop(); - }; + return MapboxToken.stop; }, []); return ( @@ -93,7 +95,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { pitchEnabled={false} initialState={{ zoom: CONST.MAPBOX.DEFAULT_ZOOM, - location: (waypointMarkers[0]?.coordinate ?? CONST.MAPBOX.DEFAULT_COORDINATE) as number[], + location: waypointMarkers?.[0]?.coordinate ?? (CONST.MAPBOX.DEFAULT_COORDINATE as [number, number]), }} directionCoordinates={coordinates} style={[styles.mapView, styles.br4]} From 4d49c6562a1d96ba084546d0ec16d8cdab27187b Mon Sep 17 00:00:00 2001 From: rayane-djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Sun, 7 Jan 2024 21:25:10 +0100 Subject: [PATCH 5/6] Fix lint errors --- src/components/ConfirmedRoute.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index 82ba490b135a..e4fbfe540cfe 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -1,6 +1,6 @@ import React, {ReactNode, useCallback, useEffect} from 'react'; import {withOnyx} from 'react-native-onyx'; -import {OnyxEntry} from 'react-native-onyx/lib/types'; +import type {OnyxEntry} from 'react-native-onyx/lib/types'; import useNetwork from '@hooks/useNetwork'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -8,9 +8,9 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import * as MapboxToken from '@userActions/MapboxToken'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import {MapboxAccessToken, Transaction} from '@src/types/onyx'; -import {WaypointCollection} from '@src/types/onyx/Transaction'; -import IconAsset from '@src/types/utils/IconAsset'; +import type {MapboxAccessToken, Transaction} from '@src/types/onyx'; +import type {WaypointCollection} from '@src/types/onyx/Transaction'; +import type IconAsset from '@src/types/utils/IconAsset'; import DistanceMapView from './DistanceMapView'; import * as Expensicons from './Icon/Expensicons'; import ImageSVG from './ImageSVG'; @@ -97,7 +97,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { zoom: CONST.MAPBOX.DEFAULT_ZOOM, location: waypointMarkers?.[0]?.coordinate ?? (CONST.MAPBOX.DEFAULT_COORDINATE as [number, number]), }} - directionCoordinates={coordinates} + directionCoordinates={coordinates as [number, number][]} style={[styles.mapView, styles.br4]} waypoints={waypointMarkers} styleURL={CONST.MAPBOX.STYLE_URL} From ee491d042c12c6747c41cac67623e3d115676189 Mon Sep 17 00:00:00 2001 From: rayane-djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Sun, 7 Jan 2024 21:33:22 +0100 Subject: [PATCH 6/6] Fix lint errors --- src/components/ConfirmedRoute.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index e4fbfe540cfe..05d6557a72e3 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -1,4 +1,5 @@ -import React, {ReactNode, useCallback, useEffect} from 'react'; +import React, {useCallback, useEffect} from 'react'; +import type {ReactNode} from 'react'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx/lib/types'; import useNetwork from '@hooks/useNetwork'; @@ -97,7 +98,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { zoom: CONST.MAPBOX.DEFAULT_ZOOM, location: waypointMarkers?.[0]?.coordinate ?? (CONST.MAPBOX.DEFAULT_COORDINATE as [number, number]), }} - directionCoordinates={coordinates as [number, number][]} + directionCoordinates={coordinates as Array<[number, number]>} style={[styles.mapView, styles.br4]} waypoints={waypointMarkers} styleURL={CONST.MAPBOX.STYLE_URL}