From 5cb8ab57d67d8f7c72ef6dd98e1f4451dfccb057 Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Wed, 6 Aug 2025 11:19:34 -0700 Subject: [PATCH 01/12] Select scooter mode when starting trip from scooter in nearby view --- lib/components/map/default-map.tsx | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index e88fa5211..46fe2d18c 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -5,10 +5,11 @@ import { connect } from 'react-redux' import { GeolocateControl, NavigationControl } from 'react-map-gl' import { getCurrentDate } from '@opentripplanner/core-utils/lib/time' import { injectIntl } from 'react-intl' +import { MapLocationActionArg } from '@opentripplanner/types' +import { QueryParamChangeEvent } from '@opentripplanner/trip-form/lib/types' import BaseMap from '@opentripplanner/base-map' import generateOTP2TileLayers from '@opentripplanner/otp2-tile-overlay' import React, { Component } from 'react' -import styled from 'styled-components' import { assembleBasePath, @@ -21,7 +22,9 @@ import { ComponentContext } from '../../util/contexts' import { getActiveItinerary, getActiveSearch } from '../../util/state' import { getCurrentPosition } from '../../actions/location' import { MainPanelContent } from '../../actions/ui-constants' +import { onSettingsUpdate } from '../form/util' import { setLocation, setMapPopupLocationAndGeocode } from '../../actions/map' +import { setQueryParam } from '../../actions/form' import { setViewedStop } from '../../actions/ui' import { updateOverlayVisibility } from '../../actions/config' import TransitOperatorIcons from '../util/connected-transit-operator-icons' @@ -278,6 +281,7 @@ class DefaultMap extends Component { carRentalQuery, carRentalStations, config, + currentQuery, getCurrentPosition, intl, itinerary, @@ -285,6 +289,7 @@ class DefaultMap extends Component { nearbyViewActive, pending, setLocation, + setQueryParam, setViewedStop, vehicleRentalQuery, vehicleRentalStations, @@ -319,6 +324,24 @@ class DefaultMap extends Component { const baseLayerUrls = baseLayersWithNames?.map((bl) => bl.url) const baseLayerNames = baseLayersWithNames?.map((bl) => bl.name) + const overlayTypes = overlays + ?.filter((overlay) => overlay?.type === 'otp2')?.[0] + ?.layers?.map((layer) => layer?.type) + const handleSetLocation = (location: MapLocationActionArg) => { + if (overlayTypes && overlayTypes.includes('rentalVehicles')) { + let selectedModeButtons = currentQuery.modeButtons ?? '' + // if selectedModeButtons is undefined, the mode buttons are in their default state, which includes transit + if (selectedModeButtons.length === 0) + selectedModeButtons = 'transit_bike_rent' + else if (!selectedModeButtons.includes('bike_rent')) + selectedModeButtons += '_bike_rent' + console.log('rentalVehicles detected! setting query params') + const evt: QueryParamChangeEvent = { modeButtons: selectedModeButtons } + onSettingsUpdate(setQueryParam)(evt) + } + setLocation(location) + } + const routeBasedTransitVehicleOverlayNameOverride = overlays?.find((o) => o.type === 'vehicles-one-route') || undefined @@ -435,7 +458,7 @@ class DefaultMap extends Component { name: getLayerName(l, config, intl) || l.network || l.type })), vectorTilesEndpoint, - setLocation, + handleSetLocation, setViewedStop, viewedRouteStops, config.companies, @@ -486,6 +509,7 @@ const mapStateToProps = (state) => { bikeRentalStations: state.otp.overlay.bikeRental.stations, carRentalStations: state.otp.overlay.carRental.stations, config: state.otp.config, + currentQuery: state.otp.currentQuery, itinerary: getActiveItinerary(state), mapConfig: state.otp.config.map, nearbyViewActive: @@ -504,6 +528,7 @@ const mapDispatchToProps = { getCurrentPosition, setLocation, setMapPopupLocationAndGeocode, + setQueryParam, setViewedStop, updateOverlayVisibility, vehicleRentalQuery From 85993ff549bb4f699145cd3a999ad5be0f4727f9 Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Wed, 6 Aug 2025 11:28:22 -0700 Subject: [PATCH 02/12] Fix missing import --- lib/components/map/default-map.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 46fe2d18c..52c0c51c8 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -10,6 +10,7 @@ import { QueryParamChangeEvent } from '@opentripplanner/trip-form/lib/types' import BaseMap from '@opentripplanner/base-map' import generateOTP2TileLayers from '@opentripplanner/otp2-tile-overlay' import React, { Component } from 'react' +import styled from 'styled-components' import { assembleBasePath, From 29d5d3f0623b07872b3d5cc15b7ca37e876af5e3 Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Wed, 6 Aug 2025 11:28:39 -0700 Subject: [PATCH 03/12] Remove console log --- lib/components/map/default-map.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 52c0c51c8..664019bfc 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -336,7 +336,6 @@ class DefaultMap extends Component { selectedModeButtons = 'transit_bike_rent' else if (!selectedModeButtons.includes('bike_rent')) selectedModeButtons += '_bike_rent' - console.log('rentalVehicles detected! setting query params') const evt: QueryParamChangeEvent = { modeButtons: selectedModeButtons } onSettingsUpdate(setQueryParam)(evt) } From 18a74a4dc9efef06d9b84981d1169c2d609ac25a Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Wed, 20 Aug 2025 15:15:03 -0500 Subject: [PATCH 04/12] Implement findRequiredOptionsForTransportMode --- lib/components/map/default-map.tsx | 47 +++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 664019bfc..60168a917 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -2,6 +2,7 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck import { connect } from 'react-redux' +import { findRequiredOptionsForTransportMode } from '@opentripplanner/trip-form' import { GeolocateControl, NavigationControl } from 'react-map-gl' import { getCurrentDate } from '@opentripplanner/core-utils/lib/time' import { injectIntl } from 'react-intl' @@ -20,10 +21,15 @@ import { vehicleRentalQuery } from '../../actions/api' import { ComponentContext } from '../../util/contexts' +import { decodeQueryParams } from 'serialize-query-params' import { getActiveItinerary, getActiveSearch } from '../../util/state' import { getCurrentPosition } from '../../actions/location' import { MainPanelContent } from '../../actions/ui-constants' -import { onSettingsUpdate } from '../form/util' +import { + modesQueryParamConfig, + onSettingsUpdate, + setModeButton +} from '../form/util' import { setLocation, setMapPopupLocationAndGeocode } from '../../actions/map' import { setQueryParam } from '../../actions/form' import { setViewedStop } from '../../actions/ui' @@ -282,7 +288,7 @@ class DefaultMap extends Component { carRentalQuery, carRentalStations, config, - currentQuery, + enabledModeButtons, getCurrentPosition, intl, itinerary, @@ -330,14 +336,26 @@ class DefaultMap extends Component { ?.layers?.map((layer) => layer?.type) const handleSetLocation = (location: MapLocationActionArg) => { if (overlayTypes && overlayTypes.includes('rentalVehicles')) { - let selectedModeButtons = currentQuery.modeButtons ?? '' - // if selectedModeButtons is undefined, the mode buttons are in their default state, which includes transit - if (selectedModeButtons.length === 0) - selectedModeButtons = 'transit_bike_rent' - else if (!selectedModeButtons.includes('bike_rent')) - selectedModeButtons += '_bike_rent' - const evt: QueryParamChangeEvent = { modeButtons: selectedModeButtons } - onSettingsUpdate(setQueryParam)(evt) + const requiredOptions: + | { modeButton: string; modeSetting?: string } + | undefined = findRequiredOptionsForTransportMode( + config.modes.modeButtons, + config.modes.modeSettingDefinitions, + { mode: 'SCOOTER', qualifier: 'RENT' } + ) + if (requiredOptions) { + const modeSetter = setModeButton( + enabledModeButtons, + onSettingsUpdate(setQueryParam) + ) + + modeSetter(requiredOptions.modeButton, true) + + if (requiredOptions.modeSetting) + onSettingsUpdate(setQueryParam)({ + [requiredOptions.modeSetting]: true + }) + } } setLocation(location) } @@ -504,12 +522,19 @@ const mapStateToProps = (state) => { ) ) : null + const urlSearchParams = new URLSearchParams(state.router.location.search) + const { modes } = state.otp.config return { bikeRentalStations: state.otp.overlay.bikeRental.stations, carRentalStations: state.otp.overlay.carRental.stations, config: state.otp.config, - currentQuery: state.otp.currentQuery, + enabledModeButtons: + decodeQueryParams(modesQueryParamConfig, { + modeButtons: urlSearchParams.get('modeButtons') + })?.modeButtons || + modes?.initialState?.enabledModeButtons || + {}, itinerary: getActiveItinerary(state), mapConfig: state.otp.config.map, nearbyViewActive: From c58f43f761b7f2a29a87c330912452a919e900ac Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Wed, 20 Aug 2025 15:17:51 -0500 Subject: [PATCH 05/12] Use find instead of filter --- lib/components/map/default-map.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 60168a917..6c648e77a 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -332,7 +332,7 @@ class DefaultMap extends Component { const baseLayerNames = baseLayersWithNames?.map((bl) => bl.name) const overlayTypes = overlays - ?.filter((overlay) => overlay?.type === 'otp2')?.[0] + ?.find((overlay) => overlay?.type === 'otp2') ?.layers?.map((layer) => layer?.type) const handleSetLocation = (location: MapLocationActionArg) => { if (overlayTypes && overlayTypes.includes('rentalVehicles')) { From 03028996127ecb3e4cdb0aa2df040e8bc02dc37e Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Thu, 28 Aug 2025 11:28:46 -0700 Subject: [PATCH 06/12] Version bump trip form package --- lib/components/map/default-map.tsx | 18 ++++++++++-------- package.json | 2 +- yarn.lock | 28 +++++++++++++++++++++++----- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 6c648e77a..6670c227a 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -2,7 +2,10 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck import { connect } from 'react-redux' -import { findRequiredOptionsForTransportMode } from '@opentripplanner/trip-form' +import { + findRequiredOptionsForTransportMode, + RequiredOptionsForTransportMode +} from '@opentripplanner/trip-form' import { GeolocateControl, NavigationControl } from 'react-map-gl' import { getCurrentDate } from '@opentripplanner/core-utils/lib/time' import { injectIntl } from 'react-intl' @@ -336,13 +339,12 @@ class DefaultMap extends Component { ?.layers?.map((layer) => layer?.type) const handleSetLocation = (location: MapLocationActionArg) => { if (overlayTypes && overlayTypes.includes('rentalVehicles')) { - const requiredOptions: - | { modeButton: string; modeSetting?: string } - | undefined = findRequiredOptionsForTransportMode( - config.modes.modeButtons, - config.modes.modeSettingDefinitions, - { mode: 'SCOOTER', qualifier: 'RENT' } - ) + const requiredOptions: RequiredOptionsForTransportMode = + findRequiredOptionsForTransportMode( + config.modes.modeButtons, + config.modes.modeSettingDefinitions, + { mode: 'SCOOTER', qualifier: 'RENT' } + ) if (requiredOptions) { const modeSetter = setModeButton( enabledModeButtons, diff --git a/package.json b/package.json index 4d7220a8d..adddb7498 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@opentripplanner/transit-vehicle-overlay": "6.0.2", "@opentripplanner/transitive-overlay": "6.0.0", "@opentripplanner/trip-details": "^8.0.1", - "@opentripplanner/trip-form": "6.0.1", + "@opentripplanner/trip-form": "6.1.0", "@opentripplanner/trip-viewer-overlay": "4.0.1", "@opentripplanner/vehicle-rental-overlay": "4.0.2", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index be65ea6b3..2918f049e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2733,6 +2733,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@14.0.1": + version "14.0.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-14.0.1.tgz#8800c9cd50680ff09e5375b4a20d2f1c24fb4a8b" + integrity sha512-LfCNtl+YORiBxeutC4+SXL4yMIumrMdL3zNfcV+mghRtpRmus36xd5rCgnzXtv1d6Arbbk+zXixJg90j/tBmwA== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.1" + "@opentripplanner/geocoder" "3.0.5" + "@styled-icons/foundation" "^10.34.0" + "@turf/along" "^6.0.1" + chroma-js "^2.4.2" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + graphql "^16.6.0" + lodash.clonedeep "^4.5.0" + lodash.isequal "^4.5.0" + qs "^6.9.1" + "@opentripplanner/endpoints-overlay@4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-4.0.1.tgz#ecc62b729db876ed3e331b7cab1a638c77a9ebf5" @@ -2975,14 +2993,14 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-6.0.1.tgz#262079589e056bf49c285a5b38257c54c59f088f" - integrity sha512-7o8frpL7rhieQmkrSaAxj+kqp8ocHyxmyB2l2LH8jJmoGgGevtQ5VxEmXaVctwpGJ12Fi1P/yiqD08PqnPG49w== +"@opentripplanner/trip-form@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-6.1.0.tgz#0238052e423436f25ecd0edc3d98c6c5b3429754" + integrity sha512-jeo6wPZBHaf5wBJI3msrjckc5C08WMj6VkRe5b+a2CqEoDwPInxRN658+H6qgxDeCxFzNiOehey3lQq35bTP/Q== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/building-blocks" "3.0.1" - "@opentripplanner/core-utils" "13.0.1" + "@opentripplanner/core-utils" "14.0.1" "@opentripplanner/icons" "4.0.0" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" From c9da892cb68156e78b84872f42618cbe56e86de3 Mon Sep 17 00:00:00 2001 From: danielhep Date: Wed, 27 Aug 2025 16:29:04 -0700 Subject: [PATCH 07/12] add an empty string handler for jest gql --- __tests__/test-utils/mock-data/empty-string.js | 1 + package.json | 1 + 2 files changed, 2 insertions(+) create mode 100644 __tests__/test-utils/mock-data/empty-string.js diff --git a/__tests__/test-utils/mock-data/empty-string.js b/__tests__/test-utils/mock-data/empty-string.js new file mode 100644 index 000000000..b0c50903a --- /dev/null +++ b/__tests__/test-utils/mock-data/empty-string.js @@ -0,0 +1 @@ +module.exports = '' diff --git a/package.json b/package.json index 4015645ac..5af80f8e9 100644 --- a/package.json +++ b/package.json @@ -210,6 +210,7 @@ "i18n/(.*)\\.yml$": "__tests__/test-utils/mock-data/empty-yml.js", "modeSettings.yml$": "__tests__/test-utils/mock-data/empty-yml.js", "i18n-loader": "__tests__/test-utils/mock-data/i18n-loader.js", + "\\.graphql$": "__tests__/test-utils/mock-data/empty-string.js", "\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "__tests__/test-utils/mock-data/fileMock.js" }, "transform": { From d3d224533dc7b04e0af35e7733b062fa796eaf85 Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Mon, 8 Sep 2025 08:41:14 -0700 Subject: [PATCH 08/12] Version bump trip form --- package.json | 2 +- yarn.lock | 28 ++++++++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 5af80f8e9..0859ebd69 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@opentripplanner/transit-vehicle-overlay": "7.0.0", "@opentripplanner/transitive-overlay": "7.0.0", "@opentripplanner/trip-details": "^8.0.1", - "@opentripplanner/trip-form": "6.1.0", + "@opentripplanner/trip-form": "6.1.2", "@opentripplanner/trip-viewer-overlay": "5.0.0", "@opentripplanner/vehicle-rental-overlay": "5.0.0", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index 1b21f1166..cbdb2b302 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2725,10 +2725,10 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/core-utils@14.0.1": - version "14.0.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-14.0.1.tgz#8800c9cd50680ff09e5375b4a20d2f1c24fb4a8b" - integrity sha512-LfCNtl+YORiBxeutC4+SXL4yMIumrMdL3zNfcV+mghRtpRmus36xd5rCgnzXtv1d6Arbbk+zXixJg90j/tBmwA== +"@opentripplanner/core-utils@14.2.0": + version "14.2.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-14.2.0.tgz#6a047b729ed0572b8ceb0ea0d46a6da64d434a1e" + integrity sha512-LR0QBVjf3WNZAL1qYoL+ovA7o2IK/Kn1XCv0z3ZAXSTDBj0bNhRN+i1yrm40KUMtqOikjSp1NUmtXURMUFkwNA== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.1" @@ -2806,6 +2806,14 @@ "@opentripplanner/core-utils" "13.0.0" prop-types "^15.7.2" +"@opentripplanner/icons@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-4.1.0.tgz#9f02b318efa9bf9ad26bfbe9ce900da31821f4a5" + integrity sha512-lAfyJ1xkOFb42Zy6mehLCEx96kzeEwLWqBotpFy/RJMlXS1jahd/VaPRBqy8dqTUrj8y6zkqWesusDQUXiYLIg== + dependencies: + "@opentripplanner/core-utils" "14.2.0" + prop-types "^15.7.2" + "@opentripplanner/itinerary-body@7.0.4": version "7.0.4" resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-7.0.4.tgz#d4d2022707f776cb26108a228c09da839dc264fc" @@ -2956,15 +2964,15 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-6.1.0.tgz#0238052e423436f25ecd0edc3d98c6c5b3429754" - integrity sha512-jeo6wPZBHaf5wBJI3msrjckc5C08WMj6VkRe5b+a2CqEoDwPInxRN658+H6qgxDeCxFzNiOehey3lQq35bTP/Q== +"@opentripplanner/trip-form@6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-6.1.2.tgz#e0628c350ae2ef8a9ee681dfefd0bc2b6618d87a" + integrity sha512-3KrkOsFUZ5Xavy5ddSiWyfF11UFYINOluKtfFp1t0y4ViPIMF7BTmVJ6JC6VBnRch2TO77r6jLnpgMSPJ2bXxg== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/building-blocks" "3.0.1" - "@opentripplanner/core-utils" "14.0.1" - "@opentripplanner/icons" "4.0.0" + "@opentripplanner/core-utils" "14.2.0" + "@opentripplanner/icons" "4.1.0" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" "@styled-icons/fa-regular" "^10.37.0" From 3eff88c140ac652ae19fc15276b48aaa68a0faf8 Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Thu, 11 Sep 2025 09:55:22 -0700 Subject: [PATCH 09/12] Run yarn --- yarn.lock | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/yarn.lock b/yarn.lock index 4afb5ef44..3101b2ff9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2725,6 +2725,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-14.0.0.tgz#8bda57dcd95a0e5b388ef34279ff3a68ff35e66b" + integrity sha512-0yk1FnZFQQpkVBN3J24bBDPJQCJvlRHeid3GjG0blEtIdSdwdShox94ZwYNoLe/lxg2nRCAP5XSgtTVkgcFjGg== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.1" + "@opentripplanner/geocoder" "3.0.5" + "@styled-icons/foundation" "^10.34.0" + "@turf/along" "^6.0.1" + chroma-js "^2.4.2" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + graphql "^16.6.0" + lodash.clonedeep "^4.5.0" + lodash.isequal "^4.5.0" + qs "^6.9.1" + "@opentripplanner/core-utils@14.2.0": version "14.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-14.2.0.tgz#6a047b729ed0572b8ceb0ea0d46a6da64d434a1e" From 3f3664c8ec37e1af58bd2207ee835cadda2365da Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Thu, 11 Sep 2025 09:55:39 -0700 Subject: [PATCH 10/12] Move createLocationHandler to its own function --- lib/components/map/default-map.tsx | 71 ++++++++++++++++++------------ 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 7e20d798e..e2fa26333 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -158,6 +158,42 @@ function getLayerName(overlay, config, intl) { } } +// add comment +const createLocationHandler = ( + config, + setQueryParam, + setLocation, + overlays +): ((location: MapLocationActionArg) => void) => { + return (location: MapLocationActionArg) => { + const overlayTypes = overlays + ?.find((overlay) => overlay?.type === 'otp2') + ?.layers?.map((layer) => layer?.type) + if (overlayTypes && overlayTypes.includes('rentalVehicles')) { + const requiredOptions: RequiredOptionsForTransportMode = + findRequiredOptionsForTransportMode( + config.modes.modeButtons, + config.modes.modeSettingDefinitions, + { mode: 'SCOOTER', qualifier: 'RENT' } + ) + if (requiredOptions) { + const modeSetter = setModeButton( + enabledModeButtons, + onSettingsUpdate(setQueryParam) + ) + + modeSetter(requiredOptions.modeButton, true) + + if (requiredOptions.modeSetting) + onSettingsUpdate(setQueryParam)({ + [requiredOptions.modeSetting]: true + }) + } + } + setLocation(location) + } +} + class DefaultMap extends Component { static contextType = ComponentContext @@ -367,34 +403,6 @@ class DefaultMap extends Component { const baseLayerUrls = baseLayersWithNames?.map((bl) => bl.url) const baseLayerNames = baseLayersWithNames?.map((bl) => bl.name) - const overlayTypes = overlays - ?.find((overlay) => overlay?.type === 'otp2') - ?.layers?.map((layer) => layer?.type) - const handleSetLocation = (location: MapLocationActionArg) => { - if (overlayTypes && overlayTypes.includes('rentalVehicles')) { - const requiredOptions: RequiredOptionsForTransportMode = - findRequiredOptionsForTransportMode( - config.modes.modeButtons, - config.modes.modeSettingDefinitions, - { mode: 'SCOOTER', qualifier: 'RENT' } - ) - if (requiredOptions) { - const modeSetter = setModeButton( - enabledModeButtons, - onSettingsUpdate(setQueryParam) - ) - - modeSetter(requiredOptions.modeButton, true) - - if (requiredOptions.modeSetting) - onSettingsUpdate(setQueryParam)({ - [requiredOptions.modeSetting]: true - }) - } - } - setLocation(location) - } - const routeBasedTransitVehicleOverlayNameOverride = overlays?.find((o) => o.type === 'vehicles-one-route') || undefined @@ -518,7 +526,12 @@ class DefaultMap extends Component { name: getLayerName(l, config, intl) || l.network || l.type })), vectorTilesEndpoint, - handleSetLocation, + createLocationHandler( + config, + setQueryParam, + setLocation, + overlays + ), setViewedStop, viewedRouteStops, config.companies, From 672843a92a87db491ae41afd14a440e6331c3b55 Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Thu, 11 Sep 2025 10:24:21 -0700 Subject: [PATCH 11/12] Add missing argument --- lib/components/map/default-map.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 46a03dab6..b50517477 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -161,6 +161,7 @@ function getLayerName(overlay, config, intl) { // add comment const createLocationHandler = ( config, + enabledModeButtons, setQueryParam, setLocation, overlays @@ -529,6 +530,7 @@ class DefaultMap extends Component { vectorTilesEndpoint, createLocationHandler( config, + enabledModeButtons, setQueryParam, setLocation, overlays From 2796903603fb1bfe53650ef1fe902504f60305ba Mon Sep 17 00:00:00 2001 From: Alec Georgoff Date: Thu, 11 Sep 2025 11:12:28 -0700 Subject: [PATCH 12/12] Add comment for createLocationHandler function --- lib/components/map/default-map.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index b50517477..074a28b8f 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -158,7 +158,12 @@ function getLayerName(overlay, config, intl) { } } -// add comment +/** + * Creates a location handler that enables rental vehicle query params when the user + * clicks "from here" on a rental vehicle in Nearby view. Ideally, this logic would take place + * at a lower level, but the location handler is passed into an OTP-UI component from here; this + * is the lowest level achievable in OTP-RR + */ const createLocationHandler = ( config, enabledModeButtons,