From fe85d07c98f15359634a3364ec06182356c0f0fc Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 25 Mar 2024 10:41:10 -0400 Subject: [PATCH 001/162] fix(SavedTripScreen): Pass GraphQL plan vars to middleware for existence check --- lib/actions/apiV2.js | 3 ++- lib/components/user/monitored-trip/saved-trip-screen.js | 4 +++- lib/components/user/types.ts | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 66d8be91b..3f00e72e0 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -1087,7 +1087,8 @@ export function routingQuery(searchId = null, updateSearchInReducer) { } } }) - ?.map(convertGraphQLResponseToLegacy) + ?.map(convertGraphQLResponseToLegacy), + modeCombination: combo }) ) diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js index fa839558d..08cb3f8ad 100644 --- a/lib/components/user/monitored-trip/saved-trip-screen.js +++ b/lib/components/user/monitored-trip/saved-trip-screen.js @@ -74,14 +74,16 @@ class SavedTripScreen extends Component { itinerary, homeTimezone ) + const { modeCombination, ...otherItineraryProps } = itinerary return { ...arrayToDayFields(monitoredDays), arrivalVarianceMinutesThreshold: 5, departureVarianceMinutesThreshold: 5, excludeFederalHolidays: true, isActive: true, - itinerary, + itinerary: otherItineraryProps, leadTimeInMinutes: 30, + otp2QueryParams: modeCombination, // when creating a monitored trip, the query params will be changed on the // backend so that the modes parameter will reflect the modes seen in the // itinerary diff --git a/lib/components/user/types.ts b/lib/components/user/types.ts index f09a3abcf..763b13b89 100644 --- a/lib/components/user/types.ts +++ b/lib/components/user/types.ts @@ -66,7 +66,8 @@ export type MonitoredTrip = Record & { itinerary: Itinerary itineraryExistence?: ItineraryExistence leadTimeInMinutes: number - queryParams: string + otp2QueryParams: Record + queryParams: Record tripName: string userId: string } From 7daa6906c69c60e8aa6920faa06a0523552aea23 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 25 Mar 2024 10:42:37 -0400 Subject: [PATCH 002/162] refactor(apiV2): Drop irrelevant params from GraphQL plan variables. --- lib/actions/apiV2.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 3f00e72e0..4bad3f796 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -986,9 +986,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) { modeSettings, numItineraries: numItineraries || config?.modes?.numItineraries || 7, time, - to: currentQuery.to, - // TODO: Does this break everything? - ...currentQuery + to: currentQuery.to } // Generate combinations if the modes for query are not specified in the query // FIXME: BICYCLE_RENT does not appear in this list unless TRANSIT is also enabled. From 9ff8d1397cbe984271fdfb97ef47ffa28e187518 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 25 Mar 2024 11:08:12 -0400 Subject: [PATCH 003/162] refactor(SavedTripScreen): Pass query.variables from apiV2 directly to monitored trip. --- lib/actions/apiV2.js | 2 +- lib/components/user/monitored-trip/saved-trip-screen.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 4bad3f796..80abd305d 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -1086,7 +1086,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) { } }) ?.map(convertGraphQLResponseToLegacy), - modeCombination: combo + otp2QueryParams: query.variables }) ) diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js index 08cb3f8ad..5a86c31f6 100644 --- a/lib/components/user/monitored-trip/saved-trip-screen.js +++ b/lib/components/user/monitored-trip/saved-trip-screen.js @@ -74,7 +74,7 @@ class SavedTripScreen extends Component { itinerary, homeTimezone ) - const { modeCombination, ...otherItineraryProps } = itinerary + const { otp2QueryParams, ...otherItineraryProps } = itinerary return { ...arrayToDayFields(monitoredDays), arrivalVarianceMinutesThreshold: 5, @@ -83,7 +83,7 @@ class SavedTripScreen extends Component { isActive: true, itinerary: otherItineraryProps, leadTimeInMinutes: 30, - otp2QueryParams: modeCombination, + otp2QueryParams, // when creating a monitored trip, the query params will be changed on the // backend so that the modes parameter will reflect the modes seen in the // itinerary From 7e18f4e88471949954d4e299963031871ffd86fa Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 25 Mar 2024 11:11:30 -0400 Subject: [PATCH 004/162] refactor(SavedTripScreen): Remove unused prop. --- lib/components/user/monitored-trip/saved-trip-screen.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js index 5a86c31f6..24cf40d08 100644 --- a/lib/components/user/monitored-trip/saved-trip-screen.js +++ b/lib/components/user/monitored-trip/saved-trip-screen.js @@ -250,7 +250,6 @@ const mapStateToProps = (state, ownProps) => { const itineraries = getActiveItineraries(state) || [] const tripId = ownProps.match.params.id return { - activeSearchId: state.otp.activeSearchId, homeTimezone: state.otp.config.homeTimezone, isCreating: tripId === 'new', itinerary: itineraries[activeItinerary], From 12692f9acfd9c208f931cda9f57481b950416d70 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 09:05:20 -0500 Subject: [PATCH 005/162] Create advanced settings panel --- example.css | 5 +- i18n/en-US.yml | 3 + lib/components/app/batch-routing-panel.tsx | 84 +++++++++++++------ .../form/advanced-settings-button.tsx | 33 ++++++++ .../form/advanced-settings-panel.tsx | 79 +++++++++++++++++ lib/components/form/batch-settings.tsx | 6 ++ lib/components/form/batch-styled.ts | 2 + lib/components/form/form.css | 2 +- lib/components/viewers/viewers.css | 3 +- 9 files changed, 187 insertions(+), 30 deletions(-) create mode 100644 lib/components/form/advanced-settings-button.tsx create mode 100644 lib/components/form/advanced-settings-panel.tsx diff --git a/example.css b/example.css index afd7900f5..6f1cd184f 100644 --- a/example.css +++ b/example.css @@ -39,12 +39,13 @@ .sidebar { height: 100%; padding: 0; - box-shadow: 3px 0px 12px #00000052; - z-index: 1000; + z-index: 99; } .map-container { + box-shadow: 3px 0px 12px #00000052; height: 100%; margin: 0px; padding: 0px; + z-index: 100; } diff --git a/i18n/en-US.yml b/i18n/en-US.yml index 3be68a8c6..dd8d1e833 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -195,8 +195,11 @@ components: BatchRoutingPanel: shortTitle: Plan Trip BatchSearchScreen: + advancedHeader: Advanced preferences + closeAdvancedPreferences: Close advanced preferences header: Plan Your Trip modeSelectorLabel: Select a travel mode + moreOptions: More options BatchSettings: destination: destination invalidModeSelection: >- diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index c1321091e..41caa1dd7 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -4,6 +4,7 @@ import React, { Component, FormEvent } from 'react' import { getActiveSearch, getShowUserSettings } from '../../util/state' import { getPersistenceMode } from '../../util/user' +import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import InvisibleA11yLabel from '../util/invisible-a11y-label' import LocationField from '../form/connected-location-field' @@ -24,7 +25,9 @@ interface Props { */ class BatchRoutingPanel extends Component { state = { - planTripClicked: false + fade: false, + planTripClicked: false, + showAdvancedModeSettings: false } handleSubmit = (e: FormEvent) => e.preventDefault() @@ -33,6 +36,20 @@ class BatchRoutingPanel extends Component { this.setState({ planTripClicked: true }) } + handleOpenAdvanceSettings = () => { + this.setState({ showAdvancedModeSettings: true }) + setTimeout(() => { + this.setState({ fade: true }) + }, 300) + } + + handleCloseAdvanceSettings = () => { + this.setState({ fade: false }) + setTimeout(() => { + this.setState({ showAdvancedModeSettings: false }) + }, 300) + } + render() { const { activeSearch, intl, mobile, showUserSettings } = this.props const { planTripClicked } = this.state @@ -44,6 +61,8 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) + console.log(this.state) + return ( { onSubmit={this.handleSubmit} style={{ padding: '10px' }} > - - - + + + +
+ +
+
+ + + )} + {this.state.showAdvancedModeSettings && ( + -
- -
-
- + )} {!activeSearch && showUserSettings && ( diff --git a/lib/components/form/advanced-settings-button.tsx b/lib/components/form/advanced-settings-button.tsx new file mode 100644 index 000000000..f192f7e39 --- /dev/null +++ b/lib/components/form/advanced-settings-button.tsx @@ -0,0 +1,33 @@ +import { ArrowRight } from '@styled-icons/fa-solid' +import { FormattedMessage } from 'react-intl' + +import { grey } from '../util/colors' +import React from 'react' +import styled from 'styled-components' + +interface Props { + onClick: () => void +} + +const StyledTransparentButton = styled.button` + align-items: center; + background: transparent; + border: none; + color: ${grey[700]}; + display: flex; + gap: 7px; + margin-bottom: 5px; + + float: right; +` + +const AdvancedSettingsButton = ({ onClick }: Props): JSX.Element => { + return ( + + + + + ) +} + +export default AdvancedSettingsButton diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx new file mode 100644 index 000000000..7dee4cb49 --- /dev/null +++ b/lib/components/form/advanced-settings-panel.tsx @@ -0,0 +1,79 @@ +import { Close } from '@styled-icons/fa-solid' +import { useIntl } from 'react-intl' + +import PageTitle from '../util/page-title' +import React, { useState } from 'react' +import styled, { keyframes } from 'styled-components' + +const panelFlyIn = keyframes` + 0% { left: 100%; } + 100% { left: 0 } +` + +const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` + left: 0; + top: 0; + height: 100vh; + width: 100%; + position: absolute; + animation: ${panelFlyIn} 400ms ease-in forwards; + animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; + z-index: 100; + background: white; + padding: 1.5em; + box-shadow: 3px 0px 12px #00000052; +` + +const CloseButton = styled.button` + border: none; + background: transparent; +` + +const HeaderContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; +` + +const AdvancedSettingsPanel = ({ + closeAdvancedSettings +}: { + closeAdvancedSettings: () => void +}): JSX.Element => { + const [reverseAnimation, setReverseAnimation] = useState(false) + const intl = useIntl() + const key = reverseAnimation.toString() + const closeButtonText = intl.formatMessage({ + id: 'components.BatchSearchScreen.closeAdvancedPreferences' + }) + const headerText = intl.formatMessage({ + id: 'components.BatchSearchScreen.advancedHeader' + }) + + const closePanel = () => { + closeAdvancedSettings() + setReverseAnimation(true) + } + + return ( + + +

{headerText}

+ + + +
+ +
+ ) +} + +export default AdvancedSettingsPanel diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index 63e748973..2a21201b9 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -34,6 +34,7 @@ import { ModeSelectorContainer, PlanTripButton } from './batch-styled' +import AdvancedSettingsButton from './advanced-settings-button' import DateTimeButton from './date-time-button' const queryParamConfig = { modeButtons: DelimitedArrayParam } @@ -48,6 +49,7 @@ type Props = { modeSettingDefinitions: ModeSetting[] modeSettingValues: ModeSettingValues onPlanTripClick: () => void + openAdvancedSettings?: () => void routingQuery: any setQueryParam: (evt: any) => void spacedOutModeSelector?: boolean @@ -80,6 +82,7 @@ function BatchSettings({ modeSettingDefinitions, modeSettingValues, onPlanTripClick, + openAdvancedSettings, routingQuery, setQueryParam, spacedOutModeSelector, @@ -240,6 +243,9 @@ function BatchSettings({ // Prevent the hover on date/time selector when mode selector has a popup open via keyboard. style={{ pointerEvents: modeSelectorPopup ? 'none' : undefined }} /> + {openAdvancedSettings && ( + + )} ` align-items: flex-start; display: flex; float: right; + justify-content: space-between; + width: 100%; ${PlanTripButton} { border-bottom-left-radius: ${(props) => (props.squashed ? 0 : 'invalid')}; diff --git a/lib/components/form/form.css b/lib/components/form/form.css index 7ef399d67..5fb1a59ee 100644 --- a/lib/components/form/form.css +++ b/lib/components/form/form.css @@ -93,7 +93,7 @@ position: absolute; top: 22px; right: 32px; - z-index: 100000; + z-index: 99; } .otp .switch-button-container-mobile { diff --git a/lib/components/viewers/viewers.css b/lib/components/viewers/viewers.css index 31e260402..060a3ae9d 100644 --- a/lib/components/viewers/viewers.css +++ b/lib/components/viewers/viewers.css @@ -60,7 +60,8 @@ } .otp .trip-viewer .header-text, -.otp .route-viewer .header-text { +.otp .route-viewer .header-text, +.otp .advanced-settings .header-text { display: contents; font-weight: 700; font-size: 24px; From 6bfcf27da3331714659d5f29cf267a16fb5ba310 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 09:26:00 -0500 Subject: [PATCH 006/162] refactor(advanced-settings-panel): clean up css, add focus trap, add headers --- i18n/en-US.yml | 4 +- .../form/advanced-settings-panel.tsx | 56 ++++++++++++------- lib/components/viewers/viewers.css | 8 +++ 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index 82ad151fa..fdbcbe346 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -195,11 +195,13 @@ components: BatchRoutingPanel: shortTitle: Plan Trip BatchSearchScreen: - advancedHeader: Advanced preferences + advancedHeader: Advanced Preferences closeAdvancedPreferences: Close advanced preferences header: Plan Your Trip + modeOptions: Mode Options modeSelectorLabel: Select a travel mode moreOptions: More options + tripOptions: Trip Options BatchSettings: destination: destination invalidModeSelection: >- diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 7dee4cb49..57deb7876 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -1,5 +1,6 @@ import { Close } from '@styled-icons/fa-solid' -import { useIntl } from 'react-intl' +import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' +import { FormattedMessage, useIntl } from 'react-intl' import PageTitle from '../util/page-title' import React, { useState } from 'react' @@ -11,17 +12,17 @@ const panelFlyIn = keyframes` ` const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` - left: 0; - top: 0; - height: 100vh; - width: 100%; - position: absolute; animation: ${panelFlyIn} 400ms ease-in forwards; animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; - z-index: 100; background: white; - padding: 1.5em; box-shadow: 3px 0px 12px #00000052; + height: 100vh; + left: 0; + padding: 1.5em; + position: absolute; + top: 0; + width: 100%; + z-index: 100; ` const CloseButton = styled.button` @@ -61,17 +62,34 @@ const AdvancedSettingsPanel = ({ key={key} reverseAnimation={reverseAnimation} > - -

{headerText}

- - - -
- + + +

{headerText}

+ + + +
+ + {/** + * Date time selector goes here + */} +

+ +

+ {/** + * Trip options (walk speed, walk reluctance, accessible routing) go here + */} +

+ +

+ {/** + * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here + */} +
) } diff --git a/lib/components/viewers/viewers.css b/lib/components/viewers/viewers.css index 060a3ae9d..370da5252 100644 --- a/lib/components/viewers/viewers.css +++ b/lib/components/viewers/viewers.css @@ -67,6 +67,14 @@ font-size: 24px; margin: 0; } + +.otp .advanced-settings h2.header-text { + display: block; + font-size: 18px; + margin: 1em 0; +} + + .otp .route-viewer .header-text.route-expanded { display: flex; align-items: center; From 9a5f4af7e4b98ce27c9df11b5ee2ffc95676864e Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 09:37:01 -0500 Subject: [PATCH 007/162] Fix animation timing --- lib/components/form/advanced-settings-panel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 57deb7876..e22fdb9db 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -12,7 +12,7 @@ const panelFlyIn = keyframes` ` const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` - animation: ${panelFlyIn} 400ms ease-in forwards; + animation: ${panelFlyIn} 300ms ease-in forwards; animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; background: white; box-shadow: 3px 0px 12px #00000052; From 88b30383cc335e885eb7a659d22500bf304f6325 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:29:14 -0500 Subject: [PATCH 008/162] Close advanced panel on page change --- lib/components/app/batch-routing-panel.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 41caa1dd7..1aaabaa09 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -16,6 +16,7 @@ import ViewerContainer from '../viewers/viewer-container' interface Props { activeSearch: any intl: IntlShape + mainPanelContent: number mobile?: boolean showUserSettings: boolean } @@ -30,6 +31,16 @@ class BatchRoutingPanel extends Component { showAdvancedModeSettings: false } + componentDidUpdate(prevProps: Readonly): void { + if ( + prevProps.mainPanelContent === null && + this.props.mainPanelContent !== null && + this.state.showAdvancedModeSettings + ) { + this.handleCloseAdvanceSettings() + } + } + handleSubmit = (e: FormEvent) => e.preventDefault() handlePlanTripClick = () => { @@ -61,8 +72,6 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) - console.log(this.state) - return ( { getShowUserSettings(state) && (state.user.loggedInUser?.hasConsentedToTerms || getPersistenceMode(state.otp.config.persistence).isLocalStorage) + const { mainPanelContent } = state.otp.ui + return { activeSearch: getActiveSearch(state), + mainPanelContent, showUserSettings } } From e5c0192698a6b84a670f5adef889285a9ad1669a Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:41:23 -0500 Subject: [PATCH 009/162] create PANEL_ANIMATION_TIMING variable --- lib/components/app/batch-routing-panel.tsx | 5 +++-- lib/components/form/advanced-settings-panel.tsx | 3 ++- lib/components/form/styled.ts | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 1aaabaa09..fc01faa60 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -4,6 +4,7 @@ import React, { Component, FormEvent } from 'react' import { getActiveSearch, getShowUserSettings } from '../../util/state' import { getPersistenceMode } from '../../util/user' +import { PANEL_ANIMATION_TIMING } from '../form/styled' import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import InvisibleA11yLabel from '../util/invisible-a11y-label' @@ -51,14 +52,14 @@ class BatchRoutingPanel extends Component { this.setState({ showAdvancedModeSettings: true }) setTimeout(() => { this.setState({ fade: true }) - }, 300) + }, PANEL_ANIMATION_TIMING) } handleCloseAdvanceSettings = () => { this.setState({ fade: false }) setTimeout(() => { this.setState({ showAdvancedModeSettings: false }) - }, 300) + }, PANEL_ANIMATION_TIMING) } render() { diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index e22fdb9db..cf04ba9b0 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -2,6 +2,7 @@ import { Close } from '@styled-icons/fa-solid' import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' import { FormattedMessage, useIntl } from 'react-intl' +import { PANEL_ANIMATION_TIMING } from './styled' import PageTitle from '../util/page-title' import React, { useState } from 'react' import styled, { keyframes } from 'styled-components' @@ -12,7 +13,7 @@ const panelFlyIn = keyframes` ` const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` - animation: ${panelFlyIn} 300ms ease-in forwards; + animation: ${panelFlyIn} ${PANEL_ANIMATION_TIMING}ms linear forwards; animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; background: white; box-shadow: 3px 0px 12px #00000052; diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 06e9449f7..5aa71488e 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -8,6 +8,9 @@ import { Input, MenuItemLi } from '@opentripplanner/location-field/lib/styled' import LocationField from '@opentripplanner/location-field' import styled, { css } from 'styled-components' +// How many ms it takes for the advanced settings panel to fly in and out +export const PANEL_ANIMATION_TIMING = 300 + const commonButtonCss = css` -webkit-user-select: none; -moz-user-select: none; From c80a8ba747f0f15156358eeed5fa3f36f392fa71 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:49:10 -0500 Subject: [PATCH 010/162] Smooth animation --- lib/components/form/advanced-settings-panel.tsx | 2 +- lib/components/form/styled.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index cf04ba9b0..2a43f31a3 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -13,7 +13,7 @@ const panelFlyIn = keyframes` ` const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` - animation: ${panelFlyIn} ${PANEL_ANIMATION_TIMING}ms linear forwards; + animation: ${panelFlyIn} ${PANEL_ANIMATION_TIMING}ms ease-in-out forwards; animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; background: white; box-shadow: 3px 0px 12px #00000052; diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 5aa71488e..000bb1245 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -9,7 +9,7 @@ import LocationField from '@opentripplanner/location-field' import styled, { css } from 'styled-components' // How many ms it takes for the advanced settings panel to fly in and out -export const PANEL_ANIMATION_TIMING = 300 +export const PANEL_ANIMATION_TIMING = 550 const commonButtonCss = css` -webkit-user-select: none; From 8fbabd2721bf37b2eb30148a27a6b3a3cca22809 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:50:56 -0500 Subject: [PATCH 011/162] revert example.css changes --- example.css | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/example.css b/example.css index 6f1cd184f..be6b5f609 100644 --- a/example.css +++ b/example.css @@ -39,13 +39,12 @@ .sidebar { height: 100%; padding: 0; - z-index: 99; + box-shadow: 3px 0px 12px #00000052; + z-index: 1000; } .map-container { - box-shadow: 3px 0px 12px #00000052; height: 100%; margin: 0px; padding: 0px; - z-index: 100; -} +} \ No newline at end of file From 5f4268ca09e91884c2ef3741e709c22124b34465 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:04:57 -0500 Subject: [PATCH 012/162] Add AdvancedModePanel to mobile search --- lib/components/form/form.css | 2 +- lib/components/mobile/batch-search-screen.tsx | 81 +++++++++++++------ 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/lib/components/form/form.css b/lib/components/form/form.css index 5fb1a59ee..9f694e155 100644 --- a/lib/components/form/form.css +++ b/lib/components/form/form.css @@ -100,7 +100,7 @@ position: absolute; top: 32px; right: 45px; - z-index: 100000; + z-index: 99; } /* Settings Selector Panel */ diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 930112a88..20c6b38b4 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -4,6 +4,8 @@ import React, { Component } from 'react' import * as uiActions from '../../actions/ui' import { MobileScreens } from '../../actions/ui-constants' +import { PANEL_ANIMATION_TIMING } from '../form/styled' +import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import DefaultMap from '../map/default-map' import LocationField from '../form/connected-location-field' @@ -22,7 +24,9 @@ interface Props { class BatchSearchScreen extends Component { state = { - planTripClicked: false + fade: false, + planTripClicked: false, + showAdvancedModeSettings: false } _fromFieldClicked = () => this.props.setMobileScreen(SET_FROM_LOCATION) @@ -33,6 +37,20 @@ class BatchSearchScreen extends Component { this.setState({ planTripClicked: true }) } + handleOpenAdvanceSettings = () => { + this.setState({ showAdvancedModeSettings: true }) + setTimeout(() => { + this.setState({ fade: true }) + }, PANEL_ANIMATION_TIMING) + } + + handleCloseAdvanceSettings = () => { + this.setState({ fade: false }) + setTimeout(() => { + this.setState({ showAdvancedModeSettings: false }) + }, PANEL_ANIMATION_TIMING) + } + render() { const { intl } = this.props const { planTripClicked } = this.state @@ -45,30 +63,43 @@ class BatchSearchScreen extends Component { />
- - -
- -
- + {!this.state.fade && ( + <> + + +
+ +
+ + + )} + + {this.state.showAdvancedModeSettings && ( + + )}
From f2462aa2293f1d3d632304b73bf92f2b9bc98b27 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:09:18 -0500 Subject: [PATCH 013/162] fix(batch-routing-panel): Remove itins and user settings if advanced panel open --- lib/components/app/batch-routing-panel.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index fc01faa60..c49923256 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -132,18 +132,20 @@ class BatchRoutingPanel extends Component { /> )} - {!activeSearch && showUserSettings && ( + {!activeSearch && showUserSettings && !this.state.fade && ( )} -
- -
+ {!this.state.fade && ( +
+ +
+ )} ) } From ab198f1fba8eff4394deb4c42bf505e54b5d7b64 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:17:34 -0500 Subject: [PATCH 014/162] Clean up animation + add prefersReducedMotion util --- lib/components/form/advanced-settings-panel.tsx | 4 ++-- lib/components/form/styled.ts | 3 ++- lib/components/util/prefersReducedMotion.tsx | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 lib/components/util/prefersReducedMotion.tsx diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 2a43f31a3..593371c32 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -8,8 +8,8 @@ import React, { useState } from 'react' import styled, { keyframes } from 'styled-components' const panelFlyIn = keyframes` - 0% { left: 100%; } - 100% { left: 0 } + 0% { left: 100%; opacity: 25% } + 100% { left: 0; opacity: 100% } ` const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 000bb1245..e8a877bc9 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -5,11 +5,12 @@ import { Styled as TripFormClasses } from '@opentripplanner/trip-form' import { Input, MenuItemLi } from '@opentripplanner/location-field/lib/styled' +import { prefersReducedMotion } from '../util/prefersReducedMotion' import LocationField from '@opentripplanner/location-field' import styled, { css } from 'styled-components' // How many ms it takes for the advanced settings panel to fly in and out -export const PANEL_ANIMATION_TIMING = 550 +export const PANEL_ANIMATION_TIMING = prefersReducedMotion ? 0 : 550 const commonButtonCss = css` -webkit-user-select: none; diff --git a/lib/components/util/prefersReducedMotion.tsx b/lib/components/util/prefersReducedMotion.tsx new file mode 100644 index 000000000..e15c19594 --- /dev/null +++ b/lib/components/util/prefersReducedMotion.tsx @@ -0,0 +1,3 @@ +export const prefersReducedMotion = window.matchMedia( + '(prefers-reduced-motion: reduce)' +).matches From 3690005baa919ddc9dcba6cf205a05e504fc8fad Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:34:45 -0500 Subject: [PATCH 015/162] Clean up comments, tweak css --- lib/components/app/batch-routing-panel.tsx | 6 ++++-- lib/components/form/advanced-settings-button.tsx | 4 +--- lib/components/mobile/batch-search-screen.tsx | 2 ++ lib/components/util/prefersReducedMotion.tsx | 6 ++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index c49923256..514225b6c 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -33,12 +33,13 @@ class BatchRoutingPanel extends Component { } componentDidUpdate(prevProps: Readonly): void { + // Close the advanced mode settings if we navigate to another page if ( prevProps.mainPanelContent === null && this.props.mainPanelContent !== null && this.state.showAdvancedModeSettings ) { - this.handleCloseAdvanceSettings() + this.setState({ fade: false, showAdvancedModeSettings: false }) } } @@ -50,6 +51,7 @@ class BatchRoutingPanel extends Component { handleOpenAdvanceSettings = () => { this.setState({ showAdvancedModeSettings: true }) + // Allow Advanced Settings panel to finish animation before removing form from DOM setTimeout(() => { this.setState({ fade: true }) }, PANEL_ANIMATION_TIMING) @@ -57,6 +59,7 @@ class BatchRoutingPanel extends Component { handleCloseAdvanceSettings = () => { this.setState({ fade: false }) + // Allow Advanced Settings panel to finish animation before removing from DOM setTimeout(() => { this.setState({ showAdvancedModeSettings: false }) }, PANEL_ANIMATION_TIMING) @@ -92,7 +95,6 @@ class BatchRoutingPanel extends Component { onSubmit={this.handleSubmit} style={{ padding: '10px' }} > - {' '} {!this.state.fade && ( <> diff --git a/lib/components/form/advanced-settings-button.tsx b/lib/components/form/advanced-settings-button.tsx index f192f7e39..281d535d5 100644 --- a/lib/components/form/advanced-settings-button.tsx +++ b/lib/components/form/advanced-settings-button.tsx @@ -13,12 +13,10 @@ const StyledTransparentButton = styled.button` align-items: center; background: transparent; border: none; - color: ${grey[700]}; + color: ${grey[800]}; display: flex; gap: 7px; margin-bottom: 5px; - - float: right; ` const AdvancedSettingsButton = ({ onClick }: Props): JSX.Element => { diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 20c6b38b4..755295b38 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -39,6 +39,7 @@ class BatchSearchScreen extends Component { handleOpenAdvanceSettings = () => { this.setState({ showAdvancedModeSettings: true }) + // Allow Advanced Settings panel to finish animation before removing form from DOM setTimeout(() => { this.setState({ fade: true }) }, PANEL_ANIMATION_TIMING) @@ -46,6 +47,7 @@ class BatchSearchScreen extends Component { handleCloseAdvanceSettings = () => { this.setState({ fade: false }) + // Allow Advanced Settings panel to finish animation before removing from DOM setTimeout(() => { this.setState({ showAdvancedModeSettings: false }) }, PANEL_ANIMATION_TIMING) diff --git a/lib/components/util/prefersReducedMotion.tsx b/lib/components/util/prefersReducedMotion.tsx index e15c19594..69e13b7d4 100644 --- a/lib/components/util/prefersReducedMotion.tsx +++ b/lib/components/util/prefersReducedMotion.tsx @@ -1,3 +1,9 @@ +/** + * Identifies whether the user's machine has "reduced motion" enabled + * in their local settings. If reduced motion is on, the app should + * show as few animations & transitions as possible. + * @returns boolean reflecting whether user prefers reduced motion + */ export const prefersReducedMotion = window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches From 31520af3b3acaae3947fc8de381cd0f62ab962a2 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:46:13 -0500 Subject: [PATCH 016/162] Sort css --- lib/components/form/advanced-settings-panel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 593371c32..0e3ed0306 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -27,14 +27,14 @@ const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` ` const CloseButton = styled.button` - border: none; background: transparent; + border: none; ` const HeaderContainer = styled.div` + align-items: center; display: flex; justify-content: space-between; - align-items: center; ` const AdvancedSettingsPanel = ({ From a6ca364d2735cde8c731a89a961ed1630582e47c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:43:33 -0500 Subject: [PATCH 017/162] update animation from homepage to advanced settings --- lib/components/app/batch-routing-panel.tsx | 73 ++++++++++++++----- .../form/advanced-settings-panel.tsx | 7 +- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 514225b6c..d53ffc992 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -10,6 +10,8 @@ import BatchSettings from '../form/batch-settings' import InvisibleA11yLabel from '../util/invisible-a11y-label' import LocationField from '../form/connected-location-field' import NarrativeItineraries from '../narrative/narrative-itineraries' +import styled, { css, keyframes } from 'styled-components' + import SwitchButton from '../form/switch-button' import UserSettings from '../form/user-settings' import ViewerContainer from '../viewers/viewer-container' @@ -22,6 +24,22 @@ interface Props { showUserSettings: boolean } +const wipeLeft = keyframes` + 0% { transform: translateX(0); opacity: 100%;} + 55% { opacity: 0% } + 100% { transform: translateX(-75px); opacity: 0%;} +` + +const animationString = css` + animation: ${wipeLeft} ${PANEL_ANIMATION_TIMING}ms linear forwards; +` + +const WipeLeftContent = styled.div<{ fade: boolean; reverse: boolean }>` + ${(props) => props.fade && animationString}; + animation-direction: ${(props) => props.reverse && 'reverse'}; + height: 100%; +` + /** * Main panel for the batch/trip comparison form. */ @@ -29,6 +47,7 @@ class BatchRoutingPanel extends Component { state = { fade: false, planTripClicked: false, + reverse: false, showAdvancedModeSettings: false } @@ -58,10 +77,10 @@ class BatchRoutingPanel extends Component { } handleCloseAdvanceSettings = () => { - this.setState({ fade: false }) + this.setState({ fade: false, reverse: true }) // Allow Advanced Settings panel to finish animation before removing from DOM setTimeout(() => { - this.setState({ showAdvancedModeSettings: false }) + this.setState({ reverse: false, showAdvancedModeSettings: false }) }, PANEL_ANIMATION_TIMING) } @@ -76,6 +95,8 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) + const reverseKey = !this.state.fade && this.state.reverse ? 'reverse' : '' + return ( { onSubmit={this.handleSubmit} style={{ padding: '10px' }} > + {this.state.showAdvancedModeSettings && ( + + )} {!this.state.fade && ( - <> + { onPlanTripClick={this.handlePlanTripClick} openAdvancedSettings={this.handleOpenAdvanceSettings} /> - - )} - {this.state.showAdvancedModeSettings && ( - + )} - {!activeSearch && showUserSettings && !this.state.fade && ( - - )} {!this.state.fade && ( -
- -
+ {!activeSearch && showUserSettings && ( + + )} + +
+ +
+ )}
) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 0e3ed0306..020ef5e67 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -8,15 +8,14 @@ import React, { useState } from 'react' import styled, { keyframes } from 'styled-components' const panelFlyIn = keyframes` - 0% { left: 100%; opacity: 25% } + 0% { left: 75px; opacity: 0 } + 45% { opacity: 0} 100% { left: 0; opacity: 100% } ` const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` - animation: ${panelFlyIn} ${PANEL_ANIMATION_TIMING}ms ease-in-out forwards; + animation: ${panelFlyIn} ${PANEL_ANIMATION_TIMING}ms linear forwards; animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; - background: white; - box-shadow: 3px 0px 12px #00000052; height: 100vh; left: 0; padding: 1.5em; From 75f8a7f5305fd5a60164b8477c3370997831cc87 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Fri, 14 Jun 2024 16:00:51 +0200 Subject: [PATCH 018/162] messy first pass of bringing in advanced settings from otp ui --- .../form/advanced-settings-panel.tsx | 102 +++++++++++++++++- lib/components/form/batch-settings.tsx | 51 ++------- lib/components/form/util.tsx | 42 ++++++++ lib/util/state-types.ts | 3 + package.json | 2 +- yarn.lock | 17 ++- 6 files changed, 165 insertions(+), 52 deletions(-) create mode 100644 lib/components/form/util.tsx diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 020ef5e67..51c5d08b1 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -1,11 +1,36 @@ +import { + addSettingsToButton, + AdvancedModeSubsettingsContainer, + populateSettingWithValue +} from '@opentripplanner/trip-form' import { Close } from '@styled-icons/fa-solid' +import { connect } from 'react-redux' +import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' import { FormattedMessage, useIntl } from 'react-intl' +import { + ModeButtonDefinition, + ModeSetting, + ModeSettingValues +} from '@opentripplanner/types' +import React, { useContext, useState } from 'react' +import styled, { keyframes } from 'styled-components' + +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' +import { + addCustomSettingLabels, + addModeButtonIcon, + pipe, + populateSettingWithIcon +} from './util' +import { AppReduxState } from '../../util/state-types' +import { ComponentContext } from '../../util/contexts' +import { generateModeSettingValues } from '../../util/api' import { PANEL_ANIMATION_TIMING } from './styled' +import { setModeButtonEnabled } from './batch-settings' import PageTitle from '../util/page-title' -import React, { useState } from 'react' -import styled, { keyframes } from 'styled-components' const panelFlyIn = keyframes` 0% { left: 75px; opacity: 0 } @@ -37,9 +62,19 @@ const HeaderContainer = styled.div` ` const AdvancedSettingsPanel = ({ - closeAdvancedSettings + closeAdvancedSettings, + enabledModeButtons, + modeButtonOptions, + modeSettingDefinitions, + modeSettingValues, + setQueryParam }: { closeAdvancedSettings: () => void + enabledModeButtons: string[] + modeButtonOptions: ModeButtonDefinition[] + modeSettingDefinitions: ModeSetting[] + modeSettingValues: ModeSettingValues + setQueryParam: (evt: any) => void }): JSX.Element => { const [reverseAnimation, setReverseAnimation] = useState(false) const intl = useIntl() @@ -56,6 +91,25 @@ const AdvancedSettingsPanel = ({ setReverseAnimation(true) } + // @ts-expect-error Context not typed + const { ModeIcon } = useContext(ComponentContext) + + const processedModeSettings = modeSettingDefinitions.map( + pipe( + populateSettingWithIcon(ModeIcon), + populateSettingWithValue(modeSettingValues), + addCustomSettingLabels(intl) + ) + ) + + const processedModeButtons = modeButtonOptions.map( + pipe( + addModeButtonIcon(ModeIcon), + addSettingsToButton(processedModeSettings), + setModeButtonEnabled(enabledModeButtons) + ) + ) + return ( ) } -export default AdvancedSettingsPanel +const queryParamConfig = { modeButtons: DelimitedArrayParam } + +const mapStateToProps = (state: AppReduxState) => { + const urlSearchParams = new URLSearchParams(state.router.location.search) + const modeSettingValues = generateModeSettingValues( + urlSearchParams, + state.otp?.modeSettingDefinitions || [], + state.otp.config.modes?.initialState?.modeSettingValues || {} + ) + return { + currentQuery: state.otp.currentQuery, + // TODO: Duplicated in apiv2.js + enabledModeButtons: + decodeQueryParams(queryParamConfig, { + modeButtons: urlSearchParams.get('modeButtons') + })?.modeButtons?.filter((mb): mb is string => mb !== null) || + state.otp.config?.modes?.initialState?.enabledModeButtons || + [], + modeButtonOptions: state.otp.config?.modes?.modeButtons || [], + modeSettingDefinitions: state.otp?.modeSettingDefinitions || [], + modeSettingValues + } +} + +const mapDispatchToProps = { + routingQuery: apiActions.routingQuery, + setQueryParam: formActions.setQueryParam, + updateQueryTimeIfLeavingNow: formActions.updateQueryTimeIfLeavingNow +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(AdvancedSettingsPanel) diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index 2a21201b9..54eb4ebc1 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -29,6 +29,12 @@ import { getFormattedMode } from '../../util/i18n' import { RoutingQueryCallResult } from '../../actions/api-constants' import { StyledIconWrapper } from '../util/styledIcon' +import { + addCustomSettingLabels, + addModeButtonIcon, + pipe, + populateSettingWithIcon +} from './util' import { MainSettingsRow, ModeSelectorContainer, @@ -56,11 +62,6 @@ type Props = { updateQueryTimeIfLeavingNow: () => void } -// This method is used to daisy-chain a series of functions together on a given value -function pipe(...fns: Array<(arg: T) => T>) { - return (value: T) => fns.reduce((acc, fn) => fn(acc), value) -} - export function setModeButtonEnabled(enabledKeys: string[]) { return (modeButton: ModeButtonDefinition): ModeButtonDefinition => { return { @@ -99,51 +100,17 @@ function BatchSettings({ // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) - const addModeButtonIcon = useCallback( - (def: ModeButtonDefinition) => ({ - ...def, - Icon: function ModeButtonIcon() { - return - } - }), - [ModeIcon] - ) - - const populateSettingWithIcon = useCallback( - (msd: ModeSetting) => ({ - ...msd, - icon: - }), - [ModeIcon] - ) - - const addCustomSettingLabels = useCallback( - (msd: ModeSetting) => { - let modeLabel - // If we're using route mode overrides, make sure we're using the custom mode name - if (msd.type === 'SUBMODE') { - modeLabel = msd.overrideMode || msd.addTransportMode.mode - return { - ...msd, - label: getFormattedMode(modeLabel, intl) - } - } - return msd - }, - [intl] - ) - const processedModeSettings = modeSettingDefinitions.map( pipe( - populateSettingWithIcon, + populateSettingWithIcon(ModeIcon), populateSettingWithValue(modeSettingValues), - addCustomSettingLabels + addCustomSettingLabels(intl) ) ) const processedModeButtons = modeButtonOptions.map( pipe( - addModeButtonIcon, + addModeButtonIcon(ModeIcon), addSettingsToButton(processedModeSettings), setModeButtonEnabled(enabledModeButtons) ) diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx new file mode 100644 index 000000000..f424a22b1 --- /dev/null +++ b/lib/components/form/util.tsx @@ -0,0 +1,42 @@ +import { IntlShape } from 'react-intl' +import { ModeButtonDefinition, ModeSetting } from '@opentripplanner/types' +import React from 'react' + +import { getFormattedMode } from '../../util/i18n' + +// This method is used to daisy-chain a series of functions together on a given value +export function pipe(...fns: Array<(arg: T) => T>) { + return (value: T) => fns.reduce((acc, fn) => fn(acc), value) +} + +export const populateSettingWithIcon = + (ModeIcon: React.ComponentType<{ mode?: string; width?: number }>) => + // eslint-disable-next-line react/display-name + (msd: ModeSetting): ModeSetting => ({ + ...msd, + icon: + }) + +export const addModeButtonIcon = + (ModeIcon: React.ComponentType<{ mode?: string; width?: number }>) => + (def: ModeButtonDefinition): ModeButtonDefinition => ({ + ...def, + Icon: function ModeButtonIcon() { + return + } + }) + +export const addCustomSettingLabels = + (intl: IntlShape) => + (msd: ModeSetting): ModeSetting => { + let modeLabel + // If we're using route mode overrides, make sure we're using the custom mode name + if (msd.type === 'SUBMODE') { + modeLabel = msd.overrideMode || msd.addTransportMode.mode + return { + ...msd, + label: getFormattedMode(modeLabel, intl) + } + } + return msd + } diff --git a/lib/util/state-types.ts b/lib/util/state-types.ts index 3daba23c6..99c321a3b 100644 --- a/lib/util/state-types.ts +++ b/lib/util/state-types.ts @@ -5,6 +5,7 @@ import { MonitoredTrip, User } from '../components/user/types' +import { ModeSetting } from '@opentripplanner/types' import { AppConfig } from './config-types' @@ -12,12 +13,14 @@ export interface OtpState { // TODO: Add other OTP states activeSearchId?: string config: AppConfig + currentQuery: any filter: { sort: { type: string } } location: any + modeSettingDefinitions: ModeSetting[] overlay: any serviceTimeRange?: { end: number diff --git a/package.json b/package.json index bf546fa3c..6930291aa 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@opentripplanner/transit-vehicle-overlay": "^4.0.10", "@opentripplanner/transitive-overlay": "^3.0.18", "@opentripplanner/trip-details": "^5.0.11", - "@opentripplanner/trip-form": "^3.6.0", + "@opentripplanner/trip-form": "^3.7.0-alpha.1", "@opentripplanner/trip-viewer-overlay": "^2.0.8", "@opentripplanner/vehicle-rental-overlay": "^2.1.7", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index 2cddcde2c..9e9a4c2ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,19 +2606,21 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.0.tgz#e02996e3e21cee951a61522c1c01ea55f978c2b8" - integrity sha512-iV3bQkRhcJxvty7BZ+RUN/ylLmH+twUcveQgHj1HUCkPhEOz98m26ykDYXQhOXP68k/y9PtaLlt+Gzsa6p+8xQ== +"@opentripplanner/trip-form@^3.7.0-alpha.1": + version "3.7.0-alpha.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.1.tgz#025c2e4f01f9e7689006eb266c73b48a9afba90c" + integrity sha512-V938paiKZhiKmrtOhAB4gA22LBWfgpLVE6RKzfdKWxVMLnbuGiUiJOWlgDVrdx/DL/IyB5L81GWcu5BIcWQBog== dependencies: "@floating-ui/react" "^0.19.2" - "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/building-blocks" "^1.0.3" + "@opentripplanner/core-utils" "^11.4.0" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" "@styled-icons/fa-regular" "^10.37.0" "@styled-icons/fa-solid" "^10.37.0" date-fns "^2.28.0" flat "^5.0.2" + react-animate-height "^3.2.3" react-indiana-drag-scroll "^2.0.1" react-inlinesvg "^2.3.0" @@ -15052,6 +15054,11 @@ react-animate-height@^3.0.4: dependencies: classnames "^2.3.1" +react-animate-height@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/react-animate-height/-/react-animate-height-3.2.3.tgz#90929aadac1bd1851cb6a685acc105b50ccfda8c" + integrity sha512-R6DSvr7ud07oeCixScyvXWEMJY/Mt2+GyOWC1KMaRc69gOBw+SsCg4TJmrp4rKUM1hyd6p+YKw90brjPH93Y2A== + react-app-polyfill@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz#a0bea50f078b8a082970a9d853dc34b6dcc6a3cf" From fc070976ca9c2d95878d0bf19b3755a99c75bb2f Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:00:16 -0500 Subject: [PATCH 019/162] add react-transition-group to advanced panel --- lib/components/app/batch-routing-panel.tsx | 258 +++++++++++------- .../form/advanced-settings-panel.tsx | 29 +- package.json | 2 + yarn.lock | 17 ++ 4 files changed, 187 insertions(+), 119 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index d53ffc992..41c332fb7 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -1,17 +1,18 @@ import { connect } from 'react-redux' +import { CSSTransition, TransitionGroup } from 'react-transition-group' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' -import React, { Component, FormEvent } from 'react' import { getActiveSearch, getShowUserSettings } from '../../util/state' import { getPersistenceMode } from '../../util/user' -import { PANEL_ANIMATION_TIMING } from '../form/styled' import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import InvisibleA11yLabel from '../util/invisible-a11y-label' import LocationField from '../form/connected-location-field' import NarrativeItineraries from '../narrative/narrative-itineraries' -import styled, { css, keyframes } from 'styled-components' +import React, { Component, FormEvent } from 'react' +import styled, { css } from 'styled-components' +import { prefersReducedMotion } from '../util/prefersReducedMotion' import SwitchButton from '../form/switch-button' import UserSettings from '../form/user-settings' import ViewerContainer from '../viewers/viewer-container' @@ -24,20 +25,59 @@ interface Props { showUserSettings: boolean } -const wipeLeft = keyframes` - 0% { transform: translateX(0); opacity: 100%;} - 55% { opacity: 0% } - 100% { transform: translateX(-75px); opacity: 0%;} +const advancedPanelClassName = 'advanced-panel' +const mainPanelClassName = 'main-panel' +const wipeOffset = 7 +const transitionDuration = prefersReducedMotion ? 0 : 200 + +const transitionMixin = css` + transition: all ${transitionDuration}ms ease-in; ` -const animationString = css` - animation: ${wipeLeft} ${PANEL_ANIMATION_TIMING}ms linear forwards; +const wipeOutMixin = (offset: number) => css` + transform: translateX(${offset}px); + opacity: 0; +` +const wipeInMixin = css` + transform: translateX(0px); + opacity: 1; ` -const WipeLeftContent = styled.div<{ fade: boolean; reverse: boolean }>` - ${(props) => props.fade && animationString}; - animation-direction: ${(props) => props.reverse && 'reverse'}; - height: 100%; +const TransitionStyles = styled.div` + display: contents; + .${advancedPanelClassName}-enter { + ${wipeOutMixin(wipeOffset)} + } + .${advancedPanelClassName}-enter-done { + ${wipeInMixin} + ${transitionMixin} + } + + .${advancedPanelClassName}-exit { + ${wipeInMixin} + } + + .${advancedPanelClassName}-exit-active { + ${wipeOutMixin(wipeOffset)} + ${transitionMixin} + } + + .${mainPanelClassName}-enter { + ${wipeOutMixin(-wipeOffset)} + } + .${mainPanelClassName}-enter-done { + ${wipeInMixin} + ${transitionMixin} + } + + .${mainPanelClassName}-exit { + ${wipeInMixin} + } + + .${mainPanelClassName}-exit-active { + ${wipeOutMixin(-wipeOffset)} + ${transitionMixin} + } ` /** @@ -45,12 +85,15 @@ const WipeLeftContent = styled.div<{ fade: boolean; reverse: boolean }>` */ class BatchRoutingPanel extends Component { state = { - fade: false, planTripClicked: false, reverse: false, showAdvancedModeSettings: false } + _advancedSettingRef = React.createRef() + _mainPanelContentRef = React.createRef() + _itinerariesAndUserRef = React.createRef() + componentDidUpdate(prevProps: Readonly): void { // Close the advanced mode settings if we navigate to another page if ( @@ -58,7 +101,9 @@ class BatchRoutingPanel extends Component { this.props.mainPanelContent !== null && this.state.showAdvancedModeSettings ) { - this.setState({ fade: false, showAdvancedModeSettings: false }) + this.setState({ + showAdvancedModeSettings: false + }) } } @@ -70,18 +115,10 @@ class BatchRoutingPanel extends Component { handleOpenAdvanceSettings = () => { this.setState({ showAdvancedModeSettings: true }) - // Allow Advanced Settings panel to finish animation before removing form from DOM - setTimeout(() => { - this.setState({ fade: true }) - }, PANEL_ANIMATION_TIMING) } handleCloseAdvanceSettings = () => { - this.setState({ fade: false, reverse: true }) - // Allow Advanced Settings panel to finish animation before removing from DOM - setTimeout(() => { - this.setState({ reverse: false, showAdvancedModeSettings: false }) - }, PANEL_ANIMATION_TIMING) + this.setState({ showAdvancedModeSettings: false }) } render() { @@ -95,8 +132,6 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) - const reverseKey = !this.state.fade && this.state.reverse ? 'reverse' : '' - return ( { height: '100%' }} > - -

- -

-
-
- {this.state.showAdvancedModeSettings && ( - + + {!this.state.showAdvancedModeSettings && ( + +

+ +

+
)} - {!this.state.fade && ( - - - - + + {this.state.showAdvancedModeSettings && ( + + + + )} + + {!this.state.showAdvancedModeSettings && ( + this.setState({ showAdvancedModeSettings: true }) + // eslint-disable-next-line react/jsx-curly-newline + } + timeout={transitionDuration} + > +
+ + + +
+ +
+
+ +
+
+ )} +
+ + + {!this.state.showAdvancedModeSettings && ( + +
+ {!activeSearch && showUserSettings && ( + )} - isRequired - locationType="to" - selfValidate={planTripClicked} - showClearButton={!mobile} - /> -
- + +
+ +
- - - - )} - - {!this.state.fade && ( - - {!activeSearch && showUserSettings && ( - + )} - -
- -
-
- )} + + ) } diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 020ef5e67..19285695f 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -2,22 +2,12 @@ import { Close } from '@styled-icons/fa-solid' import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' import { FormattedMessage, useIntl } from 'react-intl' -import { PANEL_ANIMATION_TIMING } from './styled' import PageTitle from '../util/page-title' -import React, { useState } from 'react' -import styled, { keyframes } from 'styled-components' +import React, { RefObject } from 'react' +import styled from 'styled-components' -const panelFlyIn = keyframes` - 0% { left: 75px; opacity: 0 } - 45% { opacity: 0} - 100% { left: 0; opacity: 100% } -` - -const PanelOverlay = styled.div<{ reverseAnimation: boolean }>` - animation: ${panelFlyIn} ${PANEL_ANIMATION_TIMING}ms linear forwards; - animation-direction: ${(props) => props.reverseAnimation && 'reverse'}; +const PanelOverlay = styled.div` height: 100vh; - left: 0; padding: 1.5em; position: absolute; top: 0; @@ -37,13 +27,13 @@ const HeaderContainer = styled.div` ` const AdvancedSettingsPanel = ({ - closeAdvancedSettings + closeAdvancedSettings, + innerRef }: { closeAdvancedSettings: () => void + innerRef: RefObject }): JSX.Element => { - const [reverseAnimation, setReverseAnimation] = useState(false) const intl = useIntl() - const key = reverseAnimation.toString() const closeButtonText = intl.formatMessage({ id: 'components.BatchSearchScreen.closeAdvancedPreferences' }) @@ -53,15 +43,10 @@ const AdvancedSettingsPanel = ({ const closePanel = () => { closeAdvancedSettings() - setReverseAnimation(true) } return ( - +

{headerText}

diff --git a/package.json b/package.json index bf546fa3c..e3e28ec89 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "@styled-icons/fa-solid": "^10.34.0", "@turf/centroid": "^6.5.0", "@turf/helpers": "^6.5.0", + "@types/react-transition-group": "^4.4.10", "blob-stream": "^0.1.3", "bootstrap": "^3.3.7", "bowser": "^1.9.3", @@ -118,6 +119,7 @@ "react-router-dom": "^5.3.4", "react-select": "^3.1.0", "react-sliding-pane": "^7.0.0", + "react-transition-group": "^4.4.5", "redux": "^4.0.4", "redux-actions": "^1.2.1", "redux-logger": "^2.7.4", diff --git a/yarn.lock b/yarn.lock index 2cddcde2c..6f2ee2bfa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3618,6 +3618,13 @@ "@types/history" "^4.7.11" "@types/react" "*" +"@types/react-transition-group@^4.4.10": + version "4.4.10" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" + integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@17": version "17.0.38" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd" @@ -15455,6 +15462,16 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-transition-group@^4.4.5: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react@<17.0.0: version "16.14.0" resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" From 9af5feb3e39103fb226a0e70df0da36394899e80 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:25:28 -0500 Subject: [PATCH 020/162] Fix innerRef --- lib/components/form/advanced-settings-panel.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index b32eb6939..581790138 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -10,8 +10,8 @@ import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' import { FormattedMessage, useIntl } from 'react-intl' import PageTitle from '../util/page-title' -import React from 'react' -import styled, { keyframes } from 'styled-components' +import React, { RefObject } from 'react' +import styled from 'styled-components' const PanelOverlay = styled.div` height: 100vh; @@ -34,9 +34,11 @@ const HeaderContainer = styled.div` ` const AdvancedSettingsPanel = ({ - closeAdvancedSettings + closeAdvancedSettings, + innerRef }: { closeAdvancedSettings: () => void + innerRef: RefObject }): JSX.Element => { const intl = useIntl() const closeButtonText = intl.formatMessage({ From 55a26dcdda44c931e99118f7b014fcdd66f5f2cf Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 14 Jun 2024 13:34:30 -0500 Subject: [PATCH 021/162] cleanup and address PR feedback --- lib/components/form/advanced-settings-panel.tsx | 2 +- lib/components/form/batch-settings.tsx | 6 ++---- lib/components/form/styled.ts | 4 ---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 581790138..ab9b89f81 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -75,6 +75,7 @@ const AdvancedSettingsPanel = ({ +

{headerText}

- {/** * Date time selector goes here */} diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index 54eb4ebc1..c4fa0dff3 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -55,7 +55,7 @@ type Props = { modeSettingDefinitions: ModeSetting[] modeSettingValues: ModeSettingValues onPlanTripClick: () => void - openAdvancedSettings?: () => void + openAdvancedSettings: () => void routingQuery: any setQueryParam: (evt: any) => void spacedOutModeSelector?: boolean @@ -210,9 +210,7 @@ function BatchSettings({ // Prevent the hover on date/time selector when mode selector has a popup open via keyboard. style={{ pointerEvents: modeSelectorPopup ? 'none' : undefined }} /> - {openAdvancedSettings && ( - - )} + Date: Fri, 14 Jun 2024 14:56:00 -0500 Subject: [PATCH 022/162] Add react-transition-group for mobile screens --- lib/components/app/batch-routing-panel.tsx | 63 +--------- .../form/advanced-settings-panel.tsx | 2 + lib/components/form/styled.ts | 57 +++++++++ lib/components/mobile/batch-search-screen.tsx | 116 ++++++++++-------- 4 files changed, 133 insertions(+), 105 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 41c332fb7..574e4ef8d 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -10,9 +10,13 @@ import InvisibleA11yLabel from '../util/invisible-a11y-label' import LocationField from '../form/connected-location-field' import NarrativeItineraries from '../narrative/narrative-itineraries' import React, { Component, FormEvent } from 'react' -import styled, { css } from 'styled-components' -import { prefersReducedMotion } from '../util/prefersReducedMotion' +import { + advancedPanelClassName, + mainPanelClassName, + transitionDuration, + TransitionStyles +} from '../form/styled' import SwitchButton from '../form/switch-button' import UserSettings from '../form/user-settings' import ViewerContainer from '../viewers/viewer-container' @@ -25,61 +29,6 @@ interface Props { showUserSettings: boolean } -const advancedPanelClassName = 'advanced-panel' -const mainPanelClassName = 'main-panel' -const wipeOffset = 7 -const transitionDuration = prefersReducedMotion ? 0 : 200 - -const transitionMixin = css` - transition: all ${transitionDuration}ms ease-in; -` - -const wipeOutMixin = (offset: number) => css` - transform: translateX(${offset}px); - opacity: 0; -` -const wipeInMixin = css` - transform: translateX(0px); - opacity: 1; -` - -const TransitionStyles = styled.div` - display: contents; - .${advancedPanelClassName}-enter { - ${wipeOutMixin(wipeOffset)} - } - .${advancedPanelClassName}-enter-done { - ${wipeInMixin} - ${transitionMixin} - } - - .${advancedPanelClassName}-exit { - ${wipeInMixin} - } - - .${advancedPanelClassName}-exit-active { - ${wipeOutMixin(wipeOffset)} - ${transitionMixin} - } - - .${mainPanelClassName}-enter { - ${wipeOutMixin(-wipeOffset)} - } - .${mainPanelClassName}-enter-done { - ${wipeInMixin} - ${transitionMixin} - } - - .${mainPanelClassName}-exit { - ${wipeInMixin} - } - - .${mainPanelClassName}-exit-active { - ${wipeOutMixin(-wipeOffset)} - ${transitionMixin} - } -` - /** * Main panel for the batch/trip comparison form. */ diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index ab9b89f81..195652a86 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -14,7 +14,9 @@ import React, { RefObject } from 'react' import styled from 'styled-components' const PanelOverlay = styled.div` + background-color: #fff; height: 100vh; + left: 0; padding: 1.5em; position: absolute; top: 0; diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 06e9449f7..2b4fd2ade 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -5,6 +5,7 @@ import { Styled as TripFormClasses } from '@opentripplanner/trip-form' import { Input, MenuItemLi } from '@opentripplanner/location-field/lib/styled' +import { prefersReducedMotion } from '../util/prefersReducedMotion' import LocationField from '@opentripplanner/location-field' import styled, { css } from 'styled-components' @@ -230,3 +231,59 @@ export const StyledLocationField = styled(LocationField)` } } ` + +export const advancedPanelClassName = 'advanced-panel' +export const mainPanelClassName = 'main-panel' +export const transitionDuration = prefersReducedMotion ? 0 : 200 + +const wipeOffset = 7 + +const transitionMixin = css` + transition: all ${transitionDuration}ms ease-in; +` + +const wipeOutMixin = (offset: number) => css` + transform: translateX(${offset}px); + opacity: 0; +` +const wipeInMixin = css` + transform: translateX(0px); + opacity: 1; +` + +export const TransitionStyles = styled.div` + display: contents; + .${advancedPanelClassName}-enter { + ${wipeOutMixin(wipeOffset)} + } + .${advancedPanelClassName}-enter-done { + ${wipeInMixin} + ${transitionMixin} + } + + .${advancedPanelClassName}-exit { + ${wipeInMixin} + } + + .${advancedPanelClassName}-exit-active { + ${wipeOutMixin(wipeOffset)} + ${transitionMixin} + } + + .${mainPanelClassName}-enter { + ${wipeOutMixin(-wipeOffset)} + } + .${mainPanelClassName}-enter-done { + ${wipeInMixin} + ${transitionMixin} + } + + .${mainPanelClassName}-exit { + ${wipeInMixin} + } + + .${mainPanelClassName}-exit-active { + ${wipeOutMixin(-wipeOffset)} + ${transitionMixin} + } +` diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 755295b38..49d500c71 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -3,8 +3,15 @@ import { injectIntl, IntlShape } from 'react-intl' import React, { Component } from 'react' import * as uiActions from '../../actions/ui' +import { + advancedPanelClassName, + mainPanelClassName, + transitionDuration, + TransitionStyles +} from '../form/styled' +import { CSSTransition, TransitionGroup } from 'react-transition-group' + import { MobileScreens } from '../../actions/ui-constants' -import { PANEL_ANIMATION_TIMING } from '../form/styled' import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import DefaultMap from '../map/default-map' @@ -24,7 +31,6 @@ interface Props { class BatchSearchScreen extends Component { state = { - fade: false, planTripClicked: false, showAdvancedModeSettings: false } @@ -33,24 +39,19 @@ class BatchSearchScreen extends Component { _toFieldClicked = () => this.props.setMobileScreen(SET_TO_LOCATION) + _mainPanelContentRef = React.createRef() + _advancedSettingRef = React.createRef() + handlePlanTripClick = () => { this.setState({ planTripClicked: true }) } handleOpenAdvanceSettings = () => { this.setState({ showAdvancedModeSettings: true }) - // Allow Advanced Settings panel to finish animation before removing form from DOM - setTimeout(() => { - this.setState({ fade: true }) - }, PANEL_ANIMATION_TIMING) } handleCloseAdvanceSettings = () => { - this.setState({ fade: false }) - // Allow Advanced Settings panel to finish animation before removing from DOM - setTimeout(() => { - this.setState({ showAdvancedModeSettings: false }) - }, PANEL_ANIMATION_TIMING) + this.setState({ showAdvancedModeSettings: false }) } render() { @@ -65,43 +66,62 @@ class BatchSearchScreen extends Component { />
- {!this.state.fade && ( - <> - - -
- -
- - - )} - - {this.state.showAdvancedModeSettings && ( - - )} + + + {!this.state.showAdvancedModeSettings && ( + +
+ + +
+ +
+ +
+
+ )} + {this.state.showAdvancedModeSettings && ( + + + + )} +
+
From 96e4bc8b54c0806a6913d5ead1115a0145edf976 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:05:08 -0500 Subject: [PATCH 023/162] fix bad merge --- .../form/advanced-settings-panel.tsx | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 195652a86..1ae2c6294 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -8,10 +8,28 @@ import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' import { FormattedMessage, useIntl } from 'react-intl' +import { + ModeButtonDefinition, + ModeSetting, + ModeSettingValues +} from '@opentripplanner/types' +import React, { RefObject, useContext } from 'react' +import styled from 'styled-components' + +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' +import { + addCustomSettingLabels, + addModeButtonIcon, + pipe, + populateSettingWithIcon +} from './util' +import { AppReduxState } from '../../util/state-types' +import { ComponentContext } from '../../util/contexts' +import { generateModeSettingValues } from '../../util/api' +import { setModeButtonEnabled } from './batch-settings' import PageTitle from '../util/page-title' -import React, { RefObject } from 'react' -import styled from 'styled-components' const PanelOverlay = styled.div` background-color: #fff; @@ -37,10 +55,20 @@ const HeaderContainer = styled.div` const AdvancedSettingsPanel = ({ closeAdvancedSettings, - innerRef + enabledModeButtons, + innerRef, + modeButtonOptions, + modeSettingDefinitions, + modeSettingValues, + setQueryParam }: { closeAdvancedSettings: () => void + enabledModeButtons: string[] innerRef: RefObject + modeButtonOptions: ModeButtonDefinition[] + modeSettingDefinitions: ModeSetting[] + modeSettingValues: ModeSettingValues + setQueryParam: (evt: any) => void }): JSX.Element => { const intl = useIntl() const closeButtonText = intl.formatMessage({ From 5eb6f417a9123efea7464aed68812bf04608bec4 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Sat, 15 Jun 2024 10:00:09 +0200 Subject: [PATCH 024/162] upgrade trip-form downgrade animate height --- package.json | 2 +- yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index ab79eac3c..223be4fe6 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@opentripplanner/transit-vehicle-overlay": "^4.0.10", "@opentripplanner/transitive-overlay": "^3.0.18", "@opentripplanner/trip-details": "^5.0.11", - "@opentripplanner/trip-form": "^3.7.0-alpha.1", + "@opentripplanner/trip-form": "^3.7.0-alpha.2", "@opentripplanner/trip-viewer-overlay": "^2.0.8", "@opentripplanner/vehicle-rental-overlay": "^2.1.7", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index a4b02a879..9965bf9ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,10 +2606,10 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.7.0-alpha.1": - version "3.7.0-alpha.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.1.tgz#025c2e4f01f9e7689006eb266c73b48a9afba90c" - integrity sha512-V938paiKZhiKmrtOhAB4gA22LBWfgpLVE6RKzfdKWxVMLnbuGiUiJOWlgDVrdx/DL/IyB5L81GWcu5BIcWQBog== +"@opentripplanner/trip-form@^3.7.0-alpha.2": + version "3.7.0-alpha.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.2.tgz#295b4a8a9233be41fb5db036a390aef0fd3d0e93" + integrity sha512-fWfpI6RGYvFeSNAnBks7kYMXjcIIhzkjdg/FOvuVbYfA2JXqojZxswQX7L0n3lgX/MpDLwM3wI7TvpEcQ6ng+g== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/building-blocks" "^1.0.3" @@ -2620,7 +2620,7 @@ "@styled-icons/fa-solid" "^10.37.0" date-fns "^2.28.0" flat "^5.0.2" - react-animate-height "^3.2.3" + react-animate-height "^3.0.4" react-indiana-drag-scroll "^2.0.1" react-inlinesvg "^2.3.0" @@ -15061,11 +15061,6 @@ react-animate-height@^3.0.4: dependencies: classnames "^2.3.1" -react-animate-height@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/react-animate-height/-/react-animate-height-3.2.3.tgz#90929aadac1bd1851cb6a685acc105b50ccfda8c" - integrity sha512-R6DSvr7ud07oeCixScyvXWEMJY/Mt2+GyOWC1KMaRc69gOBw+SsCg4TJmrp4rKUM1hyd6p+YKw90brjPH93Y2A== - react-app-polyfill@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz#a0bea50f078b8a082970a9d853dc34b6dcc6a3cf" From 55511879e8f272403688bdf301f39a6fa006f446 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Sat, 15 Jun 2024 10:20:08 +0200 Subject: [PATCH 025/162] finish wiring up advanced settings pane --- .../form/advanced-settings-panel.tsx | 11 +++-- lib/components/form/batch-settings.tsx | 46 ++++--------------- lib/components/form/util.tsx | 29 ++++++++++++ 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 1ae2c6294..3e4157be0 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -22,8 +22,10 @@ import * as formActions from '../../actions/form' import { addCustomSettingLabels, addModeButtonIcon, + onSettingsUpdate, pipe, - populateSettingWithIcon + populateSettingWithIcon, + setModeButton } from './util' import { AppReduxState } from '../../util/state-types' import { ComponentContext } from '../../util/contexts' @@ -134,8 +136,11 @@ const AdvancedSettingsPanel = ({ fillModeIcons label="test" modeButtons={processedModeButtons} - onSettingsUpdate={setQueryParam} - onToggleModeButton={setQueryParam} + onSettingsUpdate={onSettingsUpdate(setQueryParam)} + onToggleModeButton={setModeButton( + enabledModeButtons, + onSettingsUpdate(setQueryParam) + )} /> diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index c4fa0dff3..aecaef103 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -25,15 +25,17 @@ import { ComponentContext } from '../../util/contexts' import { generateModeSettingValues } from '../../util/api' import { getActiveSearch, hasValidLocation } from '../../util/state' import { getBaseColor, getDarkenedBaseColor } from '../util/colors' -import { getFormattedMode } from '../../util/i18n' import { RoutingQueryCallResult } from '../../actions/api-constants' import { StyledIconWrapper } from '../util/styledIcon' import { addCustomSettingLabels, addModeButtonIcon, + modesQueryParamConfig, + onSettingsUpdate, pipe, - populateSettingWithIcon + populateSettingWithIcon, + setModeButton } from './util' import { MainSettingsRow, @@ -43,8 +45,6 @@ import { import AdvancedSettingsButton from './advanced-settings-button' import DateTimeButton from './date-time-button' -const queryParamConfig = { modeButtons: DelimitedArrayParam } - // TYPESCRIPT TODO: better types type Props = { activeSearch: any @@ -159,35 +159,6 @@ function BatchSettings({ updateQueryTimeIfLeavingNow ]) - /** - * Stores parameters in both the Redux `currentQuery` and URL - * @param params Params to store - */ - const _onSettingsUpdate = useCallback( - (params: any) => { - setQueryParam({ queryParamData: params, ...params }) - }, - [setQueryParam] - ) - - const _toggleModeButton = useCallback( - (buttonId: string, newState: boolean) => { - let newButtons - if (newState) { - newButtons = [...enabledModeButtons, buttonId] - } else { - newButtons = enabledModeButtons.filter((c) => c !== buttonId) - } - - // encodeQueryParams serializes the mode buttons for the URL - // to get nice looking URL params and consistency - _onSettingsUpdate( - encodeQueryParams(queryParamConfig, { modeButtons: newButtons }) - ) - }, - [enabledModeButtons, _onSettingsUpdate] - ) - /** * Check whether the mode selector is showing a popup. */ @@ -224,8 +195,11 @@ function BatchSettings({ id: 'components.BatchSearchScreen.modeSelectorLabel' })} modeButtons={processedModeButtons} - onSettingsUpdate={_onSettingsUpdate} - onToggleModeButton={_toggleModeButton} + onSettingsUpdate={onSettingsUpdate(setQueryParam)} + onToggleModeButton={setModeButton( + enabledModeButtons, + onSettingsUpdate(setQueryParam) + )} /> { currentQuery: state.otp.currentQuery, // TODO: Duplicated in apiv2.js enabledModeButtons: - decodeQueryParams(queryParamConfig, { + decodeQueryParams(modesQueryParamConfig, { modeButtons: urlSearchParams.get('modeButtons') })?.modeButtons || state.otp.config?.modes?.initialState?.enabledModeButtons || diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx index f424a22b1..12aeeead0 100644 --- a/lib/components/form/util.tsx +++ b/lib/components/form/util.tsx @@ -1,3 +1,4 @@ +import { DelimitedArrayParam, encodeQueryParams } from 'serialize-query-params' import { IntlShape } from 'react-intl' import { ModeButtonDefinition, ModeSetting } from '@opentripplanner/types' import React from 'react' @@ -9,6 +10,8 @@ export function pipe(...fns: Array<(arg: T) => T>) { return (value: T) => fns.reduce((acc, fn) => fn(acc), value) } +export const modesQueryParamConfig = { modeButtons: DelimitedArrayParam } + export const populateSettingWithIcon = (ModeIcon: React.ComponentType<{ mode?: string; width?: number }>) => // eslint-disable-next-line react/display-name @@ -40,3 +43,29 @@ export const addCustomSettingLabels = } return msd } + +/** + * Stores parameters in both the Redux `currentQuery` and URL + * @param params Params to store + */ +export const onSettingsUpdate = + (setQueryParam: (evt: any) => void) => (params: any) => { + setQueryParam({ queryParamData: params, ...params }) + } + +export const setModeButton = + (enabledModeButtons: string[], updateHandler: (params: any) => void) => + (buttonId: string, newState: boolean) => { + let newButtons + if (newState) { + newButtons = [...enabledModeButtons, buttonId] + } else { + newButtons = enabledModeButtons.filter((c) => c !== buttonId) + } + + // encodeQueryParams serializes the mode buttons for the URL + // to get nice looking URL params and consistency + updateHandler( + encodeQueryParams(modesQueryParamConfig, { modeButtons: newButtons }) + ) + } From 58e1258d31602099192cfff66fbbdb67410ddd50 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:43:15 -0500 Subject: [PATCH 026/162] tweak styling and remove focustrapwrapper --- .../form/advanced-settings-panel.tsx | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 3e4157be0..9c7ae9013 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -6,7 +6,6 @@ import { import { Close } from '@styled-icons/fa-solid' import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' -import { FocusTrapWrapper } from '@opentripplanner/map-popup/lib' import { FormattedMessage, useIntl } from 'react-intl' import { ModeButtonDefinition, @@ -35,13 +34,14 @@ import PageTitle from '../util/page-title' const PanelOverlay = styled.div` background-color: #fff; - height: 100vh; + height: 100%; left: 0; padding: 1.5em; position: absolute; top: 0; width: 100%; z-index: 100; + overflow-y: scroll; ` const CloseButton = styled.button` @@ -105,44 +105,42 @@ const AdvancedSettingsPanel = ({ return ( - - - -

{headerText}

- - - -
- {/** - * Date time selector goes here - */} -

- -

- {/** - * Trip options (walk speed, walk reluctance, accessible routing) go here - */} -

- -

- {/** - * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here - */} - -
+ + +

{headerText}

+ + + +
+ {/** + * Date time selector goes here + */} +

+ +

+ {/** + * Trip options (walk speed, walk reluctance, accessible routing) go here + */} +

+ +

+ {/** + * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here + */} +
) } From e4ee080d9c2e7e2c6c97fea685ce8887aec47bf2 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:19:37 -0500 Subject: [PATCH 027/162] Update accentColor for AdvancedModeSubsettingsContainer and update alpha package --- .../form/advanced-settings-panel.tsx | 26 +++++++++++++------ package.json | 2 +- yarn.lock | 8 +++--- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 9c7ae9013..6a97db93f 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -1,22 +1,32 @@ +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' import { addSettingsToButton, AdvancedModeSubsettingsContainer, populateSettingWithValue } from '@opentripplanner/trip-form' +import { AppReduxState } from '../../util/state-types' +import { blue, getBaseColor } from '../util/colors' + import { Close } from '@styled-icons/fa-solid' + +import { ComponentContext } from '../../util/contexts' + import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FormattedMessage, useIntl } from 'react-intl' + +import { generateModeSettingValues } from '../../util/api' + import { ModeButtonDefinition, ModeSetting, ModeSettingValues } from '@opentripplanner/types' -import React, { RefObject, useContext } from 'react' -import styled from 'styled-components' -import * as apiActions from '../../actions/api' -import * as formActions from '../../actions/form' +import PageTitle from '../util/page-title' + +import React, { RefObject, useContext } from 'react' import { addCustomSettingLabels, @@ -26,11 +36,9 @@ import { populateSettingWithIcon, setModeButton } from './util' -import { AppReduxState } from '../../util/state-types' -import { ComponentContext } from '../../util/contexts' -import { generateModeSettingValues } from '../../util/api' import { setModeButtonEnabled } from './batch-settings' -import PageTitle from '../util/page-title' + +import styled from 'styled-components' const PanelOverlay = styled.div` background-color: #fff; @@ -54,6 +62,7 @@ const HeaderContainer = styled.div` display: flex; justify-content: space-between; ` +const baseColor = getBaseColor() !== 'fff' ? getBaseColor() : blue[900] const AdvancedSettingsPanel = ({ closeAdvancedSettings, @@ -132,6 +141,7 @@ const AdvancedSettingsPanel = ({ * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here */} Date: Tue, 18 Jun 2024 17:29:29 -0500 Subject: [PATCH 028/162] Turn h2 into subheader component --- lib/components/form/advanced-settings-panel.tsx | 15 +++++++++++---- lib/components/viewers/viewers.css | 7 ------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 6a97db93f..7f9ebd061 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -62,6 +62,13 @@ const HeaderContainer = styled.div` display: flex; justify-content: space-between; ` + +const Subheader = styled.h2` + display: block; + font-size: 18px; + font-weight: 700; + margin: 1em 0; +` const baseColor = getBaseColor() !== 'fff' ? getBaseColor() : blue[900] const AdvancedSettingsPanel = ({ @@ -128,15 +135,15 @@ const AdvancedSettingsPanel = ({ {/** * Date time selector goes here */} -

+ -

+ {/** * Trip options (walk speed, walk reluctance, accessible routing) go here */} -

+ -

+ {/** * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here */} diff --git a/lib/components/viewers/viewers.css b/lib/components/viewers/viewers.css index 370da5252..26fd3315a 100644 --- a/lib/components/viewers/viewers.css +++ b/lib/components/viewers/viewers.css @@ -68,13 +68,6 @@ margin: 0; } -.otp .advanced-settings h2.header-text { - display: block; - font-size: 18px; - margin: 1em 0; -} - - .otp .route-viewer .header-text.route-expanded { display: flex; align-items: center; From 5a359ff9045e2c142f4830d079c91db385a45680 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:46:14 -0500 Subject: [PATCH 029/162] Create toggle and global settings --- .../form/advanced-settings-panel.tsx | 61 +++++++++++------ lib/components/form/styled.ts | 67 +++++++++++++++++++ 2 files changed, 109 insertions(+), 19 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 7f9ebd061..dbdcc37ee 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -1,17 +1,13 @@ -import * as apiActions from '../../actions/api' -import * as formActions from '../../actions/form' import { addSettingsToButton, AdvancedModeSubsettingsContainer, + ModeSettingRenderer, populateSettingWithValue } from '@opentripplanner/trip-form' -import { AppReduxState } from '../../util/state-types' -import { blue, getBaseColor } from '../util/colors' +import { blue, getBaseColor } from '../util/colors' import { Close } from '@styled-icons/fa-solid' -import { ComponentContext } from '../../util/contexts' - import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FormattedMessage, useIntl } from 'react-intl' @@ -24,9 +20,14 @@ import { ModeSettingValues } from '@opentripplanner/types' +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' +import { AppReduxState } from '../../util/state-types' +import { ComponentContext } from '../../util/contexts' import PageTitle from '../util/page-title' import React, { RefObject, useContext } from 'react' +import styled from 'styled-components' import { addCustomSettingLabels, @@ -37,8 +38,7 @@ import { setModeButton } from './util' import { setModeButtonEnabled } from './batch-settings' - -import styled from 'styled-components' +import { styledCheckboxCss } from './styled' const PanelOverlay = styled.div` background-color: #fff; @@ -52,6 +52,14 @@ const PanelOverlay = styled.div` overflow-y: scroll; ` +const GlobalSettingsContainer = styled.div` + display: flex; + flex-direction: column; + gap: 10px; + + ${styledCheckboxCss} +` + const CloseButton = styled.button` background: transparent; border: none; @@ -69,7 +77,7 @@ const Subheader = styled.h2` font-weight: 700; margin: 1em 0; ` -const baseColor = getBaseColor() !== 'fff' ? getBaseColor() : blue[900] +const baseColor = getBaseColor() || blue[900] const AdvancedSettingsPanel = ({ closeAdvancedSettings, @@ -103,14 +111,29 @@ const AdvancedSettingsPanel = ({ // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) - const processedModeSettings = modeSettingDefinitions.map( - pipe( - populateSettingWithIcon(ModeIcon), - populateSettingWithValue(modeSettingValues), - addCustomSettingLabels(intl) + const processSettings = (settings: any) => + settings.map( + pipe( + populateSettingWithIcon(ModeIcon), + populateSettingWithValue(modeSettingValues), + addCustomSettingLabels(intl) + ) + ) + + const globalSettings = modeSettingDefinitions.filter((x) => !x.applicableMode) + const processedGlobalSettings = processSettings(globalSettings) + + const globalSettingsComponents = processedGlobalSettings.map( + (setting: any) => ( + ) ) + const processedModeSettings = processSettings(modeSettingDefinitions) const processedModeButtons = modeButtonOptions.map( pipe( addModeButtonIcon(ModeIcon), @@ -135,13 +158,13 @@ const AdvancedSettingsPanel = ({ {/** * Date time selector goes here */} - + - {/** - * Trip options (walk speed, walk reluctance, accessible routing) go here - */} - + + {globalSettingsComponents} + + {/** diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 2b4fd2ade..f42da3c64 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -287,3 +287,70 @@ export const TransitionStyles = styled.div` ${transitionMixin} } ` + +const toggleTransition = css` + transition: all 150ms ease-in; +` + +export const styledCheckboxCss = css` + & > div { + width: 100%; + margin-left: 0; + } + input[type='checkbox'] + label { + align-items: center; + display: flex; + position: relative; + justify-content: space-between; + width: 100%; + + &::after { + content: ''; + position: relative; + width: 33px; + height: 22px; + background-color: ${grey[600]}; + border-radius: 20px; + ${toggleTransition}; + cursor: pointer; + } + + &::before { + content: ''; + position: absolute; + width: 18px; + height: 18px; + background-color: white; + border-radius: 100%; + right: 13px; + z-index: 99; + ${toggleTransition}; + cursor: pointer; + } + } + + input[type='checkbox'] { + clip: rect(0, 0, 0, 0); + height: 0; + overflow: hidden; + position: absolute; + width: 0; + + &:checked + label { + &::after { + background-color: ${blue[700]}; + ${toggleTransition}; + } + + &::before { + right: 2px; + ${toggleTransition}; + box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px; + } + } + + &:focus-visible + label { + outline: 1px solid blue; + } + } +` From 96555b83d3e9ba29d351f82b204abe226f1d53fa Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 19 Jun 2024 15:43:04 -0500 Subject: [PATCH 030/162] fix passing accent color to AdvancedModeSubsettingsContainer --- lib/components/form/advanced-settings-panel.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index dbdcc37ee..612ac30d1 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -77,7 +77,8 @@ const Subheader = styled.h2` font-weight: 700; margin: 1em 0; ` -const baseColor = getBaseColor() || blue[900] +const baseColor = getBaseColor() +const accentColor = baseColor || blue[900] const AdvancedSettingsPanel = ({ closeAdvancedSettings, @@ -171,7 +172,7 @@ const AdvancedSettingsPanel = ({ * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here */} Date: Wed, 19 Jun 2024 15:43:04 -0500 Subject: [PATCH 031/162] fix passing accent color to AdvancedModeSubsettingsContainer --- lib/components/form/advanced-settings-panel.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 7f9ebd061..546fb4686 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -69,7 +69,8 @@ const Subheader = styled.h2` font-weight: 700; margin: 1em 0; ` -const baseColor = getBaseColor() !== 'fff' ? getBaseColor() : blue[900] +const baseColor = getBaseColor() +const accentColor = baseColor || blue[900] const AdvancedSettingsPanel = ({ closeAdvancedSettings, @@ -148,7 +149,7 @@ const AdvancedSettingsPanel = ({ * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here */} Date: Wed, 19 Jun 2024 16:05:34 -0500 Subject: [PATCH 032/162] remove unnecessary classname from subheader --- lib/components/form/advanced-settings-panel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 546fb4686..0c99d20d7 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -136,13 +136,13 @@ const AdvancedSettingsPanel = ({ {/** * Date time selector goes here */} - + {/** * Trip options (walk speed, walk reluctance, accessible routing) go here */} - + {/** From cb142d08f9c297eb35943389a2f2d4d2e74c0253 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:10:48 -0500 Subject: [PATCH 033/162] update otp-ui and animation durations --- lib/components/form/styled.ts | 2 +- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 2b4fd2ade..a10c063b5 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -234,7 +234,7 @@ export const StyledLocationField = styled(LocationField)` export const advancedPanelClassName = 'advanced-panel' export const mainPanelClassName = 'main-panel' -export const transitionDuration = prefersReducedMotion ? 0 : 200 +export const transitionDuration = prefersReducedMotion ? 0 : 175 const wipeOffset = 7 diff --git a/package.json b/package.json index 43dd2e15f..dc15e32c9 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@opentripplanner/transit-vehicle-overlay": "^4.0.10", "@opentripplanner/transitive-overlay": "^3.0.18", "@opentripplanner/trip-details": "^5.0.11", - "@opentripplanner/trip-form": "^3.7.0-alpha.3", + "@opentripplanner/trip-form": "^3.7.0-alpha.4", "@opentripplanner/trip-viewer-overlay": "^2.0.8", "@opentripplanner/vehicle-rental-overlay": "^2.1.7", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index 9a7d23f86..2f8ec9bcf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,10 +2606,10 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.7.0-alpha.3": - version "3.7.0-alpha.3" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.3.tgz#dcda6ab782ec8a487245486c377b17c491770f00" - integrity sha512-TabCfcLjNINddX9QHDPwSdMkrMlFKLR0QfGU56h9YLZdwJP1+guOmD0TvdmikG+VaqXiGFHgMZJlYOEmgY07+Q== +"@opentripplanner/trip-form@^3.7.0-alpha.4": + version "3.7.0-alpha.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.4.tgz#595b41c7d6d598939e2899a350ac0046acf131ce" + integrity sha512-uVkiP9qU1RSHo2ffm+tBIsnf/1pc8id0Giyy5Y61iQswDRmXh8ubTz/LUuhC3fiAYOwm3kYnHZ01tmwQ9XIvTQ== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/building-blocks" "^1.0.3" From c7d2b92c97fb47286c83e4e9ca12fb3495e7be51 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:09:19 -0500 Subject: [PATCH 034/162] remove unecessary closepanel function --- lib/components/form/advanced-settings-panel.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 0c99d20d7..76f5d7e24 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -97,10 +97,6 @@ const AdvancedSettingsPanel = ({ id: 'components.BatchSearchScreen.advancedHeader' }) - const closePanel = () => { - closeAdvancedSettings() - } - // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) @@ -127,7 +123,7 @@ const AdvancedSettingsPanel = ({

{headerText}

From 4f3ccf09976ada76194c607250b722f91a4a3575 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:29:06 -0500 Subject: [PATCH 035/162] remove unnecessary comment --- lib/components/form/advanced-settings-panel.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 87962f8d3..da61de324 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -165,9 +165,6 @@ const AdvancedSettingsPanel = ({ - {/** - * AdvancedModeSubsettingsContainer (import from Otp-ui) goes here - */} Date: Tue, 25 Jun 2024 12:52:39 -0500 Subject: [PATCH 036/162] fix: overflow bug on itinerary results --- lib/components/app/batch-routing-panel.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 574e4ef8d..0ef568403 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -162,7 +162,7 @@ class BatchRoutingPanel extends Component { )} - + {!this.state.showAdvancedModeSettings && ( { >
{!activeSearch && showUserSettings && ( )} -
From 8d75fb9befe30b7655d93633b877016769e6394c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:39:58 -0500 Subject: [PATCH 037/162] Make subheaders invisible and address feedback --- lib/components/form/advanced-settings-panel.tsx | 13 +++++++------ lib/components/form/styled.ts | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index da61de324..7f1cd955e 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -37,6 +37,9 @@ import { populateSettingWithIcon, setModeButton } from './util' + +import { invisibleCss } from '@opentripplanner/trip-form/lib/MetroModeSelector' + import { setModeButtonEnabled } from './batch-settings' import { styledCheckboxCss } from './styled' @@ -56,6 +59,7 @@ const GlobalSettingsContainer = styled.div` display: flex; flex-direction: column; gap: 10px; + margin: 2em 0; ${styledCheckboxCss} ` @@ -72,10 +76,7 @@ const HeaderContainer = styled.div` ` const Subheader = styled.h2` - display: block; - font-size: 18px; - font-weight: 700; - margin: 1em 0; + ${invisibleCss} ` const baseColor = getBaseColor() const accentColor = baseColor || blue[900] @@ -108,7 +109,7 @@ const AdvancedSettingsPanel = ({ // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) - const processSettings = (settings: any) => + const processSettings = (settings: ModeSetting[]) => settings.map( pipe( populateSettingWithIcon(ModeIcon), @@ -121,7 +122,7 @@ const AdvancedSettingsPanel = ({ const processedGlobalSettings = processSettings(globalSettings) const globalSettingsComponents = processedGlobalSettings.map( - (setting: any) => ( + (setting: ModeSetting) => ( Date: Mon, 1 Jul 2024 13:55:58 -0500 Subject: [PATCH 038/162] adjust form for if there are no processedGlobalSettings --- .../form/advanced-settings-panel.tsx | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 7f1cd955e..c2b09213e 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -59,7 +59,7 @@ const GlobalSettingsContainer = styled.div` display: flex; flex-direction: column; gap: 10px; - margin: 2em 0; + margin-bottom: 2em; ${styledCheckboxCss} ` @@ -73,6 +73,7 @@ const HeaderContainer = styled.div` align-items: center; display: flex; justify-content: space-between; + margin-bottom: 2em; ` const Subheader = styled.h2` @@ -156,13 +157,16 @@ const AdvancedSettingsPanel = ({ {/** * Date time selector goes here */} - - - - - - {globalSettingsComponents} - + {processedGlobalSettings.length > 0 && ( + <> + + + + + {globalSettingsComponents} + + + )} From 71128ac670621ccee1aa494fc60be86c6e0c63fa Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:11:53 -0500 Subject: [PATCH 039/162] Add Plan trip and back buttons to advanced trip form --- lib/components/app/batch-routing-panel.tsx | 6 ++ .../form/advanced-settings-panel.tsx | 68 +++++++++++++++---- lib/components/form/batch-settings.tsx | 51 ++------------ lib/components/form/util.tsx | 45 ++++++++++++ lib/components/mobile/batch-search-screen.tsx | 5 ++ 5 files changed, 116 insertions(+), 59 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 0ef568403..2038ef335 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -18,6 +18,9 @@ import { TransitionStyles } from '../form/styled' import SwitchButton from '../form/switch-button' + +import toast from 'react-hot-toast' + import UserSettings from '../form/user-settings' import ViewerContainer from '../viewers/viewer-container' @@ -67,6 +70,8 @@ class BatchRoutingPanel extends Component { } handleCloseAdvanceSettings = () => { + const { intl } = this.props + toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' })) this.setState({ showAdvancedModeSettings: false }) } @@ -113,6 +118,7 @@ class BatchRoutingPanel extends Component { )} diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 76f5d7e24..2ecfadebc 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -1,23 +1,15 @@ -import * as apiActions from '../../actions/api' -import * as formActions from '../../actions/form' import { addSettingsToButton, AdvancedModeSubsettingsContainer, populateSettingWithValue } from '@opentripplanner/trip-form' -import { AppReduxState } from '../../util/state-types' -import { blue, getBaseColor } from '../util/colors' - import { Close } from '@styled-icons/fa-solid' - -import { ComponentContext } from '../../util/contexts' - import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FormattedMessage, useIntl } from 'react-intl' +import { Search } from '@styled-icons/fa-solid/Search' import { generateModeSettingValues } from '../../util/api' - import { ModeButtonDefinition, ModeSetting, @@ -28,20 +20,30 @@ import PageTitle from '../util/page-title' import React, { RefObject, useContext } from 'react' +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' + import { addCustomSettingLabels, addModeButtonIcon, + alertUserTripPlan, onSettingsUpdate, pipe, populateSettingWithIcon, setModeButton } from './util' +import { AppReduxState } from '../../util/state-types' import { setModeButtonEnabled } from './batch-settings' +import { blue, getBaseColor } from '../util/colors' +import { ComponentContext } from '../../util/contexts' + import styled from 'styled-components' +const baseColor = getBaseColor() +const accentColor = baseColor || blue[900] + const PanelOverlay = styled.div` - background-color: #fff; height: 100%; left: 0; padding: 1.5em; @@ -69,24 +71,52 @@ const Subheader = styled.h2` font-weight: 700; margin: 1em 0; ` -const baseColor = getBaseColor() -const accentColor = baseColor || blue[900] + +const PlanTripButton = styled.button` + align-items: center; + display: flex; + justify-content: center; + gap: 0.5em; + background-color: ${baseColor}; + border: 0; + width: 45%; + height: 51px; + color: white; + font-weight: 700; +` + +const ReturnToTripPlanButton = styled(PlanTripButton)` + border: 2px solid ${baseColor}; + background-color: white; + color: ${baseColor}; +` +const ButtonContainer = styled.div` + display: flex; + justify-content: space-between; + margin-top: 2em; +` const AdvancedSettingsPanel = ({ closeAdvancedSettings, + currentQuery, enabledModeButtons, innerRef, modeButtonOptions, modeSettingDefinitions, modeSettingValues, + onPlanTripClick, + routingQuery, setQueryParam }: { closeAdvancedSettings: () => void + currentQuery: any enabledModeButtons: string[] innerRef: RefObject modeButtonOptions: ModeButtonDefinition[] modeSettingDefinitions: ModeSetting[] modeSettingValues: ModeSettingValues + onPlanTripClick: () => void + routingQuery: () => void setQueryParam: (evt: any) => void }): JSX.Element => { const intl = useIntl() @@ -100,6 +130,11 @@ const AdvancedSettingsPanel = ({ // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) + const planTrip = () => { + alertUserTripPlan(intl, currentQuery, onPlanTripClick, routingQuery) + closeAdvancedSettings() + } + const processedModeSettings = modeSettingDefinitions.map( pipe( populateSettingWithIcon(ModeIcon), @@ -155,6 +190,15 @@ const AdvancedSettingsPanel = ({ onSettingsUpdate(setQueryParam) )} /> + + + Back to Trip Plan + + + + + + ) } diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index aecaef103..1c50355a7 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -4,11 +4,7 @@ import { populateSettingWithValue } from '@opentripplanner/trip-form' import { connect } from 'react-redux' -import { - decodeQueryParams, - DelimitedArrayParam, - encodeQueryParams -} from 'use-query-params' +import { decodeQueryParams } from 'use-query-params' import { ModeButtonDefinition, ModeSetting, @@ -25,12 +21,12 @@ import { ComponentContext } from '../../util/contexts' import { generateModeSettingValues } from '../../util/api' import { getActiveSearch, hasValidLocation } from '../../util/state' import { getBaseColor, getDarkenedBaseColor } from '../util/colors' -import { RoutingQueryCallResult } from '../../actions/api-constants' import { StyledIconWrapper } from '../util/styledIcon' import { addCustomSettingLabels, addModeButtonIcon, + alertUserTripPlan, modesQueryParamConfig, onSettingsUpdate, pipe, @@ -117,47 +113,8 @@ function BatchSettings({ ) const _planTrip = useCallback(() => { - // Check for any validation issues in query. - const issues = [] - if (!hasValidLocation(currentQuery, 'from')) { - issues.push(intl.formatMessage({ id: 'components.BatchSettings.origin' })) - } - if (!hasValidLocation(currentQuery, 'to')) { - issues.push( - intl.formatMessage({ id: 'components.BatchSettings.destination' }) - ) - } - onPlanTripClick && onPlanTripClick() - if (issues.length > 0) { - // TODO: replace with less obtrusive validation. - window.alert( - intl.formatMessage( - { id: 'components.BatchSettings.validationMessage' }, - { issues: intl.formatList(issues, { type: 'conjunction' }) } - ) - ) - return - } - - // Plan trip. - updateQueryTimeIfLeavingNow() - const routingQueryResult = routingQuery() - - // If mode combination is not valid (i.e. produced no query), alert the user. - if (routingQueryResult === RoutingQueryCallResult.INVALID_MODE_SELECTION) { - window.alert( - intl.formatMessage({ - id: 'components.BatchSettings.invalidModeSelection' - }) - ) - } - }, [ - currentQuery, - intl, - onPlanTripClick, - routingQuery, - updateQueryTimeIfLeavingNow - ]) + alertUserTripPlan(intl, currentQuery, onPlanTripClick, routingQuery) + }, [currentQuery, intl, onPlanTripClick, routingQuery]) /** * Check whether the mode selector is showing a popup. diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx index 12aeeead0..662d68273 100644 --- a/lib/components/form/util.tsx +++ b/lib/components/form/util.tsx @@ -4,6 +4,9 @@ import { ModeButtonDefinition, ModeSetting } from '@opentripplanner/types' import React from 'react' import { getFormattedMode } from '../../util/i18n' +import { hasValidLocation } from '../../util/state' +import { RoutingQueryCallResult } from '../../actions/api-constants' +import { updateQueryTimeIfLeavingNow } from '../../actions/form' // This method is used to daisy-chain a series of functions together on a given value export function pipe(...fns: Array<(arg: T) => T>) { @@ -69,3 +72,45 @@ export const setModeButton = encodeQueryParams(modesQueryParamConfig, { modeButtons: newButtons }) ) } + +export const alertUserTripPlan = ( + intl, + currentQuery, + onPlanTripClick, + routingQuery +) => { + // Check for any validation issues in query. + const issues = [] + if (!hasValidLocation(currentQuery, 'from')) { + issues.push(intl.formatMessage({ id: 'components.BatchSettings.origin' })) + } + if (!hasValidLocation(currentQuery, 'to')) { + issues.push( + intl.formatMessage({ id: 'components.BatchSettings.destination' }) + ) + } + onPlanTripClick && onPlanTripClick() + if (issues.length > 0) { + // TODO: replace with less obtrusive validation. + window.alert( + intl.formatMessage( + { id: 'components.BatchSettings.validationMessage' }, + { issues: intl.formatList(issues, { type: 'conjunction' }) } + ) + ) + return + } + + // Plan trip. + updateQueryTimeIfLeavingNow() + const routingQueryResult = routingQuery() + + // If mode combination is not valid (i.e. produced no query), alert the user. + if (routingQueryResult === RoutingQueryCallResult.INVALID_MODE_SELECTION) { + window.alert( + intl.formatMessage({ + id: 'components.BatchSettings.invalidModeSelection' + }) + ) + } +} diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 49d500c71..e84b0a0fd 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -21,6 +21,8 @@ import SwitchButton from '../form/switch-button' import MobileContainer from './container' import MobileNavigationBar from './navigation-bar' +import toast from 'react-hot-toast' + const { SET_FROM_LOCATION, SET_TO_LOCATION } = MobileScreens interface Props { @@ -51,7 +53,9 @@ class BatchSearchScreen extends Component { } handleCloseAdvanceSettings = () => { + const { intl } = this.props this.setState({ showAdvancedModeSettings: false }) + toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' })) } render() { @@ -117,6 +121,7 @@ class BatchSearchScreen extends Component { )} From 176145f38ec5b7855e7af1bdb3508615b2ca5a2e Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Tue, 9 Jul 2024 20:50:44 +0100 Subject: [PATCH 040/162] address PR comments --- lib/components/app/batch-routing-panel.tsx | 19 ++++++++----------- .../form/advanced-settings-panel.tsx | 19 +++++++------------ lib/components/form/util.tsx | 14 +++++++------- lib/components/mobile/batch-search-screen.tsx | 6 ++---- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 2038ef335..e81354323 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -1,15 +1,8 @@ import { connect } from 'react-redux' import { CSSTransition, TransitionGroup } from 'react-transition-group' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' - -import { getActiveSearch, getShowUserSettings } from '../../util/state' -import { getPersistenceMode } from '../../util/user' -import AdvancedSettingsPanel from '../form/advanced-settings-panel' -import BatchSettings from '../form/batch-settings' -import InvisibleA11yLabel from '../util/invisible-a11y-label' -import LocationField from '../form/connected-location-field' -import NarrativeItineraries from '../narrative/narrative-itineraries' import React, { Component, FormEvent } from 'react' +import toast from 'react-hot-toast' import { advancedPanelClassName, @@ -17,10 +10,14 @@ import { transitionDuration, TransitionStyles } from '../form/styled' +import { getActiveSearch, getShowUserSettings } from '../../util/state' +import { getPersistenceMode } from '../../util/user' +import AdvancedSettingsPanel from '../form/advanced-settings-panel' +import BatchSettings from '../form/batch-settings' +import InvisibleA11yLabel from '../util/invisible-a11y-label' +import LocationField from '../form/connected-location-field' +import NarrativeItineraries from '../narrative/narrative-itineraries' import SwitchButton from '../form/switch-button' - -import toast from 'react-hot-toast' - import UserSettings from '../form/user-settings' import ViewerContainer from '../viewers/viewer-container' diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 2ecfadebc..db0f74b05 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -7,21 +7,22 @@ import { Close } from '@styled-icons/fa-solid' import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FormattedMessage, useIntl } from 'react-intl' -import { Search } from '@styled-icons/fa-solid/Search' - -import { generateModeSettingValues } from '../../util/api' import { ModeButtonDefinition, ModeSetting, ModeSettingValues } from '@opentripplanner/types' - -import PageTitle from '../util/page-title' - +import { Search } from '@styled-icons/fa-solid/Search' import React, { RefObject, useContext } from 'react' +import styled from 'styled-components' import * as apiActions from '../../actions/api' import * as formActions from '../../actions/form' +import { AppReduxState } from '../../util/state-types' +import { blue, getBaseColor } from '../util/colors' +import { ComponentContext } from '../../util/contexts' +import { generateModeSettingValues } from '../../util/api' +import PageTitle from '../util/page-title' import { addCustomSettingLabels, @@ -32,14 +33,8 @@ import { populateSettingWithIcon, setModeButton } from './util' -import { AppReduxState } from '../../util/state-types' import { setModeButtonEnabled } from './batch-settings' -import { blue, getBaseColor } from '../util/colors' -import { ComponentContext } from '../../util/contexts' - -import styled from 'styled-components' - const baseColor = getBaseColor() const accentColor = baseColor || blue[900] diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx index 662d68273..23b5ab8fe 100644 --- a/lib/components/form/util.tsx +++ b/lib/components/form/util.tsx @@ -74,13 +74,13 @@ export const setModeButton = } export const alertUserTripPlan = ( - intl, - currentQuery, - onPlanTripClick, - routingQuery -) => { + intl: IntlShape, + currentQuery: any, + onPlanTripClick: () => void, + routingQuery: () => any +): void => { // Check for any validation issues in query. - const issues = [] + const issues: string[] = [] if (!hasValidLocation(currentQuery, 'from')) { issues.push(intl.formatMessage({ id: 'components.BatchSettings.origin' })) } @@ -89,7 +89,7 @@ export const alertUserTripPlan = ( intl.formatMessage({ id: 'components.BatchSettings.destination' }) ) } - onPlanTripClick && onPlanTripClick() + onPlanTripClick() if (issues.length > 0) { // TODO: replace with less obtrusive validation. window.alert( diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index e84b0a0fd..77ba3302a 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -1,6 +1,8 @@ import { connect } from 'react-redux' +import { CSSTransition, TransitionGroup } from 'react-transition-group' import { injectIntl, IntlShape } from 'react-intl' import React, { Component } from 'react' +import toast from 'react-hot-toast' import * as uiActions from '../../actions/ui' import { @@ -9,8 +11,6 @@ import { transitionDuration, TransitionStyles } from '../form/styled' -import { CSSTransition, TransitionGroup } from 'react-transition-group' - import { MobileScreens } from '../../actions/ui-constants' import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' @@ -21,8 +21,6 @@ import SwitchButton from '../form/switch-button' import MobileContainer from './container' import MobileNavigationBar from './navigation-bar' -import toast from 'react-hot-toast' - const { SET_FROM_LOCATION, SET_TO_LOCATION } = MobileScreens interface Props { From f96bd5427c37d3621e5c018268dcd30310e5b008 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Tue, 9 Jul 2024 23:45:07 +0100 Subject: [PATCH 041/162] fix issue with base color race condition --- lib/components/form/advanced-settings-panel.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index f0c239254..6763185a1 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -39,9 +39,6 @@ import { setModeButton } from './util' -const baseColor = getBaseColor() -const accentColor = baseColor || blue[900] - const PanelOverlay = styled.div` height: 100%; left: 0; @@ -83,7 +80,7 @@ const PlanTripButton = styled.button` display: flex; justify-content: center; gap: 0.5em; - background-color: ${baseColor}; + background-color: var(--main-base-color, ${blue[900]}); border: 0; width: 45%; height: 51px; @@ -92,9 +89,9 @@ const PlanTripButton = styled.button` ` const ReturnToTripPlanButton = styled(PlanTripButton)` - border: 2px solid ${baseColor}; + border: 2px solid var(--main-base-color, ${blue[900]}); background-color: white; - color: ${baseColor}; + color: var(--main-base-color, ${blue[900]}); ` const ButtonContainer = styled.div` display: flex; @@ -125,6 +122,9 @@ const AdvancedSettingsPanel = ({ routingQuery: () => void setQueryParam: (evt: any) => void }): JSX.Element => { + const baseColor = getBaseColor() + const accentColor = baseColor || blue[900] + const intl = useIntl() const closeButtonText = intl.formatMessage({ id: 'components.BatchSearchScreen.closeAdvancedPreferences' From d390bb7b77cb29b4a076d2ac515c1db4a233d416 Mon Sep 17 00:00:00 2001 From: josh-willis-arcadis <168561922+josh-willis-arcadis@users.noreply.github.com> Date: Tue, 9 Jul 2024 23:11:38 -0400 Subject: [PATCH 042/162] refactor(AdvancedSettingsPanel): sort imports --- lib/components/form/advanced-settings-panel.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 6763185a1..c36a77396 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -24,9 +24,6 @@ import { AppReduxState } from '../../util/state-types' import { blue, getBaseColor } from '../util/colors' import { ComponentContext } from '../../util/contexts' import { generateModeSettingValues } from '../../util/api' - -import { setModeButtonEnabled } from './batch-settings' -import { styledCheckboxCss } from './styled' import PageTitle from '../util/page-title' import { @@ -38,6 +35,8 @@ import { populateSettingWithIcon, setModeButton } from './util' +import { setModeButtonEnabled } from './batch-settings' +import { styledCheckboxCss } from './styled' const PanelOverlay = styled.div` height: 100%; From 52906bcc2de8a020c1273b3b638784665e5fd8ab Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:28:22 -0500 Subject: [PATCH 043/162] fix when toast announces changes saved --- lib/components/app/batch-routing-panel.tsx | 3 --- lib/components/form/advanced-settings-panel.tsx | 10 ++++++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index e81354323..b7a1778bf 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -2,7 +2,6 @@ import { connect } from 'react-redux' import { CSSTransition, TransitionGroup } from 'react-transition-group' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' import React, { Component, FormEvent } from 'react' -import toast from 'react-hot-toast' import { advancedPanelClassName, @@ -67,8 +66,6 @@ class BatchRoutingPanel extends Component { } handleCloseAdvanceSettings = () => { - const { intl } = this.props - toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' })) this.setState({ showAdvancedModeSettings: false }) } diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index c36a77396..192420c21 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -25,6 +25,7 @@ import { blue, getBaseColor } from '../util/colors' import { ComponentContext } from '../../util/contexts' import { generateModeSettingValues } from '../../util/api' import PageTitle from '../util/page-title' +import toast from 'react-hot-toast' import { addCustomSettingLabels, @@ -140,6 +141,11 @@ const AdvancedSettingsPanel = ({ closeAdvancedSettings() } + const closeAndAnnounce = () => { + closeAdvancedSettings() + toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' })) + } + const processSettings = (settings: ModeSetting[]) => settings.map( pipe( @@ -178,7 +184,7 @@ const AdvancedSettingsPanel = ({

{headerText}

@@ -212,7 +218,7 @@ const AdvancedSettingsPanel = ({ )} /> - + Back to Trip Plan From ee9e579b55e53e0a6edebcd7c13c6b019643c06b Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:30:40 -0500 Subject: [PATCH 044/162] fix width on advanced-panel buttons --- lib/components/form/advanced-settings-panel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 192420c21..34afe9ca6 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -82,7 +82,7 @@ const PlanTripButton = styled.button` gap: 0.5em; background-color: var(--main-base-color, ${blue[900]}); border: 0; - width: 45%; + width: 47%; height: 51px; color: white; font-weight: 700; From b2f864763333d72729c5cde95c8cdf91941d9257 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:35:38 -0500 Subject: [PATCH 045/162] fix height container bug AGAIN --- lib/components/app/batch-routing-panel.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 0ef568403..17895747c 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -182,6 +182,7 @@ class BatchRoutingPanel extends Component { className="desktop-narrative-container" style={{ flexGrow: 1, + height: '100%', overflowY: 'hidden' }} > From be55193d771d29459b7dc06d195a6f4ba88e8c5c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:44:57 -0500 Subject: [PATCH 046/162] use variables in toggle checkboxes --- lib/components/form/styled.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index f9816f938..0ecf13634 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -1,4 +1,4 @@ -import { blue, getBaseColor, grey } from '../util/colors' +import { blue, grey } from '../util/colors' import { DateTimeSelector, SettingsSelectorPanel, @@ -235,7 +235,6 @@ export const StyledLocationField = styled(LocationField)` export const advancedPanelClassName = 'advanced-panel' export const mainPanelClassName = 'main-panel' export const transitionDuration = prefersReducedMotion ? 0 : 175 -const baseColor = getBaseColor() const wipeOffset = 7 @@ -339,7 +338,7 @@ export const styledCheckboxCss = css` &:checked + label { &::after { - background-color: ${baseColor || blue[700]}; + background-color: var(--main-base-color, ${blue[700]}); ${toggleTransition}; } From 1c495497f65e2599c112bf408670be23626c44ff Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:41:38 -0500 Subject: [PATCH 047/162] remove unnecessary toast from mobile --- lib/components/mobile/batch-search-screen.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 77ba3302a..d2aab6a9f 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -51,9 +51,7 @@ class BatchSearchScreen extends Component { } handleCloseAdvanceSettings = () => { - const { intl } = this.props this.setState({ showAdvancedModeSettings: false }) - toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' })) } render() { From 04401767bf9ce8405e1ba91876bc67a0ec78e78c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:42:46 -0500 Subject: [PATCH 048/162] Change mobile container height on advanced panel open --- lib/components/mobile/batch-search-screen.tsx | 31 +++++++++++++++---- lib/components/mobile/mobile.css | 13 +------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index d2aab6a9f..556700742 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -2,7 +2,7 @@ import { connect } from 'react-redux' import { CSSTransition, TransitionGroup } from 'react-transition-group' import { injectIntl, IntlShape } from 'react-intl' import React, { Component } from 'react' -import toast from 'react-hot-toast' +import styled from 'styled-components' import * as uiActions from '../../actions/ui' import { @@ -23,6 +23,20 @@ import MobileNavigationBar from './navigation-bar' const { SET_FROM_LOCATION, SET_TO_LOCATION } = MobileScreens +const MobileSearchSettings = styled.div<{ advancedPanelOpen: boolean }>` + background: white; + box-shadow: 3px 0px 12px #00000052; + position: fixed; + top: 50px; + left: 0; + right: 0; + transition: all 200ms ease; + height: ${(props) => + props.advancedPanelOpen ? 'calc(100% - 50px)' : '230px'}; + /* Must appear under the 'hamburger' dropdown which has z-index of 1000. */ + z-index: 999; +` + interface Props { intl: IntlShape map: React.ReactElement @@ -56,7 +70,7 @@ class BatchSearchScreen extends Component { render() { const { intl } = this.props - const { planTripClicked } = this.state + const { planTripClicked, showAdvancedModeSettings } = this.state return ( { })} />
-
+ - {!this.state.showAdvancedModeSettings && ( + {!showAdvancedModeSettings && ( {
)} - {this.state.showAdvancedModeSettings && ( + {showAdvancedModeSettings && ( { )} -
+
diff --git a/lib/components/mobile/mobile.css b/lib/components/mobile/mobile.css index b0b6fb3db..b1197cfbd 100644 --- a/lib/components/mobile/mobile.css +++ b/lib/components/mobile/mobile.css @@ -121,20 +121,9 @@ /* Batch routing search screen */ -.otp.mobile .batch-search-settings { - position: fixed; - top: 50px; - left: 0; - right: 0; - height: 216px; - /* Must appear under the 'hamburger' dropdown which has z-index of 1000. */ - z-index: 999; - box-shadow: 3px 0px 12px #00000052; -} - .otp.mobile .batch-search-map { position: fixed; - top: 266px; + top: 282px; left: 0; right: 0; bottom: 0; From c895829a39d036afb5f1d1600abf7231e8878332 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:43:09 -0500 Subject: [PATCH 049/162] update trip-from alpha --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index dc15e32c9..6b9be8d9b 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@opentripplanner/transit-vehicle-overlay": "^4.0.10", "@opentripplanner/transitive-overlay": "^3.0.18", "@opentripplanner/trip-details": "^5.0.11", - "@opentripplanner/trip-form": "^3.7.0-alpha.4", + "@opentripplanner/trip-form": "^3.7.0-alpha.5", "@opentripplanner/trip-viewer-overlay": "^2.0.8", "@opentripplanner/vehicle-rental-overlay": "^2.1.7", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index 2f8ec9bcf..5ea291352 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,10 +2606,10 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.7.0-alpha.4": - version "3.7.0-alpha.4" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.4.tgz#595b41c7d6d598939e2899a350ac0046acf131ce" - integrity sha512-uVkiP9qU1RSHo2ffm+tBIsnf/1pc8id0Giyy5Y61iQswDRmXh8ubTz/LUuhC3fiAYOwm3kYnHZ01tmwQ9XIvTQ== +"@opentripplanner/trip-form@^3.7.0-alpha.5": + version "3.7.0-alpha.5" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.5.tgz#326b501807fda4a5b5630d57641ed3a48e2c56f8" + integrity sha512-WrKXIUOmutvZBRdOsJmzprf2AUIOFhcpR/AYI8ev8HmrQeETEbOdWzOlhUr9E9jaPb6+St2Bs6XuHcOtlgWNgw== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/building-blocks" "^1.0.3" From 7edd335573bfddf6e8c54d7f2723e0d7919eac3e Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:43:29 -0500 Subject: [PATCH 050/162] add classname for custom styling --- lib/components/form/advanced-settings-panel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 34afe9ca6..4c2421c10 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -198,7 +198,7 @@ const AdvancedSettingsPanel = ({ - + {globalSettingsComponents} From 248924aee350aab36a41cfbf220439c9597d209a Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 11 Jul 2024 13:43:49 -0500 Subject: [PATCH 051/162] fix react-transition-group d/t bug --- lib/components/form/styled.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 0ecf13634..a0c86426a 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -247,7 +247,6 @@ const wipeOutMixin = (offset: number) => css` opacity: 0; ` const wipeInMixin = css` - transform: translateX(0px); opacity: 1; ` From 58a06681934a0e2f6074ed2ddbd3528a2c6d26c5 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:40:51 -0500 Subject: [PATCH 052/162] import dt selector to the advanced settings panel --- .../form/advanced-settings-panel.tsx | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 4c2421c10..57f3b2ac6 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -38,6 +38,7 @@ import { } from './util' import { setModeButtonEnabled } from './batch-settings' import { styledCheckboxCss } from './styled' +import DateTimeModal from './date-time-modal' const PanelOverlay = styled.div` height: 100%; @@ -68,7 +69,6 @@ const HeaderContainer = styled.div` align-items: center; display: flex; justify-content: space-between; - margin-bottom: 2em; ` const Subheader = styled.h2` @@ -99,6 +99,24 @@ const ButtonContainer = styled.div` margin-top: 2em; ` +const DtSelectorContainer = styled.div` + padding: 1em; + margin: 2em 0; + background-color: ${blue[50]}; + + .date-time-modal { + padding: 0; + + .main-panel { + margin: 0; + + .date-time-selector { + margin: 15px 0; + } + } + } +` + const AdvancedSettingsPanel = ({ closeAdvancedSettings, currentQuery, @@ -190,9 +208,9 @@ const AdvancedSettingsPanel = ({ - {/** - * Date time selector goes here - */} + + + {processedGlobalSettings.length > 0 && ( <> From 6baf3f13f0be132ed6b4af694f7f92c3f235b26f Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:41:28 -0500 Subject: [PATCH 053/162] remove unneccesary hover + subsettings states in batch settings --- lib/components/form/batch-settings.tsx | 75 +++----------------------- 1 file changed, 8 insertions(+), 67 deletions(-) diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index 1c50355a7..3ec0ac155 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -1,15 +1,7 @@ -import { - addSettingsToButton, - MetroModeSelector, - populateSettingWithValue -} from '@opentripplanner/trip-form' import { connect } from 'react-redux' import { decodeQueryParams } from 'use-query-params' -import { - ModeButtonDefinition, - ModeSetting, - ModeSettingValues -} from '@opentripplanner/types' +import { MetroModeSelector } from '@opentripplanner/trip-form' +import { ModeButtonDefinition } from '@opentripplanner/types' import { Search } from '@styled-icons/fa-solid/Search' import { SyncAlt } from '@styled-icons/fa-solid/SyncAlt' import { useIntl } from 'react-intl' @@ -18,19 +10,16 @@ import React, { useCallback, useContext, useState } from 'react' import * as apiActions from '../../actions/api' import * as formActions from '../../actions/form' import { ComponentContext } from '../../util/contexts' -import { generateModeSettingValues } from '../../util/api' import { getActiveSearch, hasValidLocation } from '../../util/state' import { getBaseColor, getDarkenedBaseColor } from '../util/colors' import { StyledIconWrapper } from '../util/styledIcon' import { - addCustomSettingLabels, addModeButtonIcon, alertUserTripPlan, modesQueryParamConfig, onSettingsUpdate, pipe, - populateSettingWithIcon, setModeButton } from './util' import { @@ -48,14 +37,11 @@ type Props = { enabledModeButtons: string[] fillModeIcons?: boolean modeButtonOptions: ModeButtonDefinition[] - modeSettingDefinitions: ModeSetting[] - modeSettingValues: ModeSettingValues onPlanTripClick: () => void openAdvancedSettings: () => void routingQuery: any setQueryParam: (evt: any) => void spacedOutModeSelector?: boolean - updateQueryTimeIfLeavingNow: () => void } export function setModeButtonEnabled(enabledKeys: string[]) { @@ -76,74 +62,37 @@ function BatchSettings({ enabledModeButtons, fillModeIcons, modeButtonOptions, - modeSettingDefinitions, - modeSettingValues, onPlanTripClick, openAdvancedSettings, routingQuery, setQueryParam, - spacedOutModeSelector, - updateQueryTimeIfLeavingNow + spacedOutModeSelector }: Props) { const intl = useIntl() // Whether the date/time selector is open const [dateTimeOpen, setDateTimeOpen] = useState(false) - // Whether the mode selector has a popup open - const [modeSelectorPopup, setModeSelectorPopup] = useState(false) - // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) - const processedModeSettings = modeSettingDefinitions.map( - pipe( - populateSettingWithIcon(ModeIcon), - populateSettingWithValue(modeSettingValues), - addCustomSettingLabels(intl) - ) - ) - const processedModeButtons = modeButtonOptions.map( - pipe( - addModeButtonIcon(ModeIcon), - addSettingsToButton(processedModeSettings), - setModeButtonEnabled(enabledModeButtons) - ) + pipe(addModeButtonIcon(ModeIcon), setModeButtonEnabled(enabledModeButtons)) ) const _planTrip = useCallback(() => { alertUserTripPlan(intl, currentQuery, onPlanTripClick, routingQuery) }, [currentQuery, intl, onPlanTripClick, routingQuery]) - /** - * Check whether the mode selector is showing a popup. - */ - const checkModeSelectorPopup = useCallback(() => { - const modeSelectorPopup = document.querySelector( - '.metro-mode-selector div[role="dialog"]' - ) - setModeSelectorPopup(!!modeSelectorPopup) - }, [setModeSelectorPopup]) - const baseColor = getBaseColor() const accentColor = getDarkenedBaseColor() return ( - - + + - + { const urlSearchParams = new URLSearchParams(state.router.location.search) - const modeSettingValues = generateModeSettingValues( - urlSearchParams, - state.otp?.modeSettingDefinitions || [], - state.otp.config.modes?.initialState?.modeSettingValues - ) return { activeSearch: getActiveSearch(state), currentQuery: state.otp.currentQuery, @@ -201,16 +145,13 @@ const mapStateToProps = (state: any) => { {}, fillModeIcons: state.otp.config.itinerary?.fillModeIcons, modeButtonOptions: state.otp.config?.modes?.modeButtons || [], - modeSettingDefinitions: state.otp?.modeSettingDefinitions || [], - modeSettingValues, spacedOutModeSelector: state.otp?.config?.modes?.spacedOut } } const mapDispatchToProps = { routingQuery: apiActions.routingQuery, - setQueryParam: formActions.setQueryParam, - updateQueryTimeIfLeavingNow: formActions.updateQueryTimeIfLeavingNow + setQueryParam: formActions.setQueryParam } export default connect(mapStateToProps, mapDispatchToProps)(BatchSettings) From d4215c58eff30662b2fd78761ec1b3f69bb221fa Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 12 Jul 2024 11:18:51 -0500 Subject: [PATCH 054/162] fix button padding d/t selector --- lib/components/form/advanced-settings-panel.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 57f3b2ac6..ac8fa72a7 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -110,6 +110,10 @@ const DtSelectorContainer = styled.div` .main-panel { margin: 0; + button { + padding: 6px 0; + } + .date-time-selector { margin: 15px 0; } From b92f82fd2a70e646b9ea9f8fb7059afdb990ce36 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:21:56 -0400 Subject: [PATCH 055/162] refactor(apiV2): Use OTP2 route response more intentionally. --- lib/actions/apiV2.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 425470d71..679f39fe1 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -1103,7 +1103,10 @@ export function routingQuery(searchId = null, updateSearchInReducer) { } } }) - ?.map(convertGraphQLResponseToLegacy), + ?.map((leg) => ({ + ...convertGraphQLResponseToLegacy(leg), + route: leg.transitLeg ? leg.route : undefined + })), otp2QueryParams: query.variables }) ) From 8b074de897f6321418fc612912b7b86a01f89537 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:17:22 -0400 Subject: [PATCH 056/162] refactor(actions/user): Parse OTP2 query params --- lib/actions/user.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 9ec2d9965..13c6e6584 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -156,12 +156,17 @@ export function fetchAuth0Token(auth0, intl) { */ function convertRequestToSearch(config) { return function (tripRequest) { - const { dateCreated, id, requestParameters = {} } = tripRequest + const { + dateCreated, + id, + otp2QueryParams = {}, + requestParameters = {} // Deprecated OTP1 + } = tripRequest const { host, path } = config.api return { canDelete: false, id, - query: planParamsToQuery(requestParameters || {}), + query: planParamsToQuery(otp2QueryParams || requestParameters || {}), timestamp: dateCreated, url: `${host}${path}/plan?${qs.stringify(requestParameters)}` } @@ -219,9 +224,12 @@ export function fetchTripRequests() { if (status === 'success') { // Convert tripRequests to search format. const { config } = getState().otp + console.log(trips.data) const convertedTrips = trips.data .map(convertRequestToSearch(config)) - .filter((tripReq) => !isEmpty(tripReq.query)) + .filter( + (tripReq) => !isEmpty(tripReq.query) || !!tripReq.otp2QueryParams + ) .filter(removeDuplicateRequestsFromBatch()) dispatch(setCurrentUserTripRequests(convertedTrips)) From 337685b970e61350017e67767eb949833f7c0bbf Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:22:51 -0400 Subject: [PATCH 057/162] fix(actions/users): Better filter duplicate entries --- lib/actions/user.js | 46 +++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 13c6e6584..8678ccde6 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -173,23 +173,38 @@ function convertRequestToSearch(config) { } } +// TODO move to a utils file +function areRequestsSame(qp1, qp2) { + // Everything except modes. + // Exclude banned/preferred/unpreferred at this time. + return ( + qp1.bikeReluctance === qp2.bikeReluctance && + qp1.carReluctance === qp2.carReluctance && + qp1.date === qp2.date && + qp1.departArrive === qp2.departArrive && + qp1.from?.name === qp2.from?.name && + qp1.departArrive === qp2.departArrive && + qp1.time === qp2.time && + qp1.to?.name === qp2.to?.name && + qp1.walkReluctance === qp2.walkReluctance && + qp1.walkSpeed === qp2.walkSpeed && + qp1.wheelchair === qp2.wheelchair + ) +} + /** - * Removes duplicate requests saved from batch queries, - * so that only one request is displayed per batch. - * (Except for the mode, all query params in the same batch are the same.) + * Removes duplicate requests so that only one request is displayed per "batch". */ -function removeDuplicateRequestsFromBatch() { - const batches = {} - return function ({ query }) { - if (!batches[query.batchId]) { - batches[query.batchId] = true - - // Remove the mode for display purposes - query.mode = '' - return true - } - return false +function removeDuplicateRequests(filtered, tripRequest) { + // Compare one trip request to the next one. + if (filtered.length == 0) { + filtered.push(tripRequest) + } else if ( + !areRequestsSame(filtered[filtered.length - 1].query, tripRequest.query) + ) { + filtered.push(tripRequest) } + return filtered } /** @@ -224,13 +239,12 @@ export function fetchTripRequests() { if (status === 'success') { // Convert tripRequests to search format. const { config } = getState().otp - console.log(trips.data) const convertedTrips = trips.data .map(convertRequestToSearch(config)) .filter( (tripReq) => !isEmpty(tripReq.query) || !!tripReq.otp2QueryParams ) - .filter(removeDuplicateRequestsFromBatch()) + .reduce(removeDuplicateRequests, []) dispatch(setCurrentUserTripRequests(convertedTrips)) } From 5bf5fa9706f372955fa0c97a3ee0a909f019dcf9 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:40:06 -0400 Subject: [PATCH 058/162] refactor(user-settings-i18n): Combine modes for displaying --- lib/actions/user.js | 4 +++- lib/components/form/user-settings-i18n.js | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 8678ccde6..149d7cf9a 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -197,12 +197,14 @@ function areRequestsSame(qp1, qp2) { */ function removeDuplicateRequests(filtered, tripRequest) { // Compare one trip request to the next one. - if (filtered.length == 0) { + if (filtered.length === 0) { filtered.push(tripRequest) } else if ( !areRequestsSame(filtered[filtered.length - 1].query, tripRequest.query) ) { filtered.push(tripRequest) + } else { + filtered[filtered.length - 1].query.modes.push(...tripRequest.query.modes) } return filtered } diff --git a/lib/components/form/user-settings-i18n.js b/lib/components/form/user-settings-i18n.js index c1a639a00..e6a89aa0d 100644 --- a/lib/components/form/user-settings-i18n.js +++ b/lib/components/form/user-settings-i18n.js @@ -50,15 +50,18 @@ export function summarizeQuery(query, intl, locations = []) { ) } + const modes = query.modes + .map(({ mode, qualifier }) => `${mode}${qualifier ? `_${qualifier}` : ''}`) + .join(',') const from = findLocationType(intl, query.from, locations) || stripAllButNameOfAddress(query.from.name) const to = findLocationType(intl, query.to, locations) || stripAllButNameOfAddress(query.to.name) - const mode = hasTransit(query.mode) + const mode = hasTransit(modes) ? intl.formatMessage({ id: 'common.modes.transit' }) - : toSentenceCase(query.mode) + : toSentenceCase(modes) return intl.formatMessage( { id: 'components.UserSettings.recentSearchSummary' }, { from, mode, to } From 4594839270352a0ebeff1be94b024051657717c2 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:34:41 -0400 Subject: [PATCH 059/162] fix: Fix parsing errors --- lib/actions/user.js | 16 ++++++++++++++++ lib/components/form/user-settings-i18n.js | 9 ++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 149d7cf9a..14287dec5 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -163,6 +163,22 @@ function convertRequestToSearch(config) { requestParameters = {} // Deprecated OTP1 } = tripRequest const { host, path } = config.api + + // FIXME: remove if OTP-UI no longer includes trailing bracket + // Don't use ?. syntax, fromPlace and toPlace need to be defined in order to be replaced. + if (otp2QueryParams.fromPlace && otp2QueryParams.fromPlace.endsWith('}')) { + otp2QueryParams.fromPlace = otp2QueryParams.fromPlace.substring( + 0, + otp2QueryParams.fromPlace.length - 2 + ) + } + if (otp2QueryParams.toPlace && otp2QueryParams.toPlace.endsWith('}')) { + otp2QueryParams.toPlace = otp2QueryParams.toPlace.substring( + 0, + otp2QueryParams.toPlace.length - 2 + ) + } + return { canDelete: false, id, diff --git a/lib/components/form/user-settings-i18n.js b/lib/components/form/user-settings-i18n.js index e6a89aa0d..246baea68 100644 --- a/lib/components/form/user-settings-i18n.js +++ b/lib/components/form/user-settings-i18n.js @@ -50,9 +50,12 @@ export function summarizeQuery(query, intl, locations = []) { ) } - const modes = query.modes - .map(({ mode, qualifier }) => `${mode}${qualifier ? `_${qualifier}` : ''}`) - .join(',') + const modes = + query.modes + ?.map( + ({ mode, qualifier }) => `${mode}${qualifier ? `_${qualifier}` : ''}` + ) + .join(',') || '' const from = findLocationType(intl, query.from, locations) || stripAllButNameOfAddress(query.from.name) From 7c361c11f657595b3c565478556723c20ecac079 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:46:46 -0400 Subject: [PATCH 060/162] chore(deps): Update core-utils version for bug fix --- package.json | 2 +- yarn.lock | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7e4c69365..48e9c2886 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@floating-ui/react": "^0.19.2", "@opentripplanner/base-map": "^3.2.0", "@opentripplanner/building-blocks": "^1.1.0", - "@opentripplanner/core-utils": "^11.4.2", + "@opentripplanner/core-utils": "^11.4.3", "@opentripplanner/endpoints-overlay": "^2.1.1", "@opentripplanner/from-to-location-picker": "^2.1.13", "@opentripplanner/geocoder": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index 1c0bb7eb6..a1728d568 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2398,7 +2398,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== -"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.4.0", "@opentripplanner/core-utils@^11.4.2": +"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.4.0": version "11.4.2" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== @@ -2416,6 +2416,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@^11.4.3": + version "11.4.3" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.3.tgz#4655f9a3bef1977e53abd81a4a0eae966f977c60" + integrity sha512-GbvchRsLfEi9JygUx6ypU+Iqv2hELseC53yQyQ/XdnB1kcHzN71BtBbz+qpD5/jk8IuM92j1taRnGMeu5ni6yA== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.0" + "@opentripplanner/geocoder" "^3.0.0" + "@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@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.1.tgz#e7029d95bd13436aacbc6f854c243d1fcf7e8570" From 9053e97d5f3e1730abc2961519fc7c840690f616 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 2 Aug 2024 17:52:02 -0400 Subject: [PATCH 061/162] refactor(actions/users): Remove obsolete location parsing code. --- lib/actions/user.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 14287dec5..149d7cf9a 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -163,22 +163,6 @@ function convertRequestToSearch(config) { requestParameters = {} // Deprecated OTP1 } = tripRequest const { host, path } = config.api - - // FIXME: remove if OTP-UI no longer includes trailing bracket - // Don't use ?. syntax, fromPlace and toPlace need to be defined in order to be replaced. - if (otp2QueryParams.fromPlace && otp2QueryParams.fromPlace.endsWith('}')) { - otp2QueryParams.fromPlace = otp2QueryParams.fromPlace.substring( - 0, - otp2QueryParams.fromPlace.length - 2 - ) - } - if (otp2QueryParams.toPlace && otp2QueryParams.toPlace.endsWith('}')) { - otp2QueryParams.toPlace = otp2QueryParams.toPlace.substring( - 0, - otp2QueryParams.toPlace.length - 2 - ) - } - return { canDelete: false, id, From ad5a491e841b9af4126a003e8ed5d945fd68f96e Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:29:02 -0400 Subject: [PATCH 062/162] chore(i18n): Revert formatting changes --- i18n/es.yml | 34 +-- i18n/zh_Hant.yml | 580 ++++++++++++++++++++++------------------------- 2 files changed, 295 insertions(+), 319 deletions(-) diff --git a/i18n/es.yml b/i18n/es.yml index 930a2bd9d..23318b41a 100644 --- a/i18n/es.yml +++ b/i18n/es.yml @@ -30,7 +30,8 @@ actions: No se puede guardar el plan: este plan no se pudo guardar debido a la falta de capacidad en uno o más vehículos. Por favor, vuelva a planificar su viaje. - maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados válidos + maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados + válidos saveItinerariesError: "No se pudieron guardar los itinerarios: {err}" setDateError: "Error al establecer la fecha:" setGroupSizeError: "No se pudo establecer el tamaño del grupo:" @@ -52,10 +53,13 @@ actions: authTokenError: Error al obtener un token de autorización. confirmDeleteMonitoredTrip: ¿Desea eliminar este viaje? confirmDeletePlace: ¿Quiere eliminar este lugar? - emailVerificationResent: El mensaje de verificación de correo electrónico ha sido reenviado. + emailVerificationResent: El mensaje de verificación de correo electrónico ha sido + reenviado. genericError: "Se ha encontrado un error: {err}" - itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado es posible. - mustAcceptTermsToSavePlace: Acepte los Términos de uso (en Mi Cuenta) para guardar las ubicaciones. + itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado + es posible. + mustAcceptTermsToSavePlace: Acepte los Términos de uso (en Mi Cuenta) para guardar + las ubicaciones. mustBeLoggedInToSavePlace: Por favor, inicia la sesión para guardar las ubicaciones. placeRemembered: La configuración de este lugar se ha guardado. preferencesSaved: Sus preferencias se han guardado. @@ -208,7 +212,8 @@ components: a incluir el transporte publico en la selección de modos. origin: origen planTripTooltip: Planificar viaje - validationMessage: "Por favor, defina los siguientes campos para planificar un viaje: {issues}" + validationMessage: "Por favor, defina los siguientes campos para planificar un + viaje: {issues}" BeforeSignInScreen: mainTitle: Iniciando sesión message: > @@ -364,12 +369,12 @@ components: disponibles}} companyBicycle: Bicicleta {company} companyScooter: Scooter {company} - distanceAway: "{localizedDistanceString} de distancia" error: Se ha producido un error al cargar los servicios cercanos. header: Ver cerca nearbyListIntro: Lista de {count} entidades cercanas. nothingNearby: No ubicaciónes cercanas. spacesAvailable: "{spacesAvailable} espacios libres disponibles" + distanceAway: '{localizedDistanceString} de distancia' NewAccountWizard: createNewAccount: Crear una nueva cuenta finish: ¡Configuración de la cuenta completa! @@ -450,8 +455,7 @@ components: minutos. verified: Verificado verify: Verificar - verifySms: >- - Por favor, complete el proceso de verificación para configurar las + verifySms: Por favor, complete el proceso de verificación para configurar las notificaciones por SMS. Place: deleteThisPlace: Borrar este lugar @@ -558,7 +562,8 @@ components: header: ¡La sesión está a punto de terminar! keepSession: Continuar sesión SimpleRealtimeAnnotation: - usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo real + usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo + real StackedPaneDisplay: savePreferences: Guardar preferencias StopScheduleTable: @@ -620,15 +625,18 @@ components: travelingAt: Viajando a {milesPerHour} vehicleName: Vehículo {vehicleNumber} TripBasicsPane: - checkingItineraryExistence: Comprobación de la existencia de itinerarios para cada día de la semana… + checkingItineraryExistence: Comprobación de la existencia de itinerarios para + cada día de la semana… tripDaysPrompt: ¿Qué días hace este viaje? - tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana indicados anteriormente. + tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana + indicados anteriormente. tripNamePrompt: "Por favor, indique un nombre para este viaje:" tripNotAvailableOnDay: El viaje no está disponible el {repeatedDay} unsavedChangesExistingTrip: >- Todavía no ha guardado su viaje. Si abandona la página, los cambios se perderán. - unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, se perderá. + unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, + se perderá. TripNotificationsPane: advancedSettings: Configuración avanzada altRouteRecommended: Se recomienda una ruta alternativa o un punto de transferencia @@ -706,10 +714,10 @@ components: leaveAt: "Salida a las " TripSummaryPane: happensOnDays: "Ocurre en: {days}" - monitoredTripDays: Días de viaje monitoreados notifications: "{leadTimeInMinutes} minutos antes de la salida programada" notificationsDisabled: Notificaciones desactivadas timeAndDuration: Tiempo y duración del viaje + monitoredTripDays: Días de viaje monitoreados TripTools: copyLink: Copiar enlace header: Herramientas diff --git a/i18n/zh_Hant.yml b/i18n/zh_Hant.yml index eb4307f2d..3cc8aebc8 100644 --- a/i18n/zh_Hant.yml +++ b/i18n/zh_Hant.yml @@ -2,19 +2,17 @@ _id: zh-Hant _name: Chinese (Traditional) actions: callTaker: + queryFetchError: 擷取查詢時發生錯誤:{err} callQuerySaveError: 儲存通話查詢時發生錯誤:{err} callSaveError: 無法儲存通話:{err} checkSessionError: 建立授權工作階段時發生錯誤:{err} couldNotFindCallError: 找不到通話。正在取消儲存查詢請求。 fetchCallsError: 擷取通話時發生錯誤:{err} - queryFetchError: 擷取查詢時發生錯誤:{err} fieldTrip: addNoteError: 新增實地考察備註時發生錯誤: - confirmOverwriteItineraries: | - 此動作將覆蓋此請求之前規劃的{outbound, select, - true {外出} - other {返回} - }預定行程。您想繼續嗎? + confirmOverwriteItineraries: "此動作將覆蓋此請求之前規劃的{outbound, select,\n true {外出}\n other + {返回}\n }預定行程。您想繼續嗎?\n" + setGroupSizeError: 設定群組大小時發生錯誤: deleteItinerariesError: 刪除實地考察計畫時發生錯誤: deleteNoteError: 刪除實地考察備註時發生錯誤: editSubmitterNotesError: 編輯提交者備註時發生錯誤: @@ -26,16 +24,8 @@ actions: maxTripRequestsExceeded: 行程請求數量過多,沒有有效結果 saveItinerariesError: 無法儲存預定行程:{err} setDateError: 設定日期時發生錯誤: - setGroupSizeError: 設定群組大小時發生錯誤: setPaymentError: 設定付款資訊時發生錯誤: setRequestStatusError: 設定請求狀態時發生錯誤: - location: - deniedAccessAlert: | - 系統已封鎖您存取地點的權限。 - 若要使用目前的地點,請從瀏覽器啟用地點權限,然後再重新載入頁面。 - geolocationNotSupportedError: 您的瀏覽器不支援地理位置 - unknownPositionError: 取得位置時發生不明錯誤 - userDeniedPermission: 使用者拒絕提供權限 map: currentLocation: (目前位置) user: @@ -45,36 +35,29 @@ actions: confirmDeletePlace: 是否要移除此地點? emailVerificationResent: 電子郵件驗證訊息已重新傳送。 genericError: 發生錯誤:{err} + mustBeLoggedInToSavePlace: 請登入,以儲存地點。 itineraryExistenceCheckFailed: 檢查您選取的行程是否可行時發生錯誤。 mustAcceptTermsToSavePlace: 請接受使用條款 (在我的帳戶下),以儲存地點。 - mustBeLoggedInToSavePlace: 請登入,以儲存地點。 placeRemembered: 此地點的設定已儲存。 preferencesSaved: 您的偏好已儲存。 smsInvalidCode: 您輸入的代碼無效。請再試一次。 smsResendThrottled: 驗證簡訊已在不到一分鐘前傳送到指定的電話號碼。請稍後再試一次。 smsVerificationFailed: 您的電話無法驗證。您輸入的代碼可能已失效。請要求新的代碼,然後再試一次。 + location: + deniedAccessAlert: "系統已封鎖您存取地點的權限。\n若要使用目前的地點,請從瀏覽器啟用地點權限,然後再重新載入頁面。 \n" + geolocationNotSupportedError: 您的瀏覽器不支援地理位置 + unknownPositionError: 取得位置時發生不明錯誤 + userDeniedPermission: 使用者拒絕提供權限 common: - coordinates: "{lat}; {lon}" - dateExpressions: - today: 今天 - tomorrow: 明天 - yesterday: 昨天 - daysOfWeek: - friday: 星期五 - monday: 星期一 - saturday: 星期六 - sunday: 星期日 - thursday: 星期四 - tuesday: 星期二 - wednesday: 星期三 + coordinates: '{lat}; {lon}' daysOfWeekCompact: - friday: 週五 - monday: 週一 - saturday: 週六 sunday: 週日 thursday: 週四 tuesday: 週二 wednesday: 週三 + friday: 週五 + monday: 週一 + saturday: 週六 daysOfWeekPlural: friday: 每星期五 monday: 每星期一 @@ -83,39 +66,16 @@ common: thursday: 每星期四 tuesday: 每星期二 wednesday: 每星期三 - forms: - back: 返回 - cancel: 取消 - close: 關閉 - defaultValue: "{value} (預設)" - edit: 編輯 - error: 錯誤! - finish: 完成 - next: 前進 - "no": 否 - print: 列印 - save: 儲存 - startOver: 重新開始 - submitting: 正在提交… - "yes": 是 - itineraryDescriptions: - calories: "{calories, number}卡" - fareUnknown: 無票價資訊 - noItineraryToDisplay: 沒有預定行程可顯示。 - relativeCo2: | - {co2}比單獨開車排放的CO₂{isMore, select, true {要多} other {少}} - transfers: "{transfers}次轉乘" - linkOpensNewWindow: (開啟新視窗) modes: + car_park: 停車轉乘 + drive: 駕車 + ferry: 渡船 + flex: 彈性路線 bicycle_rent: 自行車共享 bike: 騎行 bus: 搭乘公車 cable_car: 纜車 car: 汽車 - car_park: 停車轉乘 - drive: 駕車 - ferry: 渡船 - flex: 彈性路線 funicular: 纜索鐵路 gondola: 空中纜車 micromobility: 電動滑板車 @@ -127,206 +87,155 @@ common: transit: 公共交通 walk: 步行 notifications: - email: 電子郵件 push: 推播通知 sms: 簡訊 + email: 電子郵件 places: custom: 自訂 dining: 餐廳 home: 住家 work: 工作 - routing: - routeAndNumber: 路線{routeId} searchForms: - click: 按一下 enterDestination: 輸入目的地或{mapAction} 地圖…… enterStartLocation: 輸入開始位置或{mapAction} 地圖…… + click: 按一下 tap: 輕觸 + dateExpressions: + today: 今天 + tomorrow: 明天 + yesterday: 昨天 + daysOfWeek: + friday: 星期五 + monday: 星期一 + saturday: 星期六 + sunday: 星期日 + thursday: 星期四 + tuesday: 星期二 + wednesday: 星期三 + forms: + back: 返回 + cancel: 取消 + close: 關閉 + defaultValue: '{value} (預設)' + edit: 編輯 + error: 錯誤! + finish: 完成 + next: 前進 + "no": 否 + print: 列印 + save: 儲存 + startOver: 重新開始 + submitting: 正在提交… + "yes": 是 + itineraryDescriptions: + calories: '{calories, number}卡' + fareUnknown: 無票價資訊 + noItineraryToDisplay: 沒有預定行程可顯示。 + relativeCo2: "{co2}比單獨開車排放的CO₂{isMore, select, true {要多} other {少}}\n" + transfers: '{transfers}次轉乘' + linkOpensNewWindow: (開啟新視窗) + routing: + routeAndNumber: 路線{routeId} time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" + departureArrivalTimes: '{startTime, time, short}—{endTime, time, short}' duration: aFewSeconds: 幾秒鐘 - nDays: "{days}天" - nHours: "{hours}小時" - nMinutes: "{minutes}分鐘" - durationAgo: "{duration}前" - tripDurationFormat: >- - {hours, plural, =0 {} other {# 小時 }}{minutes} 分鐘 { seconds, plural, =0 {} - other {# 秒鐘}} + nDays: '{days}天' + nHours: '{hours}小時' + nMinutes: '{minutes}分鐘' + durationAgo: '{duration}前' + tripDurationFormat: '{hours, plural, =0 {} other {# 小時 }}{minutes} 分鐘 { seconds, + plural, =0 {} other {# 秒鐘}}' components: - A11yPrefs: - accessibilityRoutingByDefault: 預設優先選擇無障礙行程 AccountSetupFinishPane: message: 您已經準備好開始規劃行程。 - AddPlaceButton: - addPlace: 新增地點 - needOriginDestination: 定義起點/目的地以新增中間地點 - tooManyPlaces: 已達到中間地點數量上限 - AdvancedOptions: - bannedRoutes: 選取禁止的路線…… - preferredRoutes: 選取首選路線…… AfterSignInScreen: mainTitle: 正在重新導向…… message: 如果頁面未在幾秒鐘後載入,請按一下這裡。 AppMenu: callHistory: 通話記錄 closeMenu: 關閉功能表 - fieldTrip: 實地考察 mailables: 可郵寄 openMenu: 開啟功能表 skipNavigation: 跳過導航 + fieldTrip: 實地考察 BackToTripPlanner: backToTripPlanner: 返回行程規劃器 BatchResultsScreen: - expandMap: 展開地圖 showResults: 顯示結果 + expandMap: 展開地圖 BatchRoutingPanel: shortTitle: 規劃行程 - BatchSearchScreen: - header: 規劃您的行程 - modeSelectorLabel: 選取出行模式 - BatchSettings: - destination: 目的地 - invalidModeSelection: 無法使用所選模式規劃行程。嘗試將公共交通納入您的模式選取內容。 - origin: 起點 - planTripTooltip: 規劃行程 - validationMessage: 請定義以下欄位以規劃行程:{issues} BeforeSignInScreen: mainTitle: 登入中 - message: | - 您必須登入才能存取此頁面。我們正在將您重新導向到登入頁面,請稍候…… - CallTakerPanel: - advancedOptions: 進階選項 - groupSize: 群組大小: - intermediateDestination: 輸入中間目的地 + message: "您必須登入才能存取此頁面。我們正在將您重新導向到登入頁面,請稍候……\n" DateTimeOptions: - arriveBy: 最晚抵達時間 departAt: 出發時間 now: 現在 + arriveBy: 最晚抵達時間 DateTimePreview: - arriveAt: "{arriveTime, time, short}抵達" + leaveNow: 現在出發 + arriveAt: '{arriveTime, time, short}抵達' dayLastWeek: 上{formattedDayOfWeek} - departAt: "{departTime, time, short}出發" + departAt: '{departTime, time, short}出發' editDepartOrArrival: 編輯出發或抵達時間 - leaveNow: 現在出發 - DateTimeScreen: - header: 設定日期/時間 DefaultItinerary: clickDetails: 按一下以檢視詳細資料 - multiModeSummary: "{accessMode} + {transitMode}" nonTransit: 替代選項 - DeleteUser: - deleteMyAccount: 刪除我的帳戶 - ErrorMessage: - header: 無法規劃行程 - warning: 警告 + multiModeSummary: '{accessMode} + {transitMode}' ExistingAccountDisplay: - a11y: 可到達性 - mainTitle: 我的設定 notifications: 通知 places: 最愛的地點 terms: 條款 + a11y: 可到達性 + mainTitle: 我的設定 FavoritePlaceList: addAnotherPlace: 新增其他地點 - description: 新增您經常使用的地點,以節省規劃行程的時間: editThisPlace: 編輯此地點 setAddressForPlaceType: 設定您的{placeType}地址 + description: 新增您經常使用的地點,以節省規劃行程的時間: FavoritePlaceScreen: + placeNotFound: 找不到地點 addNewPlace: 新增地點 editPlace: 編輯{placeName} editPlaceGeneric: 編輯地點 invalidAddress: 請為此地點設定位置。 invalidName: 請為此地點輸入名稱。 nameAlreadyUsed: 您已經對其他地點使用此名稱。請輸入其他名稱。 - placeNotFound: 找不到地點 placeNotFoundDescription: 很抱歉,找不到請求的地點。 - FormNavigationButtons: - ariaLabel: 表單導航 - ItinerarySummary: - itineraryDetails: 路線詳細資訊 - minMaxFare: "{minTotalFare} - {maxTotalFare}" - LocationSearch: - enterLocation: 輸入位置 - setDestination: 設定目的地 - setOrigin: 設定起點 MapLayers: - bike-rental: "{companies}共享自行車" - car-rental: 自行車租賃位置 - micromobility-rental: "{companies}電動滑板車" - park-and-ride: 停車轉乘位置 satellite: 衛星 shared-vehicles: 共享車輛 stops: 公共交通車站 streets: 街道 - MapillaryFrame: - title: 街道圖像 + bike-rental: '{companies}共享自行車' + car-rental: 自行車租賃位置 + micromobility-rental: '{companies}電動滑板車' + park-and-ride: 停車轉乘位置 MetroUI: + originallyScheduledTime: (原定 {originalTime}) + singleModeItineraryDescription: '{time} {mode} 路線' arriveAt: 您已抵達目的地 - itineraryDescription: "{time}預定行程,使用{routes}" + itineraryDescription: '{time}預定行程,使用{routes}' leaveAt: 您出發 multipleOptions: 多個選項 orAlternatives: 或相同方向的其他路線 - originallyScheduledTime: (原定 {originalTime}) - singleModeItineraryDescription: "{time} {mode} 路線" timeWalking: 步行{time} - MobileOptions: - header: 設定搜尋選項 - NarrativeItinerariesHeader: - changeSortDir: 變更排序方向 - howToFindResults: 要檢視結果,請參閱下方「找到的預定行程」標題。 - itinerariesFound: "{itineraryNum}個預定行程已找到" - numIssues: "{issueNum}個問題" - resultsSortedBy: 行程結果目前依{sortSelected}排序。如需變更結果的排序方式,請使用下方「排序結果」按鈕。 - searching: 正在尋找您的選項…… - selectArrivalTime: 抵達時間 - selectBest: 最佳選項 - selectCost: 費用 - selectDepartureTime: 出發時間 - selectDuration: 期間 - selectWalkTime: 步行時間 - sortResults: 對結果排序 - viewAll: 檢視所有選項 - NavLoginButton: - help: 說明 - myAccount: 我的帳戶 - signIn: 登入 - signOut: 登出 - NearbyView: - bikeRentalStation: 自行車租車站 - bikesAvailable: "{bikesAvailable}輛自行車可用" - companyBicycle: "{company} 自行車" - companyScooter: "{company} 滑板車" - error: 載入鄰近設施時發生錯誤。 - header: 檢視附近 - spacesAvailable: "{spacesAvailable} 有未佔用的空間" - NewAccountWizard: - createNewAccount: 建立新帳戶 - finish: 帳戶設定完成! - notifications: 通知偏好 - places: 新增您的位置 - verify: 驗證您的電子郵件地址 - NotFound: - description: 您要求的內容無法使用。 - header: 找不到內容 - NotificationPrefsPane: - devicesRegistered: "{count}個裝置 已註冊" - noDeviceForPush: 使用行動應用程式註冊您的裝置以存取推播通知。 - notificationChannelPrompt: 透過以下方式接收有關您已儲存之行程的通知: OTP2ErrorRenderer: - LOCATION_NOT_FOUND: - body: "{inputFields} 地點 未鄰近任何街道。" - header: 地點無法到達 NO_STOPS_IN_RANGE: - body: "{inputFields} 地點 未鄰近任何公共交通車站。" + body: '{inputFields} 地點 未鄰近任何公共交通車站。' header: 範圍內無車站 NO_TRANSIT_CONNECTION: body: 在所選服務日當天使用所選車輛類型進行搜尋後,在您的出發地和目的地之間找不到公共交通連接路線。 header: 無公共交通連接路線 + LOCATION_NOT_FOUND: + body: '{inputFields} 地點 未鄰近任何街道。' + header: 地點無法到達 NO_TRANSIT_CONNECTION_IN_SEARCH_WINDOW: body: 找到一個公共交通連接路線,但此路線超出搜尋視窗範圍,請使用您所選擇的車輛類型試著調整您的搜尋視窗。 header: 搜尋視窗內無公共交通連接路線 OUTSIDE_BOUNDS: - body: "{inputFields} 地點 不在行程規劃器的範圍內。" + body: '{inputFields} 地點 不在行程規劃器的範圍內。' header: 地點超出範圍 OUTSIDE_SERVICE_PERIOD: body: 指定的日期超出目前載入行程規劃器中的資料範圍。 @@ -341,6 +250,8 @@ components: FROM: 起點 TO: 目的地 PhoneNumberEditor: + requestNewCode: 要求新代碼 + sendVerificationText: 傳送驗證簡訊 changeNumber: 變更號碼 invalidCode: 請輸入6位數的驗證碼。 invalidPhone: 請輸入有效的電話號碼。 @@ -349,20 +260,11 @@ components: phoneNumberVerified: 已順利驗證電話號碼 {phoneNumber} 。 placeholder: 輸入您的電話號碼 prompt: 輸入您用來接收簡訊通知的電話號碼: - requestNewCode: 要求新代碼 - sendVerificationText: 傳送驗證簡訊 - smsConsent: | - 一旦提供您的電話號碼,即表示您同意接收驗證和行程監控簡訊。您的行動電信商可能會收取額外費用。 + smsConsent: "一旦提供您的電話號碼,即表示您同意接收驗證和行程監控簡訊。您的行動電信商可能會收取額外費用。\n" verificationCode: 驗證碼: - verificationInstructions: | - 請查看您手機的簡訊應用程式是否收到含有驗證碼的簡訊,並在下方輸入該驗證碼 (驗證碼將在10分鐘後失效)。 + verificationInstructions: "請查看您手機的簡訊應用程式是否收到含有驗證碼的簡訊,並在下方輸入該驗證碼 (驗證碼將在10分鐘後失效)。\n" verified: 已驗證 verify: 驗證 - Place: - deleteThisPlace: 刪除此地點 - enterAlert: | - 請在表單內輸入起點/目的地 (或按一下地圖來設定),然後按一下產生的標記以設定為{placeType}位置。 - viewStop: 檢視車站 PlaceEditor: addressPrompt: 地址: genericLocationPlaceholder: 搜尋位置 @@ -371,10 +273,10 @@ components: nameExample: 我的咖啡館 namePrompt: 定地名: PlanFirstLastButtons: + previous: 上一個 first: 第一個 last: 最後一個 next: 前進 - previous: 上一個 PlanTripButton: planTrip: 規劃行程 PointPopup: @@ -382,53 +284,28 @@ components: PrintLayout: itinerary: 預定行程 toggleMap: 切換地圖 - RealtimeAnnotation: - delaysShownInResults: | - 您的行程結果已依據即時資訊調整。在一般情況下,此形成使用以下路線會需要{normalDuration}:{routes}。 - serviceUpdate: 服務更新 RealtimeStatusLabel: early: 提早{minutes} late: 延後{minutes} onTime: 準時 scheduled: 預定 - ResultsError: - backToSearch: 返回搜尋 ResultsHeader: noTripFound: 找不到行程 tripsFound: 我們找到了{count} 個選項 waiting: 等待中…… - RouteDetails: - headsignTo: "{headsign} ({lastStop})" - moreDetails: 更多詳細資訊 - operatedBy: 由{agencyName}營運 - selectADirection: 選取方向…… - stopsTo: 朝向 RouteViewer: - agencyFilter: 機構篩選 allAgencies: 所有機構 allModes: 所有模式 - details: " " + details: ' ' findARoute: 尋找路線 header: 路線檢視器 modeFilter: 模式篩選 noFilteredRoutesFound: 沒有路線符合您的篩選條件! + agencyFilter: 機構篩選 openPatternViewer: 檢視預定行程詳細資訊 shortTitle: 檢視路線 stopsInDirectionOfTravel: 此行駛方向的沿路車站: title: 路線檢視器 - SaveTripButton: - cantSaveText: 無法儲存 - cantSaveTooltip: 僅能監控包括公共交通且沒有租賃或叫車服務的預定行程。 - saveTripText: 儲存行程 - signInText: 登入以儲存行程 - signInTooltip: 請登入以儲存行程。 - SavedTripEditor: - editSavedTrip: 編輯儲存的行程 - saveNewTrip: 儲存新行程 - tripInformation: 行程資訊 - tripNotFound: 找不到行程 - tripNotFoundDescription: 很抱歉,找不到請求的行程。 - tripNotifications: 行程通知 SavedTripList: fromTo: 從 {from} 到 {to} myTrips: 我的行程 @@ -436,19 +313,6 @@ components: noSavedTripsInstructions: 請先從地圖進行行程搜尋。 pause: 暫停 resume: 繼續 - SavedTripScreen: - itineraryLoaded: 路線已載入 - itineraryLoading: 正在載入路線 - tooManyTrips: | - 您已經達到五個儲存行程上限。請將未使用的行程從已儲存行程中移除,然後再試一次。 - tripNameAlreadyUsed: 已經有另一個儲存的行程使用此名稱。請選擇其他名稱。 - tripNameRequired: 請輸入行程名稱。 - SequentialPaneDisplay: - stepNumber: 第{step}步,共{total}步 - SessionTimeout: - body: 您的工作階段將在一分鐘內失效。請按下「Continue Session」(繼續工作階段) 以保留搜尋。 - header: 工作階段即將逾時! - keepSession: 繼續工作階段 SimpleRealtimeAnnotation: usingRealtimeInfo: 此行程使用即時交通和延誤資訊。 StackedPaneDisplay: @@ -458,19 +322,15 @@ components: departure: 出發 destination: 至 route: 路線 - StopTimeCell: - imminentArrival: 到 - realtime: 依據即時資料 - scheduled: 依據排程資料 StopViewer: displayStopId: 車站ID:{stopId} findSchedule: 依日期尋找排程 - flexStop: 這是彈性車站。車輛將依要求在彈性區域讓乘客上下車。您在此地區可能需要事先呼叫服務。 forStop: 針對 {stopName} + flexStop: 這是彈性車站。車輛將依要求在彈性區域讓乘客上下車。您在此地區可能需要事先呼叫服務。 header: 車站檢視器 loadingText: 正在載入車站…… noStopsFound: 此日期找不到車站時間。 - operatorLogoAriaLabel: "{operatorName} 車站:" + operatorLogoAriaLabel: '{operatorName} 車站:' schedule: 時程表 timezoneWarning: 出發時間是以{timezoneCode}顯示。 titleBarStopId: 車站{stopId} @@ -478,30 +338,28 @@ components: viewSchedule: 檢視時程 zoomToStop: 縮放到車站 SubNav: - languageSelector: 選取語言 - languages: 語言 - myAccount: 我的帳戶 selectALanguage: 選取語言 settings: 設定 trips: 行程 userMenu: 設定檔選項 + languageSelector: 選取語言 + languages: 語言 + myAccount: 我的帳戶 SwitchButton: defaultContent: 切換 switchLocations: 切換位置 TermsOfUsePane: - confirmDeletionPrompt: | - 如果移除您對儲存歷史行程的同意,將導致系統刪除您的行程記錄。確定要繼續嗎? mustAgreeToTerms: 您必須同意服務條款才能繼續。 - termsOfServiceStatement: | - 我確認我已年滿18歲,且我以閱讀並同意使用行程規劃器的服務條款。 - termsOfStorageStatement: > - 選擇性:我同意行程規劃器儲存我的歷史規劃行程,以改善我所在地區的公共交通服務。更多資訊…… + termsOfServiceStatement: "我確認我已年滿18歲,且我以閱讀並同意使用行程規劃器的服務條款。\n" + termsOfStorageStatement: "選擇性:我同意行程規劃器儲存我的歷史規劃行程,以改善我所在地區的公共交通服務。更多資訊……\n" + confirmDeletionPrompt: "如果移除您對儲存歷史行程的同意,將導致系統刪除您的行程記錄。確定要繼續嗎?\n" TransitVehicleOverlay: + travelingAt: 以{milesPerHour}前進 + vehicleName: 車輛{vehicleNumber} in_transit_to: 下一個車站:{stop} incoming_at: 即將抵達:{stop} stopped_at: 車門將在{stop}開啟 - travelingAt: 以{milesPerHour}前進 - vehicleName: 車輛{vehicleNumber} TripBasicsPane: checkingItineraryExistence: 正在檢查一週中每一天是否存在預定行程…… tripDaysPrompt: 您在哪些日子使用此行程? @@ -512,20 +370,15 @@ components: unsavedChangesNewTrip: 您尚未儲存新的行程。如果離開,該行程就會遺失。 TripNotificationsPane: advancedSettings: 進階設定 + notifyViaChannelWhen: 以下情形時透過{channel}通知我: altRouteRecommended: 建議使用備選方案路線或轉乘點 delaysAboveThreshold: 延誤或中斷超過 - howToReceiveAlerts: | - 若要針對您儲存的行程接收警示,請在帳戶設定中啟用通知,然後嘗試再次儲存行程。 + howToReceiveAlerts: "若要針對您儲存的行程接收警示,請在帳戶設定中啟用通知,然後嘗試再次儲存行程。\n" monitorThisTrip: 開始前先監控此行程: notificationsTurnedOff: 您的帳戶已關閉通知。 - notifyViaChannelWhen: 以下情形時透過{channel}通知我: oneHour: 1小時 realtimeAlertFlagged: 我的旅程上有一個即時警示標記 - timeBefore: "{time} 之前" - TripStatus: - alerts: "{alerts}個警示!" - deleteTrip: 刪除行程 - planNewTrip: 規劃新行程 + timeBefore: '{time} 之前' TripStatusRenderers: active: delayedHeading: 行程正在進行中,而且已延誤{formattedDuration}! @@ -534,23 +387,21 @@ components: noDataHeading: 行程正在進行中 (沒有可用的即時更新)。 onTimeHeading: 行程正在進行中,而且大約準時。 base: - lastCheckedDefaultText: 最後檢查時間未知 lastCheckedText: 最後檢查時間:{formattedDuration}前 togglePause: 暫停 tripIsNotSnoozed: 今天整天延遲 tripIsSnoozed: 取消延遲行程分析 unknownState: 未知的行程狀態 untogglePause: 繼續 + lastCheckedDefaultText: 最後檢查時間未知 inactive: description: 繼續行程監控,以查看更新的狀態 heading: 行程監控已暫停 nextTripNotPossible: - description: | - 行程規劃器無法找到您今天的行程。請嘗試重新規劃預定行程,以尋找替代路線。 + description: "行程規劃器無法找到您今天的行程。請嘗試重新規劃預定行程,以尋找替代路線。\n" heading: 行程今天不可行 noLongerPossible: - description: | - 行程規劃器無法找到您在週間任一選取日期的行程。請嘗試重新規劃預定行程,以尋找替代路線。 + description: "行程規劃器無法找到您在週間任一選取日期的行程。請嘗試重新規劃預定行程,以尋找替代路線。\n" heading: 行程已不再可行 notCalculated: awaiting: 正在等待計算…… @@ -560,112 +411,229 @@ components: description: 取消延遲行程監控,以查看更新的狀態。 heading: 已為今天延遲行程監控 upcoming: - nextTripBegins: >- - 下一個行程將在{tripDatetime, date, ::eeeee yyyyMMdd}的{tripDatetime, time, - short}開始。 - tripBegins: >- - 行程預計在{tripStart, time, short}開始。(即時監控將在{monitoringStart, time, - short}開始。) + nextTripBegins: 下一個行程將在{tripDatetime, date, ::eeeee yyyyMMdd}的{tripDatetime, + time, short}開始。 + tripBegins: 行程預計在{tripStart, time, short}開始。(即時監控將在{monitoringStart, time, short}開始。) tripStartIsDelayed: 行程開始時間延誤${duration}! tripStartIsEarly: 行程開始時間比預期提早${duration}! tripStartsSoonNoUpdates: 行程即將開始 (沒有可用的即時更新)。 tripStartsSoonOnTime: 行程即將開始且大約準時。 TripSummary: - arriveAt: "抵達 " - leaveAt: "離開點 " + leaveAt: '離開點 ' + arriveAt: '抵達 ' TripSummaryPane: happensOnDays: 發生於:{days} notifications: 預定出發前{leadTimeInMinutes}分鐘 notificationsDisabled: 通知已停用 TripTools: copyLink: 複製連結 + reportEmailSubject: 回報OpenTripPlanner的問題 header: 行程工具 linkCopied: 已複製 - reportEmailSubject: 回報OpenTripPlanner的問題 - reportEmailTemplate: | - "*** 給使用者的指示 *** - 此功能可讓您透過電子郵件寄送報告給網站管理員進行審查。 - 請填寫下方的提示部分,並使用您平常的電子郵件程式寄送。 - - *** 請填寫以下內容 *** - - 遇到的問題: - - 您想要使用的行程類型 (例如步行+公共交通、自行車+公共交通、汽車+公共交通): - - *** 技術詳細資訊 ***" + reportEmailTemplate: "\"*** 給使用者的指示 ***\n此功能可讓您透過電子郵件寄送報告給網站管理員進行審查。\n 請填寫下方的提示部分,並使用您平常的電子郵件程式寄送。\n + \n*** 請填寫以下內容 *** \n \n 遇到的問題:\n \n 您想要使用的行程類型 (例如步行+公共交通、自行車+公共交通、汽車+公共交通):\n + \n*** 技術詳細資訊 ***\"\n" reportIssue: 回報問題 TripViewer: + listOfRouteStops: 此路線上的車站清單 + startOfTrip: 行程從這裡開始 accessible: 無障礙 bicyclesAllowed: 已允許 endOfTrip: 行程到此結束 header: 行程檢視器 - listOfRouteStops: 此路線上的車站清單 routeHeader: 路線:{routeShortName} {routeLongName} - startOfTrip: 行程從這裡開始 tripDescription: 在 {boardAtStop} 上車,在 {disembarkAtStop} 下車 viewStop: 檢視 UserAccountScreen: confirmDelete: 您確定要刪除使用者帳戶嗎?一旦刪除,就無法復原。 errorUpdatingProfile: 更新設定檔時發生錯誤。 fieldUpdated: 此設定已更新。 + updating: 正在更新 fields: storeTripHistory: 儲存行程歷史紀錄 - updating: 正在更新 UserSettings: - confirmDeletion: 您有儲存的最近的搜尋和/或地點。停用儲存最近的地點/搜尋將移除這些項目。是否要繼續? - favoriteStops: 最愛的車站 - myPreferences: 我的偏好 mySavedPlaces: 我的已儲存地點 (管理) noFavoriteStops: 沒有最愛的車站 recentPlaces: 最近的地點 - recentSearchSummary: "{mode},從{from}到{to}" + recentSearchSummary: '{mode},從{from}到{to}' recentSearches: 最近的搜尋 rememberSearches: 要記住最近的搜尋/地點嗎? stopId: 車站ID:{stopId} - storageDisclaimer: > - 您選擇儲存的任何偏好、地點或設定都將儲存在您瀏覽器的本機儲存空間。TriMet無法存取有關您住家、工作或任何其他位置的資訊。您可以隨時選擇不要記住最近的地點/搜尋,並清除您的已儲存住家/工作位置和最愛的車站。 - UserTripSettings: - forgetOptions: 忘記我的選項 - rememberOptions: 記住行程選項 - restoreDefaults: 還原預設值 - restoreMyDefaults: 還原我的預設值 + confirmDeletion: 您有儲存的最近的搜尋和/或地點。停用儲存最近的地點/搜尋將移除這些項目。是否要繼續? + favoriteStops: 最愛的車站 + myPreferences: 我的偏好 + storageDisclaimer: "您選擇儲存的任何偏好、地點或設定都將儲存在您瀏覽器的本機儲存空間。TriMet無法存取有關您住家、工作或任何其他位置的資訊。您可以隨時選擇不要記住最近的地點/搜尋,並清除您的已儲存住家/工作位置和最愛的車站。\n" VerifyEmailPane: - emailIsVerified: 我的電子郵件已驗證! - instructions1: | - 請查看您的電子郵件收件匣,並前往信件中的連結以驗證您的電子郵件地址,再完成帳戶設定。 instructions2: 驗證之後,請按下方按鈕以繼續。 resendVerification: 重新寄送驗證電子郵件 + emailIsVerified: 我的電子郵件已驗證! + instructions1: "請查看您的電子郵件收件匣,並前往信件中的連結以驗證您的電子郵件地址,再完成帳戶設定。\n" ViewSwitcher: nearby: 檢視附近 switcher: 切換工具 WelcomeScreen: prompt: 您想要去哪裡? + A11yPrefs: + accessibilityRoutingByDefault: 預設優先選擇無障礙行程 + AddPlaceButton: + addPlace: 新增地點 + needOriginDestination: 定義起點/目的地以新增中間地點 + tooManyPlaces: 已達到中間地點數量上限 + AdvancedOptions: + bannedRoutes: 選取禁止的路線…… + preferredRoutes: 選取首選路線…… + BatchSearchScreen: + header: 規劃您的行程 + modeSelectorLabel: 選取出行模式 + BatchSettings: + destination: 目的地 + invalidModeSelection: 無法使用所選模式規劃行程。嘗試將公共交通納入您的模式選取內容。 + origin: 起點 + planTripTooltip: 規劃行程 + validationMessage: 請定義以下欄位以規劃行程:{issues} + CallTakerPanel: + advancedOptions: 進階選項 + groupSize: 群組大小: + intermediateDestination: 輸入中間目的地 + DateTimeScreen: + header: 設定日期/時間 + DeleteUser: + deleteMyAccount: 刪除我的帳戶 + ErrorMessage: + header: 無法規劃行程 + warning: 警告 + FormNavigationButtons: + ariaLabel: 表單導航 + ItinerarySummary: + itineraryDetails: 路線詳細資訊 + minMaxFare: '{minTotalFare} - {maxTotalFare}' + LocationSearch: + enterLocation: 輸入位置 + setDestination: 設定目的地 + setOrigin: 設定起點 + MapillaryFrame: + title: 街道圖像 + MobileOptions: + header: 設定搜尋選項 + NarrativeItinerariesHeader: + changeSortDir: 變更排序方向 + howToFindResults: 要檢視結果,請參閱下方「找到的預定行程」標題。 + itinerariesFound: '{itineraryNum}個預定行程已找到' + numIssues: '{issueNum}個問題' + resultsSortedBy: 行程結果目前依{sortSelected}排序。如需變更結果的排序方式,請使用下方「排序結果」按鈕。 + searching: 正在尋找您的選項…… + selectArrivalTime: 抵達時間 + selectBest: 最佳選項 + selectCost: 費用 + selectDepartureTime: 出發時間 + selectDuration: 期間 + selectWalkTime: 步行時間 + sortResults: 對結果排序 + viewAll: 檢視所有選項 + NavLoginButton: + help: 說明 + myAccount: 我的帳戶 + signIn: 登入 + signOut: 登出 + NearbyView: + bikeRentalStation: 自行車租車站 + bikesAvailable: '{bikesAvailable}輛自行車可用' + companyBicycle: '{company} 自行車' + companyScooter: '{company} 滑板車' + error: 載入鄰近設施時發生錯誤。 + header: 檢視附近 + spacesAvailable: '{spacesAvailable} 有未佔用的空間' + NewAccountWizard: + createNewAccount: 建立新帳戶 + finish: 帳戶設定完成! + notifications: 通知偏好 + places: 新增您的位置 + verify: 驗證您的電子郵件地址 + NotFound: + description: 您要求的內容無法使用。 + header: 找不到內容 + NotificationPrefsPane: + devicesRegistered: '{count}個裝置 已註冊' + noDeviceForPush: 使用行動應用程式註冊您的裝置以存取推播通知。 + notificationChannelPrompt: 透過以下方式接收有關您已儲存之行程的通知: + Place: + deleteThisPlace: 刪除此地點 + enterAlert: "請在表單內輸入起點/目的地 (或按一下地圖來設定),然後按一下產生的標記以設定為{placeType}位置。\n" + viewStop: 檢視車站 + RealtimeAnnotation: + delaysShownInResults: "您的行程結果已依據即時資訊調整。在一般情況下,此形成使用以下路線會需要{normalDuration}:{routes}。\n" + serviceUpdate: 服務更新 + ResultsError: + backToSearch: 返回搜尋 + RouteDetails: + headsignTo: '{headsign} ({lastStop})' + moreDetails: 更多詳細資訊 + operatedBy: 由{agencyName}營運 + selectADirection: 選取方向…… + stopsTo: 朝向 + SaveTripButton: + cantSaveText: 無法儲存 + cantSaveTooltip: 僅能監控包括公共交通且沒有租賃或叫車服務的預定行程。 + saveTripText: 儲存行程 + signInText: 登入以儲存行程 + signInTooltip: 請登入以儲存行程。 + SavedTripEditor: + editSavedTrip: 編輯儲存的行程 + saveNewTrip: 儲存新行程 + tripInformation: 行程資訊 + tripNotFound: 找不到行程 + tripNotFoundDescription: 很抱歉,找不到請求的行程。 + tripNotifications: 行程通知 + SavedTripScreen: + itineraryLoaded: 路線已載入 + itineraryLoading: 正在載入路線 + tooManyTrips: "您已經達到五個儲存行程上限。請將未使用的行程從已儲存行程中移除,然後再試一次。\n" + tripNameAlreadyUsed: 已經有另一個儲存的行程使用此名稱。請選擇其他名稱。 + tripNameRequired: 請輸入行程名稱。 + SequentialPaneDisplay: + stepNumber: 第{step}步,共{total}步 + SessionTimeout: + body: 您的工作階段將在一分鐘內失效。請按下「Continue Session」(繼續工作階段) 以保留搜尋。 + header: 工作階段即將逾時! + keepSession: 繼續工作階段 + StopTimeCell: + imminentArrival: 到 + realtime: 依據即時資料 + scheduled: 依據排程資料 + TripStatus: + alerts: '{alerts}個警示!' + deleteTrip: 刪除行程 + planNewTrip: 規劃新行程 + UserTripSettings: + forgetOptions: 忘記我的選項 + rememberOptions: 記住行程選項 + restoreDefaults: 還原預設值 + restoreMyDefaults: 還原我的預設值 config: accessModes: - bicycle: 公共交通+個人自行車 - bicycle_rent: 公共交通+共享自行車 car_hail: 叫車服務 car_park: 停車轉乘 micromobility: 公共交通+個人滑板車 micromobility_rent: 公共交通+電動滑板車租賃 + bicycle: 公共交通+個人自行車 + bicycle_rent: 公共交通+共享自行車 bicycleModes: bicycle: 自有自行車 bicycle_rent: 自行車共享 + micromobilityModes: + micromobility: 自有電動滑板車 + micromobility_rent: 租賃電動滑板車 flex: both: 請查看預定行程底部以瞭解詳細資訊 call-ahead: 致電預約 continuous-dropoff: 與業者溝通車站事宜 flex-service: 彈性服務 flex-service-colon: 彈性服務: - micromobilityModes: - micromobility: 自有電動滑板車 - micromobility_rent: 租賃電動滑板車 util: state: + noTripFoundReason: 指定的最大距離內或指定的時間可能沒有公共交通服務,或是您的起點或終點可能無法安全前往。 + noTripFoundWithReason: '{noTripFound} {reason}' errorPlanningTrip: 規劃行程時發生錯誤。 - networkUnavailable: "{network}網路目前無法使用。" + networkUnavailable: '{network}網路目前無法使用。' noTripFound: 找不到行程。 noTripFoundForMode: 找不到{modes}的行程。 - noTripFoundReason: 指定的最大距離內或指定的時間可能沒有公共交通服務,或是您的起點或終點可能無法安全前往。 - noTripFoundWithReason: "{noTripFound} {reason}" From c5b1974e8590c5816c754cdced222e155ffcdec9 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:56:54 -0500 Subject: [PATCH 063/162] remove styling on d/t selector, revert checkboxes, move to one button --- .../form/advanced-settings-panel.tsx | 55 ++-------------- lib/components/form/styled.ts | 65 +++---------------- 2 files changed, 15 insertions(+), 105 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index ac8fa72a7..343877e63 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -14,23 +14,19 @@ import { ModeSetting, ModeSettingValues } from '@opentripplanner/types' -import { Search } from '@styled-icons/fa-solid/Search' import React, { RefObject, useContext } from 'react' import styled from 'styled-components' -import * as apiActions from '../../actions/api' import * as formActions from '../../actions/form' import { AppReduxState } from '../../util/state-types' import { blue, getBaseColor } from '../util/colors' import { ComponentContext } from '../../util/contexts' import { generateModeSettingValues } from '../../util/api' import PageTitle from '../util/page-title' -import toast from 'react-hot-toast' import { addCustomSettingLabels, addModeButtonIcon, - alertUserTripPlan, onSettingsUpdate, pipe, populateSettingWithIcon, @@ -54,7 +50,7 @@ const PanelOverlay = styled.div` const GlobalSettingsContainer = styled.div` display: flex; flex-direction: column; - gap: 10px; + gap: 13px; margin-bottom: 2em; ${styledCheckboxCss} @@ -75,34 +71,19 @@ const Subheader = styled.h2` ${invisibleCss} ` -const PlanTripButton = styled.button` - align-items: center; - display: flex; - justify-content: center; - gap: 0.5em; +const ReturnToTripPlanButton = styled.button` background-color: var(--main-base-color, ${blue[900]}); border: 0; - width: 47%; + width: 100%; height: 51px; color: white; font-weight: 700; -` - -const ReturnToTripPlanButton = styled(PlanTripButton)` - border: 2px solid var(--main-base-color, ${blue[900]}); - background-color: white; - color: var(--main-base-color, ${blue[900]}); -` -const ButtonContainer = styled.div` - display: flex; - justify-content: space-between; margin-top: 2em; ` const DtSelectorContainer = styled.div` padding: 1em; margin: 2em 0; - background-color: ${blue[50]}; .date-time-modal { padding: 0; @@ -123,25 +104,20 @@ const DtSelectorContainer = styled.div` const AdvancedSettingsPanel = ({ closeAdvancedSettings, - currentQuery, enabledModeButtons, innerRef, modeButtonOptions, modeSettingDefinitions, modeSettingValues, - onPlanTripClick, - routingQuery, setQueryParam }: { closeAdvancedSettings: () => void - currentQuery: any enabledModeButtons: string[] innerRef: RefObject modeButtonOptions: ModeButtonDefinition[] modeSettingDefinitions: ModeSetting[] modeSettingValues: ModeSettingValues onPlanTripClick: () => void - routingQuery: () => void setQueryParam: (evt: any) => void }): JSX.Element => { const baseColor = getBaseColor() @@ -158,16 +134,6 @@ const AdvancedSettingsPanel = ({ // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) - const planTrip = () => { - alertUserTripPlan(intl, currentQuery, onPlanTripClick, routingQuery) - closeAdvancedSettings() - } - - const closeAndAnnounce = () => { - closeAdvancedSettings() - toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' })) - } - const processSettings = (settings: ModeSetting[]) => settings.map( pipe( @@ -206,7 +172,7 @@ const AdvancedSettingsPanel = ({

{headerText}

@@ -239,15 +205,9 @@ const AdvancedSettingsPanel = ({ onSettingsUpdate(setQueryParam) )} /> - - - Back to Trip Plan - - - - - - + + Save and return + ) } @@ -277,7 +237,6 @@ const mapStateToProps = (state: AppReduxState) => { } const mapDispatchToProps = { - routingQuery: apiActions.routingQuery, setQueryParam: formActions.setQueryParam, updateQueryTimeIfLeavingNow: formActions.updateQueryTimeIfLeavingNow } diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index a0c86426a..41cf8566e 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -286,70 +286,21 @@ export const TransitionStyles = styled.div` ${transitionMixin} } ` - -const toggleTransition = css` - transition: all 150ms ease-in; -` - export const styledCheckboxCss = css` - & > div { - width: 100%; - margin-left: 0; - } - input[type='checkbox'] + label { + div { align-items: center; - display: flex; - position: relative; justify-content: space-between; - width: 100%; - &::after { - content: ''; - position: relative; - width: 33px; - height: 22px; - background-color: ${grey[600]}; - border-radius: 20px; - ${toggleTransition}; - cursor: pointer; - } - - &::before { - content: ''; - position: absolute; - width: 18px; - height: 18px; - background-color: white; - border-radius: 100%; - right: 13px; - z-index: 99; - ${toggleTransition}; - cursor: pointer; + label { + margin-bottom: 0; } - } + input[type='checkbox'] { + margin-top: 0; + order: 2; - input[type='checkbox'] { - clip: rect(0, 0, 0, 0); - height: 0; - overflow: hidden; - position: absolute; - width: 0; - - &:checked + label { - &::after { - background-color: var(--main-base-color, ${blue[700]}); - ${toggleTransition}; + &:focus-visible + label { + outline: 1px solid blue; } - - &::before { - right: 2px; - ${toggleTransition}; - box-shadow: rgba(0, 0, 0, 0.15) 0px 5px 15px 0px; - } - } - - &:focus-visible + label { - outline: 1px solid blue; } } ` From e417ac3a2040ba8e16a2f5df723c1e1388d22eff Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 6 Aug 2024 20:39:08 -0500 Subject: [PATCH 064/162] add save feedback in save button and close button --- i18n/en-US.yml | 3 +- lib/components/app/batch-routing-panel.tsx | 13 ++++-- .../form/advanced-settings-panel.tsx | 43 +++++++++++++++---- lib/components/form/styled.ts | 2 + 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index fdbcbe346..564de34be 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -196,11 +196,12 @@ components: shortTitle: Plan Trip BatchSearchScreen: advancedHeader: Advanced Preferences - closeAdvancedPreferences: Close advanced preferences header: Plan Your Trip modeOptions: Mode Options modeSelectorLabel: Select a travel mode moreOptions: More options + saveAndReturn: Save and return + saved: Saved tripOptions: Trip Options BatchSettings: destination: destination diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 9dc568f17..7ca6507de 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -6,6 +6,7 @@ import React, { Component, FormEvent } from 'react' import { advancedPanelClassName, mainPanelClassName, + transitionDelay, transitionDuration, TransitionStyles } from '../form/styled' @@ -34,7 +35,6 @@ interface Props { class BatchRoutingPanel extends Component { state = { planTripClicked: false, - reverse: false, showAdvancedModeSettings: false } @@ -80,6 +80,8 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) + const transitionDurationWithDelay = transitionDuration + transitionDelay + return ( { { () => this.setState({ showAdvancedModeSettings: true }) // eslint-disable-next-line react/jsx-curly-newline } - timeout={transitionDuration} + timeout={transitionDurationWithDelay} >
@@ -167,7 +172,7 @@ class BatchRoutingPanel extends Component {
void setQueryParam: (evt: any) => void }): JSX.Element => { + const [closingBySave, setClosingBySave] = useState(false) + const [closingByX, setClosingByX] = useState(false) const baseColor = getBaseColor() const accentColor = baseColor || blue[900] const intl = useIntl() const closeButtonText = intl.formatMessage({ - id: 'components.BatchSearchScreen.closeAdvancedPreferences' + id: 'components.BatchSearchScreen.saveAndReturn' }) const headerText = intl.formatMessage({ id: 'components.BatchSearchScreen.advancedHeader' @@ -172,10 +184,13 @@ const AdvancedSettingsPanel = ({

{headerText}

{ + setClosingByX(true) + closeAdvancedSettings() + }} title={closeButtonText} > - + {closingByX ? : } @@ -205,8 +220,20 @@ const AdvancedSettingsPanel = ({ onSettingsUpdate(setQueryParam) )} /> - - Save and return + { + setClosingBySave(true) + closeAdvancedSettings() + }} + > + {closingBySave ? ( + <> + + + + ) : ( + + )} ) diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 41cf8566e..a0056a851 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -235,6 +235,7 @@ export const StyledLocationField = styled(LocationField)` export const advancedPanelClassName = 'advanced-panel' export const mainPanelClassName = 'main-panel' export const transitionDuration = prefersReducedMotion ? 0 : 175 +export const transitionDelay = prefersReducedMotion ? 0 : 300 const wipeOffset = 7 @@ -267,6 +268,7 @@ export const TransitionStyles = styled.div` .${advancedPanelClassName}-exit-active { ${wipeOutMixin(wipeOffset)} ${transitionMixin} + transition-delay: ${transitionDelay}ms; } .${mainPanelClassName}-enter { From 62ef9a339c90e3349bc553cfc1c4d756e37f4f4c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 6 Aug 2024 20:49:39 -0500 Subject: [PATCH 065/162] some scroll + padding cleanup --- lib/components/app/batch-routing-panel.tsx | 4 ++-- lib/components/form/advanced-settings-panel.tsx | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 7ca6507de..0fb118a1f 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -176,7 +176,7 @@ class BatchRoutingPanel extends Component { >
{!activeSearch && showUserSettings && ( { className="desktop-narrative-container" style={{ flexGrow: 1, - height: '100%', + height: activeSearch ? '100%' : 'auto', overflowY: 'hidden' }} > diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 966ff5094..458f165ea 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -45,7 +45,7 @@ const PanelOverlay = styled.div` top: 0; width: 100%; z-index: 100; - overflow-y: scroll; + overflow-y: auto; ` const GlobalSettingsContainer = styled.div` @@ -92,7 +92,6 @@ const ReturnToTripPlanButton = styled.button` ` const DtSelectorContainer = styled.div` - padding: 1em; margin: 2em 0; .date-time-modal { From 0ae71aafdef09d74633af5a1cf8597a7b174808a Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 6 Aug 2024 20:50:26 -0500 Subject: [PATCH 066/162] update yarn.lock --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 3c481f59b..a96622472 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2393,7 +2393,7 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@^1.1.0": +"@opentripplanner/building-blocks@^1.0.3", "@opentripplanner/building-blocks@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== From 9d907713a9a5f8559e7963881abb3060c6a925d3 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:00:58 -0500 Subject: [PATCH 067/162] add button classname for styling --- lib/components/form/advanced-settings-panel.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 458f165ea..a76b3f85d 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -220,6 +220,7 @@ const AdvancedSettingsPanel = ({ )} /> { setClosingBySave(true) closeAdvancedSettings() From fc2a0fe7d54a3144a926d8525dda79d38be7d768 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 9 Aug 2024 17:08:06 -0500 Subject: [PATCH 068/162] update packages --- package.json | 10 ++++---- yarn.lock | 72 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 4bd463a0b..370983d21 100644 --- a/package.json +++ b/package.json @@ -44,14 +44,14 @@ "@floating-ui/react": "^0.19.2", "@opentripplanner/base-map": "^3.2.0", "@opentripplanner/building-blocks": "^1.1.0", - "@opentripplanner/core-utils": "^11.4.2", + "@opentripplanner/core-utils": "^11.4.3", "@opentripplanner/endpoints-overlay": "^2.1.1", "@opentripplanner/from-to-location-picker": "^2.1.13", "@opentripplanner/geocoder": "^3.0.1", "@opentripplanner/humanize-distance": "^1.2.0", "@opentripplanner/icons": "^2.0.11", - "@opentripplanner/itinerary-body": "^5.3.3", - "@opentripplanner/location-field": "^2.0.20", + "@opentripplanner/itinerary-body": "^5.3.5", + "@opentripplanner/location-field": "^2.0.22", "@opentripplanner/location-icon": "^1.4.1", "@opentripplanner/map-popup": "^3.1.1", "@opentripplanner/otp2-tile-overlay": "^1.0.12", @@ -61,7 +61,7 @@ "@opentripplanner/stop-viewer-overlay": "^2.0.8", "@opentripplanner/stops-overlay": "^5.3.0", "@opentripplanner/transit-vehicle-overlay": "^4.0.11", - "@opentripplanner/transitive-overlay": "^3.0.18", + "@opentripplanner/transitive-overlay": "^3.0.20", "@opentripplanner/trip-details": "^5.0.13", "@opentripplanner/trip-form": "^3.7.0-alpha.5", "@opentripplanner/trip-viewer-overlay": "^2.0.8", @@ -142,7 +142,7 @@ "@graphql-tools/schema": "^10.0.0", "@jackwilsdon/craco-use-babelrc": "^1.0.0", "@opentripplanner/scripts": "^1.2.0", - "@opentripplanner/types": "^6.5.1", + "@opentripplanner/types": "^6.5.2", "@percy/cli": "^1.20.3", "@percy/puppeteer": "^2.0.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1", diff --git a/yarn.lock b/yarn.lock index a96622472..ee53af883 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2398,7 +2398,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== -"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.4.0", "@opentripplanner/core-utils@^11.4.2": +"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.4.0": version "11.4.2" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== @@ -2416,6 +2416,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@^11.4.1", "@opentripplanner/core-utils@^11.4.3": + version "11.4.3" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.3.tgz#4655f9a3bef1977e53abd81a4a0eae966f977c60" + integrity sha512-GbvchRsLfEi9JygUx6ypU+Iqv2hELseC53yQyQ/XdnB1kcHzN71BtBbz+qpD5/jk8IuM92j1taRnGMeu5ni6yA== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.0" + "@opentripplanner/geocoder" "^3.0.0" + "@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@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.1.tgz#e7029d95bd13436aacbc6f854c243d1fcf7e8570" @@ -2460,7 +2478,7 @@ "@opentripplanner/core-utils" "^11.4.0" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@^5.2.6", "@opentripplanner/itinerary-body@^5.3.0", "@opentripplanner/itinerary-body@^5.3.3": +"@opentripplanner/itinerary-body@^5.3.0": version "5.3.3" resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.3.tgz#5202060ccd1a38fd6ed823331a00233a15305957" integrity sha512-3G0szbSObrQh3uliQI6Hx62iCqqpxvrxGo7X69r28S7s8fexoI1B/3B4lRC0D14BUUPaOisE5Rc2N10SjI6MtQ== @@ -2478,13 +2496,31 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" -"@opentripplanner/location-field@^2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.20.tgz#ade02af802ba9295aa73cabc2351da758fcfeb4d" - integrity sha512-sYiemP4v2OmNWRKh2J0soLq9EO53piuJ8I5Du8X6wUfsTIk7yFH+xVLHN1IfA3XPRHy0gE8wEAnWzhxh4Qa+NQ== +"@opentripplanner/itinerary-body@^5.3.5": + version "5.3.5" + resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.5.tgz#e31ea005f374acaf9050653d5e77464d70522fa4" + integrity sha512-Ku/KX+G1wGhNqFUTqjXLGz5cYkujEg2fdnpOhyoKayidQbux+CbX0BkpVBR7DBMkVJsN7wWUWVirfbYFBCCSdA== + dependencies: + "@opentripplanner/core-utils" "^11.4.1" + "@opentripplanner/humanize-distance" "^1.2.0" + "@opentripplanner/icons" "^2.0.10" + "@opentripplanner/location-icon" "^1.4.1" + "@styled-icons/fa-solid" "^10.34.0" + "@styled-icons/foundation" "^10.34.0" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + flat "^5.0.2" + react-animate-height "^3.0.4" + react-resize-detector "^4.2.1" + string-similarity "^4.0.4" + +"@opentripplanner/location-field@^2.0.22": + version "2.0.22" + resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.22.tgz#9ed68dee8660223d4c25ab78a19baf8cfe7d7ec2" + integrity sha512-OiowT7EJ3UWGQzseaN9oCW1BcsdA4XawQCF/AhTmpT3CUfG7SmzHe6kMcyGSKEqTRiNiJ5hBoTvR49gHdrUToQ== dependencies: "@conveyal/geocoder-arcgis-geojson" "^0.0.3" - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.4.1" "@opentripplanner/geocoder" "^3.0.0" "@opentripplanner/humanize-distance" "^1.2.0" "@opentripplanner/location-icon" "^1.4.1" @@ -2580,15 +2616,15 @@ "@opentripplanner/icons" "^2.0.10" flat "^5.0.2" -"@opentripplanner/transitive-overlay@^3.0.18": - version "3.0.18" - resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.18.tgz#c225564355125a0978061704fa4de3e899902869" - integrity sha512-zOcxhNszDg/87flr3SZ9J53YA5L0P+YFHQc/so4ceuaVXfkCkuaE6WvubG0FFM7Dj7JE+vqbjqz5bEYI6Xj8qg== +"@opentripplanner/transitive-overlay@^3.0.20": + version "3.0.20" + resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.20.tgz#ff794938bdd4a051d52a78b874fd109629740bc9" + integrity sha512-3S8LNTPhipGWLDxP3FSoVXc8ob0K8XsKLMi+NWEl2S8nxQoHAHIWZHh6uIHwOLglQNKuseyhOy9kvIT4QJJPCA== dependencies: "@mapbox/polyline" "^1.1.1" - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/core-utils" "^11.2.3" - "@opentripplanner/itinerary-body" "^5.2.6" + "@opentripplanner/base-map" "^3.1.0" + "@opentripplanner/core-utils" "^11.4.1" + "@opentripplanner/itinerary-body" "^5.3.0" "@turf/bbox" "^6.5.0" "@turf/bearing" "^6.5.0" "@turf/destination" "^6.5.0" @@ -2634,10 +2670,10 @@ "@opentripplanner/base-map" "^3.0.16" "@opentripplanner/core-utils" "^11.2.3" -"@opentripplanner/types@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.1.tgz#c19c73e051e516e187e79202de276f6ed3bbc59e" - integrity sha512-5S4otkjzlNLqcbDeMXy3Xi6tcPQgQRoyQZX+uvEdPOTzIERr7wJoltyQCBwi49GX99F+jqyRbd08TJ6SnLapbA== +"@opentripplanner/types@^6.5.2": + version "6.5.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.2.tgz#1373d738479568d880a3b13670b0ec53a1a75bd5" + integrity sha512-2qDcKOrsLoXdwjRAdi4xcdDUsZGTnwBM+vfEf8TTuuWSnA+WYav3ldlMB4sugxIdLaVKXlOfe3F5lCEh9jAHWA== "@opentripplanner/vehicle-rental-overlay@^2.1.7": version "2.1.7" From 0b27c318ad3cec4ad4bd1a621e290b316bf691a6 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:29:53 -0500 Subject: [PATCH 069/162] inline state change function --- lib/components/app/batch-routing-panel.tsx | 19 +++++++++---------- lib/components/mobile/batch-search-screen.tsx | 19 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 0fb118a1f..fa65d0471 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -61,14 +61,6 @@ class BatchRoutingPanel extends Component { this.setState({ planTripClicked: true }) } - handleOpenAdvanceSettings = () => { - this.setState({ showAdvancedModeSettings: true }) - } - - handleCloseAdvanceSettings = () => { - this.setState({ showAdvancedModeSettings: false }) - } - render() { const { activeSearch, intl, mobile, showUserSettings } = this.props const { planTripClicked } = this.state @@ -115,7 +107,10 @@ class BatchRoutingPanel extends Component { }} > this.setState({ showAdvancedModeSettings: false }) + // eslint-disable-next-line react/jsx-curly-newline + } innerRef={this._advancedSettingRef} onPlanTripClick={this.handlePlanTripClick} /> @@ -160,7 +155,11 @@ class BatchRoutingPanel extends Component { + this.setState({ + showAdvancedModeSettings: true + // eslint-disable-next-line prettier/prettier + })} />
diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 556700742..1c866eef9 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -60,14 +60,6 @@ class BatchSearchScreen extends Component { this.setState({ planTripClicked: true }) } - handleOpenAdvanceSettings = () => { - this.setState({ showAdvancedModeSettings: true }) - } - - handleCloseAdvanceSettings = () => { - this.setState({ showAdvancedModeSettings: false }) - } - render() { const { intl } = this.props const { planTripClicked, showAdvancedModeSettings } = this.state @@ -122,7 +114,11 @@ class BatchSearchScreen extends Component {
+ this.setState({ showAdvancedModeSettings: true }) + // eslint-disable-next-line react/jsx-curly-newline + } />
@@ -134,7 +130,10 @@ class BatchSearchScreen extends Component { timeout={transitionDuration} > this.setState({ showAdvancedModeSettings: false }) + // eslint-disable-next-line prettier/prettier + } innerRef={this._advancedSettingRef} onPlanTripClick={this.handlePlanTripClick} /> From af8fff5fda1bb87b526d35881bfea1432d6e1754 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:30:23 -0500 Subject: [PATCH 070/162] keep animation delay even with prefersReducedMotion --- lib/components/form/styled.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index a0056a851..c8c72d669 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -235,7 +235,7 @@ export const StyledLocationField = styled(LocationField)` export const advancedPanelClassName = 'advanced-panel' export const mainPanelClassName = 'main-panel' export const transitionDuration = prefersReducedMotion ? 0 : 175 -export const transitionDelay = prefersReducedMotion ? 0 : 300 +export const transitionDelay = 300 const wipeOffset = 7 From 8496d37e5bc10ed911ba5e7576d91139ef2a9aeb Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:47:46 -0500 Subject: [PATCH 071/162] Switch animation timing to ease-in-out --- lib/components/form/styled.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index c8c72d669..b844bb4a2 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -240,7 +240,7 @@ export const transitionDelay = 300 const wipeOffset = 7 const transitionMixin = css` - transition: all ${transitionDuration}ms ease-in; + transition: all ${transitionDuration}ms ease-in-out; ` const wipeOutMixin = (offset: number) => css` From 6bee58af160e8d8dd4c4d063bb7575097ab4c89c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 30 Aug 2024 14:54:10 -0500 Subject: [PATCH 072/162] Code cleanup --- i18n/en-US.yml | 1 + .../form/advanced-settings-button.tsx | 14 ++++----- .../form/advanced-settings-panel.tsx | 17 ++++++----- lib/components/form/batch-settings.tsx | 7 +++-- lib/components/form/styled.ts | 2 +- lib/components/form/util.tsx | 16 +++++----- lib/components/mobile/batch-search-screen.tsx | 8 ++--- yarn.lock | 29 +++++++++++++++++++ 8 files changed, 63 insertions(+), 31 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index 4720008a5..3540434a8 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -202,6 +202,7 @@ components: moreOptions: More options saveAndReturn: Save and return saved: Saved + submodeSelectorLabel: Select travel modes and submodes tripOptions: Trip Options BatchSettings: destination: destination diff --git a/lib/components/form/advanced-settings-button.tsx b/lib/components/form/advanced-settings-button.tsx index 281d535d5..4e43386bd 100644 --- a/lib/components/form/advanced-settings-button.tsx +++ b/lib/components/form/advanced-settings-button.tsx @@ -19,13 +19,11 @@ const StyledTransparentButton = styled.button` margin-bottom: 5px; ` -const AdvancedSettingsButton = ({ onClick }: Props): JSX.Element => { - return ( - - - - - ) -} +const AdvancedSettingsButton = ({ onClick }: Props): JSX.Element => ( + + + + +) export default AdvancedSettingsButton diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index a76b3f85d..04b948fb3 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -40,12 +40,12 @@ import DateTimeModal from './date-time-modal' const PanelOverlay = styled.div` height: 100%; left: 0; + overflow-y: auto; padding: 1.5em; position: absolute; top: 0; width: 100%; z-index: 100; - overflow-y: auto; ` const GlobalSettingsContainer = styled.div` @@ -65,8 +65,8 @@ const CloseButton = styled.button` const HeaderContainer = styled.div` align-items: center; display: flex; - justify-content: space-between; height: 30px; + justify-content: space-between; ` const Subheader = styled.h2` @@ -211,7 +211,9 @@ const AdvancedSettingsPanel = ({ { const urlSearchParams = new URLSearchParams(state.router.location.search) + const { modes } = state.otp.config const modeSettingValues = generateModeSettingValues( urlSearchParams, - state.otp?.modeSettingDefinitions || [], - state.otp.config.modes?.initialState?.modeSettingValues || {} + state.otp.modeSettingDefinitions || [], + modes?.initialState?.modeSettingValues || {} ) return { currentQuery: state.otp.currentQuery, @@ -255,9 +258,9 @@ const mapStateToProps = (state: AppReduxState) => { decodeQueryParams(queryParamConfig, { modeButtons: urlSearchParams.get('modeButtons') })?.modeButtons?.filter((mb): mb is string => mb !== null) || - state.otp.config?.modes?.initialState?.enabledModeButtons || + modes?.initialState?.enabledModeButtons || [], - modeButtonOptions: state.otp.config?.modes?.modeButtons || [], + modeButtonOptions: modes?.modeButtons || [], modeSettingDefinitions: state.otp?.modeSettingDefinitions || [], modeSettingValues } diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index 3ec0ac155..23bd13a6c 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -133,6 +133,7 @@ function BatchSettings({ // TODO: Typescript const mapStateToProps = (state: any) => { const urlSearchParams = new URLSearchParams(state.router.location.search) + const { modes } = state.otp.config return { activeSearch: getActiveSearch(state), currentQuery: state.otp.currentQuery, @@ -141,11 +142,11 @@ const mapStateToProps = (state: any) => { decodeQueryParams(modesQueryParamConfig, { modeButtons: urlSearchParams.get('modeButtons') })?.modeButtons || - state.otp.config?.modes?.initialState?.enabledModeButtons || + modes?.initialState?.enabledModeButtons || {}, fillModeIcons: state.otp.config.itinerary?.fillModeIcons, - modeButtonOptions: state.otp.config?.modes?.modeButtons || [], - spacedOutModeSelector: state.otp?.config?.modes?.spacedOut + modeButtonOptions: modes?.modeButtons || [], + spacedOutModeSelector: modes?.spacedOut } } diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index b844bb4a2..c567ef293 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -244,8 +244,8 @@ const transitionMixin = css` ` const wipeOutMixin = (offset: number) => css` - transform: translateX(${offset}px); opacity: 0; + transform: translateX(${offset}px); ` const wipeInMixin = css` opacity: 1; diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx index 23b5ab8fe..3caf997a8 100644 --- a/lib/components/form/util.tsx +++ b/lib/components/form/util.tsx @@ -18,9 +18,9 @@ export const modesQueryParamConfig = { modeButtons: DelimitedArrayParam } export const populateSettingWithIcon = (ModeIcon: React.ComponentType<{ mode?: string; width?: number }>) => // eslint-disable-next-line react/display-name - (msd: ModeSetting): ModeSetting => ({ - ...msd, - icon: + (modeSetting: ModeSetting): ModeSetting => ({ + ...modeSetting, + icon: }) export const addModeButtonIcon = @@ -34,17 +34,17 @@ export const addModeButtonIcon = export const addCustomSettingLabels = (intl: IntlShape) => - (msd: ModeSetting): ModeSetting => { + (modeSetting: ModeSetting): ModeSetting => { let modeLabel // If we're using route mode overrides, make sure we're using the custom mode name - if (msd.type === 'SUBMODE') { - modeLabel = msd.overrideMode || msd.addTransportMode.mode + if (modeSetting.type === 'SUBMODE') { + modeLabel = modeSetting.overrideMode || modeSetting.addTransportMode.mode return { - ...msd, + ...modeSetting, label: getFormattedMode(modeLabel, intl) } } - return msd + return modeSetting } /** diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 1c866eef9..778cade10 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -26,13 +26,13 @@ const { SET_FROM_LOCATION, SET_TO_LOCATION } = MobileScreens const MobileSearchSettings = styled.div<{ advancedPanelOpen: boolean }>` background: white; box-shadow: 3px 0px 12px #00000052; - position: fixed; - top: 50px; + height: ${(props) => + props.advancedPanelOpen ? 'calc(100% - 50px)' : '230px'}; left: 0; + position: fixed; right: 0; + top: 50px; transition: all 200ms ease; - height: ${(props) => - props.advancedPanelOpen ? 'calc(100% - 50px)' : '230px'}; /* Must appear under the 'hamburger' dropdown which has z-index of 1000. */ z-index: 999; ` diff --git a/yarn.lock b/yarn.lock index 634ff87b2..a9dca0a61 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2416,6 +2416,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@^11.4.1": + version "11.4.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.4.tgz#11c1be91a5e90afda4fc265831c761d3e044d933" + integrity sha512-WKhOuG7Q+Yxdm+P5MPmJyXndx+JUtGn44GTeilOnUqDdO8lTLTvqqt0hYeEWjA77jWP0u8tG7fAAsft8IZn2cg== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.0" + "@opentripplanner/geocoder" "^3.0.2" + "@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@^11.4.3": version "11.4.3" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.3.tgz#4655f9a3bef1977e53abd81a4a0eae966f977c60" @@ -2465,6 +2483,17 @@ isomorphic-mapzen-search "^1.6.1" lodash.memoize "^4.1.2" +"@opentripplanner/geocoder@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" + integrity sha512-pl7tCiodex0hXWKLH3WE+I+HzoSgOOWp9kR3xMcuRiE5g6k2JXNneoD/ZfSS1n6Oorxcjv3U2DbMSXT2j/39dQ== + dependencies: + "@conveyal/geocoder-arcgis-geojson" "^0.0.3" + "@conveyal/lonlat" "^1.4.1" + "@leeoniya/ufuzzy" "^1.0.14" + isomorphic-mapzen-search "^1.6.1" + lodash.memoize "^4.1.2" + "@opentripplanner/humanize-distance@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" From a32d9ee9d6e08930cf31e4a47a632010c35a079a Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Tue, 3 Sep 2024 13:30:30 -0700 Subject: [PATCH 073/162] sync sort order with departarrive --- lib/components/form/date-time-modal.js | 76 ------------- lib/components/form/date-time-modal.tsx | 107 ++++++++++++++++++ .../narrative-itineraries-header.tsx | 10 +- lib/util/config-types.ts | 6 + lib/util/state-types.ts | 16 ++- 5 files changed, 125 insertions(+), 90 deletions(-) delete mode 100644 lib/components/form/date-time-modal.js create mode 100644 lib/components/form/date-time-modal.tsx diff --git a/lib/components/form/date-time-modal.js b/lib/components/form/date-time-modal.js deleted file mode 100644 index 0936ebbe9..000000000 --- a/lib/components/form/date-time-modal.js +++ /dev/null @@ -1,76 +0,0 @@ -// TODO: TypeScript with props. -/* eslint-disable react/prop-types */ -import { connect } from 'react-redux' -import coreUtils from '@opentripplanner/core-utils' -import PropTypes from 'prop-types' -import React, { Component } from 'react' - -import { setQueryParam } from '../../actions/form' - -import { StyledDateTimeSelector } from './styled' - -class DateTimeModal extends Component { - static propTypes = { - setQueryParam: PropTypes.func - } - - render() { - const { - config, - date, - dateFormatLegacy, - departArrive, - setQueryParam, - time, - timeFormatLegacy - } = this.props - const { homeTimezone, isTouchScreenOnDesktop } = config - const touchClassName = isTouchScreenOnDesktop - ? 'with-desktop-touchscreen' - : '' - - return ( -
-
- `. - // These props are not relevant in modern browsers, - // where `` already - // formats the time|date according to the OS settings. - // eslint-disable-next-line react/jsx-sort-props - timeFormatLegacy={timeFormatLegacy} - timeZone={homeTimezone} - /> -
-
- ) - } -} - -const mapStateToProps = (state) => { - const { date, departArrive, time } = state.otp.currentQuery - const config = state.otp.config - return { - config, - date, - // This prop is for legacy browsers (see render method above). - dateFormatLegacy: coreUtils.time.getDateFormat(config), - departArrive, - time, - // This prop is for legacy browsers (see render method above). - timeFormatLegacy: coreUtils.time.getTimeFormat(config) - } -} - -const mapDispatchToProps = { - setQueryParam -} - -export default connect(mapStateToProps, mapDispatchToProps)(DateTimeModal) diff --git a/lib/components/form/date-time-modal.tsx b/lib/components/form/date-time-modal.tsx new file mode 100644 index 000000000..7f83decd9 --- /dev/null +++ b/lib/components/form/date-time-modal.tsx @@ -0,0 +1,107 @@ +// TODO: TypeScript with props. +/* eslint-disable react/prop-types */ +import { connect } from 'react-redux' +import coreUtils from '@opentripplanner/core-utils' +import React from 'react' + +import { AppConfig } from '../../util/config-types' +import { AppReduxState, FilterType, SortType } from '../../util/state-types' +import { setQueryParam } from '../../actions/form' + +import { StyledDateTimeSelector } from './styled' +import { updateItineraryFilter } from '../../actions/narrative' + +type Props = { + config: AppConfig + date: string + dateFormatLegacy?: string + departArrive: DepartArriveValue + setQueryParam: (params: any) => void + sort: SortType + time: string + timeFormatLegacy?: string + updateItineraryFilter: (payload: FilterType) => void +} + +type DepartArriveValue = 'NOW' | 'DEPART' | 'ARRIVE' + +function DateTimeModal(props: Props) { + const { + config, + date, + dateFormatLegacy, + departArrive, + setQueryParam, + sort, + time, + timeFormatLegacy, + updateItineraryFilter + } = props + const { homeTimezone, isTouchScreenOnDesktop } = config + const touchClassName = isTouchScreenOnDesktop + ? 'with-desktop-touchscreen' + : '' + + const setQueryParamMiddleware = (params: any) => { + switch (params.departArrive) { + case 'NOW': + updateItineraryFilter({ sort: { ...sort, type: 'DURATION' } }) + break + case 'DEPART': + updateItineraryFilter({ sort: { ...sort, type: 'DEPARTURETIME' } }) + break + case 'ARRIVE': + updateItineraryFilter({ sort: { ...sort, type: 'ARRIVALTIME' } }) + break + } + setQueryParam(params) + } + return ( +
+
+ `. + // These props are not relevant in modern browsers, + // where `` already + // formats the time|date according to the OS settings. + // eslint-disable-next-line react/jsx-sort-props + timeFormatLegacy={timeFormatLegacy} + timeZone={homeTimezone} + /> +
+
+ ) +} + +const mapStateToProps = (state: AppReduxState) => { + const { date, departArrive, time } = state.otp.currentQuery + const config = state.otp.config + const { sort } = state.otp.filter + return { + config, + date, + // This prop is for legacy browsers (see render method above). + // @ts-expect-error Msimatched config types + dateFormatLegacy: coreUtils.time.getDateFormat(config), + departArrive, + sort, + time, + // This prop is for legacy browsers (see render method above). + // @ts-expect-error Msimatched config types + timeFormatLegacy: coreUtils.time.getTimeFormat(config) + } +} + +const mapDispatchToProps = { + setQueryParam, + updateItineraryFilter +} + +export default connect(mapStateToProps, mapDispatchToProps)(DateTimeModal) diff --git a/lib/components/narrative/narrative-itineraries-header.tsx b/lib/components/narrative/narrative-itineraries-header.tsx index 46fe56dff..921140c09 100644 --- a/lib/components/narrative/narrative-itineraries-header.tsx +++ b/lib/components/narrative/narrative-itineraries-header.tsx @@ -46,7 +46,6 @@ export default function NarrativeItinerariesHeader({ enabledSortModes, errors, itineraries, - itinerary, itineraryIsExpanded, onSortChange, onSortDirChange, @@ -109,13 +108,6 @@ export default function NarrativeItinerariesHeader({ const sortOptionsArr = sortOptions(intl, enabledSortModes) const sortText = sortOptionsArr.find((x) => x.value === sort.type)?.text - const handleSortClick = useCallback( - (value) => { - onSortChange(value) - }, - [onSortChange] - ) - return (
handleSortClick(sortOption.value)} + onClick={() => onSortChange(sortOption.value)} role="option" > {sortOption.text} diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 3995d0ba8..761daf45e 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -356,6 +356,11 @@ export interface StopScheduleViewerConfig { showBlockIds?: boolean } +export interface DateTimeConfig { + dateFormat: string + timeFormat: string +} + /** The main application configuration object */ export interface AppConfig { accessibilityScore?: AccessibilityScoreConfig @@ -368,6 +373,7 @@ export interface AppConfig { bugsnag?: BugsnagConfig co2?: CO2Config companies?: Company[] + dateTime?: DateTimeConfig elevationProfile?: boolean extraMenuItems?: AppMenuItemConfig[] geocoder: GeocoderConfig diff --git a/lib/util/state-types.ts b/lib/util/state-types.ts index 3daba23c6..05b89d3cc 100644 --- a/lib/util/state-types.ts +++ b/lib/util/state-types.ts @@ -12,11 +12,8 @@ export interface OtpState { // TODO: Add other OTP states activeSearchId?: string config: AppConfig - filter: { - sort: { - type: string - } - } + currentQuery: any + filter: FilterType location: any overlay: any serviceTimeRange?: { @@ -28,6 +25,15 @@ export interface OtpState { ui: any // TODO } +export interface SortType { + direction: string + type: string +} + +export interface FilterType { + sort: SortType +} + export interface UserState { itineraryExistence?: ItineraryExistence localUser?: any From cc0d7e5d955c475ddbc07aa20ee5511f20993eda Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Tue, 3 Sep 2024 13:30:48 -0700 Subject: [PATCH 074/162] add datetime to example config --- example-config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/example-config.yml b/example-config.yml index 77caef21f..143084509 100644 --- a/example-config.yml +++ b/example-config.yml @@ -111,6 +111,9 @@ persistence: # iconType: 'car' # iconUrl: '' # href: '' +dateTime: + timeFormat: h:mm a + dateFormat: MM/dd/yyyy map: initLat: 45.52 From 6c01a5e066be468121964f35742bdcd7c731c39e Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Tue, 3 Sep 2024 14:07:37 -0700 Subject: [PATCH 075/162] add configuration for syncing sort --- example-config.yml | 2 ++ lib/components/form/date-time-modal.tsx | 36 ++++++++++++++----------- lib/util/config-types.ts | 1 + 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/example-config.yml b/example-config.yml index 143084509..99b64e377 100644 --- a/example-config.yml +++ b/example-config.yml @@ -414,6 +414,8 @@ itinerary: displayA11yError: false # Whether to display itinerary info in the side of the preview or next to the departure times showInlineItinerarySummary: false + # Whether to sync the sort type with the depart/arrive time in the date/time modal + syncSortWithDepartArrive: true # The sort option to use by default # Available sort options: 'BEST', 'DURATION', 'ARRIVALTIME', 'WALKTIME', 'COST', 'DEPARTURETIME' # defaultSort: "BEST" # Default diff --git a/lib/components/form/date-time-modal.tsx b/lib/components/form/date-time-modal.tsx index 7f83decd9..f97450ec2 100644 --- a/lib/components/form/date-time-modal.tsx +++ b/lib/components/form/date-time-modal.tsx @@ -2,7 +2,7 @@ /* eslint-disable react/prop-types */ import { connect } from 'react-redux' import coreUtils from '@opentripplanner/core-utils' -import React from 'react' +import React, { useCallback } from 'react' import { AppConfig } from '../../util/config-types' import { AppReduxState, FilterType, SortType } from '../../util/state-types' @@ -42,20 +42,26 @@ function DateTimeModal(props: Props) { ? 'with-desktop-touchscreen' : '' - const setQueryParamMiddleware = (params: any) => { - switch (params.departArrive) { - case 'NOW': - updateItineraryFilter({ sort: { ...sort, type: 'DURATION' } }) - break - case 'DEPART': - updateItineraryFilter({ sort: { ...sort, type: 'DEPARTURETIME' } }) - break - case 'ARRIVE': - updateItineraryFilter({ sort: { ...sort, type: 'ARRIVALTIME' } }) - break - } - setQueryParam(params) - } + const syncSortWithDepartArrive = config?.itinerary?.syncSortWithDepartArrive + const setQueryParamMiddleware = useCallback( + (params: any) => { + if (syncSortWithDepartArrive !== false) { + switch (params.departArrive) { + case 'NOW': + updateItineraryFilter({ sort: { ...sort, type: 'DURATION' } }) + break + case 'DEPART': + updateItineraryFilter({ sort: { ...sort, type: 'DEPARTURETIME' } }) + break + case 'ARRIVE': + updateItineraryFilter({ sort: { ...sort, type: 'ARRIVALTIME' } }) + break + } + } + setQueryParam(params) + }, + [setQueryParam, updateItineraryFilter, sort, syncSortWithDepartArrive] + ) return (
diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 761daf45e..eced69936 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -289,6 +289,7 @@ export interface ItineraryConfig { showPlanFirstLastButtons?: boolean showRouteFares?: boolean sortModes?: ItinerarySortOption[] + syncSortWithDepartArrive?: boolean weights?: ItineraryCostWeights } From 667e2045b7bccf8fc052747675d4f4f89adc8fe0 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 4 Sep 2024 17:10:01 -0700 Subject: [PATCH 076/162] replace isTransit() with leg.transitLeg --- .../narrative/default/itinerary-description.tsx | 2 +- .../narrative/line-itin/LegIconWithA11y.tsx | 12 ++++++++---- .../narrative/line-itin/realtime-time-column.tsx | 2 +- lib/util/itinerary.tsx | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/components/narrative/default/itinerary-description.tsx b/lib/components/narrative/default/itinerary-description.tsx index d26e348f5..2c12d358d 100644 --- a/lib/components/narrative/default/itinerary-description.tsx +++ b/lib/components/narrative/default/itinerary-description.tsx @@ -68,7 +68,7 @@ export function ItineraryDescription({ itinerary }: Props): JSX.Element { let transitMode itinerary.legs.forEach((leg) => { const { duration, mode, rentedBike, rentedVehicle } = leg - if (isTransit(mode) && duration > primaryTransitDuration) { + if (leg.transitLeg && duration > primaryTransitDuration) { primaryTransitDuration = duration // If custom TransitModes have been defined for the given mode/leg, attempt to use them, diff --git a/lib/components/narrative/line-itin/LegIconWithA11y.tsx b/lib/components/narrative/line-itin/LegIconWithA11y.tsx index ab5e8dacc..307819393 100644 --- a/lib/components/narrative/line-itin/LegIconWithA11y.tsx +++ b/lib/components/narrative/line-itin/LegIconWithA11y.tsx @@ -1,3 +1,5 @@ +import { Leg } from '@opentripplanner/types' + import { getFormattedMode } from '../../../util/i18n' import coreUtils from '@opentripplanner/core-utils' import InvisibleA11yLabel from '../../util/invisible-a11y-label' @@ -8,15 +10,17 @@ import { ComponentContext } from '../../../util/contexts' import { useIntl } from 'react-intl' -const { isTransit } = coreUtils.itinerary +type Props = { + leg: Leg +} -const LegIconWithA11y = (props: any) => { +const LegIconWithA11y = (props: Props): JSX.Element => { // @ts-expect-error No type on ComponentContext const { LegIcon } = useContext(ComponentContext) const intl = useIntl() const { leg } = props - const { mode } = leg - const ariaLabel = isTransit(mode) ? getFormattedMode(mode, intl) : null + const { mode, transitLeg } = leg + const ariaLabel = transitLeg ? getFormattedMode(mode, intl) : null return ( <> diff --git a/lib/components/narrative/line-itin/realtime-time-column.tsx b/lib/components/narrative/line-itin/realtime-time-column.tsx index 2e14834a8..f9858b038 100644 --- a/lib/components/narrative/line-itin/realtime-time-column.tsx +++ b/lib/components/narrative/line-itin/realtime-time-column.tsx @@ -33,7 +33,7 @@ function RealtimeTimeColumn({ isDestination, leg }: Props): ReactElement { } const timeMillis = isDestination ? leg.endTime : leg.startTime - const isTransitLeg = isTransit(leg.mode) + const isTransitLeg = leg.transitLeg const isRealtimeTransitLeg = isTransitLeg && leg.realTime // For non-transit legs show only the scheduled time. diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index 6cebee5b3..b6b1cb524 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -373,7 +373,7 @@ export function getTotalFare( ) { hasBikeshare = true } - if (coreUtils.itinerary.isTransit(leg.mode) && transitFare == null) { + if (leg.transitLeg && transitFare == null) { transitFareNotProvided = true } }) From cdde8115addb3b486c5106d618287ee7a9b9378e Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 4 Sep 2024 17:10:12 -0700 Subject: [PATCH 077/162] delete unused itin-summary file --- .../narrative/line-itin/itin-summary.tsx | 247 ------------------ 1 file changed, 247 deletions(-) delete mode 100644 lib/components/narrative/line-itin/itin-summary.tsx diff --git a/lib/components/narrative/line-itin/itin-summary.tsx b/lib/components/narrative/line-itin/itin-summary.tsx deleted file mode 100644 index 482aa9a72..000000000 --- a/lib/components/narrative/line-itin/itin-summary.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import { connect } from 'react-redux' -import { FareProductSelector, Itinerary, Leg } from '@opentripplanner/types' -import { FormattedMessage, FormattedNumber } from 'react-intl' -import coreUtils from '@opentripplanner/core-utils' -import React, { Component } from 'react' -import styled from 'styled-components' - -import { AppReduxState } from '../../../util/state-types' -import { ComponentContext } from '../../../util/contexts' -import { getFare } from '../../../util/itinerary' -import { GREY_ON_WHITE } from '../../util/colors' -import FormattedDuration from '../../util/formatted-duration' - -// TODO: make this a prop -const defaultRouteColor = '#008' - -const Container = styled.div` - display: ${() => (coreUtils.ui.isMobile() ? 'table' : 'none')}; - height: 60px; - margin-bottom: 15px; - padding-right: 5px; - width: 100%; -` - -const Detail = styled.div` - color: ${GREY_ON_WHITE}; - font-size: 13px; -` - -const Details = styled.div` - display: table-cell; - vertical-align: top; -` - -const Header = styled.div` - font-size: 18px; - font-weight: bold; - margin-top: -3px; -` - -const LegIconContainer = styled.div` - height: 30px; - width: 30px; -` - -const NonTransitSpacer = styled.div` - height: 30px; - overflow: hidden; -` - -const RoutePreview = styled.div` - display: inline-block; - margin-left: 8px; - vertical-align: top; -` - -const Routes = styled.div` - display: table-cell; - text-align: right; -` - -const ShortName = styled.div<{ leg: Leg }>` - background-color: ${(props) => getRouteColorForBadge(props.leg)}; - border-radius: 15px; - border: 2px solid white; - box-shadow: 0 0 0.5em #000; - color: white; - font-size: 15px; - font-weight: 500; - height: 30px; - margin-top: 6px; - overflow: hidden; - padding-top: 4px; - text-align: center; - text-overflow: ellipsis; - white-space: nowrap; - width: 30px; -` - -type Props = { - currency?: string - defaultFareType?: FareProductSelector - itinerary: Itinerary - onClick: () => void -} - -export class ItinerarySummary extends Component { - static contextType = ComponentContext - - _onSummaryClicked = (): void => { - if (typeof this.props.onClick === 'function') this.props.onClick() - } - - render(): JSX.Element { - const { defaultFareType, itinerary } = this.props - const { LegIcon } = this.context - - const { fareCurrency, maxTNCFare, minTNCFare, transitFare } = getFare( - itinerary, - defaultFareType - ) - - const minTotalFare = minTNCFare * 100 + (transitFare || 0) - const maxTotalFare = maxTNCFare * 100 + (transitFare || 0) - - const { endTime, startTime } = itinerary - - const { caloriesBurned } = - coreUtils.itinerary.calculatePhysicalActivity(itinerary) - - const minTotalFareFormatted = minTotalFare > 0 && ( - - ) - - return ( - -
- {/* Travel time in hrs/mins */} -
- -
- - {/* Duration as time range */} - - - - - {/* Fare / Calories */} - - {minTotalFare > 0 && ( - - {minTotalFare === maxTotalFare ? ( - minTotalFareFormatted - ) : ( - - ), - minTotalFare: minTotalFareFormatted - }} - /> - )} - - - )} - - - - {/* Number of transfers, if applicable */} - - - -
- - {itinerary.legs - .filter((leg: Leg) => { - return !(leg.mode === 'WALK' && itinerary.transitTime > 0) - }) - .map((leg: Leg, k: number) => { - return ( - - - - - {coreUtils.itinerary.isTransit(leg.mode) ? ( - {getRouteNameForBadge(leg)} - ) : ( - - )} - - ) - })} - -
- ) - } -} - -// Helper functions - -// Leg is any for now until types package is updated with correct Leg type -function getRouteLongName(leg: any) { - return leg.routes && leg.routes.length > 0 - ? leg.routes[0].longName - : leg.routeLongName -} - -function getRouteNameForBadge(leg: any) { - const shortName = - leg.routes && leg.routes.length > 0 - ? leg.routes[0].shortName - : leg.routeShortName - - const longName = getRouteLongName(leg) - - // check for max - if (longName && longName.toLowerCase().startsWith('max')) return null - - // check for streetcar - if (longName && longName.startsWith('Portland Streetcar')) - return longName.split('-')[1].trim().split(' ')[0] - - return shortName || longName -} - -function getRouteColorForBadge(leg: Leg): string { - return leg.routeColor ? '#' + leg.routeColor : defaultRouteColor -} - -const mapStateToProps = (state: AppReduxState) => { - return { - defaultFareType: state.otp.config.itinerary?.defaultFareType - } -} - -export default connect(mapStateToProps)(ItinerarySummary) From 4d1792ad48965d9cddfeb21025e42ff2da54edf5 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 6 Sep 2024 08:45:47 -0400 Subject: [PATCH 078/162] fix: Add new originalMode field to legs. --- lib/actions/user.js | 6 ++++++ lib/reducers/create-otp-reducer.js | 15 ++------------- lib/util/itinerary.tsx | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index ea2069d36..7c038abb9 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -5,6 +5,7 @@ import isEmpty from 'lodash.isempty' import qs from 'qs' import toast from 'react-hot-toast' +import { applyRouteModeOverrides } from '../util/itinerary' import { convertToPlace, getPersistenceMode, @@ -128,6 +129,11 @@ export function fetchMonitoredTrips() { 'GET' ) if (status === 'success') { + const { routeModeOverrides } = getState().otp.config + trips.data.forEach((trip) => { + applyRouteModeOverrides(trip.itinerary, routeModeOverrides) + }) + dispatch(setCurrentUserMonitoredTrips(trips.data)) } } diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js index 0bc899936..fa0f082ef 100644 --- a/lib/reducers/create-otp-reducer.js +++ b/lib/reducers/create-otp-reducer.js @@ -6,7 +6,7 @@ import deepmerge from 'deepmerge' import objectPath from 'object-path' import update from 'immutability-helper' -import { checkForRouteModeOverride } from '../util/config' +import { applyRouteModeOverrides } from '../util/itinerary' import { FETCH_STATUS, PERSIST_TO_LOCAL_STORAGE, @@ -311,18 +311,7 @@ function createOtpReducer(config) { response.requestId = requestId response.plan.itineraries = response.plan?.itineraries?.map( (itinerary) => { - itinerary.legs = itinerary.legs.map((leg) => { - if (leg.routeId) { - leg.mode = checkForRouteModeOverride( - { - id: leg.routeId, - mode: leg.mode - }, - state.config?.routeModeOverrides - ) - } - return leg - }) + applyRouteModeOverrides(itinerary, state.config.routeModeOverrides) return itinerary } ) diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index 6cebee5b3..6b05bc3c8 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -6,6 +6,7 @@ import hash from 'object-hash' import memoize from 'lodash.memoize' import { AppConfig, CO2Config } from './config-types' +import { checkForRouteModeOverride } from './config' import { WEEKDAYS, WEEKEND_DAYS } from './monitored-trip' export interface ItineraryStartTime { @@ -449,3 +450,28 @@ export function addSortingCosts( totalFare } } + +interface LegWithOriginalMode extends Leg { + originalMode?: string +} + +/** Applies route mode overrides to a list of itineraries. */ +export function applyRouteModeOverrides( + itinerary: Itinerary, + routeModeOverrides: Record +): void { + itinerary.legs.forEach((leg: LegWithOriginalMode) => { + // Use OTP2 leg route first, fallback on legacy leg routeId. + const routeId = leg.route?.id || leg.routeId + if (routeId) { + leg.originalMode = leg.mode + leg.mode = checkForRouteModeOverride( + { + id: routeId, + mode: leg.mode + }, + routeModeOverrides + ) + } + }) +} From 5428f46e51811cee31a201002e9be258d6b91517 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 6 Sep 2024 08:55:42 -0400 Subject: [PATCH 079/162] refactor(itinerary): Fix comment --- lib/util/itinerary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index 6b05bc3c8..a76aa4466 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -455,7 +455,7 @@ interface LegWithOriginalMode extends Leg { originalMode?: string } -/** Applies route mode overrides to a list of itineraries. */ +/** Applies route mode overrides to an itinerary. */ export function applyRouteModeOverrides( itinerary: Itinerary, routeModeOverrides: Record From 8bfd731c7e8db57511867ae95c2e6b11da0df6d5 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:04:57 -0400 Subject: [PATCH 080/162] fix(SavedTripScreen): Remove route mode overrides when saving trip. --- .../user/monitored-trip/saved-trip-screen.js | 14 +++++++++++--- lib/util/itinerary.tsx | 13 +++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js index c46c3184a..cb7f61ebe 100644 --- a/lib/components/user/monitored-trip/saved-trip-screen.js +++ b/lib/components/user/monitored-trip/saved-trip-screen.js @@ -11,8 +11,11 @@ import * as formActions from '../../../actions/form' import * as uiActions from '../../../actions/ui' import * as userActions from '../../../actions/user' import { arrayToDayFields } from '../../../util/monitored-trip' +import { + copyAndRemoveRouteModeOverrides, + getItineraryDefaultMonitoredDays +} from '../../../util/itinerary' import { getActiveItineraries, getActiveSearch } from '../../../util/state' -import { getItineraryDefaultMonitoredDays } from '../../../util/itinerary' import { RETURN_TO_CURRENT_ROUTE } from '../../../util/ui' import { TRIPS_PATH } from '../../../util/constants' import AccountPage from '../account-page' @@ -67,7 +70,7 @@ class SavedTripScreen extends Component { departureVarianceMinutesThreshold: 5, excludeFederalHolidays: true, isActive: true, - itinerary: otherItineraryProps, + itinerary: copyAndRemoveRouteModeOverrides(otherItineraryProps), leadTimeInMinutes: 30, otp2QueryParams, // when creating a monitored trip, the query params will be changed on the @@ -89,8 +92,13 @@ class SavedTripScreen extends Component { */ _updateMonitoredTrip = (monitoredTrip) => { const { createOrUpdateUserMonitoredTrip, intl, isCreating } = this.props + const tripToSave = { + ...monitoredTrip, + itinerary: copyAndRemoveRouteModeOverrides(monitoredTrip.itinerary) + } + createOrUpdateUserMonitoredTrip( - monitoredTrip, + tripToSave, isCreating, undefined, undefined, diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index a76aa4466..be5bfe172 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -475,3 +475,16 @@ export function applyRouteModeOverrides( } }) } + +/** Remove mode overrides from an itinerary */ +export function copyAndRemoveRouteModeOverrides( + itinerary: Itinerary +): Itinerary { + return { + ...itinerary, + legs: itinerary.legs.map((leg) => ({ + ...leg, + mode: leg.originalMode || leg.mode + })) + } +} From cf68453eb944d70ed90ced8747fccd1d4d9251b7 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:05:44 -0400 Subject: [PATCH 081/162] fix(DefaultRouteRenderer): Prefer OTP2 leg route data. --- lib/components/narrative/metro/default-route-renderer.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/components/narrative/metro/default-route-renderer.tsx b/lib/components/narrative/metro/default-route-renderer.tsx index c16d100ad..b1733073d 100644 --- a/lib/components/narrative/metro/default-route-renderer.tsx +++ b/lib/components/narrative/metro/default-route-renderer.tsx @@ -37,10 +37,14 @@ const DefaultRouteRenderer = ({ leg, style }: RouteRendererProps): JSX.Element => { - const routeTitle = leg.routeShortName || leg.routeLongName + const routeTitle = + leg.route?.shortName || + leg.route?.longName || + leg.routeShortName || + leg.routeLongName return ( Date: Fri, 6 Sep 2024 11:30:59 -0400 Subject: [PATCH 082/162] refactor(itinerary): Fix types --- lib/util/itinerary.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index be5bfe172..e77cf8dec 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -462,7 +462,7 @@ export function applyRouteModeOverrides( ): void { itinerary.legs.forEach((leg: LegWithOriginalMode) => { // Use OTP2 leg route first, fallback on legacy leg routeId. - const routeId = leg.route?.id || leg.routeId + const routeId = typeof leg.route === 'object' ? leg.route.id : leg.routeId if (routeId) { leg.originalMode = leg.mode leg.mode = checkForRouteModeOverride( @@ -482,7 +482,7 @@ export function copyAndRemoveRouteModeOverrides( ): Itinerary { return { ...itinerary, - legs: itinerary.legs.map((leg) => ({ + legs: itinerary.legs.map((leg: LegWithOriginalMode) => ({ ...leg, mode: leg.originalMode || leg.mode })) From 54c72078c3d884f1784ec6ff2a27b5a94500b3bb Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 6 Sep 2024 11:32:22 -0400 Subject: [PATCH 083/162] refactor(DefaultRouteRenderer): Fix types --- .../narrative/metro/default-route-renderer.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/components/narrative/metro/default-route-renderer.tsx b/lib/components/narrative/metro/default-route-renderer.tsx index b1733073d..728ae9036 100644 --- a/lib/components/narrative/metro/default-route-renderer.tsx +++ b/lib/components/narrative/metro/default-route-renderer.tsx @@ -38,13 +38,15 @@ const DefaultRouteRenderer = ({ style }: RouteRendererProps): JSX.Element => { const routeTitle = - leg.route?.shortName || - leg.route?.longName || - leg.routeShortName || - leg.routeLongName + typeof leg.route === 'object' + ? leg.route.shortName || leg.route.longName + : leg.routeShortName || leg.routeLongName return ( Date: Fri, 6 Sep 2024 13:11:59 -0400 Subject: [PATCH 084/162] set `viewedRouteStops` when route viewer is active --- lib/components/map/default-map.tsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 027462f3b..2b6cfdeec 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -267,7 +267,8 @@ class DefaultMap extends Component { setLocation, setViewedStop, vehicleRentalQuery, - vehicleRentalStations + vehicleRentalStations, + viewedRouteStops } = this.props const { getCustomMapOverlays, getTransitiveRouteLabel, ModeIcon } = this.context @@ -405,6 +406,7 @@ class DefaultMap extends Component { vectorTilesEndpoint, setLocation, setViewedStop, + viewedRouteStops, config.companies ) default: @@ -427,6 +429,19 @@ class DefaultMap extends Component { const mapStateToProps = (state) => { const activeSearch = getActiveSearch(state) + const viewedRoute = state.otp?.ui?.viewedRoute?.routeId + const nearbyViewerActive = + state.otp.ui.mainPanelContent === MainPanelContent.NEARBY_VIEW + const viewedRouteStops = + viewedRoute && !nearbyViewerActive + ? Object.entries( + state.otp?.transitIndex?.routes?.[viewedRoute]?.patterns || {} + ).reduce((acc, cur) => { + return Array.from( + new Set([...cur?.[1]?.stops.map((s) => s.id), ...acc]) + ) + }, []) + : null return { bikeRentalStations: state.otp.overlay.bikeRental.stations, @@ -438,7 +453,8 @@ const mapStateToProps = (state) => { state.otp.ui.mainPanelContent === MainPanelContent.NEARBY_VIEW, pending: activeSearch ? Boolean(activeSearch.pending) : false, query: state.otp.currentQuery, - vehicleRentalStations: state.otp.overlay.vehicleRental.stations + vehicleRentalStations: state.otp.overlay.vehicleRental.stations, + viewedRouteStops } } From 50299ab374ec0a903767d0cb483e9832eeff0040 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:44:24 -0500 Subject: [PATCH 085/162] fix(advanced-settings-panel): Replace close button with back button, make save button configurable --- example-config.yml | 3 + lib/components/app/batch-routing-panel.tsx | 16 +++++- .../form/advanced-settings-panel.tsx | 57 ++++++++++--------- lib/components/form/styled.ts | 5 +- lib/util/config-types.ts | 5 ++ 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/example-config.yml b/example-config.yml index d132b835e..d1a28456d 100644 --- a/example-config.yml +++ b/example-config.yml @@ -426,6 +426,9 @@ itinerary: # - 'DEPARTURETIME' # In the batch itinerary UI, this setting will always show both departure/arrival times alwaysShowBothTimes: false +advancedSettingsPanel: + # Show button in advanced panel that allows users to save and return + saveAndReturnButton: true # The transitOperators key is a list of transit operators that can be used to # order transit agencies when sorting by route. Also, this can optionally diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index fa65d0471..525e01fd5 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -6,7 +6,6 @@ import React, { Component, FormEvent } from 'react' import { advancedPanelClassName, mainPanelClassName, - transitionDelay, transitionDuration, TransitionStyles } from '../form/styled' @@ -34,6 +33,7 @@ interface Props { */ class BatchRoutingPanel extends Component { state = { + closeAdvancedSettingsWithDelay: false, planTripClicked: false, showAdvancedModeSettings: false } @@ -72,6 +72,9 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) + /* If there is a save button in advanced preferences, add a transition delay to allow + the saved state to be displayed to users */ + const transitionDelay = this.state.closeAdvancedSettingsWithDelay ? 300 : 0 const transitionDurationWithDelay = transitionDuration + transitionDelay return ( @@ -83,7 +86,7 @@ class BatchRoutingPanel extends Component { height: '100%' }} > - + {!this.state.showAdvancedModeSettings && (

@@ -112,7 +115,13 @@ class BatchRoutingPanel extends Component { // eslint-disable-next-line react/jsx-curly-newline } innerRef={this._advancedSettingRef} - onPlanTripClick={this.handlePlanTripClick} + setCloseAdvancedSettingsWithDelay={ + () => + this.setState({ + closeAdvancedSettingsWithDelay: true + }) + // eslint-disable-next-line react/jsx-curly-newline + } /> )} @@ -157,6 +166,7 @@ class BatchRoutingPanel extends Component { onPlanTripClick={this.handlePlanTripClick} openAdvancedSettings={() => this.setState({ + closeAdvancedSettingsWithDelay: false, showAdvancedModeSettings: true // eslint-disable-next-line prettier/prettier })} diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 04b948fb3..86b0125ec 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -4,8 +4,8 @@ import { ModeSettingRenderer, populateSettingWithValue } from '@opentripplanner/trip-form' +import { ArrowLeft } from '@styled-icons/fa-solid/ArrowLeft' import { Check } from '@styled-icons/boxicons-regular' -import { Close } from '@styled-icons/fa-solid' import { connect } from 'react-redux' import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' import { FormattedMessage, useIntl } from 'react-intl' @@ -23,7 +23,6 @@ import { AppReduxState } from '../../util/state-types' import { blue, getBaseColor } from '../util/colors' import { ComponentContext } from '../../util/contexts' import { generateModeSettingValues } from '../../util/api' -import PageTitle from '../util/page-title' import { addCustomSettingLabels, @@ -65,8 +64,8 @@ const CloseButton = styled.button` const HeaderContainer = styled.div` align-items: center; display: flex; + gap: 10px; height: 30px; - justify-content: space-between; ` const Subheader = styled.h2` @@ -118,6 +117,8 @@ const AdvancedSettingsPanel = ({ modeButtonOptions, modeSettingDefinitions, modeSettingValues, + saveAndReturnButton, + setCloseAdvancedSettingsWithDelay, setQueryParam }: { closeAdvancedSettings: () => void @@ -126,11 +127,11 @@ const AdvancedSettingsPanel = ({ modeButtonOptions: ModeButtonDefinition[] modeSettingDefinitions: ModeSetting[] modeSettingValues: ModeSettingValues - onPlanTripClick: () => void + saveAndReturnButton?: boolean + setCloseAdvancedSettingsWithDelay: () => void setQueryParam: (evt: any) => void }): JSX.Element => { const [closingBySave, setClosingBySave] = useState(false) - const [closingByX, setClosingByX] = useState(false) const baseColor = getBaseColor() const accentColor = baseColor || blue[900] @@ -179,18 +180,16 @@ const AdvancedSettingsPanel = ({ return ( - -

{headerText}

{ - setClosingByX(true) closeAdvancedSettings() }} title={closeButtonText} > - {closingByX ? : } + +

{headerText}

@@ -221,22 +220,25 @@ const AdvancedSettingsPanel = ({ onSettingsUpdate(setQueryParam) )} /> - { - setClosingBySave(true) - closeAdvancedSettings() - }} - > - {closingBySave ? ( - <> - - - - ) : ( - - )} - + {saveAndReturnButton && ( + { + await setCloseAdvancedSettingsWithDelay() + setClosingBySave(true) + closeAdvancedSettings() + }} + > + {closingBySave ? ( + <> + + + + ) : ( + + )} + + )}
) } @@ -251,6 +253,8 @@ const mapStateToProps = (state: AppReduxState) => { state.otp.modeSettingDefinitions || [], modes?.initialState?.modeSettingValues || {} ) + const saveAndReturnButton = + state.otp.config?.advancedSettingsPanel?.saveAndReturnButton return { currentQuery: state.otp.currentQuery, // TODO: Duplicated in apiv2.js @@ -262,7 +266,8 @@ const mapStateToProps = (state: AppReduxState) => { [], modeButtonOptions: modes?.modeButtons || [], modeSettingDefinitions: state.otp?.modeSettingDefinitions || [], - modeSettingValues + modeSettingValues, + saveAndReturnButton } } diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index c567ef293..5033db42f 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -235,7 +235,6 @@ export const StyledLocationField = styled(LocationField)` export const advancedPanelClassName = 'advanced-panel' export const mainPanelClassName = 'main-panel' export const transitionDuration = prefersReducedMotion ? 0 : 175 -export const transitionDelay = 300 const wipeOffset = 7 @@ -251,7 +250,7 @@ const wipeInMixin = css` opacity: 1; ` -export const TransitionStyles = styled.div` +export const TransitionStyles = styled.div<{ transitionDelay: number }>` display: contents; .${advancedPanelClassName}-enter { ${wipeOutMixin(wipeOffset)} @@ -268,7 +267,7 @@ export const TransitionStyles = styled.div` .${advancedPanelClassName}-exit-active { ${wipeOutMixin(wipeOffset)} ${transitionMixin} - transition-delay: ${transitionDelay}ms; + transition-delay: ${(props) => props.transitionDelay}ms; } .${mainPanelClassName}-enter { diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 18e27ca37..48d13fe01 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -337,6 +337,10 @@ export interface TransitOperatorConfig extends TransitOperator { routeIcons?: boolean } +export interface AdvancedSettingsPanelConfig { + saveAndReturnButton?: boolean +} + /** Route Viewer config */ export interface RouteViewerConfig { /** Whether to hide the route linear shape inside a flex zone of that route. */ @@ -360,6 +364,7 @@ export interface StopScheduleViewerConfig { /** The main application configuration object */ export interface AppConfig { accessibilityScore?: AccessibilityScoreConfig + advancedSettingsPanel?: AdvancedSettingsPanelConfig api: ApiConfig // Optional on declaration, populated with defaults in reducer if not configured. autoPlan?: boolean | AutoPlanConfig From 7bdc7a2bef2a867c93663d6b81c51e0dad1cf9fa Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:58:23 -0500 Subject: [PATCH 086/162] fix: update advanced settings props for mobile --- lib/components/mobile/batch-search-screen.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 778cade10..bd6afc9f9 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -45,6 +45,7 @@ interface Props { class BatchSearchScreen extends Component { state = { + closeAdvancedSettingsWithDelay: false, planTripClicked: false, showAdvancedModeSettings: false } @@ -63,6 +64,9 @@ class BatchSearchScreen extends Component { render() { const { intl } = this.props const { planTripClicked, showAdvancedModeSettings } = this.state + + const transitionDelay = this.state.closeAdvancedSettingsWithDelay ? 300 : 0 + const transitionDurationWithDelay = transitionDuration + transitionDelay return ( { showAdvancedModeSettings && 'advanced-mode-open' }`} > - + {!showAdvancedModeSettings && ( { { // eslint-disable-next-line prettier/prettier } innerRef={this._advancedSettingRef} - onPlanTripClick={this.handlePlanTripClick} + setCloseAdvancedSettingsWithDelay={ + () => + this.setState({ + closeAdvancedSettingsWithDelay: true + }) + // eslint-disable-next-line react/jsx-curly-newline + } /> )} From 4c68565ca8936e551fd1af938a1daffaed168fab Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:54:29 -0400 Subject: [PATCH 087/162] feat(TripPreviewLayout): Add trip preview path+UI by duplicating print layout --- lib/components/app/responsive-webapp.js | 3 +- lib/components/app/trip-preview-layout.tsx | 175 +++++++++++++++++++++ lib/util/webapp-trip-preview-routes.js | 18 +++ 3 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 lib/components/app/trip-preview-layout.tsx create mode 100644 lib/util/webapp-trip-preview-routes.js diff --git a/lib/components/app/responsive-webapp.js b/lib/components/app/responsive-webapp.js index dc7d26f72..537e13bc3 100644 --- a/lib/components/app/responsive-webapp.js +++ b/lib/components/app/responsive-webapp.js @@ -33,6 +33,7 @@ import BeforeSignInScreen from '../user/before-signin-screen' import Map from '../map/map' import MobileMain from '../mobile/main' import printRoutes from '../../util/webapp-print-routes' +import tripPreviewRoutes from '../../util/webapp-trip-preview-routes' import webAppRoutes from '../../util/webapp-routes' import withLoggedInUserSupport from '../user/with-logged-in-user-support' import withMap from '../map/with-map' @@ -43,7 +44,7 @@ import SessionTimeout from './session-timeout' const { isMobile } = coreUtils.ui -const routes = [...webAppRoutes, ...printRoutes] +const routes = [...webAppRoutes, ...printRoutes, ...tripPreviewRoutes] class ResponsiveWebapp extends Component { static propTypes = { diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx new file mode 100644 index 000000000..4b4142e11 --- /dev/null +++ b/lib/components/app/trip-preview-layout.tsx @@ -0,0 +1,175 @@ +import { Button } from 'react-bootstrap' +import { connect } from 'react-redux' +import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' +import { Itinerary } from '@opentripplanner/types' +import { Map } from '@styled-icons/fa-solid/Map' +import { Print } from '@styled-icons/fa-solid/Print' +import { Times } from '@styled-icons/fa-solid/Times' +// @ts-expect-error not typescripted yet +import PrintableItinerary from '@opentripplanner/printable-itinerary' +import React, { Component } from 'react' + +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' +import { + addPrintViewClassToRootHtml, + clearClassFromRootHtml +} from '../../util/print' +import { ComponentContext } from '../../util/contexts' +import { getActiveItinerary, getActiveSearch } from '../../util/state' +import { IconWithText } from '../util/styledIcon' +import { summarizeQuery } from '../form/user-settings-i18n' +import DefaultMap from '../map/default-map' +import PageTitle from '../util/page-title' +import SpanWithSpace from '../util/span-with-space' +import TripDetails from '../narrative/connected-trip-details' + +type Props = { + // TODO: Typescript activeSearch type + activeSearch: any + // TODO: Typescript config type + config: any + currentQuery: any + intl: IntlShape + itinerary: Itinerary + location?: { search?: string } + parseUrlQueryString: (params?: any, source?: string) => any + // TODO: Typescript user type + user: any +} + +type State = { + mapVisible?: boolean +} + +class TripPreviewLayout extends Component { + static contextType = ComponentContext + + constructor(props: Props) { + super(props) + this.state = { + mapVisible: true + } + } + + _toggleMap = () => { + this.setState({ mapVisible: !this.state.mapVisible }) + } + + _print = () => { + window.print() + } + + _close = () => { + window.location.replace(String(window.location).replace('print/', '')) + } + + componentDidMount() { + const { itinerary, location, parseUrlQueryString } = this.props + + // Add print-view class to html tag to ensure that iOS scroll fix only applies + // to non-print views. + addPrintViewClassToRootHtml() + // Parse the URL query parameters, if present + if (!itinerary && location && location.search) { + parseUrlQueryString() + } + + // TODO: use currentQuery to pan/zoom to the correct part of the map + } + + componentWillUnmount() { + clearClassFromRootHtml() + } + + render() { + const { activeSearch, config, intl, itinerary, user } = this.props + const { LegIcon } = this.context + const printVerb = intl.formatMessage({ id: 'common.forms.print' }) + + return ( +
+ + {/* The header bar, including the Toggle Map and Print buttons */} +
+
+ + + + + + + +
+ +
+ + {/* The map, if visible */} + {this.state.mapVisible && ( +
+ {/* FIXME: Improve reframing/setting map bounds when itinerary is received. */} + +
+ )} + + {/* The main itinerary body */} + {itinerary && ( + <> + + + + )} +
+ ) + } +} + +// connect to the redux store + +// TODO: Typescript state +const mapStateToProps = (state: any) => { + const activeSearch = getActiveSearch(state) + const { localUser, loggedInUser } = state.user + const user = loggedInUser || localUser + return { + activeSearch, + config: state.otp.config, + currentQuery: state.otp.currentQuery, + itinerary: getActiveItinerary(state) as Itinerary, + user + } +} + +const mapDispatchToProps = { + parseUrlQueryString: formActions.parseUrlQueryString, + routingQuery: apiActions.routingQuery +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(injectIntl(TripPreviewLayout)) diff --git a/lib/util/webapp-trip-preview-routes.js b/lib/util/webapp-trip-preview-routes.js new file mode 100644 index 000000000..70f35b506 --- /dev/null +++ b/lib/util/webapp-trip-preview-routes.js @@ -0,0 +1,18 @@ +import TripPreviewLayout from '../components/app/trip-preview-layout' + +/** + * Contains mapping of the component(s) to display for each URL printing route. + * + * Note: This file is separate from webapp-routes to isolate the import of printing components + * (YML file from @opentripplanner/trip-details). + * that cause build errors during the a11y test. + */ +const routes = [ + { + a11yIgnore: true, + component: TripPreviewLayout, + path: '/previewtrip/:id' + } +] + +export default routes From 36f166e5c354be7d169892aa348ebe778786c47a Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:37:29 -0400 Subject: [PATCH 088/162] refactor(TripPreviewLayout): Display trip from tripId and redux state --- lib/components/app/trip-preview-layout.tsx | 83 +++++++++++----------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index 4b4142e11..ef2b3f23a 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -1,41 +1,35 @@ import { Button } from 'react-bootstrap' import { connect } from 'react-redux' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' -import { Itinerary } from '@opentripplanner/types' import { Map } from '@styled-icons/fa-solid/Map' import { Print } from '@styled-icons/fa-solid/Print' import { Times } from '@styled-icons/fa-solid/Times' +import { withAuthenticationRequired } from '@auth0/auth0-react' // @ts-expect-error not typescripted yet import PrintableItinerary from '@opentripplanner/printable-itinerary' import React, { Component } from 'react' -import * as apiActions from '../../actions/api' -import * as formActions from '../../actions/form' import { addPrintViewClassToRootHtml, clearClassFromRootHtml } from '../../util/print' +import { AppConfig } from '../../util/config-types' +import { AppReduxState } from '../../util/state-types' import { ComponentContext } from '../../util/contexts' -import { getActiveItinerary, getActiveSearch } from '../../util/state' import { IconWithText } from '../util/styledIcon' -import { summarizeQuery } from '../form/user-settings-i18n' +import { MonitoredTrip } from '../user/types' +import { RETURN_TO_CURRENT_ROUTE } from '../../util/ui' +import AwaitingScreen from '../user/awaiting-screen' import DefaultMap from '../map/default-map' import PageTitle from '../util/page-title' import SpanWithSpace from '../util/span-with-space' import TripDetails from '../narrative/connected-trip-details' +import withLoggedInUserSupport from '../user/with-logged-in-user-support' type Props = { - // TODO: Typescript activeSearch type - activeSearch: any - // TODO: Typescript config type - config: any - currentQuery: any + config: AppConfig intl: IntlShape - itinerary: Itinerary - location?: { search?: string } - parseUrlQueryString: (params?: any, source?: string) => any - // TODO: Typescript user type - user: any + tripId: string } type State = { @@ -52,6 +46,14 @@ class TripPreviewLayout extends Component { } } + /** + * Gets the trip to view from the props. + */ + _getTripToEdit = (): MonitoredTrip => { + const { monitoredTrips, tripId } = this.props + return monitoredTrips.find((trip) => trip.id === tripId) + } + _toggleMap = () => { this.setState({ mapVisible: !this.state.mapVisible }) } @@ -64,7 +66,7 @@ class TripPreviewLayout extends Component { window.location.replace(String(window.location).replace('print/', '')) } - componentDidMount() { + componentDidUpdate() { const { itinerary, location, parseUrlQueryString } = this.props // Add print-view class to html tag to ensure that iOS scroll fix only applies @@ -83,19 +85,22 @@ class TripPreviewLayout extends Component { } render() { - const { activeSearch, config, intl, itinerary, user } = this.props + const { config, intl, monitoredTrips } = this.props const { LegIcon } = this.context const printVerb = intl.formatMessage({ id: 'common.forms.print' }) + const isAwaiting = !monitoredTrips + if (isAwaiting) { + // Flash an indication while the selected and saved user trips are being loaded. + return + } + + const monitoredTrip = this._getTripToEdit() + const itinerary = + monitoredTrip.journeyState?.matchingItinerary || monitoredTrip.itinerary return (
- + {/* The header bar, including the Toggle Map and Print buttons */}
@@ -151,25 +156,21 @@ class TripPreviewLayout extends Component { // connect to the redux store // TODO: Typescript state -const mapStateToProps = (state: any) => { - const activeSearch = getActiveSearch(state) - const { localUser, loggedInUser } = state.user - const user = loggedInUser || localUser +const mapStateToProps = (state: AppReduxState, ownProps: Props) => { + const { loggedInUserMonitoredTrips: monitoredTrips } = state.user + const tripId = ownProps.match.params.id + return { - activeSearch, config: state.otp.config, - currentQuery: state.otp.currentQuery, - itinerary: getActiveItinerary(state) as Itinerary, - user + monitoredTrips, + tripId } } -const mapDispatchToProps = { - parseUrlQueryString: formActions.parseUrlQueryString, - routingQuery: apiActions.routingQuery -} - -export default connect( - mapStateToProps, - mapDispatchToProps -)(injectIntl(TripPreviewLayout)) +export default withLoggedInUserSupport( + withAuthenticationRequired( + connect(mapStateToProps)(injectIntl(TripPreviewLayout)), + RETURN_TO_CURRENT_ROUTE + ), + true +) From 9a6cd8c8c9ede5542a10d124dc6e169f8d3728f4 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:37:20 -0400 Subject: [PATCH 089/162] feat(SavedTripList): Add link to preview trips --- .../user/monitored-trip/saved-trip-list.tsx | 31 ++++++++++++------- lib/components/user/styled.ts | 6 +++- lib/util/constants.js | 1 + 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/components/user/monitored-trip/saved-trip-list.tsx b/lib/components/user/monitored-trip/saved-trip-list.tsx index 0df5ff909..abb591300 100644 --- a/lib/components/user/monitored-trip/saved-trip-list.tsx +++ b/lib/components/user/monitored-trip/saved-trip-list.tsx @@ -1,13 +1,15 @@ import { connect } from 'react-redux' +import { Edit, Map } from '@styled-icons/fa-solid' import { FormattedMessage, injectIntl, IntlShape, useIntl } from 'react-intl' import { Panel } from 'react-bootstrap' import { TriangleExclamation } from '@styled-icons/fa-solid/TriangleExclamation' import { withAuthenticationRequired } from '@auth0/auth0-react' import React, { Component } from 'react' +import styled from 'styled-components' import * as userActions from '../../../actions/user' import { AppReduxState } from '../../../util/state-types' -import { Edit } from '@styled-icons/fa-solid' +import { ComponentContext } from '../../../util/contexts' import { IconWithText } from '../../util/styledIcon' import { MonitoredTrip } from '../types' import { @@ -19,23 +21,17 @@ import { TripPanelTitle } from '../styled' import { RETURN_TO_CURRENT_ROUTE } from '../../../util/ui' -import { TRIPS_PATH } from '../../../util/constants' +import { TRIP_PREVIEW_PATH, TRIPS_PATH } from '../../../util/constants' import AccountPage from '../account-page' import AwaitingScreen from '../awaiting-screen' import BackToTripPlanner from '../back-to-trip-planner' -import PageTitle from '../../util/page-title' - -import styled from 'styled-components' - -import withLoggedInUserSupport from '../with-logged-in-user-support' - -import getRenderData from './trip-status-rendering-strategies' import InvisibleA11yLabel from '../../util/invisible-a11y-label' - -import { ComponentContext } from '../../../util/contexts' import Link from '../../util/link' import MetroItineraryRoutes from '../../narrative/metro/metro-itinerary-routes' +import PageTitle from '../../util/page-title' +import withLoggedInUserSupport from '../with-logged-in-user-support' +import getRenderData from './trip-status-rendering-strategies' import TripSummaryPane from './trip-summary-pane' interface ItemOwnProps { @@ -111,6 +107,7 @@ class TripListItem extends Component { const from = legs[0].from const to = legs[legs.length - 1].to const editTripPath = `${TRIPS_PATH}/${trip.id}` + const previewPath = `${TRIP_PREVIEW_PATH}/${trip.id}` const { LegIcon } = this.context return ( @@ -119,6 +116,18 @@ class TripListItem extends Component { {trip.tripName} + + + + Preview Trip + {/* + div:first-child { + flex-grow: 1; + } ` export const TripPanelHeading = styled(Panel.Heading)` diff --git a/lib/util/constants.js b/lib/util/constants.js index 07f0abf3e..0c4303772 100644 --- a/lib/util/constants.js +++ b/lib/util/constants.js @@ -23,6 +23,7 @@ export const CREATE_ACCOUNT_PLACES_PATH = `${CREATE_ACCOUNT_PATH}/places` export const CREATE_TRIP_PATH = `${TRIPS_PATH}/new` export const TERMS_OF_SERVICE_PATH = '/terms-of-service' export const TERMS_OF_STORAGE_PATH = '/terms-of-storage' +export const TRIP_PREVIEW_PATH = '/previewtrip' // Contains ignored actions when determining timeout, // such as actions triggered by a timer. From dd64366e9484bccabede8185d52d0819678f5356 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:54:51 -0400 Subject: [PATCH 090/162] refactor(SavedTripList): Add trip preview i18n, combine strings --- i18n/en-US.yml | 2 ++ i18n/fr.yml | 2 ++ .../user/monitored-trip/saved-trip-list.tsx | 29 +++++++------------ 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index f03fa5bce..4a1ae407b 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -623,6 +623,8 @@ components: oneHour: 1 hour realtimeAlertFlagged: There is a realtime alert flagged on my journey timeBefore: "{time} before" + TripPreviewLayout: + previewTrip: Preview Trip TripStatus: alerts: "{alerts, plural, one {# alert!} other {# alerts!}}" deleteTrip: Delete Trip diff --git a/i18n/fr.yml b/i18n/fr.yml index 082b0e96a..bf90f8469 100644 --- a/i18n/fr.yml +++ b/i18n/fr.yml @@ -658,6 +658,8 @@ components: oneHour: 1 heure realtimeAlertFlagged: Une alerte en temps réel affecte mon trajet timeBefore: "{time} avant" + TripPreviewLayout: + previewTrip: Aperçu du trajet TripStatus: alerts: "{alerts, plural, =0 {# alerte !} one {# alerte !} other {# alertes !}}" deleteTrip: Supprimer le trajet diff --git a/lib/components/user/monitored-trip/saved-trip-list.tsx b/lib/components/user/monitored-trip/saved-trip-list.tsx index abb591300..03e33f80f 100644 --- a/lib/components/user/monitored-trip/saved-trip-list.tsx +++ b/lib/components/user/monitored-trip/saved-trip-list.tsx @@ -107,7 +107,12 @@ class TripListItem extends Component { const from = legs[0].from const to = legs[legs.length - 1].to const editTripPath = `${TRIPS_PATH}/${trip.id}` - const previewPath = `${TRIP_PREVIEW_PATH}/${trip.id}` + const editTripText = intl.formatMessage({ + id: 'components.SavedTripEditor.editSavedTrip' + }) + const previewTripText = intl.formatMessage({ + id: 'components.TripPreviewLayout.previewTrip' + }) const { LegIcon } = this.context return ( @@ -117,27 +122,15 @@ class TripListItem extends Component { {trip.tripName} - - Preview Trip - {/* + {previewTripText} - + - - - + {editTripText} From 51546dc1f07144b466e1ecac94bedc23a4cec645 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 11:47:46 -0400 Subject: [PATCH 091/162] refactor(TripPreviewLayout): Remove unneeded code --- lib/components/app/trip-preview-layout.tsx | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index ef2b3f23a..7a0ab3aba 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -3,7 +3,6 @@ import { connect } from 'react-redux' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' import { Map } from '@styled-icons/fa-solid/Map' import { Print } from '@styled-icons/fa-solid/Print' -import { Times } from '@styled-icons/fa-solid/Times' import { withAuthenticationRequired } from '@auth0/auth0-react' // @ts-expect-error not typescripted yet import PrintableItinerary from '@opentripplanner/printable-itinerary' @@ -62,20 +61,10 @@ class TripPreviewLayout extends Component { window.print() } - _close = () => { - window.location.replace(String(window.location).replace('print/', '')) - } - componentDidUpdate() { - const { itinerary, location, parseUrlQueryString } = this.props - // Add print-view class to html tag to ensure that iOS scroll fix only applies // to non-print views. addPrintViewClassToRootHtml() - // Parse the URL query parameters, if present - if (!itinerary && location && location.search) { - parseUrlQueryString() - } // TODO: use currentQuery to pan/zoom to the correct part of the map } @@ -120,13 +109,8 @@ class TripPreviewLayout extends Component { {printVerb} -
- +
{/* The map, if visible */} @@ -155,7 +139,6 @@ class TripPreviewLayout extends Component { // connect to the redux store -// TODO: Typescript state const mapStateToProps = (state: AppReduxState, ownProps: Props) => { const { loggedInUserMonitoredTrips: monitoredTrips } = state.user const tripId = ownProps.match.params.id From 662651f9dc424189065d205b6f6fb5f7dfcd2e3b Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 12:37:12 -0400 Subject: [PATCH 092/162] refactor(TripPreviewLayout): Update title --- lib/components/app/trip-preview-layout.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index 7a0ab3aba..dee0d787e 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -77,6 +77,9 @@ class TripPreviewLayout extends Component { const { config, intl, monitoredTrips } = this.props const { LegIcon } = this.context const printVerb = intl.formatMessage({ id: 'common.forms.print' }) + const previewTripText = intl.formatMessage({ + id: 'components.TripPreviewLayout.previewTrip' + }) const isAwaiting = !monitoredTrips if (isAwaiting) { // Flash an indication while the selected and saved user trips are being loaded. @@ -89,7 +92,7 @@ class TripPreviewLayout extends Component { return (
- + {/* The header bar, including the Toggle Map and Print buttons */}
@@ -110,7 +113,7 @@ class TripPreviewLayout extends Component {
- + {previewTripText}
{/* The map, if visible */} From f2057efa2d202999eea922169413fe62706f36f5 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:08:47 -0400 Subject: [PATCH 093/162] refactor(SimpleMap): Introduce component, use with TripPreviewLayout. --- lib/components/app/trip-preview-layout.tsx | 5 +- lib/components/map/simple-map.tsx | 95 ++++++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 lib/components/map/simple-map.tsx diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index dee0d787e..30f3df206 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -19,8 +19,8 @@ import { IconWithText } from '../util/styledIcon' import { MonitoredTrip } from '../user/types' import { RETURN_TO_CURRENT_ROUTE } from '../../util/ui' import AwaitingScreen from '../user/awaiting-screen' -import DefaultMap from '../map/default-map' import PageTitle from '../util/page-title' +import SimpleMap from '../map/simple-map' import SpanWithSpace from '../util/span-with-space' import TripDetails from '../narrative/connected-trip-details' import withLoggedInUserSupport from '../user/with-logged-in-user-support' @@ -119,8 +119,7 @@ class TripPreviewLayout extends Component { {/* The map, if visible */} {this.state.mapVisible && (
- {/* FIXME: Improve reframing/setting map bounds when itinerary is received. */} - +
)} diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx new file mode 100644 index 000000000..b7937163b --- /dev/null +++ b/lib/components/map/simple-map.tsx @@ -0,0 +1,95 @@ +import { connect } from 'react-redux' +import { GeolocateControl, NavigationControl } from 'react-map-gl' +import { Itinerary } from '@opentripplanner/types' +import { useIntl } from 'react-intl' +import BaseMap from '@opentripplanner/base-map' +import EndpointsOverlay from '@opentripplanner/endpoints-overlay' +import React, { useContext } from 'react' +import styled from 'styled-components' +import TransitiveOverlay, { + itineraryToTransitive +} from '@opentripplanner/transitive-overlay' + +import { AppConfig } from '../../util/config-types' +import { AppReduxState } from '../../util/state-types' +import { ComponentContext } from '../../util/contexts' + +interface Props { + config: AppConfig + itinerary: Itinerary +} + +const MapContainer = styled.div` + height: 100%; + width: 100%; + + .map { + height: 100%; + width: 100%; + } +` + +function noop() { + return null +} + +const DefaultMap = ({ config, itinerary }: Props): JSX.Element => { + const intl = useIntl() + const { getTransitiveRouteLabel } = useContext(ComponentContext) + const { + baseLayers, + initLat, + initLon, + initZoom, + maxZoom, + navigationControlPosition, + transitive + } = config.map || {} + const baseLayerUrls = baseLayers?.map((bl) => bl.url) + const { disableFlexArc, labeledModes, styles } = transitive || {} + const { legs } = itinerary + + return ( + + 1 ? baseLayerUrls : baseLayerUrls?.[0] + } + center={[initLat, initLon]} + mapLibreProps={{ reuseMaps: true }} + maxZoom={maxZoom} + zoom={initZoom} + > + + + + + + + + ) +} + +// connect to the redux store + +const mapStateToProps = (state: AppReduxState) => ({ + config: state.otp.config +}) + +export default connect(mapStateToProps)(DefaultMap) From ae22791ee21b8207eaccba56e587b3c7ce76f1b5 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:29:06 -0400 Subject: [PATCH 094/162] refactor: Improve types --- lib/components/app/trip-preview-layout.tsx | 17 +++++++++++------ .../map/connected-transitive-overlay.tsx | 13 ++++--------- lib/components/map/simple-map.tsx | 12 +++++------- lib/components/user/types.ts | 5 +++++ lib/util/config-types.ts | 13 ++++++++++++- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index 30f3df206..aae4bb2bf 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -3,6 +3,7 @@ import { connect } from 'react-redux' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' import { Map } from '@styled-icons/fa-solid/Map' import { Print } from '@styled-icons/fa-solid/Print' +import { RouteComponentProps } from 'react-router' import { withAuthenticationRequired } from '@auth0/auth0-react' // @ts-expect-error not typescripted yet import PrintableItinerary from '@opentripplanner/printable-itinerary' @@ -28,6 +29,7 @@ import withLoggedInUserSupport from '../user/with-logged-in-user-support' type Props = { config: AppConfig intl: IntlShape + monitoredTrips?: MonitoredTrip[] | null tripId: string } @@ -48,9 +50,9 @@ class TripPreviewLayout extends Component { /** * Gets the trip to view from the props. */ - _getTripToEdit = (): MonitoredTrip => { + _getTripToEdit = (): MonitoredTrip | undefined => { const { monitoredTrips, tripId } = this.props - return monitoredTrips.find((trip) => trip.id === tripId) + return monitoredTrips?.find((trip) => trip.id === tripId) } _toggleMap = () => { @@ -74,19 +76,19 @@ class TripPreviewLayout extends Component { } render() { - const { config, intl, monitoredTrips } = this.props + const { config, intl } = this.props const { LegIcon } = this.context const printVerb = intl.formatMessage({ id: 'common.forms.print' }) const previewTripText = intl.formatMessage({ id: 'components.TripPreviewLayout.previewTrip' }) - const isAwaiting = !monitoredTrips + const monitoredTrip = this._getTripToEdit() + const isAwaiting = !monitoredTrip if (isAwaiting) { // Flash an indication while the selected and saved user trips are being loaded. return } - const monitoredTrip = this._getTripToEdit() const itinerary = monitoredTrip.journeyState?.matchingItinerary || monitoredTrip.itinerary @@ -141,7 +143,10 @@ class TripPreviewLayout extends Component { // connect to the redux store -const mapStateToProps = (state: AppReduxState, ownProps: Props) => { +const mapStateToProps = ( + state: AppReduxState, + ownProps: Props & RouteComponentProps<{ id: string }> +) => { const { loggedInUserMonitoredTrips: monitoredTrips } = state.user const tripId = ownProps.match.params.id diff --git a/lib/components/map/connected-transitive-overlay.tsx b/lib/components/map/connected-transitive-overlay.tsx index 71af754b8..7ed9d628c 100644 --- a/lib/components/map/connected-transitive-overlay.tsx +++ b/lib/components/map/connected-transitive-overlay.tsx @@ -2,19 +2,14 @@ import { connect } from 'react-redux' import { injectIntl, IntlShape } from 'react-intl' import TransitiveCanvasOverlay from '@opentripplanner/transitive-overlay' +import { AppReduxState } from '../../util/state-types' import { getActiveLeg, getTransitiveData } from '../../util/state' +import { TransitiveConfig } from '../../util/config-types' -type Props = { - intl?: IntlShape - labeledModes?: string[] - styles?: { - labels: Record - segmentLabels: Record - } -} +type Props = TransitiveConfig & IntlShape // connect to the redux store -const mapStateToProps = (state: Record, ownProps: Props) => { +const mapStateToProps = (state: AppReduxState, ownProps: Props) => { const { labeledModes, styles } = state.otp.config.map.transitive || {} const { viewedRoute } = state.otp.ui diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index b7937163b..de7079e6a 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -35,25 +35,26 @@ function noop() { const DefaultMap = ({ config, itinerary }: Props): JSX.Element => { const intl = useIntl() + // @ts-expect-error ComponentContext not typed yet. const { getTransitiveRouteLabel } = useContext(ComponentContext) const { baseLayers, - initLat, - initLon, + initLat = 0, + initLon = 0, initZoom, maxZoom, navigationControlPosition, transitive } = config.map || {} const baseLayerUrls = baseLayers?.map((bl) => bl.url) - const { disableFlexArc, labeledModes, styles } = transitive || {} + const { disableFlexArc } = transitive || {} const { legs } = itinerary return ( 1 ? baseLayerUrls : baseLayerUrls?.[0] + (baseLayerUrls?.length || 0) > 1 ? baseLayerUrls : baseLayerUrls?.[0] } center={[initLat, initLon]} mapLibreProps={{ reuseMaps: true }} @@ -67,9 +68,6 @@ const DefaultMap = ({ config, itinerary }: Props): JSX.Element => { /> +export interface JourneyState { + matchingItinerary?: Itinerary +} + export type MonitoredTrip = Record & { arrivalVarianceMinutesThreshold: number departureVarianceMinutesThreshold: number @@ -65,6 +69,7 @@ export type MonitoredTrip = Record & { isActive: boolean itinerary: Itinerary itineraryExistence?: ItineraryExistence + journeyState?: JourneyState leadTimeInMinutes: number queryParams: string tripName: string diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 18e27ca37..f0bce5320 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -15,6 +15,7 @@ import { TransitOperator, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' +import { ControlPosition } from 'react-map-gl' import { GeocoderConfig as GeocoderConfigOtpUI } from '@opentripplanner/geocoder' /** Accessibility threshold settings */ @@ -221,6 +222,15 @@ export type SupportedOverlays = | Otp1StopsOverlayConfig | MapTileLayerConfig +export interface TransitiveConfig { + disableFlexArc?: boolean + labeledModes?: string[] + styles?: { + labels: Record + segmentLabels: Record + } +} + export interface MapConfig { autoFlyOnTripFormUpdate?: boolean baseLayers?: BaseLayerConfig[] @@ -228,8 +238,9 @@ export interface MapConfig { initLon?: number initZoom?: number maxZoom?: number - navigationControlPosition?: string + navigationControlPosition?: ControlPosition overlays?: SupportedOverlays[] + transitive?: TransitiveConfig views?: MapViewConfig[] } From 8d1da2424555da34d0f14f94fa61094cafaf1240 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:49:41 -0400 Subject: [PATCH 095/162] refactor(webapp-trip-preview-routes): Tweak comments --- lib/util/webapp-trip-preview-routes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/webapp-trip-preview-routes.js b/lib/util/webapp-trip-preview-routes.js index 70f35b506..004fd1767 100644 --- a/lib/util/webapp-trip-preview-routes.js +++ b/lib/util/webapp-trip-preview-routes.js @@ -1,9 +1,9 @@ import TripPreviewLayout from '../components/app/trip-preview-layout' /** - * Contains mapping of the component(s) to display for each URL printing route. + * Contains mapping of the component(s) to display for the trip preview URL. * - * Note: This file is separate from webapp-routes to isolate the import of printing components + * Note: This file is separate from webapp-routes to isolate the import of trip preview components * (YML file from @opentripplanner/trip-details). * that cause build errors during the a11y test. */ From af5f569ca5b8d1615c92df9817c5cf36c7c1ccd0 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:55:43 -0400 Subject: [PATCH 096/162] refactor(SimpleMap): Move container out of component --- lib/components/app/trip-preview-layout.tsx | 15 ++++- lib/components/map/simple-map.tsx | 71 +++++++++------------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index aae4bb2bf..7b0e92d4d 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -8,6 +8,7 @@ import { withAuthenticationRequired } from '@auth0/auth0-react' // @ts-expect-error not typescripted yet import PrintableItinerary from '@opentripplanner/printable-itinerary' import React, { Component } from 'react' +import styled from 'styled-components' import { addPrintViewClassToRootHtml, @@ -37,6 +38,16 @@ type State = { mapVisible?: boolean } +const MapContainer = styled.div` + height: 100%; + width: 100%; + + .map { + height: 100%; + width: 100%; + } +` + class TripPreviewLayout extends Component { static contextType = ComponentContext @@ -120,9 +131,9 @@ class TripPreviewLayout extends Component { {/* The map, if visible */} {this.state.mapVisible && ( -
+ -
+
)} {/* The main itinerary body */} diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index de7079e6a..a62aca608 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -5,7 +5,6 @@ import { useIntl } from 'react-intl' import BaseMap from '@opentripplanner/base-map' import EndpointsOverlay from '@opentripplanner/endpoints-overlay' import React, { useContext } from 'react' -import styled from 'styled-components' import TransitiveOverlay, { itineraryToTransitive } from '@opentripplanner/transitive-overlay' @@ -19,21 +18,11 @@ interface Props { itinerary: Itinerary } -const MapContainer = styled.div` - height: 100%; - width: 100%; - - .map { - height: 100%; - width: 100%; - } -` - function noop() { return null } -const DefaultMap = ({ config, itinerary }: Props): JSX.Element => { +const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { const intl = useIntl() // @ts-expect-error ComponentContext not typed yet. const { getTransitiveRouteLabel } = useContext(ComponentContext) @@ -51,36 +40,34 @@ const DefaultMap = ({ config, itinerary }: Props): JSX.Element => { const { legs } = itinerary return ( - - 1 ? baseLayerUrls : baseLayerUrls?.[0] - } - center={[initLat, initLon]} - mapLibreProps={{ reuseMaps: true }} - maxZoom={maxZoom} - zoom={initZoom} - > - - - + 1 ? baseLayerUrls : baseLayerUrls?.[0] + } + center={[initLat, initLon]} + mapLibreProps={{ reuseMaps: true }} + maxZoom={maxZoom} + zoom={initZoom} + > + + + - - - + + ) } @@ -90,4 +77,4 @@ const mapStateToProps = (state: AppReduxState) => ({ config: state.otp.config }) -export default connect(mapStateToProps)(DefaultMap) +export default connect(mapStateToProps)(SimpleMap) From 3db6d5a0a576fd0a04e3464bdc651095c0b3e7aa Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:26:10 -0500 Subject: [PATCH 097/162] Pass transit operator logos to map-popup Co-authored-by: otp-data-tools-ibi-group --- lib/components/map/default-map.tsx | 15 +++- .../util/connected-transit-operator-icons.tsx | 44 +++++++++++ .../util/transit-operator-icons.tsx | 78 +++++++++++++++++++ .../viewers/nearby/stop-card-header.tsx | 59 ++------------ 4 files changed, 142 insertions(+), 54 deletions(-) create mode 100644 lib/components/util/connected-transit-operator-icons.tsx create mode 100644 lib/components/util/transit-operator-icons.tsx diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 027462f3b..f8c0b3261 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -3,6 +3,7 @@ // @ts-nocheck 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 BaseMap from '@opentripplanner/base-map' import generateOTP2TileLayers from '@opentripplanner/otp2-tile-overlay' @@ -13,6 +14,7 @@ import { assembleBasePath, bikeRentalQuery, carRentalQuery, + findStopTimesForStop, vehicleRentalQuery } from '../../actions/api' import { ComponentContext } from '../../util/contexts' @@ -34,6 +36,7 @@ import RoutePreviewOverlay from './route-preview-overlay' import RouteViewerOverlay from './connected-route-viewer-overlay' import StopsOverlay from './connected-stops-overlay' import TransitiveOverlay from './connected-transitive-overlay' +import TransitOperatorLogos from '../util/connected-transit-operator-icons' import TransitVehicleOverlay from './connected-transit-vehicle-overlay' import TripViewerOverlay from './connected-trip-viewer-overlay' import VehicleRentalOverlay from './connected-vehicle-rental-overlay' @@ -153,6 +156,14 @@ class DefaultMap extends Component { } } + // Generate operator logos to pass through OTP tile layer to map-popup + getEntityPrefix = (entity) => { + // todo: only grab agency data, not stop times?. i'd do this by adding a new arugment to findStopTImesForStop that doesnt download all the scheeudle data. have it have a secondary graphql query that gets only fired if this random thing is set to true and then you can swap between the 2. + const stopId = entity.gtfsId + this.props.findStopTimesForStop({ date: getCurrentDate(), stopId }) + return + } + /** * Checks whether the modes have changed between old and new queries and * whether to update the map overlays accordingly (e.g., to show rental vehicle @@ -405,7 +416,8 @@ class DefaultMap extends Component { vectorTilesEndpoint, setLocation, setViewedStop, - config.companies + config.companies, + this.getEntityPrefix ) default: return null @@ -445,6 +457,7 @@ const mapStateToProps = (state) => { const mapDispatchToProps = { bikeRentalQuery, carRentalQuery, + findStopTimesForStop, getCurrentPosition, setLocation, setMapPopupLocationAndGeocode, diff --git a/lib/components/util/connected-transit-operator-icons.tsx b/lib/components/util/connected-transit-operator-icons.tsx new file mode 100644 index 000000000..c90564131 --- /dev/null +++ b/lib/components/util/connected-transit-operator-icons.tsx @@ -0,0 +1,44 @@ +import { connect } from 'react-redux' +import { TransitOperator } from '@opentripplanner/types' +import React, { Component } from 'react' + +import { AppReduxState } from '../../util/state-types' + +import { StopData } from './types' +import TransitOperatorLogos from './transit-operator-icons' + +interface Props { + stopData?: StopData + transitOperators: TransitOperator[] +} + +class ConnectedTransitOperatorLogos extends Component { + // clean this up + render() { + return ( + + ) + } +} + +const mapDispatchToProps = {} + +const mapStateToProps = ( + state: AppReduxState, + ownProps: Props & { stopId: string } +) => { + const stops = state.otp.transitIndex.stops + // clean this up + return { + stopData: stops?.[ownProps.stopId], + transitOperators: state.otp.config.transitOperators || [] + } +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(ConnectedTransitOperatorLogos) diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx new file mode 100644 index 000000000..da055121a --- /dev/null +++ b/lib/components/util/transit-operator-icons.tsx @@ -0,0 +1,78 @@ +import { MapPin } from '@styled-icons/fa-solid' +import { useIntl } from 'react-intl' +import React from 'react' +import type { TransitOperator } from '@opentripplanner/types' + +import InvisibleA11yLabel from './invisible-a11y-label' +import OperatorLogo from './operator-logo' +import type { StopData } from './types' + +const Operator = ({ operator }: { operator?: TransitOperator }) => { + const intl = useIntl() + + if (!operator) { + return null + } else { + const operatorLogoAriaLabel = intl.formatMessage( + { + id: 'components.StopViewer.operatorLogoAriaLabel' + }, + { + operatorName: operator.name + } + ) + return operator.logo ? ( + // Span with agency classname allows optional contrast/customization in user + // config for logos with poor contrast. Class name is hyphenated agency name + // e.g. "sound-transit" + + + + ) : ( + // If operator exists but logo is missing, + // we still need to announce the operator name to screen readers. + <> + + {operatorLogoAriaLabel} + + ) + } +} + +const TransitOperatorLogos = ({ + stopData, + transitOperators +}: { + stopData: StopData | undefined + transitOperators?: TransitOperator[] +}): JSX.Element => { + const agencies = + (stopData && + stopData.stoptimesForPatterns?.reduce>((prev, cur) => { + // @ts-expect-error The agency type is not yet compatible with OTP2 + const agencyGtfsId = cur.pattern.route.agency?.gtfsId + return agencyGtfsId ? prev.add(agencyGtfsId) : prev + }, new Set())) || + new Set() + + return ( + <> + {transitOperators + ?.filter((to) => Array.from(agencies).includes(to.agencyId)) + // Second pass to remove duplicates based on name + .filter( + (to, index, arr) => + index === arr.findIndex((t) => t?.name === to?.name) + ) + .map((to) => ( + + ))} + + ) +} + +export default TransitOperatorLogos diff --git a/lib/components/viewers/nearby/stop-card-header.tsx b/lib/components/viewers/nearby/stop-card-header.tsx index 045616e60..d161ba7d6 100644 --- a/lib/components/viewers/nearby/stop-card-header.tsx +++ b/lib/components/viewers/nearby/stop-card-header.tsx @@ -1,6 +1,5 @@ import { connect } from 'react-redux' import { FormattedMessage, useIntl } from 'react-intl' -import { MapPin } from '@styled-icons/fa-solid' import { Search } from '@styled-icons/fa-solid/Search' import { TransitOperator } from '@opentripplanner/types' import React, { ComponentType } from 'react' @@ -10,8 +9,8 @@ import { Icon, IconWithText } from '../../util/styledIcon' import { StopData } from '../../util/types' import InvisibleA11yLabel from '../../util/invisible-a11y-label' import Link from '../../util/link' -import OperatorLogo from '../../util/operator-logo' import Strong from '../../util/strong-text' +import TransitOperatorLogos from '../../util/transit-operator-icons' import { CardBody, CardHeader, CardTitle } from './styled' import DistanceDisplay from './distance-display' @@ -28,41 +27,6 @@ type Props = { transitOperators?: TransitOperator[] } -const Operator = ({ operator }: { operator?: TransitOperator }) => { - const intl = useIntl() - if (!operator) { - return null - } else { - const operatorLogoAriaLabel = intl.formatMessage( - { - id: 'components.StopViewer.operatorLogoAriaLabel' - }, - { - operatorName: operator.name - } - ) - return operator.logo ? ( - // Span with agency classname allows optional contrast/customization in user - // config for logos with poor contrast. Class name is hyphenated agency name - // e.g. "sound-transit" - - - - ) : ( - // If operator exists but logo is missing, - // we still need to announce the operator name to screen readers. - <> - - {operatorLogoAriaLabel} - - ) - } -} - const StopCardHeader = ({ actionIcon, actionParams, @@ -75,12 +39,7 @@ const StopCardHeader = ({ transitOperators }: Props): JSX.Element => { const intl = useIntl() - const agencies = - stopData.stoptimesForPatterns?.reduce>((prev, cur) => { - // @ts-expect-error The agency type is not yet compatible with OTP2 - const agencyGtfsId = cur.pattern.route.agency?.gtfsId - return agencyGtfsId ? prev.add(agencyGtfsId) : prev - }, new Set()) || new Set() + const zoomButtonText = onZoomClick ? intl.formatMessage({ id: 'components.StopViewer.zoomToStop' @@ -92,16 +51,10 @@ const StopCardHeader = ({ {/* @ts-expect-error The 'as' prop in styled-components is not listed for TypeScript. */} - {transitOperators - ?.filter((to) => Array.from(agencies).includes(to.agencyId)) - // Second pass to remove duplicates based on name - .filter( - (to, index, arr) => - index === arr.findIndex((t) => t?.name === to?.name) - ) - .map((to) => ( - - ))} + {stopData.name} From 7817c5b9f592a7c4d5d78999d813f28e555d515b Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:05:43 -0400 Subject: [PATCH 098/162] refactor(actions/user): Rename function and tweak comments --- lib/actions/user.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 7c038abb9..60fd42d47 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -175,8 +175,12 @@ function convertRequestToSearch(config) { } // TODO move to a utils file -function areRequestsSame(qp1, qp2) { - // Everything except modes. +/** + * Determines whether two GraphQL sets of variables are for the same trip request/search. + * Modes are excluded from the comparison because the UI triggers multiple queries + * with the same GraphQL variables but with different combinations of modes. + */ +function areRequestsSameExceptModes(qp1, qp2) { // Exclude banned/preferred/unpreferred at this time. return ( qp1.bikeReluctance === qp2.bikeReluctance && @@ -201,7 +205,10 @@ function removeDuplicateRequests(filtered, tripRequest) { if (filtered.length === 0) { filtered.push(tripRequest) } else if ( - !areRequestsSame(filtered[filtered.length - 1].query, tripRequest.query) + !areRequestsSameExceptModes( + filtered[filtered.length - 1].query, + tripRequest.query + ) ) { filtered.push(tripRequest) } else { From 23fafce32f07e0f4b059fe7adf578e27799b6cfb Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:21:02 -0500 Subject: [PATCH 099/162] Add some spacing to operator icons --- lib/components/util/operator-logo.tsx | 24 ++++++++++++++++--- .../util/transit-operator-icons.tsx | 7 +++++- lib/components/viewers/nearby/styled.tsx | 1 - 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/components/util/operator-logo.tsx b/lib/components/util/operator-logo.tsx index 420e37ce7..e7000faa0 100644 --- a/lib/components/util/operator-logo.tsx +++ b/lib/components/util/operator-logo.tsx @@ -2,21 +2,39 @@ import { TransitOperator } from '@opentripplanner/types' import React from 'react' import styled from 'styled-components' -const OperatorImg = styled.img` +const OperatorImg = styled.img<{ marginRight?: number; maxHeight?: number }>` &:not(:last-of-type) { margin-right: 0.5ch; } + margin-right: ${(props) => props.marginRight && props.marginRight}ch; + max-height: ${(props) => props.maxHeight && props.maxHeight}em; + // Make sure icons stay square + max-width: ${(props) => props.maxHeight && props.maxHeight}em; width: 25px; ` type Props = { alt?: string + marginRight?: number + maxHeight?: number operator?: TransitOperator } -const OperatorLogo = ({ alt, operator }: Props): JSX.Element | null => { +const OperatorLogo = ({ + alt, + marginRight, + maxHeight, + operator +}: Props): JSX.Element | null => { if (!operator?.logo) return null - return + return ( + + ) } export default OperatorLogo diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx index da055121a..afdcd7eab 100644 --- a/lib/components/util/transit-operator-icons.tsx +++ b/lib/components/util/transit-operator-icons.tsx @@ -30,7 +30,12 @@ const Operator = ({ operator }: { operator?: TransitOperator }) => { operator.name ? operator.name.replace(/\s+/g, '-').toLowerCase() : '' } > - + ) : ( // If operator exists but logo is missing, diff --git a/lib/components/viewers/nearby/styled.tsx b/lib/components/viewers/nearby/styled.tsx index 1ffd1dc76..d088ebbfe 100644 --- a/lib/components/viewers/nearby/styled.tsx +++ b/lib/components/viewers/nearby/styled.tsx @@ -48,7 +48,6 @@ export const CardTitle = styled.p` display: flex; font-size: 22px; font-weight: 600; - gap: 0.5ch; grid-column: 1; margin: 0; /* Prevent svg and images to be taller than the text. */ From ed5f0ad46b92ac710b956ccf09ad6b3d9ebf4054 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:32:56 -0400 Subject: [PATCH 100/162] refactor(actions/user): Use lodash.isEqual for comparison. --- lib/actions/user.js | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/lib/actions/user.js b/lib/actions/user.js index 60fd42d47..1a1e9e993 100644 --- a/lib/actions/user.js +++ b/lib/actions/user.js @@ -2,6 +2,7 @@ import { createAction } from 'redux-actions' import clone from 'clone' import coreUtils from '@opentripplanner/core-utils' import isEmpty from 'lodash.isempty' +import isEqual from 'lodash.isequal' import qs from 'qs' import toast from 'react-hot-toast' @@ -174,27 +175,18 @@ function convertRequestToSearch(config) { } } -// TODO move to a utils file /** * Determines whether two GraphQL sets of variables are for the same trip request/search. + * * Modes are excluded from the comparison because the UI triggers multiple queries * with the same GraphQL variables but with different combinations of modes. + * Modes exclusion also means that if someone makes the same search with different mode settings + * (e.g. excludes/adds transit modes), that search will also be combined with the previous ones. */ function areRequestsSameExceptModes(qp1, qp2) { - // Exclude banned/preferred/unpreferred at this time. - return ( - qp1.bikeReluctance === qp2.bikeReluctance && - qp1.carReluctance === qp2.carReluctance && - qp1.date === qp2.date && - qp1.departArrive === qp2.departArrive && - qp1.from?.name === qp2.from?.name && - qp1.departArrive === qp2.departArrive && - qp1.time === qp2.time && - qp1.to?.name === qp2.to?.name && - qp1.walkReluctance === qp2.walkReluctance && - qp1.walkSpeed === qp2.walkSpeed && - qp1.wheelchair === qp2.wheelchair - ) + const { modes: modes1, ...otherParams1 } = qp1 + const { modes: modes2, ...otherParams2 } = qp2 + return isEqual(otherParams1, otherParams2) } /** From 205a16910fb018cc8f31702fce9705f1ff1bc6d8 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:50:13 -0500 Subject: [PATCH 101/162] Create shorter query for operators --- lib/actions/apiV2.js | 50 +++++++++++++++++++++++++++--- lib/components/map/default-map.tsx | 6 +++- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index b8206e056..1ad3faff6 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -498,15 +498,13 @@ export const fetchNearby = (position, radius) => { export const findStopTimesForStop = (params) => function (dispatch, getState) { dispatch(fetchingStopTimesForStop(params)) - const { date, stopId } = params + const { date, onlyRequestForOperators, stopId } = params const timeZone = getState().otp.config.homeTimezone // Create a service date timestamp from 3:30am local. const serviceDay = getServiceStart(date, timeZone).getTime() / 1000 - return dispatch( - createGraphQLQueryAction( - `query StopTimes( + const fullStopTimesQuery = `query StopTimes( $serviceDay: Long! $stopId: String! ) { @@ -566,7 +564,49 @@ export const findStopTimesForStop = (params) => } } } - }`, + }` + + const shorterStopTimesQueryForOperators = `query StopTimes( + $serviceDay: Long! + $stopId: String! + ) { + stop(id: $stopId) { + gtfsId + code + routes { + id: gtfsId + agency { + gtfsId + name + } + patterns { + id + headsign + } + } + stoptimesForPatterns(numberOfDepartures: 100, startTime: $serviceDay, omitNonPickups: true, omitCanceled: false) { + pattern { + desc: name + headsign + id: code + route { + agency { + gtfsId + } + gtfsId + } + } + } + } + }` + + const query = onlyRequestForOperators + ? shorterStopTimesQueryForOperators + : fullStopTimesQuery + + return dispatch( + createGraphQLQueryAction( + query, { serviceDay, stopId diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index f8c0b3261..a16936c8c 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -160,7 +160,11 @@ class DefaultMap extends Component { getEntityPrefix = (entity) => { // todo: only grab agency data, not stop times?. i'd do this by adding a new arugment to findStopTImesForStop that doesnt download all the scheeudle data. have it have a secondary graphql query that gets only fired if this random thing is set to true and then you can swap between the 2. const stopId = entity.gtfsId - this.props.findStopTimesForStop({ date: getCurrentDate(), stopId }) + this.props.findStopTimesForStop({ + date: getCurrentDate(), + onlyRequestForOperators: true, + stopId + }) return } From 4a4d54c13885503b264b05a164925a9eea094b23 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:14:20 -0500 Subject: [PATCH 102/162] fix graphql query, add loading --- lib/actions/apiV2.js | 3 +- lib/components/map/default-map.tsx | 1 - .../util/connected-transit-operator-icons.tsx | 4 ++- .../util/transit-operator-icons.tsx | 29 ++++++++++++------- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 1ad3faff6..f7d220b1f 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -567,7 +567,6 @@ export const findStopTimesForStop = (params) => }` const shorterStopTimesQueryForOperators = `query StopTimes( - $serviceDay: Long! $stopId: String! ) { stop(id: $stopId) { @@ -584,7 +583,7 @@ export const findStopTimesForStop = (params) => headsign } } - stoptimesForPatterns(numberOfDepartures: 100, startTime: $serviceDay, omitNonPickups: true, omitCanceled: false) { + stoptimesForPatterns(numberOfDepartures: 100, omitNonPickups: true, omitCanceled: false) { pattern { desc: name headsign diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index a16936c8c..6abc20ad8 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -158,7 +158,6 @@ class DefaultMap extends Component { // Generate operator logos to pass through OTP tile layer to map-popup getEntityPrefix = (entity) => { - // todo: only grab agency data, not stop times?. i'd do this by adding a new arugment to findStopTImesForStop that doesnt download all the scheeudle data. have it have a secondary graphql query that gets only fired if this random thing is set to true and then you can swap between the 2. const stopId = entity.gtfsId this.props.findStopTimesForStop({ date: getCurrentDate(), diff --git a/lib/components/util/connected-transit-operator-icons.tsx b/lib/components/util/connected-transit-operator-icons.tsx index c90564131..64b804e53 100644 --- a/lib/components/util/connected-transit-operator-icons.tsx +++ b/lib/components/util/connected-transit-operator-icons.tsx @@ -3,6 +3,7 @@ import { TransitOperator } from '@opentripplanner/types' import React, { Component } from 'react' import { AppReduxState } from '../../util/state-types' +import { FETCH_STATUS } from '../../util/constants' import { StopData } from './types' import TransitOperatorLogos from './transit-operator-icons' @@ -13,10 +14,11 @@ interface Props { } class ConnectedTransitOperatorLogos extends Component { - // clean this up render() { + const loading = this.props.stopData?.fetchStatus === FETCH_STATUS.FETCHING return ( diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx index afdcd7eab..885f08b63 100644 --- a/lib/components/util/transit-operator-icons.tsx +++ b/lib/components/util/transit-operator-icons.tsx @@ -3,6 +3,8 @@ import { useIntl } from 'react-intl' import React from 'react' import type { TransitOperator } from '@opentripplanner/types' +import { InlineLoading } from '../narrative/loading' + import InvisibleA11yLabel from './invisible-a11y-label' import OperatorLogo from './operator-logo' import type { StopData } from './types' @@ -49,9 +51,11 @@ const Operator = ({ operator }: { operator?: TransitOperator }) => { } const TransitOperatorLogos = ({ + loading = false, stopData, transitOperators }: { + loading?: boolean stopData: StopData | undefined transitOperators?: TransitOperator[] }): JSX.Element => { @@ -66,16 +70,21 @@ const TransitOperatorLogos = ({ return ( <> - {transitOperators - ?.filter((to) => Array.from(agencies).includes(to.agencyId)) - // Second pass to remove duplicates based on name - .filter( - (to, index, arr) => - index === arr.findIndex((t) => t?.name === to?.name) - ) - .map((to) => ( - - ))} + {loading ? ( + <> + + + + ) : ( + transitOperators + ?.filter((to) => Array.from(agencies).includes(to.agencyId)) + // Second pass to remove duplicates based on name + .filter( + (to, index, arr) => + index === arr.findIndex((t) => t?.name === to?.name) + ) + .map((to) => ) + )} ) } From 898d4539dc1bdceaf76985fe448f873301032495 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Fri, 13 Sep 2024 16:28:39 -0400 Subject: [PATCH 103/162] deps: update otp-ui --- package.json | 44 ++++---- yarn.lock | 288 +++++++++++++++++++++++++++------------------------ 2 files changed, 177 insertions(+), 155 deletions(-) diff --git a/package.json b/package.json index 8c3c622fd..7b08da443 100644 --- a/package.json +++ b/package.json @@ -42,30 +42,30 @@ "@bugsnag/js": "^7.17.0", "@bugsnag/plugin-react": "^7.17.0", "@floating-ui/react": "^0.19.2", - "@opentripplanner/base-map": "^3.2.0", - "@opentripplanner/building-blocks": "^1.1.0", - "@opentripplanner/core-utils": "^11.4.3", - "@opentripplanner/endpoints-overlay": "^2.1.1", - "@opentripplanner/from-to-location-picker": "^2.1.13", - "@opentripplanner/geocoder": "^3.0.1", + "@opentripplanner/base-map": "^3.2.2", + "@opentripplanner/building-blocks": "^1.2.3", + "@opentripplanner/core-utils": "^11.4.4", + "@opentripplanner/endpoints-overlay": "^2.1.4", + "@opentripplanner/from-to-location-picker": "^2.1.14", + "@opentripplanner/geocoder": "^3.0.2", "@opentripplanner/humanize-distance": "^1.2.0", - "@opentripplanner/icons": "^2.0.11", - "@opentripplanner/itinerary-body": "^5.3.5", - "@opentripplanner/location-field": "^2.0.22", + "@opentripplanner/icons": "^2.0.13", + "@opentripplanner/itinerary-body": "^5.3.7", + "@opentripplanner/location-field": "^2.0.24", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "^3.1.1", - "@opentripplanner/otp2-tile-overlay": "^1.0.12", - "@opentripplanner/park-and-ride-overlay": "^2.0.8", - "@opentripplanner/printable-itinerary": "^2.0.21", - "@opentripplanner/route-viewer-overlay": "^2.0.15", - "@opentripplanner/stop-viewer-overlay": "^2.0.8", - "@opentripplanner/stops-overlay": "^5.3.0", - "@opentripplanner/transit-vehicle-overlay": "^4.0.11", - "@opentripplanner/transitive-overlay": "3.0.15", - "@opentripplanner/trip-details": "^5.0.13", - "@opentripplanner/trip-form": "^3.6.2", - "@opentripplanner/trip-viewer-overlay": "^2.0.8", - "@opentripplanner/vehicle-rental-overlay": "^2.1.7", + "@opentripplanner/map-popup": "^4.0.1", + "@opentripplanner/otp2-tile-overlay": "^1.0.16", + "@opentripplanner/park-and-ride-overlay": "^2.0.9", + "@opentripplanner/printable-itinerary": "^2.0.23", + "@opentripplanner/route-viewer-overlay": "^2.0.17", + "@opentripplanner/stop-viewer-overlay": "^2.0.10", + "@opentripplanner/stops-overlay": "^5.3.3", + "@opentripplanner/transit-vehicle-overlay": "^4.0.13", + "@opentripplanner/transitive-overlay": "3.0.22", + "@opentripplanner/trip-details": "^5.0.15", + "@opentripplanner/trip-form": "^3.6.4", + "@opentripplanner/trip-viewer-overlay": "^2.0.10", + "@opentripplanner/vehicle-rental-overlay": "^2.1.9", "@styled-icons/fa-regular": "^10.34.0", "@styled-icons/fa-solid": "^10.34.0", "@turf/centroid": "^6.5.0", diff --git a/yarn.lock b/yarn.lock index 44a964276..367b0743a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,7 +2383,7 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@^3.0.14", "@opentripplanner/base-map@^3.0.16", "@opentripplanner/base-map@^3.1.0", "@opentripplanner/base-map@^3.2.0": +"@opentripplanner/base-map@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" integrity sha512-d/yTKEnXqrw9pXhSvCERT+wLFa077Xr4wEFu4pYB+WYoZFflNxuTuAXXjm268HS/d0kjNndkjSMkxaKk6AjsvA== @@ -2393,15 +2393,25 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" - integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== +"@opentripplanner/base-map@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.2.tgz#6dc15f3af0bfe483ffea220dcd2220272fa31040" + integrity sha512-Neg+rvAr9lWx+8V8/4ZlPE+l91wxM0fbbsM5vp45L1zCRE4WszD7XtmLocnNMyuYzo3xEijoKF+ICiENsOM9bg== + dependencies: + "@opentripplanner/building-blocks" "^1.2.2" + mapbox-gl "npm:empty-npm-package@1.0.0" + maplibre-gl "^2.1.9" + react-map-gl "^7.0.15" + +"@opentripplanner/building-blocks@^1.2.2", "@opentripplanner/building-blocks@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" + integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@^11.0.2", "@opentripplanner/core-utils@^11.4.1", "@opentripplanner/core-utils@^11.4.3": - version "11.4.3" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.3.tgz#4655f9a3bef1977e53abd81a4a0eae966f977c60" - integrity sha512-GbvchRsLfEi9JygUx6ypU+Iqv2hELseC53yQyQ/XdnB1kcHzN71BtBbz+qpD5/jk8IuM92j1taRnGMeu5ni6yA== +"@opentripplanner/core-utils@^11.4.0": + version "11.4.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" + integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" @@ -2416,14 +2426,14 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.4.0": - version "11.4.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" - integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== +"@opentripplanner/core-utils@^11.4.4": + version "11.4.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.4.tgz#11c1be91a5e90afda4fc265831c761d3e044d933" + integrity sha512-WKhOuG7Q+Yxdm+P5MPmJyXndx+JUtGn44GTeilOnUqDdO8lTLTvqqt0hYeEWjA77jWP0u8tG7fAAsft8IZn2cg== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/geocoder" "^3.0.2" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" @@ -2434,19 +2444,19 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/endpoints-overlay@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.1.tgz#e7029d95bd13436aacbc6f854c243d1fcf7e8570" - integrity sha512-llBGk8eRa8JRJreMp73zWXeCzTzirBNd2N4UtK66vLL9s7YYPFm/yKGLTIKg1MRHrJ+DGpaFkEOi/ajos8YiLA== +"@opentripplanner/endpoints-overlay@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.4.tgz#f81088bce83236344dfa4a51b2efe00092a5c87a" + integrity sha512-VLRZArhoRQ38aafc/w986Uv1lnq/WLJOgBqnpvuUbLhLR/qHU9h5X3wg3jgwf2GA0BIn03Z99VJbCkGfkyd0LA== dependencies: - "@opentripplanner/base-map" "^3.1.0" - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/location-icon" "^1.4.1" - "@opentripplanner/map-popup" "^3.1.0" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" -"@opentripplanner/from-to-location-picker@^2.1.11", "@opentripplanner/from-to-location-picker@^2.1.12", "@opentripplanner/from-to-location-picker@^2.1.13": +"@opentripplanner/from-to-location-picker@^2.1.12", "@opentripplanner/from-to-location-picker@^2.1.13": version "2.1.13" resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-2.1.13.tgz#d13acd582929175c676cd4303a6cdc6e1c289d99" integrity sha512-6/7+wYQuuQhnGvxkDQcvoACdmuwUL1BlPqBIUFwyBpkdJ1VQGZiUSAAZTxXdY1Fv/p5mKR1vRsvZgtSPhcxgcg== @@ -2454,7 +2464,15 @@ "@opentripplanner/location-icon" "^1.4.1" flat "^5.0.2" -"@opentripplanner/geocoder@^3.0.0", "@opentripplanner/geocoder@^3.0.1": +"@opentripplanner/from-to-location-picker@^2.1.14": + version "2.1.14" + resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-2.1.14.tgz#7386fe93cd486a67a119a81fb46a5a442f9aa7ec" + integrity sha512-V0slZKBxGj6J4QxrIc3hpcHmZzAW6F1qZGBFJG/0Lpx3MiT5BVnaYyapedJOJW7zdzcIt16FBg774RjvwBu3fQ== + dependencies: + "@opentripplanner/location-icon" "^1.4.1" + flat "^5.0.2" + +"@opentripplanner/geocoder@^3.0.0": version "3.0.1" resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.1.tgz#834960bc52f515e1223346a8002fb847674d33bc" integrity sha512-+LHTqY8pHmPE39IjVev5T5baa+BohEyvsLwVwFB2bYWzM+m/RgAJ188uBcDzXKdqk5y3dZR9ZODYVMtrvIiKzQ== @@ -2465,27 +2483,38 @@ isomorphic-mapzen-search "^1.6.1" lodash.memoize "^4.1.2" +"@opentripplanner/geocoder@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" + integrity sha512-pl7tCiodex0hXWKLH3WE+I+HzoSgOOWp9kR3xMcuRiE5g6k2JXNneoD/ZfSS1n6Oorxcjv3U2DbMSXT2j/39dQ== + dependencies: + "@conveyal/geocoder-arcgis-geojson" "^0.0.3" + "@conveyal/lonlat" "^1.4.1" + "@leeoniya/ufuzzy" "^1.0.14" + isomorphic-mapzen-search "^1.6.1" + lodash.memoize "^4.1.2" + "@opentripplanner/humanize-distance@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA== -"@opentripplanner/icons@^2.0.10", "@opentripplanner/icons@^2.0.11": - version "2.0.11" - resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.11.tgz#08ac56bee164c988748fb2b94a60e9e932dfbb3f" - integrity sha512-VOdp/SGn/bnVIQCdqGrLwqI0EFexw7eIuHIP1yNYGgDZETO2d6f/FUr6suw69Y59/4l6CoZvGZD5jCPi2vz/bA== +"@opentripplanner/icons@^2.0.12", "@opentripplanner/icons@^2.0.13": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.13.tgz#45c4c16d8f208cff73811941f2def0fa23f87780" + integrity sha512-1oEPCmFuyS88bJZ2U9eFlEw2kQ0ZZW+wOI1dggr0omJDD6L+nVNQJ6TUtosNHYL1S35Jpx4aSQEG3iwwlXOHMg== dependencies: - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.4.4" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@^5.0.2", "@opentripplanner/itinerary-body@^5.3.5": - version "5.3.5" - resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.5.tgz#e31ea005f374acaf9050653d5e77464d70522fa4" - integrity sha512-Ku/KX+G1wGhNqFUTqjXLGz5cYkujEg2fdnpOhyoKayidQbux+CbX0BkpVBR7DBMkVJsN7wWUWVirfbYFBCCSdA== +"@opentripplanner/itinerary-body@^5.3.6", "@opentripplanner/itinerary-body@^5.3.7": + version "5.3.7" + resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.7.tgz#e32437f804defc19aef23685e45c0a363ac8bc31" + integrity sha512-ZnbxI78WsY6/Ynl3QY026JqimGG+gqXcN8ZEXY/BPMrNhSul27HgFFT2Flo37Fnc5gN2+jE8LsR1yxq05H3kvQ== dependencies: - "@opentripplanner/core-utils" "^11.4.1" + "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/humanize-distance" "^1.2.0" - "@opentripplanner/icons" "^2.0.10" + "@opentripplanner/icons" "^2.0.12" "@opentripplanner/location-icon" "^1.4.1" "@styled-icons/fa-solid" "^10.34.0" "@styled-icons/foundation" "^10.34.0" @@ -2496,32 +2525,14 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" -"@opentripplanner/itinerary-body@^5.3.0": - version "5.3.3" - resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.3.tgz#5202060ccd1a38fd6ed823331a00233a15305957" - integrity sha512-3G0szbSObrQh3uliQI6Hx62iCqqpxvrxGo7X69r28S7s8fexoI1B/3B4lRC0D14BUUPaOisE5Rc2N10SjI6MtQ== - dependencies: - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/humanize-distance" "^1.2.0" - "@opentripplanner/icons" "^2.0.10" - "@opentripplanner/location-icon" "^1.4.1" - "@styled-icons/fa-solid" "^10.34.0" - "@styled-icons/foundation" "^10.34.0" - date-fns "^2.28.0" - date-fns-tz "^1.2.2" - flat "^5.0.2" - react-animate-height "^3.0.4" - react-resize-detector "^4.2.1" - string-similarity "^4.0.4" - -"@opentripplanner/location-field@^2.0.22": - version "2.0.22" - resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.22.tgz#9ed68dee8660223d4c25ab78a19baf8cfe7d7ec2" - integrity sha512-OiowT7EJ3UWGQzseaN9oCW1BcsdA4XawQCF/AhTmpT3CUfG7SmzHe6kMcyGSKEqTRiNiJ5hBoTvR49gHdrUToQ== +"@opentripplanner/location-field@^2.0.24": + version "2.0.24" + resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.24.tgz#32e7109142bd754d28bd28ebbdf68d4e5ef4c812" + integrity sha512-fOAyanDnLLHC39kHG6kMSY6i09n4l0KSVQACFoosGZgUcJmz5CUCMl0/x3RszIwh3g2wqxKh6fagh4V56YEpfQ== dependencies: "@conveyal/geocoder-arcgis-geojson" "^0.0.3" - "@opentripplanner/core-utils" "^11.4.1" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/geocoder" "^3.0.2" "@opentripplanner/humanize-distance" "^1.2.0" "@opentripplanner/location-icon" "^1.4.1" "@styled-icons/fa-solid" "^10.34.0" @@ -2535,7 +2546,7 @@ "@styled-icons/fa-regular" "^10.34.0" "@styled-icons/fa-solid" "^10.34.0" -"@opentripplanner/map-popup@^3.0.2", "@opentripplanner/map-popup@^3.1.0", "@opentripplanner/map-popup@^3.1.1": +"@opentripplanner/map-popup@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.1.1.tgz#54f081162d328cc4bb0e89562f9ea200e29e01a1" integrity sha512-yWBIPuYGw7biaRNIpglQm5+opZ+D5QQgXHLhKnYaCR0eNijjl9cx34lGXdyKPXt26S6MiyJZXL81uc6w6CnQ3A== @@ -2544,37 +2555,48 @@ "@opentripplanner/from-to-location-picker" "^2.1.12" flat "^5.0.2" -"@opentripplanner/otp2-tile-overlay@^1.0.12": - version "1.0.12" - resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-1.0.12.tgz#1fc6ea68f47c44ff39fd04c13d946a68ed62d279" - integrity sha512-6BizhZkMvs6IuztqfAiZNLTczI4BHDXgd6XenMTPDhA+q2MCcxyJezxZWdWqaN9Eov/MI677Xp3+91hjiTsM5Q== +"@opentripplanner/map-popup@^4.0.0", "@opentripplanner/map-popup@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-4.0.1.tgz#18d40f339b09e2ebd5f722a0734cc259013b3400" + integrity sha512-FDgYkS0AvUCH4Em9kiZsMLhg6zvd1NKXXpNLVBPt3Xerq0weLpLZPP96TeP3JlXVMJ2wkMCr4AKtZ/9103HYTA== dependencies: - "@opentripplanner/map-popup" "^3.0.2" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/from-to-location-picker" "^2.1.14" + flat "^5.0.2" -"@opentripplanner/park-and-ride-overlay@^2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-2.0.8.tgz#43042fadefa98e557fcf3abdddfe27a1cd9ea38b" - integrity sha512-X10vHCD3Rp+taegQeDtopWUmqxMl8ogUlzcBi+sFniDzhndQ7qPFWxz34KfMD7LK4pmkEUqQTBSYAAuWvHlWXw== +"@opentripplanner/otp2-tile-overlay@^1.0.16": + version "1.0.16" + resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-1.0.16.tgz#4259b775b14078a697818e88ec61e19175232a61" + integrity sha512-BqWynzopdVrorQ75rn3zFTu40oOR/Y2sDE8jwip04KYqn3gJwgYzdi6q3saGKm4An49gVVxcxQTlk+fLizSmAQ== dependencies: - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/from-to-location-picker" "^2.1.11" + "@opentripplanner/map-popup" "^4.0.0" -"@opentripplanner/printable-itinerary@^2.0.21": - version "2.0.21" - resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.21.tgz#2b85ad6017491bbae682ece53d57e35819b79959" - integrity sha512-MWcHWmZRiqygjrwJt6I/LyHin88cjsmgqdxx2lh3oLGMgjrF657sxAbXfXAySqsW1rZ1MtHRuZ7IA2ph93GfMQ== +"@opentripplanner/park-and-ride-overlay@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-2.0.9.tgz#0efe2bf8a7595b56c4da6396e89db5f04e4b3ec8" + integrity sha512-ekf6kcCgMVTzXDMY3Ed8qclaL3YY2/1BrArdpRY8DxciGWmE1HKOW90Vf1aP18aLrwcW9kpvv1Kdbl60tY6mCQ== dependencies: - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/itinerary-body" "^5.3.0" + "@opentripplanner/base-map" "^3.2.0" + "@opentripplanner/from-to-location-picker" "^2.1.13" -"@opentripplanner/route-viewer-overlay@^2.0.15": - version "2.0.15" - resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-2.0.15.tgz#f1bc74a8832dcf548efbda5f7aaa277bfb095dfe" - integrity sha512-RpoXZWxII8VefPCpguzdgNV1VovdvkhJjE0/U4qY4aGHRg8ocUuwry73CzLt5o2/J3VbGDdYMi5hMT1pul8SFA== +"@opentripplanner/printable-itinerary@^2.0.23": + version "2.0.23" + resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.23.tgz#31f11e0e22bb9f223c4c1d8fa97c6eea18496cfa" + integrity sha512-Cb5SX7ts0rX0P1XSStjqbTITP5ueWlDe1b7U4KMaRNqEOaK2tELEyb/qZGo9kMpXTT/17jmEQZsKHQj43C5Eyg== + dependencies: + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/itinerary-body" "^5.3.6" + +"@opentripplanner/route-viewer-overlay@^2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-2.0.17.tgz#f34686fd965cf39650a10f64df599e7aca468415" + integrity sha512-3UTTLxHhaMg4iKP4oJlobvUCbvC/TjCW6ss8PxxC3UurwiMeSFNVkaWGLElPc9YoKg0QqKxrIY7zq0WClIPa6g== dependencies: "@mapbox/polyline" "^1.1.0" - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/core-utils" "^11.4.4" point-in-polygon "^1.1.0" "@opentripplanner/scripts@^1.2.0": @@ -2588,43 +2610,43 @@ glob-promise "^4.2.2" js-yaml "^4.1.0" -"@opentripplanner/stop-viewer-overlay@^2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-2.0.8.tgz#3613e8cf99985082bf493933fc0fbf63c0fafa06" - integrity sha512-xeiVn1FMLM291ogjJyPHqoHgTIiwWDtBUfIvwup+gqkrtDerpHg8onqL42GN1+T0mDyREENjKwh5jqkqRNVlHQ== +"@opentripplanner/stop-viewer-overlay@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-2.0.10.tgz#0749fe7ffb28dac7a6925ed7c663e2fdd5156f3b" + integrity sha512-rFmaqQ7uJ+ZE80O6fveiNxlEVSJW5PwFSMh1B9pN0HaVTB1U27+yKbIMMuP7GtWve31mPy+PaWYXDW3hMlsi8A== dependencies: - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/core-utils" "^11.4.4" -"@opentripplanner/stops-overlay@^5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.3.0.tgz#1f35927a769a5fac80e40cfdaf85a7275b90cec5" - integrity sha512-bQBH5vf/F8n7yL6zhWpiU1XyJOkarcZVLovKYGseJpLs+qnPUd+3MMK9W0cQAMn7iuxAjcDHmSNmeK99kwb3jw== +"@opentripplanner/stops-overlay@^5.3.3": + version "5.3.3" + resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.3.3.tgz#711dd9316de93ac6c959dc3191d31884dc0a9589" + integrity sha512-GYADErZLIG3KPJ4OiigWkyHaGrWJ/wiCenH0RTbQ5J0XbYrenUIlWBsI5kpQNZPGBXocvF77sOTOUM8gex1AUA== dependencies: - "@opentripplanner/base-map" "^3.1.0" - "@opentripplanner/from-to-location-picker" "^2.1.12" - "@opentripplanner/map-popup" "^3.1.0" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/from-to-location-picker" "^2.1.14" + "@opentripplanner/map-popup" "^4.0.0" flat "^5.0.2" -"@opentripplanner/transit-vehicle-overlay@^4.0.11": - version "4.0.11" - resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.11.tgz#3485514b6000612bba32c4610d9a5f692e01cf95" - integrity sha512-1xwPqAB/NbBKyv+5wJKaXz7mww3Sznbk2MISbjCecpbYaCrYwcXTVhoXDnrkgAELI1mz739mud6qKr/X77SEEg== +"@opentripplanner/transit-vehicle-overlay@^4.0.13": + version "4.0.13" + resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.13.tgz#6f66c7c6a27d2473353b7c8c14acc8c540fb01ad" + integrity sha512-Sh3c3+q2dIhFZP5uyhPboyLSsTv8unVsPYKjFWVJaK19z6wN8KqFVmSqWysrcEnooRJd+D4+4erQiUbabomDLQ== dependencies: - "@opentripplanner/base-map" "^3.1.0" - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/icons" "^2.0.10" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/icons" "^2.0.12" flat "^5.0.2" -"@opentripplanner/transitive-overlay@3.0.15": - version "3.0.15" - resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.15.tgz#5ae65111f2977a8bcb4a09127c9db3460ba2c2cb" - integrity sha512-1A28QWt87iJmzT9xC9Fxz/jq9Hd38oj+Ur9n4f2vIfQ+WMgkY6CGOsz60+CWq2yN+9tXY7Pj1g5I5klT/F43rw== +"@opentripplanner/transitive-overlay@3.0.22": + version "3.0.22" + resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.22.tgz#631096b12e08671e5da05ffe1c0a0e01331750a4" + integrity sha512-Ix3+2qz1+iSbeLnMfd4tU+0AUU1LDjq4y8cTzfKHayqHe0pzHpYY9Ib2zrXbvog7Mav/Jozn2ycL27R4UgzQaA== dependencies: "@mapbox/polyline" "^1.1.1" - "@opentripplanner/base-map" "^3.0.14" - "@opentripplanner/core-utils" "^11.0.2" - "@opentripplanner/itinerary-body" "^5.0.2" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/itinerary-body" "^5.3.6" "@turf/bbox" "^6.5.0" "@turf/bearing" "^6.5.0" "@turf/destination" "^6.5.0" @@ -2633,23 +2655,23 @@ "@turf/midpoint" "^6.5.0" lodash.isequal "^4.5.0" -"@opentripplanner/trip-details@^5.0.13": - version "5.0.13" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.13.tgz#96b0171d78235246346139a85cff6a6f64a11e45" - integrity sha512-kjXCUrCzX9cJ1DoMS6OSkfZTFtzEfy4Kt4OjWAsUGbgguPumuvAJLu7LhH7KuAC6cOxxSldKqrCsUGAc7sogsQ== +"@opentripplanner/trip-details@^5.0.15": + version "5.0.15" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.15.tgz#73cfd7427aed49af53fec4ded9de7d17b0ed5377" + integrity sha512-1OfCEju90PXGH9DVy2dbBk8Jz8/8zSJ35/OCgodenGT3FyokQPoJsQhPjr6MPIIYMTyAdUSDT9C372thA+rU2Q== dependencies: - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.4.4" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.2.tgz#910432d222aafa598e85cce134faffe956ac5c25" - integrity sha512-NWD2WtVjn5Iq/B4Verv+LnZIdt5vYcTMkMn+9Yyc5YBPt5hzK2HUdQbAh35ap30gj77KJFbNJ8lLJ3VPn9A8yg== +"@opentripplanner/trip-form@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.4.tgz#e741bb190dbea845c826d0021618daf568cc3df7" + integrity sha512-wnoJyI8jR3DbtTmg//FWWy+yhd6Yej843XxSnnGCuBhZjUnvC9aYffKa/FI1W9s8Xw+tJ7DsZ9wADiSOWEjmwA== dependencies: "@floating-ui/react" "^0.19.2" - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.4.4" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" "@styled-icons/fa-regular" "^10.37.0" @@ -2659,29 +2681,29 @@ react-indiana-drag-scroll "^2.0.1" react-inlinesvg "^2.3.0" -"@opentripplanner/trip-viewer-overlay@^2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-2.0.8.tgz#53eeb01f56ea38b2f1f5973979e1840a4f252645" - integrity sha512-NUAf6eoW9uTMOh82CVWMbWjJC9YbY4jHDvpH6lQ41KOwQ38e1FPyPeNMpIRmUVkD9P/if3C+UUU1HC4JAooUwA== +"@opentripplanner/trip-viewer-overlay@^2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-2.0.10.tgz#2c0809b2d54da4d57d0a0683a4739e29cb13a326" + integrity sha512-7M9l7fF8shtD/566bci+zEkPncf/L+ZWIYAl5gnIgrBxwLagN/+E2zkoDebYamGFGb236FXpvTS30i1BJzhcPA== dependencies: "@mapbox/polyline" "^1.1.0" - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/types@^6.5.2": version "6.5.2" resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.2.tgz#1373d738479568d880a3b13670b0ec53a1a75bd5" integrity sha512-2qDcKOrsLoXdwjRAdi4xcdDUsZGTnwBM+vfEf8TTuuWSnA+WYav3ldlMB4sugxIdLaVKXlOfe3F5lCEh9jAHWA== -"@opentripplanner/vehicle-rental-overlay@^2.1.7": - version "2.1.7" - resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-2.1.7.tgz#f0558e34f69396b49e9e090094d3905f21b383ff" - integrity sha512-FClQcsDTJ1Z2d9g8RpqZ6P4d9MGQmDlW5V9DnoF3kEp/PQev0x3NcV4UyoORdVQrl1/LObL3ERsbvedNtXldOA== +"@opentripplanner/vehicle-rental-overlay@^2.1.9": + version "2.1.9" + resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-2.1.9.tgz#c373e1400874a00f473be0f029b28e0944652c88" + integrity sha512-VYWqnuk5j1yHF/zH5NEqDIVjsSbIsIgiCK6SaYtQHOBwszWauIubpqviTBASAcY72JfKE36AQfGjPuYILd9oTw== dependencies: - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/core-utils" "^11.2.3" - "@opentripplanner/from-to-location-picker" "^2.1.11" - "@opentripplanner/map-popup" "^3.0.2" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/from-to-location-picker" "^2.1.14" + "@opentripplanner/map-popup" "^4.0.0" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" lodash.memoize "^4.1.2" From 39b9e1e3aab93c911b15fae256b956db54e06f9c Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Mon, 16 Sep 2024 10:31:43 -0400 Subject: [PATCH 104/162] chore(deps): downgrade from broken versions --- package.json | 38 ++++++++++++------------ yarn.lock | 84 ++++++++++++++++++++++++++-------------------------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index 7b08da443..f8afaf811 100644 --- a/package.json +++ b/package.json @@ -42,30 +42,30 @@ "@bugsnag/js": "^7.17.0", "@bugsnag/plugin-react": "^7.17.0", "@floating-ui/react": "^0.19.2", - "@opentripplanner/base-map": "^3.2.2", - "@opentripplanner/building-blocks": "^1.2.3", - "@opentripplanner/core-utils": "^11.4.4", - "@opentripplanner/endpoints-overlay": "^2.1.4", - "@opentripplanner/from-to-location-picker": "^2.1.14", - "@opentripplanner/geocoder": "^3.0.2", + "@opentripplanner/base-map": "^3.2.0", + "@opentripplanner/building-blocks": "^1.1.0", + "@opentripplanner/core-utils": "^11.4.3", + "@opentripplanner/endpoints-overlay": "^2.1.1", + "@opentripplanner/from-to-location-picker": "^2.1.13", + "@opentripplanner/geocoder": "^3.0.1", "@opentripplanner/humanize-distance": "^1.2.0", - "@opentripplanner/icons": "^2.0.13", - "@opentripplanner/itinerary-body": "^5.3.7", - "@opentripplanner/location-field": "^2.0.24", + "@opentripplanner/icons": "^2.0.11", + "@opentripplanner/itinerary-body": "^5.3.5", + "@opentripplanner/location-field": "^2.0.22", "@opentripplanner/location-icon": "^1.4.1", "@opentripplanner/map-popup": "^4.0.1", "@opentripplanner/otp2-tile-overlay": "^1.0.16", - "@opentripplanner/park-and-ride-overlay": "^2.0.9", - "@opentripplanner/printable-itinerary": "^2.0.23", "@opentripplanner/route-viewer-overlay": "^2.0.17", - "@opentripplanner/stop-viewer-overlay": "^2.0.10", - "@opentripplanner/stops-overlay": "^5.3.3", - "@opentripplanner/transit-vehicle-overlay": "^4.0.13", - "@opentripplanner/transitive-overlay": "3.0.22", - "@opentripplanner/trip-details": "^5.0.15", - "@opentripplanner/trip-form": "^3.6.4", - "@opentripplanner/trip-viewer-overlay": "^2.0.10", - "@opentripplanner/vehicle-rental-overlay": "^2.1.9", + "@opentripplanner/park-and-ride-overlay": "^2.0.8", + "@opentripplanner/printable-itinerary": "^2.0.21", + "@opentripplanner/stop-viewer-overlay": "^2.0.8", + "@opentripplanner/stops-overlay": "^5.3.0", + "@opentripplanner/transit-vehicle-overlay": "^4.0.11", + "@opentripplanner/transitive-overlay": "3.0.15", + "@opentripplanner/trip-details": "^5.0.13", + "@opentripplanner/trip-form": "^3.6.2", + "@opentripplanner/trip-viewer-overlay": "^2.0.8", + "@opentripplanner/vehicle-rental-overlay": "^2.1.7", "@styled-icons/fa-regular": "^10.34.0", "@styled-icons/fa-solid": "^10.34.0", "@turf/centroid": "^6.5.0", diff --git a/yarn.lock b/yarn.lock index 367b0743a..5c7044140 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,39 +2383,39 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" - integrity sha512-d/yTKEnXqrw9pXhSvCERT+wLFa077Xr4wEFu4pYB+WYoZFflNxuTuAXXjm268HS/d0kjNndkjSMkxaKk6AjsvA== +"@opentripplanner/base-map@^3.0.14", "@opentripplanner/base-map@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.2.tgz#6dc15f3af0bfe483ffea220dcd2220272fa31040" + integrity sha512-Neg+rvAr9lWx+8V8/4ZlPE+l91wxM0fbbsM5vp45L1zCRE4WszD7XtmLocnNMyuYzo3xEijoKF+ICiENsOM9bg== dependencies: - "@opentripplanner/map-popup" "^3.1.0" + "@opentripplanner/building-blocks" "^1.2.2" mapbox-gl "npm:empty-npm-package@1.0.0" maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/base-map@^3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.2.tgz#6dc15f3af0bfe483ffea220dcd2220272fa31040" - integrity sha512-Neg+rvAr9lWx+8V8/4ZlPE+l91wxM0fbbsM5vp45L1zCRE4WszD7XtmLocnNMyuYzo3xEijoKF+ICiENsOM9bg== +"@opentripplanner/base-map@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" + integrity sha512-d/yTKEnXqrw9pXhSvCERT+wLFa077Xr4wEFu4pYB+WYoZFflNxuTuAXXjm268HS/d0kjNndkjSMkxaKk6AjsvA== dependencies: - "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/map-popup" "^3.1.0" mapbox-gl "npm:empty-npm-package@1.0.0" maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@^1.2.2", "@opentripplanner/building-blocks@^1.2.3": +"@opentripplanner/building-blocks@^1.1.0", "@opentripplanner/building-blocks@^1.2.2": version "1.2.3" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@^11.4.0": - version "11.4.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" - integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== +"@opentripplanner/core-utils@^11.0.2", "@opentripplanner/core-utils@^11.4.3", "@opentripplanner/core-utils@^11.4.4": + version "11.4.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.4.tgz#11c1be91a5e90afda4fc265831c761d3e044d933" + integrity sha512-WKhOuG7Q+Yxdm+P5MPmJyXndx+JUtGn44GTeilOnUqDdO8lTLTvqqt0hYeEWjA77jWP0u8tG7fAAsft8IZn2cg== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/geocoder" "^3.0.2" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" @@ -2426,14 +2426,14 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/core-utils@^11.4.4": - version "11.4.4" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.4.tgz#11c1be91a5e90afda4fc265831c761d3e044d933" - integrity sha512-WKhOuG7Q+Yxdm+P5MPmJyXndx+JUtGn44GTeilOnUqDdO8lTLTvqqt0hYeEWjA77jWP0u8tG7fAAsft8IZn2cg== +"@opentripplanner/core-utils@^11.4.0": + version "11.4.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" + integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.2" + "@opentripplanner/geocoder" "^3.0.0" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" @@ -2444,7 +2444,7 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/endpoints-overlay@^2.1.4": +"@opentripplanner/endpoints-overlay@^2.1.1": version "2.1.4" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.4.tgz#f81088bce83236344dfa4a51b2efe00092a5c87a" integrity sha512-VLRZArhoRQ38aafc/w986Uv1lnq/WLJOgBqnpvuUbLhLR/qHU9h5X3wg3jgwf2GA0BIn03Z99VJbCkGfkyd0LA== @@ -2483,7 +2483,7 @@ isomorphic-mapzen-search "^1.6.1" lodash.memoize "^4.1.2" -"@opentripplanner/geocoder@^3.0.2": +"@opentripplanner/geocoder@^3.0.1", "@opentripplanner/geocoder@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" integrity sha512-pl7tCiodex0hXWKLH3WE+I+HzoSgOOWp9kR3xMcuRiE5g6k2JXNneoD/ZfSS1n6Oorxcjv3U2DbMSXT2j/39dQ== @@ -2499,7 +2499,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA== -"@opentripplanner/icons@^2.0.12", "@opentripplanner/icons@^2.0.13": +"@opentripplanner/icons@^2.0.11", "@opentripplanner/icons@^2.0.12": version "2.0.13" resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.13.tgz#45c4c16d8f208cff73811941f2def0fa23f87780" integrity sha512-1oEPCmFuyS88bJZ2U9eFlEw2kQ0ZZW+wOI1dggr0omJDD6L+nVNQJ6TUtosNHYL1S35Jpx4aSQEG3iwwlXOHMg== @@ -2507,7 +2507,7 @@ "@opentripplanner/core-utils" "^11.4.4" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@^5.3.6", "@opentripplanner/itinerary-body@^5.3.7": +"@opentripplanner/itinerary-body@^5.0.2", "@opentripplanner/itinerary-body@^5.3.5", "@opentripplanner/itinerary-body@^5.3.6": version "5.3.7" resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.7.tgz#e32437f804defc19aef23685e45c0a363ac8bc31" integrity sha512-ZnbxI78WsY6/Ynl3QY026JqimGG+gqXcN8ZEXY/BPMrNhSul27HgFFT2Flo37Fnc5gN2+jE8LsR1yxq05H3kvQ== @@ -2525,7 +2525,7 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" -"@opentripplanner/location-field@^2.0.24": +"@opentripplanner/location-field@^2.0.22": version "2.0.24" resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.24.tgz#32e7109142bd754d28bd28ebbdf68d4e5ef4c812" integrity sha512-fOAyanDnLLHC39kHG6kMSY6i09n4l0KSVQACFoosGZgUcJmz5CUCMl0/x3RszIwh3g2wqxKh6fagh4V56YEpfQ== @@ -2573,7 +2573,7 @@ dependencies: "@opentripplanner/map-popup" "^4.0.0" -"@opentripplanner/park-and-ride-overlay@^2.0.9": +"@opentripplanner/park-and-ride-overlay@^2.0.8": version "2.0.9" resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-2.0.9.tgz#0efe2bf8a7595b56c4da6396e89db5f04e4b3ec8" integrity sha512-ekf6kcCgMVTzXDMY3Ed8qclaL3YY2/1BrArdpRY8DxciGWmE1HKOW90Vf1aP18aLrwcW9kpvv1Kdbl60tY6mCQ== @@ -2581,7 +2581,7 @@ "@opentripplanner/base-map" "^3.2.0" "@opentripplanner/from-to-location-picker" "^2.1.13" -"@opentripplanner/printable-itinerary@^2.0.23": +"@opentripplanner/printable-itinerary@^2.0.21": version "2.0.23" resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.23.tgz#31f11e0e22bb9f223c4c1d8fa97c6eea18496cfa" integrity sha512-Cb5SX7ts0rX0P1XSStjqbTITP5ueWlDe1b7U4KMaRNqEOaK2tELEyb/qZGo9kMpXTT/17jmEQZsKHQj43C5Eyg== @@ -2610,7 +2610,7 @@ glob-promise "^4.2.2" js-yaml "^4.1.0" -"@opentripplanner/stop-viewer-overlay@^2.0.10": +"@opentripplanner/stop-viewer-overlay@^2.0.8": version "2.0.10" resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-2.0.10.tgz#0749fe7ffb28dac7a6925ed7c663e2fdd5156f3b" integrity sha512-rFmaqQ7uJ+ZE80O6fveiNxlEVSJW5PwFSMh1B9pN0HaVTB1U27+yKbIMMuP7GtWve31mPy+PaWYXDW3hMlsi8A== @@ -2618,7 +2618,7 @@ "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" -"@opentripplanner/stops-overlay@^5.3.3": +"@opentripplanner/stops-overlay@^5.3.0": version "5.3.3" resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.3.3.tgz#711dd9316de93ac6c959dc3191d31884dc0a9589" integrity sha512-GYADErZLIG3KPJ4OiigWkyHaGrWJ/wiCenH0RTbQ5J0XbYrenUIlWBsI5kpQNZPGBXocvF77sOTOUM8gex1AUA== @@ -2628,7 +2628,7 @@ "@opentripplanner/map-popup" "^4.0.0" flat "^5.0.2" -"@opentripplanner/transit-vehicle-overlay@^4.0.13": +"@opentripplanner/transit-vehicle-overlay@^4.0.11": version "4.0.13" resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.13.tgz#6f66c7c6a27d2473353b7c8c14acc8c540fb01ad" integrity sha512-Sh3c3+q2dIhFZP5uyhPboyLSsTv8unVsPYKjFWVJaK19z6wN8KqFVmSqWysrcEnooRJd+D4+4erQiUbabomDLQ== @@ -2638,15 +2638,15 @@ "@opentripplanner/icons" "^2.0.12" flat "^5.0.2" -"@opentripplanner/transitive-overlay@3.0.22": - version "3.0.22" - resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.22.tgz#631096b12e08671e5da05ffe1c0a0e01331750a4" - integrity sha512-Ix3+2qz1+iSbeLnMfd4tU+0AUU1LDjq4y8cTzfKHayqHe0pzHpYY9Ib2zrXbvog7Mav/Jozn2ycL27R4UgzQaA== +"@opentripplanner/transitive-overlay@3.0.15": + version "3.0.15" + resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.15.tgz#5ae65111f2977a8bcb4a09127c9db3460ba2c2cb" + integrity sha512-1A28QWt87iJmzT9xC9Fxz/jq9Hd38oj+Ur9n4f2vIfQ+WMgkY6CGOsz60+CWq2yN+9tXY7Pj1g5I5klT/F43rw== dependencies: "@mapbox/polyline" "^1.1.1" - "@opentripplanner/base-map" "^3.2.2" - "@opentripplanner/core-utils" "^11.4.4" - "@opentripplanner/itinerary-body" "^5.3.6" + "@opentripplanner/base-map" "^3.0.14" + "@opentripplanner/core-utils" "^11.0.2" + "@opentripplanner/itinerary-body" "^5.0.2" "@turf/bbox" "^6.5.0" "@turf/bearing" "^6.5.0" "@turf/destination" "^6.5.0" @@ -2655,7 +2655,7 @@ "@turf/midpoint" "^6.5.0" lodash.isequal "^4.5.0" -"@opentripplanner/trip-details@^5.0.15": +"@opentripplanner/trip-details@^5.0.13": version "5.0.15" resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.15.tgz#73cfd7427aed49af53fec4ded9de7d17b0ed5377" integrity sha512-1OfCEju90PXGH9DVy2dbBk8Jz8/8zSJ35/OCgodenGT3FyokQPoJsQhPjr6MPIIYMTyAdUSDT9C372thA+rU2Q== @@ -2665,7 +2665,7 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.6.4": +"@opentripplanner/trip-form@^3.6.2": version "3.6.4" resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.4.tgz#e741bb190dbea845c826d0021618daf568cc3df7" integrity sha512-wnoJyI8jR3DbtTmg//FWWy+yhd6Yej843XxSnnGCuBhZjUnvC9aYffKa/FI1W9s8Xw+tJ7DsZ9wADiSOWEjmwA== @@ -2681,7 +2681,7 @@ react-indiana-drag-scroll "^2.0.1" react-inlinesvg "^2.3.0" -"@opentripplanner/trip-viewer-overlay@^2.0.10": +"@opentripplanner/trip-viewer-overlay@^2.0.8": version "2.0.10" resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-2.0.10.tgz#2c0809b2d54da4d57d0a0683a4739e29cb13a326" integrity sha512-7M9l7fF8shtD/566bci+zEkPncf/L+ZWIYAl5gnIgrBxwLagN/+E2zkoDebYamGFGb236FXpvTS30i1BJzhcPA== @@ -2695,7 +2695,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.2.tgz#1373d738479568d880a3b13670b0ec53a1a75bd5" integrity sha512-2qDcKOrsLoXdwjRAdi4xcdDUsZGTnwBM+vfEf8TTuuWSnA+WYav3ldlMB4sugxIdLaVKXlOfe3F5lCEh9jAHWA== -"@opentripplanner/vehicle-rental-overlay@^2.1.9": +"@opentripplanner/vehicle-rental-overlay@^2.1.7": version "2.1.9" resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-2.1.9.tgz#c373e1400874a00f473be0f029b28e0944652c88" integrity sha512-VYWqnuk5j1yHF/zH5NEqDIVjsSbIsIgiCK6SaYtQHOBwszWauIubpqviTBASAcY72JfKE36AQfGjPuYILd9oTw== From d9d4c9729dff4603501e109124e0c2aea277dbf3 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Mon, 16 Sep 2024 10:38:25 -0400 Subject: [PATCH 105/162] chore(deps): downgrade from broken map-popup --- package.json | 2 +- yarn.lock | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f8afaf811..2fa85704f 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@opentripplanner/itinerary-body": "^5.3.5", "@opentripplanner/location-field": "^2.0.22", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "^4.0.1", + "@opentripplanner/map-popup": "^3.1.1", "@opentripplanner/otp2-tile-overlay": "^1.0.16", "@opentripplanner/route-viewer-overlay": "^2.0.17", "@opentripplanner/park-and-ride-overlay": "^2.0.8", diff --git a/yarn.lock b/yarn.lock index 5c7044140..b677a8213 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2555,7 +2555,16 @@ "@opentripplanner/from-to-location-picker" "^2.1.12" flat "^5.0.2" -"@opentripplanner/map-popup@^4.0.0", "@opentripplanner/map-popup@^4.0.1": +"@opentripplanner/map-popup@^3.1.1": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.1.3.tgz#70f0afde138642a60678f3c486ed48d2fe580790" + integrity sha512-IuWl+K/SP+WuzyYk9lDHTOFJi0irV3jayamKcGllEplnOe2wa4SxaKsvZxT+A+f/E0/rD2r3Jk7eUWnba5LVzw== + dependencies: + "@opentripplanner/core-utils" "^11.4.3" + "@opentripplanner/from-to-location-picker" "^2.1.13" + flat "^5.0.2" + +"@opentripplanner/map-popup@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-4.0.1.tgz#18d40f339b09e2ebd5f722a0734cc259013b3400" integrity sha512-FDgYkS0AvUCH4Em9kiZsMLhg6zvd1NKXXpNLVBPt3Xerq0weLpLZPP96TeP3JlXVMJ2wkMCr4AKtZ/9103HYTA== From aa629af9ac7aa14b1b303881f720d0758580f8dc Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Mon, 16 Sep 2024 10:44:16 -0400 Subject: [PATCH 106/162] why was this needed --- .../viewers/__snapshots__/nearby-view.js.snap | 320 +++++++++--------- 1 file changed, 160 insertions(+), 160 deletions(-) diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 48064f0f4..5d8edb4b2 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -4406,11 +4406,11 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` > + ) : ( transitOperators From d95936acf646d30254869500f6a9970e77ecc520 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Tue, 17 Sep 2024 08:33:51 -0400 Subject: [PATCH 109/162] clean up --- lib/components/util/transit-operator-icons.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx index 4e23e9e3b..b1d7a3ca5 100644 --- a/lib/components/util/transit-operator-icons.tsx +++ b/lib/components/util/transit-operator-icons.tsx @@ -70,9 +70,7 @@ const TransitOperatorLogos = ({ return ( <> {loading ? ( - <> - - + ) : ( transitOperators ?.filter((to) => Array.from(agencies).includes(to.agencyId)) From a9c432bddd6a500037141b69a0dd0ddfa55cb1d4 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Tue, 17 Sep 2024 17:12:47 -0700 Subject: [PATCH 110/162] change default to false --- lib/components/form/date-time-modal.tsx | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/components/form/date-time-modal.tsx b/lib/components/form/date-time-modal.tsx index f97450ec2..bf11a0806 100644 --- a/lib/components/form/date-time-modal.tsx +++ b/lib/components/form/date-time-modal.tsx @@ -25,6 +25,15 @@ type Props = { type DepartArriveValue = 'NOW' | 'DEPART' | 'ARRIVE' +const DepartArriveTypeMap: Record< + DepartArriveValue, + FilterType['sort']['type'] +> = { + ARRIVE: 'ARRIVALTIME', + DEPART: 'DEPARTURETIME', + NOW: 'DURATION' +} + function DateTimeModal(props: Props) { const { config, @@ -45,18 +54,13 @@ function DateTimeModal(props: Props) { const syncSortWithDepartArrive = config?.itinerary?.syncSortWithDepartArrive const setQueryParamMiddleware = useCallback( (params: any) => { - if (syncSortWithDepartArrive !== false) { - switch (params.departArrive) { - case 'NOW': - updateItineraryFilter({ sort: { ...sort, type: 'DURATION' } }) - break - case 'DEPART': - updateItineraryFilter({ sort: { ...sort, type: 'DEPARTURETIME' } }) - break - case 'ARRIVE': - updateItineraryFilter({ sort: { ...sort, type: 'ARRIVALTIME' } }) - break - } + if (syncSortWithDepartArrive) { + updateItineraryFilter({ + sort: { + ...sort, + type: DepartArriveTypeMap[params.departArrive as DepartArriveValue] + } + }) } setQueryParam(params) }, From 65efdd7438f9f2ef21cffa5277ad7c335cf46366 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup <86619099+miles-grant-ibigroup@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:23:27 -0400 Subject: [PATCH 111/162] Update lib/components/util/transit-operator-icons.tsx Co-authored-by: Amy Corson <115499534+amy-corson-ibigroup@users.noreply.github.com> --- lib/components/util/transit-operator-icons.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx index b1d7a3ca5..1f008b2ef 100644 --- a/lib/components/util/transit-operator-icons.tsx +++ b/lib/components/util/transit-operator-icons.tsx @@ -70,7 +70,7 @@ const TransitOperatorLogos = ({ return ( <> {loading ? ( - + ) : ( transitOperators ?.filter((to) => Array.from(agencies).includes(to.agencyId)) From ddda7fbd52294f4f1cba50ed0d0cdebebd92ae38 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 18 Sep 2024 11:35:21 -0700 Subject: [PATCH 112/162] attempt to clean up event type --- lib/components/form/util.tsx | 6 ++++-- lib/components/util/types.ts | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx index 3caf997a8..399b0df90 100644 --- a/lib/components/form/util.tsx +++ b/lib/components/form/util.tsx @@ -5,6 +5,7 @@ import React from 'react' import { getFormattedMode } from '../../util/i18n' import { hasValidLocation } from '../../util/state' +import { QueryParamChangeHandler } from '../util/types' import { RoutingQueryCallResult } from '../../actions/api-constants' import { updateQueryTimeIfLeavingNow } from '../../actions/form' @@ -52,13 +53,14 @@ export const addCustomSettingLabels = * @param params Params to store */ export const onSettingsUpdate = - (setQueryParam: (evt: any) => void) => (params: any) => { + (setQueryParam: QueryParamChangeHandler) => + (params: any): void => { setQueryParam({ queryParamData: params, ...params }) } export const setModeButton = (enabledModeButtons: string[], updateHandler: (params: any) => void) => - (buttonId: string, newState: boolean) => { + (buttonId: string, newState: boolean): void => { let newButtons if (newState) { newButtons = [...enabledModeButtons, buttonId] diff --git a/lib/components/util/types.ts b/lib/components/util/types.ts index 9b21030fa..83bcd7930 100644 --- a/lib/components/util/types.ts +++ b/lib/components/util/types.ts @@ -108,3 +108,5 @@ export type ZoomToPlaceHandler = ( place?: { lat: number; lon: number }, zoom?: number ) => void + +export type QueryParamChangeHandler = (event: any) => void From f389d34d171e890d53eb9e5b18ae5d1b410f2ea9 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:54:55 -0500 Subject: [PATCH 113/162] Revert unnecessary example.css change --- example.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example.css b/example.css index be6b5f609..afd7900f5 100644 --- a/example.css +++ b/example.css @@ -47,4 +47,4 @@ height: 100%; margin: 0px; padding: 0px; -} \ No newline at end of file +} From 4939a18c45ff9f50185ce9838e06dd4f9261f448 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Thu, 19 Sep 2024 11:22:12 -0400 Subject: [PATCH 114/162] allow for appendages to headsign --- i18n/en-US.yml | 1 + lib/components/viewers/pattern-row.tsx | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index f03fa5bce..b40495deb 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -357,6 +357,7 @@ components: distanceAway: "{localizedDistanceString} away" error: An error occurred loading nearby amenities. header: Nearby View + headsign: "{destination}" nearbyListIntro: List of {count} nearby entities. nothingNearby: There are no places nearby. spacesAvailable: "{spacesAvailable} empty spaces available" diff --git a/lib/components/viewers/pattern-row.tsx b/lib/components/viewers/pattern-row.tsx index 73bc22006..4f87a8c7a 100644 --- a/lib/components/viewers/pattern-row.tsx +++ b/lib/components/viewers/pattern-row.tsx @@ -1,5 +1,6 @@ import { Calendar } from '@styled-icons/fa-regular' import { format, utcToZonedTime } from 'date-fns-tz' +import { FormattedMessage } from 'react-intl' import { getMostReadableTextColor } from '@opentripplanner/core-utils/lib/route' import { isSameDay } from 'date-fns' import React, { useContext } from 'react' @@ -108,8 +109,15 @@ const PatternRow = ({ {pattern.route.longName} )} - {extractHeadsignFromPattern(pattern) || - (pattern.route.longName !== routeName && pattern.route.longName)} +
{/* next departure preview (only shows up to 3 entries) */} From 8f215744fa48b831f2c608dca6372ddd03af17e7 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Thu, 19 Sep 2024 11:28:31 -0400 Subject: [PATCH 115/162] update snapshots --- .../viewers/__snapshots__/nearby-view.js.snap | 253 ++++++++++++++++-- i18n/fr.yml | 1 + 2 files changed, 231 insertions(+), 23 deletions(-) diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 48064f0f4..32f677339 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -11734,7 +11734,16 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` } title="Loyal Heights Greenwood" > - Loyal Heights Greenwood + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="Downtown Seattle Fremont" > - Downtown Seattle Fremont + + components.NearbyView.headsign +

viewers > nearby view renders proper scooter dates 1`] = ` } title="Roosevelt Station Sand Point" > - Roosevelt Station Sand Point + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="Angle Lake" > - Angle Lake + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="Northgate" > - Northgate + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="Capitol Hill" > - Capitol Hill + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Roosevelt Station" > - University District Roosevelt Station + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="Sand Point East Green Lake" > - Sand Point East Green Lake + + components.NearbyView.headsign +
viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Sand Point" > - University District Sand Point + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Madrona Special" > - Madrona Special + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Roosevelt" > - University District Roosevelt + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Maple Leaf" > - University District Maple Leaf + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Downtown Seattle Special" > - Downtown Seattle Special + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Northgate" > - Northgate + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Bothell" > - Bothell + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Northgate Station Roosevelt Station" > - Northgate Station Roosevelt Station + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Woodinville" > - Woodinville + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Jackson Park Maple Leaf" > - Jackson Park Maple Leaf + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Kenmore P&R Roosevelt Station" > - Kenmore P&R Roosevelt Station + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Kenmore P&R" > - Kenmore P&R + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Loyal Heights Greenwood" > - Loyal Heights Greenwood + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Downtown Seattle Fremont" > - Downtown Seattle Fremont + + components.NearbyView.headsign + viewers > nearby view renders proper scooter dates 1`] = ` } title="Roosevelt Station Sand Point" > - Roosevelt Station Sand Point + + components.NearbyView.headsign + Date: Thu, 19 Sep 2024 14:22:59 -0400 Subject: [PATCH 116/162] chore(i18n): Add FR strings --- i18n/fr.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/i18n/fr.yml b/i18n/fr.yml index 082b0e96a..b910c123c 100644 --- a/i18n/fr.yml +++ b/i18n/fr.yml @@ -209,8 +209,15 @@ components: BatchRoutingPanel: shortTitle: Planifier un trajet BatchSearchScreen: + advancedHeader: Préférences avancées header: Votre trajet + modeOptions: Choix du mode modeSelectorLabel: Sélectionnez un mode de déplacement + moreOptions: Plus d'options + saveAndReturn: Enregistrer et fermer + saved: Enregistré + submodeSelectorLabel: Sélectionnez vos modes et sous-modes de déplacement + tripOptions: Options concernant le trajet BatchSettings: destination: destination invalidModeSelection: >- From 8017627278f9c492bc09360ee692667ce94f2af3 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 19 Sep 2024 18:16:14 -0500 Subject: [PATCH 117/162] Code cleanup --- lib/components/form/advanced-settings-panel.tsx | 14 ++++++++------ lib/components/form/util.tsx | 13 +++++-------- lib/components/mobile/batch-search-screen.tsx | 1 + lib/components/viewers/viewers.css | 6 +++++- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index 86b0125ec..a0a6c5cc5 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -15,7 +15,7 @@ import { ModeSetting, ModeSettingValues } from '@opentripplanner/types' -import React, { RefObject, useContext, useState } from 'react' +import React, { RefObject, useCallback, useContext, useState } from 'react' import styled from 'styled-components' import * as formActions from '../../actions/form' @@ -177,6 +177,12 @@ const AdvancedSettingsPanel = ({ ) ) + const onSaveAndReturnClick = useCallback(async () => { + await setCloseAdvancedSettingsWithDelay() + setClosingBySave(true) + closeAdvancedSettings() + }, [closeAdvancedSettings, setCloseAdvancedSettingsWithDelay]) + return ( @@ -223,11 +229,7 @@ const AdvancedSettingsPanel = ({ {saveAndReturnButton && ( { - await setCloseAdvancedSettingsWithDelay() - setClosingBySave(true) - closeAdvancedSettings() - }} + onClick={onSaveAndReturnClick} > {closingBySave ? ( <> diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx index 399b0df90..85dd3107d 100644 --- a/lib/components/form/util.tsx +++ b/lib/components/form/util.tsx @@ -36,10 +36,10 @@ export const addModeButtonIcon = export const addCustomSettingLabels = (intl: IntlShape) => (modeSetting: ModeSetting): ModeSetting => { - let modeLabel // If we're using route mode overrides, make sure we're using the custom mode name if (modeSetting.type === 'SUBMODE') { - modeLabel = modeSetting.overrideMode || modeSetting.addTransportMode.mode + const modeLabel = + modeSetting.overrideMode || modeSetting.addTransportMode.mode return { ...modeSetting, label: getFormattedMode(modeLabel, intl) @@ -61,12 +61,9 @@ export const onSettingsUpdate = export const setModeButton = (enabledModeButtons: string[], updateHandler: (params: any) => void) => (buttonId: string, newState: boolean): void => { - let newButtons - if (newState) { - newButtons = [...enabledModeButtons, buttonId] - } else { - newButtons = enabledModeButtons.filter((c) => c !== buttonId) - } + const newButtons = newState + ? [...enabledModeButtons, buttonId] + : enabledModeButtons.filter((c) => c !== buttonId) // encodeQueryParams serializes the mode buttons for the URL // to get nice looking URL params and consistency diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index bd6afc9f9..ad3eb4c3a 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -83,6 +83,7 @@ class BatchSearchScreen extends Component { > + {/* Unfortunately we can't use a ternary operator here because it is cancelling out the CSSTransition animations. */} {!showAdvancedModeSettings && ( Date: Fri, 20 Sep 2024 09:36:37 -0500 Subject: [PATCH 118/162] Whoops fix weird merge --- package.json | 2 +- yarn.lock | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 5b4a1881e..c70d313d7 100644 --- a/package.json +++ b/package.json @@ -255,4 +255,4 @@ "percy-css": ".percy-hide { opacity: 0!important; } " } } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e9bae79d3..7e76bf6b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2382,6 +2382,7 @@ integrity sha512-RDxZBAFMtqs1ZPnbUu1e7ohPNfoNhTiep4fErY7tZs995BeHu369Vsh5woMIaFbllRWEZBfvTCS4hvDnMPiHrA== dependencies: "@octokit/openapi-types" "^10.0.0" + "@opentripplanner/base-map@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" @@ -2414,7 +2415,7 @@ dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.2" + "@opentripplanner/geocoder" "^3.0.0" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" @@ -2482,7 +2483,6 @@ isomorphic-mapzen-search "^1.6.1" lodash.memoize "^4.1.2" - "@opentripplanner/geocoder@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" @@ -2588,7 +2588,7 @@ dependencies: "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/itinerary-body" "^5.3.6" - + "@opentripplanner/route-viewer-overlay@^2.0.17": version "2.0.17" resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-2.0.17.tgz#f34686fd965cf39650a10f64df599e7aca468415" @@ -2610,7 +2610,6 @@ glob-promise "^4.2.2" js-yaml "^4.1.0" - "@opentripplanner/stop-viewer-overlay@^2.0.10": version "2.0.10" resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-2.0.10.tgz#0749fe7ffb28dac7a6925ed7c663e2fdd5156f3b" @@ -19120,4 +19119,4 @@ yup@^0.29.3: lodash-es "^4.17.11" property-expr "^2.0.2" synchronous-promise "^2.0.13" - toposort "^2.0.2" + toposort "^2.0.2" \ No newline at end of file From bfca0e431bc322d8b9265cc057f0f5f3a8e97ec7 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:38:26 -0500 Subject: [PATCH 119/162] Add newline back --- package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c70d313d7..5b4a1881e 100644 --- a/package.json +++ b/package.json @@ -255,4 +255,4 @@ "percy-css": ".percy-hide { opacity: 0!important; } " } } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 7e76bf6b8..930fe34b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19119,4 +19119,4 @@ yup@^0.29.3: lodash-es "^4.17.11" property-expr "^2.0.2" synchronous-promise "^2.0.13" - toposort "^2.0.2" \ No newline at end of file + toposort "^2.0.2" From 0778c58e3cf601a67e34fb54e3702a790b320146 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:28:46 -0500 Subject: [PATCH 120/162] turn inline functions into class methods --- lib/components/app/batch-routing-panel.tsx | 40 ++++++++++--------- lib/components/mobile/batch-search-screen.tsx | 34 +++++++++------- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index 525e01fd5..5c6a69c73 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -55,6 +55,23 @@ class BatchRoutingPanel extends Component { } } + openAdvancedSettings = () => { + this.setState({ + closeAdvancedSettingsWithDelay: false, + showAdvancedModeSettings: true + }) + } + + closeAdvancedSettings = () => { + this.setState({ showAdvancedModeSettings: false }) + } + + setCloseAdvancedSettingsWithDelay = () => { + this.setState({ + closeAdvancedSettingsWithDelay: true + }) + } + handleSubmit = (e: FormEvent) => e.preventDefault() handlePlanTripClick = () => { @@ -110,17 +127,10 @@ class BatchRoutingPanel extends Component { }} > this.setState({ showAdvancedModeSettings: false }) - // eslint-disable-next-line react/jsx-curly-newline - } + closeAdvancedSettings={this.closeAdvancedSettings} innerRef={this._advancedSettingRef} setCloseAdvancedSettingsWithDelay={ - () => - this.setState({ - closeAdvancedSettingsWithDelay: true - }) - // eslint-disable-next-line react/jsx-curly-newline + this.setCloseAdvancedSettingsWithDelay } /> @@ -130,10 +140,7 @@ class BatchRoutingPanel extends Component { this.setState({ showAdvancedModeSettings: true }) - // eslint-disable-next-line react/jsx-curly-newline - } + onExit={this.openAdvancedSettings} timeout={transitionDurationWithDelay} >
@@ -164,12 +171,7 @@ class BatchRoutingPanel extends Component { - this.setState({ - closeAdvancedSettingsWithDelay: false, - showAdvancedModeSettings: true - // eslint-disable-next-line prettier/prettier - })} + openAdvancedSettings={this.openAdvancedSettings} />
diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index ad3eb4c3a..eb732a4a4 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -61,6 +61,23 @@ class BatchSearchScreen extends Component { this.setState({ planTripClicked: true }) } + openAdvancedSettings = () => { + this.setState({ + closeAdvancedSettingsWithDelay: false, + showAdvancedModeSettings: true + }) + } + + closeAdvancedSettings = () => { + this.setState({ showAdvancedModeSettings: false }) + } + + setCloseAdvancedSettingsWithDelay = () => { + this.setState({ + closeAdvancedSettingsWithDelay: true + }) + } + render() { const { intl } = this.props const { planTripClicked, showAdvancedModeSettings } = this.state @@ -119,11 +136,7 @@ class BatchSearchScreen extends Component { - this.setState({ showAdvancedModeSettings: true }) - // eslint-disable-next-line react/jsx-curly-newline - } + openAdvancedSettings={this.openAdvancedSettings} /> @@ -138,17 +151,10 @@ class BatchSearchScreen extends Component { }} > this.setState({ showAdvancedModeSettings: false }) - // eslint-disable-next-line prettier/prettier - } + closeAdvancedSettings={this.closeAdvancedSettings} innerRef={this._advancedSettingRef} setCloseAdvancedSettingsWithDelay={ - () => - this.setState({ - closeAdvancedSettingsWithDelay: true - }) - // eslint-disable-next-line react/jsx-curly-newline + this.setCloseAdvancedSettingsWithDelay } /> From b9445094881bf87fca306f3678a7d326207375a5 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Mon, 23 Sep 2024 11:12:38 -0400 Subject: [PATCH 121/162] refactor: address pr feedback --- lib/components/map/default-map.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 2b6cfdeec..38d7570e4 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -432,15 +432,22 @@ const mapStateToProps = (state) => { const viewedRoute = state.otp?.ui?.viewedRoute?.routeId const nearbyViewerActive = state.otp.ui.mainPanelContent === MainPanelContent.NEARBY_VIEW + + const viewedRoutePatterns = Object.entries( + state.otp?.transitIndex?.routes?.[viewedRoute]?.patterns || {} + ) const viewedRouteStops = viewedRoute && !nearbyViewerActive - ? Object.entries( - state.otp?.transitIndex?.routes?.[viewedRoute]?.patterns || {} - ).reduce((acc, cur) => { - return Array.from( - new Set([...cur?.[1]?.stops.map((s) => s.id), ...acc]) + ? // Ensure we don't have duplicates + Array.from( + new Set( + // Generate a list of every stop id the pattern stops at + viewedRoutePatterns.reduce((acc, cur) => { + // Convert pattern object to list of the pattern's stops + return [...cur?.[1]?.stops.map((s) => s.id), ...acc] + }, []) ) - }, []) + ) : null return { From cf8e32255d96792194239b7ddca13d506c7c8b71 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:58:19 -0500 Subject: [PATCH 122/162] Fix mobile transition timing --- lib/components/mobile/batch-search-screen.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index eb732a4a4..c24b4dacb 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -23,7 +23,11 @@ import MobileNavigationBar from './navigation-bar' const { SET_FROM_LOCATION, SET_TO_LOCATION } = MobileScreens -const MobileSearchSettings = styled.div<{ advancedPanelOpen: boolean }>` +const MobileSearchSettings = styled.div<{ + advancedPanelOpen: boolean + transitionDelay: number + transitionDuration: number +}>` background: white; box-shadow: 3px 0px 12px #00000052; height: ${(props) => @@ -32,7 +36,8 @@ const MobileSearchSettings = styled.div<{ advancedPanelOpen: boolean }>` position: fixed; right: 0; top: 50px; - transition: all 200ms ease; + transition: ${(props) => `all ${props.transitionDuration}ms ease`}; + transition-delay: ${(props) => props.transitionDelay}ms; /* Must appear under the 'hamburger' dropdown which has z-index of 1000. */ z-index: 999; ` @@ -97,6 +102,8 @@ class BatchSearchScreen extends Component { className={`batch-search-settings mobile-padding ${ showAdvancedModeSettings && 'advanced-mode-open' }`} + transitionDelay={transitionDelay} + transitionDuration={transitionDuration} > @@ -105,7 +112,7 @@ class BatchSearchScreen extends Component {
Date: Mon, 23 Sep 2024 12:57:01 -0500 Subject: [PATCH 123/162] Update snapshots --- .../viewers/__snapshots__/nearby-view.js.snap | 1154 ++++++++--------- .../stop-schedule-viewer.ts.snap | 6 +- 2 files changed, 580 insertions(+), 580 deletions(-) diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 3d4a9501a..3f82632bd 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -46,7 +46,7 @@ exports[`components > viewers > nearby view renders nothing on a blank page 1`] className="nearby-view base-color-bg" >
viewers > nearby view renders nothing on a blank page 1`] } >
    viewers > nearby view renders proper scooter dates 1`] = ` className="nearby-view base-color-bg" >
    viewers > nearby view renders proper scooter dates 1`] = ` } >
      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
      viewers > nearby view renders proper scooter dates 1`] = ` >

      Roosevelt Station - Bay 2 @@ -10036,7 +10036,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = ` >

              Roosevelt @@ -16883,7 +16883,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = `

              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
              • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      Roosevelt Station - Bay 1 @@ -26397,7 +26397,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="988" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                Roosevelt Station Bay 5 - Bay 5 @@ -35949,7 +35949,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                  viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                • viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="984" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                        Roosevelt @@ -43780,7 +43780,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                        • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = ` >

                                            Roosevelt Station - Bay 3 @@ -51332,7 +51332,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = `

                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                            • viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          NE 65th St & 14th Ave NE @@ -62499,7 +62499,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                            viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                          • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > stop viewer should render with initial stop id a > viewers > stop viewer should render with initial stop id a

                                                                Date: Mon, 23 Sep 2024 13:20:19 -0500 Subject: [PATCH 124/162] Update percy tests --- lib/components/form/advanced-settings-button.tsx | 2 +- lib/components/form/advanced-settings-panel.tsx | 1 + percy/percy.test.js | 11 +++++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/components/form/advanced-settings-button.tsx b/lib/components/form/advanced-settings-button.tsx index 4e43386bd..0449dc85d 100644 --- a/lib/components/form/advanced-settings-button.tsx +++ b/lib/components/form/advanced-settings-button.tsx @@ -20,7 +20,7 @@ const StyledTransparentButton = styled.button` ` const AdvancedSettingsButton = ({ onClick }: Props): JSX.Element => ( - + diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx index a0a6c5cc5..ea085d017 100644 --- a/lib/components/form/advanced-settings-panel.tsx +++ b/lib/components/form/advanced-settings-panel.tsx @@ -188,6 +188,7 @@ const AdvancedSettingsPanel = ({ { closeAdvancedSettings() }} diff --git a/percy/percy.test.js b/percy/percy.test.js index c4ac7142e..52fdcdb63 100644 --- a/percy/percy.test.js +++ b/percy/percy.test.js @@ -133,16 +133,19 @@ async function executeTest(page, isMobile, isCallTaker) { await page.keyboard.press('Escape') await page.waitForTimeout(200) - // Check submode selector (this will have no effect on mock query) - await page.hover('label[title="Transit"]') + // Open advanced settings and wait for animation + await page.click('#open-advanced-settings-button') await page.waitForTimeout(500) + + // Check submode selector (this will have no effect on mock query) await page.click('#id-query-param-tram') // Enable accessible routing (this will have no effect on mock query) - await page.hover('label[title="Transit"]') - await page.waitForTimeout(500) await page.click('#id-query-param-wheelchair') + // Close advanced settings + await page.click('#close-advanced-settings-button') + // Delete both origin and destination await page.click('.from-form-control') From 61e9e19df87baf62563d0c325bef02ab310b9481 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Mon, 23 Sep 2024 14:23:39 -0700 Subject: [PATCH 125/162] implement new isTransitLeg func --- lib/actions/field-trip.js | 7 ++--- .../narrative/default/default-itinerary.js | 4 +-- .../default/itinerary-description.tsx | 9 ++---- .../narrative/default/itinerary-summary.js | 13 +++++--- .../line-itin/realtime-time-column.tsx | 5 ++- .../narrative/narrative-itineraries.js | 6 ++-- .../trip-notifications-pane.tsx | 6 ++-- lib/util/itinerary.tsx | 5 +-- lib/util/viewer.js | 3 +- package.json | 2 +- yarn.lock | 31 ++++++++++++++++++- 11 files changed, 58 insertions(+), 33 deletions(-) diff --git a/lib/actions/field-trip.js b/lib/actions/field-trip.js index c9f085e52..c1f19e5b4 100644 --- a/lib/actions/field-trip.js +++ b/lib/actions/field-trip.js @@ -6,7 +6,7 @@ import { getRoutingParams, planParamsToQueryAsync } from '@opentripplanner/core-utils/lib/query' -import { isTransit } from '@opentripplanner/core-utils/lib/itinerary' +import { isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import { OTP_API_DATE_FORMAT, OTP_API_TIME_FORMAT @@ -396,7 +396,7 @@ function makeSaveFieldTripItinerariesData(request, outbound, state) { const gtfsTripsForItinerary = [] itinerary.legs - .filter((leg) => isTransit(leg.mode)) + .filter((leg) => isTransitLeg(leg)) .forEach((leg) => { let routeName = leg.routeShortName ? `(${leg.routeShortName}) ` : '' routeName = `${routeName}${leg.routeLongName}` @@ -613,7 +613,6 @@ function getMissingTripHashesForActiveItineraries() { }) ) } - return true } /** @@ -710,7 +709,7 @@ function checkValidityAndCapacity(state, request) { // check each individual trip to see if there aren't any trips in this // itinerary that are already in use by another field trip itinerary.legs - .filter((leg) => isTransit(leg.mode)) + .filter((leg) => isTransitLeg(leg.mode)) .forEach((leg) => { const tripId = leg?.trip?.gtfsId diff --git a/lib/components/narrative/default/default-itinerary.js b/lib/components/narrative/default/default-itinerary.js index 89219244f..bdfdb7b7c 100644 --- a/lib/components/narrative/default/default-itinerary.js +++ b/lib/components/narrative/default/default-itinerary.js @@ -36,7 +36,7 @@ const { isAdvanceBookingRequired, isCoordinationRequired, isFlex, - isTransit + isTransitLeg } = coreUtils.itinerary // Styled components @@ -164,7 +164,7 @@ const ITINERARY_ATTRIBUTES = [ order: 3, render: (itinerary, options) => { const leg = clone(itinerary.legs[0]) - if (isTransit(leg.mode)) { + if (isTransitLeg(leg.mode)) { leg.mode = 'WALK' } diff --git a/lib/components/narrative/default/itinerary-description.tsx b/lib/components/narrative/default/itinerary-description.tsx index 2c12d358d..9e2f1327a 100644 --- a/lib/components/narrative/default/itinerary-description.tsx +++ b/lib/components/narrative/default/itinerary-description.tsx @@ -9,7 +9,7 @@ import FormattedMode from '../../util/formatted-mode' const { isRideshareLeg } = coreUtils.itinerary -const { isBicycle, isMicromobility, isTransit } = coreUtils.itinerary +const { isBicycle, isMicromobility, isTransitLeg } = coreUtils.itinerary type Props = { combineTransitModes?: boolean @@ -32,10 +32,7 @@ export function getMainItineraryModes({ let transitMode itinerary.legs.forEach((leg, i) => { const { duration, mode, rentedBike, rentedVehicle } = leg - if ( - (leg.transitLeg || isTransit(mode)) && - duration > primaryTransitDuration - ) { + if (isTransitLeg(leg) && duration > primaryTransitDuration) { primaryTransitDuration = duration transitMode = getFormattedMode( combineTransitModes ? 'transit' : mode.toLowerCase(), @@ -68,7 +65,7 @@ export function ItineraryDescription({ itinerary }: Props): JSX.Element { let transitMode itinerary.legs.forEach((leg) => { const { duration, mode, rentedBike, rentedVehicle } = leg - if (leg.transitLeg && duration > primaryTransitDuration) { + if (isTransitLeg(leg) && duration > primaryTransitDuration) { primaryTransitDuration = duration // If custom TransitModes have been defined for the given mode/leg, attempt to use them, diff --git a/lib/components/narrative/default/itinerary-summary.js b/lib/components/narrative/default/itinerary-summary.js index 5ff8dcc8f..5d327407b 100644 --- a/lib/components/narrative/default/itinerary-summary.js +++ b/lib/components/narrative/default/itinerary-summary.js @@ -1,7 +1,10 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ import { connect } from 'react-redux' -import { getCompanyFromLeg } from '@opentripplanner/core-utils/lib/itinerary' +import { + getCompanyFromLeg, + isTransitLeg +} from '@opentripplanner/core-utils/lib/itinerary' import PropTypes from 'prop-types' import React, { Component } from 'react' import styled from 'styled-components' @@ -93,16 +96,16 @@ export default class ItinerarySummary extends Component { if ( i > 0 && i < itinerary.legs.length - 1 && - !leg.transitLeg && - itinerary.legs[i - 1].transitLeg && - itinerary.legs[i + 1].transitLeg + !isTransitLeg(leg) && + isTransitLeg(itinerary.legs[i - 1]) && + isTransitLeg(itinerary.legs[i + 1]) ) { return null } // Add the mode icon let title = leg.mode - if (leg.transitLeg) { + if (isTransitLeg(leg)) { title = leg.routeShortName ? `${leg.routeShortName}${ leg.routeLongName ? ` - ${leg.routeLongName}` : '' diff --git a/lib/components/narrative/line-itin/realtime-time-column.tsx b/lib/components/narrative/line-itin/realtime-time-column.tsx index f9858b038..0c5f802f8 100644 --- a/lib/components/narrative/line-itin/realtime-time-column.tsx +++ b/lib/components/narrative/line-itin/realtime-time-column.tsx @@ -1,5 +1,5 @@ import { FormattedTime } from 'react-intl' -import { isTransit } from '@opentripplanner/core-utils/lib/itinerary' +import { isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import { Leg } from '@opentripplanner/types' import React, { ReactElement } from 'react' import styled from 'styled-components' @@ -33,8 +33,7 @@ function RealtimeTimeColumn({ isDestination, leg }: Props): ReactElement { } const timeMillis = isDestination ? leg.endTime : leg.startTime - const isTransitLeg = leg.transitLeg - const isRealtimeTransitLeg = isTransitLeg && leg.realTime + const isRealtimeTransitLeg = isTransitLeg(leg) && leg.realTime // For non-transit legs show only the scheduled time. if (!isTransitLeg) { diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index 7d9faded6..5c7faf9f0 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux' import { differenceInDays } from 'date-fns' import { FormattedMessage, injectIntl } from 'react-intl' -import { isFlex, isTransit } from '@opentripplanner/core-utils/lib/itinerary' +import { isFlex, isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import clone from 'clone' import coreUtils from '@opentripplanner/core-utils' import memoize from 'lodash.memoize' @@ -423,9 +423,7 @@ class NarrativeItineraries extends Component { }) // Identify whether an itinerary uses transit & sort into appropriate bucket - const transitLegs = cur.legs.filter( - (leg) => isTransit(leg.mode) | leg.transitLeg - ) + const transitLegs = cur.legs.filter((leg) => isTransitLeg(leg.mode)) const modeContainer = transitLegs.length > 0 ? modeItinMap.multi : modeItinMap.single diff --git a/lib/components/user/monitored-trip/trip-notifications-pane.tsx b/lib/components/user/monitored-trip/trip-notifications-pane.tsx index 197275a4a..d02bbf52c 100644 --- a/lib/components/user/monitored-trip/trip-notifications-pane.tsx +++ b/lib/components/user/monitored-trip/trip-notifications-pane.tsx @@ -2,7 +2,7 @@ import { Alert, FormControl } from 'react-bootstrap' import { ExclamationTriangle } from '@styled-icons/fa-solid/ExclamationTriangle' import { FormattedList, FormattedMessage } from 'react-intl' import { FormikProps } from 'formik' -import { Leg } from '@opentripplanner/types' +import { isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import React, { Component, FormEvent } from 'react' import styled from 'styled-components' @@ -74,9 +74,7 @@ class TripNotificationsPane extends Component { values.arrivalVarianceMinutesThreshold, values.departureVarianceMinutesThreshold ) - const hasTransit = values.itinerary?.legs?.some( - (leg: Leg) => leg.transitLeg - ) + const hasTransit = values.itinerary?.legs?.some(isTransitLeg) let notificationSettingsContent if (areNotificationsDisabled) { diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index b6b1cb524..f1d5f4f5a 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -1,4 +1,5 @@ import { differenceInMinutes } from 'date-fns' +import { isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import { Itinerary, Leg, Place } from '@opentripplanner/types' import { toDate, utcToZonedTime } from 'date-fns-tz' import coreUtils from '@opentripplanner/core-utils' @@ -81,7 +82,7 @@ export function getMinutesUntilItineraryStart(itinerary: Itinerary): number { * Gets the first transit leg of the given itinerary, or null if none found. */ function getFirstTransitLeg(itinerary: Itinerary) { - return itinerary?.legs?.find((leg) => leg.transitLeg) + return itinerary?.legs?.find((leg) => isTransitLeg(leg)) } /** @@ -373,7 +374,7 @@ export function getTotalFare( ) { hasBikeshare = true } - if (leg.transitLeg && transitFare == null) { + if (isTransitLeg(leg) && transitFare == null) { transitFareNotProvided = true } }) diff --git a/lib/util/viewer.js b/lib/util/viewer.js index 9aabdacc2..706a84f11 100644 --- a/lib/util/viewer.js +++ b/lib/util/viewer.js @@ -4,6 +4,7 @@ import { getMostReadableTextColor } from '@opentripplanner/core-utils/lib/route' import tinycolor from 'tinycolor2' import { DARK_TEXT_GREY } from '../components/util/colors' +import { isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import { checkForRouteModeOverride } from './config' import { getOperatorAndRoute } from './state' @@ -254,7 +255,7 @@ export function getTripStatus( * has realtime info */ export function firstTransitLegIsRealtime(itinerary) { - const firstTransitLeg = itinerary.legs.find((leg) => !!leg.transitLeg) + const firstTransitLeg = itinerary.legs.find((leg) => !!isTransitLeg(leg)) return firstTransitLeg?.realTime } diff --git a/package.json b/package.json index 109ae8d1f..1c7dc6791 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@floating-ui/react": "^0.19.2", "@opentripplanner/base-map": "^3.2.0", "@opentripplanner/building-blocks": "^1.1.0", - "@opentripplanner/core-utils": "^11.4.3", + "@opentripplanner/core-utils": "^11.5.0", "@opentripplanner/endpoints-overlay": "^2.1.1", "@opentripplanner/from-to-location-picker": "^2.1.13", "@opentripplanner/geocoder": "^3.0.1", diff --git a/yarn.lock b/yarn.lock index 652b8cc0a..306fb94b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2398,7 +2398,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== -"@opentripplanner/core-utils@^11.0.2", "@opentripplanner/core-utils@^11.4.1", "@opentripplanner/core-utils@^11.4.3": +"@opentripplanner/core-utils@^11.0.2", "@opentripplanner/core-utils@^11.4.1": version "11.4.3" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.3.tgz#4655f9a3bef1977e53abd81a4a0eae966f977c60" integrity sha512-GbvchRsLfEi9JygUx6ypU+Iqv2hELseC53yQyQ/XdnB1kcHzN71BtBbz+qpD5/jk8IuM92j1taRnGMeu5ni6yA== @@ -2434,6 +2434,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@^11.5.0": + version "11.5.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.5.0.tgz#b0aaa7724bb44fadc71c7027fe9eacac09e4e042" + integrity sha512-kRn50DSnET6t8Zdwx5hoGz6ZwOegvq70Ovxs6shgJJRKuEj5tEhkPyuqY+LndTG8NWuZj9Ql9Vb4Va7kZbHAvA== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.0" + "@opentripplanner/geocoder" "^3.0.2" + "@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@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.1.tgz#e7029d95bd13436aacbc6f854c243d1fcf7e8570" @@ -2465,6 +2483,17 @@ isomorphic-mapzen-search "^1.6.1" lodash.memoize "^4.1.2" +"@opentripplanner/geocoder@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" + integrity sha512-pl7tCiodex0hXWKLH3WE+I+HzoSgOOWp9kR3xMcuRiE5g6k2JXNneoD/ZfSS1n6Oorxcjv3U2DbMSXT2j/39dQ== + dependencies: + "@conveyal/geocoder-arcgis-geojson" "^0.0.3" + "@conveyal/lonlat" "^1.4.1" + "@leeoniya/ufuzzy" "^1.0.14" + isomorphic-mapzen-search "^1.6.1" + lodash.memoize "^4.1.2" + "@opentripplanner/humanize-distance@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" From 7b7f23864a0ed1abe91fa4c7bbd35a62084f842b Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Mon, 23 Sep 2024 14:32:10 -0700 Subject: [PATCH 126/162] i18n: delete unused keys --- i18n/en-US.yml | 4 ---- i18n/fr.yml | 6 ------ 2 files changed, 10 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index f03fa5bce..9d8db0352 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -109,13 +109,11 @@ common: submitting: Submitting… "yes": "Yes" itineraryDescriptions: - calories: "{calories, number} Cal" fareUnknown: No fare information noItineraryToDisplay: No itinerary to display. relativeCo2: | {co2} {isMore, select, true {more} other {less} } CO₂ than driving alone timeStartEnd: "{start} – {end}" - transfers: "{transfers, plural, =0 {} one {# transfer} other {# transfers}}" linkOpensNewWindow: (Opens new window) modes: bicycle_rent: Bikeshare @@ -154,7 +152,6 @@ common: enterStartLocation: Enter start location or {mapAction} on map… tap: tap time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" duration: aFewSeconds: a few seconds nDays: "{days, plural, =1 {one day} other {# days}}" @@ -262,7 +259,6 @@ components: ariaLabel: Form navigation ItinerarySummary: itineraryDetails: Itinerary details - minMaxFare: "{minTotalFare} - {maxTotalFare}" LocationSearch: enterLocation: Enter location setDestination: Set Destination diff --git a/i18n/fr.yml b/i18n/fr.yml index 082b0e96a..e5043f89b 100644 --- a/i18n/fr.yml +++ b/i18n/fr.yml @@ -118,15 +118,11 @@ common: submitting: Envoi en cours… "yes": Oui itineraryDescriptions: - calories: "{calories, number} kcal" fareUnknown: Tarif inconnu noItineraryToDisplay: Aucun trajet à afficher. relativeCo2: | {co2} de CO₂ en {isMore, select, true {plus} other {moins} } qu'en voiture timeStartEnd: "{start} – {end}" - transfers: >- - {transfers, plural, =0 {} one {# correspondance} other {# - correspondances}} linkOpensNewWindow: (Ouvre une nouvelle fenêtre) modes: bicycle_rent: En vélo en libre-service @@ -165,7 +161,6 @@ common: enterStartLocation: Entrez votre point de départ ou {mapAction} sur la carte… tap: appuyez time: - departureArrivalTimes: "{startTime, time, short}—{endTime, time, short}" duration: aFewSeconds: quelques secondes nDays: "{days, plural, =1 {un jour} other {# jours}}" @@ -279,7 +274,6 @@ components: ariaLabel: Navigation du formulaire ItinerarySummary: itineraryDetails: Détails du trajet - minMaxFare: "{minTotalFare} - {maxTotalFare}" LocationSearch: enterLocation: Entrez le lieu setDestination: Destination From 45e47e58bc6f3ca19735cbe978cd281c127601d8 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:29:09 -0500 Subject: [PATCH 127/162] update otp-ui packages --- package.json | 42 +++--- yarn.lock | 388 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 252 insertions(+), 178 deletions(-) diff --git a/package.json b/package.json index e6f6f0785..34e1e7c8f 100644 --- a/package.json +++ b/package.json @@ -42,30 +42,30 @@ "@bugsnag/js": "^7.17.0", "@bugsnag/plugin-react": "^7.17.0", "@floating-ui/react": "^0.19.2", - "@opentripplanner/base-map": "^3.2.2", - "@opentripplanner/building-blocks": "^1.2.3", - "@opentripplanner/core-utils": "^11.4.4", - "@opentripplanner/endpoints-overlay": "^2.1.4", - "@opentripplanner/from-to-location-picker": "^2.1.14", + "@opentripplanner/base-map": "4.0.0", + "@opentripplanner/building-blocks": "2.0.0", + "@opentripplanner/core-utils": "12.0.0", + "@opentripplanner/endpoints-overlay": "3.0.0", + "@opentripplanner/from-to-location-picker": "3.0.0", "@opentripplanner/geocoder": "^3.0.2", "@opentripplanner/humanize-distance": "^1.2.0", - "@opentripplanner/icons": "^2.0.13", - "@opentripplanner/itinerary-body": "^5.3.7", - "@opentripplanner/location-field": "^2.0.24", + "@opentripplanner/icons": "3.0.0", + "@opentripplanner/itinerary-body": "6.0.0", + "@opentripplanner/location-field": "3.0.0", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "^4.0.2", - "@opentripplanner/otp2-tile-overlay": "^1.0.17", - "@opentripplanner/park-and-ride-overlay": "^2.0.9", - "@opentripplanner/printable-itinerary": "^2.0.23", - "@opentripplanner/route-viewer-overlay": "^2.0.17", - "@opentripplanner/stop-viewer-overlay": "^2.0.10", - "@opentripplanner/stops-overlay": "^5.3.3", - "@opentripplanner/transit-vehicle-overlay": "^4.0.13", - "@opentripplanner/transitive-overlay": "3.0.22", - "@opentripplanner/trip-details": "^5.0.15", - "@opentripplanner/trip-form": "^3.7.0-alpha.5", - "@opentripplanner/trip-viewer-overlay": "^2.0.10", - "@opentripplanner/vehicle-rental-overlay": "^2.1.9", + "@opentripplanner/map-popup": "5.0.0", + "@opentripplanner/otp2-tile-overlay": "2.0.0", + "@opentripplanner/park-and-ride-overlay": "3.0.0", + "@opentripplanner/printable-itinerary": "3.0.0", + "@opentripplanner/route-viewer-overlay": "3.0.0", + "@opentripplanner/stop-viewer-overlay": "3.0.0", + "@opentripplanner/stops-overlay": "6.0.0", + "@opentripplanner/transit-vehicle-overlay": "5.0.0", + "@opentripplanner/transitive-overlay": "4.0.0", + "@opentripplanner/trip-details": "6.0.0", + "@opentripplanner/trip-form": "4.0.0", + "@opentripplanner/trip-viewer-overlay": "3.0.0", + "@opentripplanner/vehicle-rental-overlay": "3.0.0", "@styled-icons/fa-regular": "^10.34.0", "@styled-icons/fa-solid": "^10.34.0", "@turf/centroid": "^6.5.0", diff --git a/yarn.lock b/yarn.lock index cae490f89..7d175cca4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,7 +43,15 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.5.5": +"@babel/code-frame@^7.0.0": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + +"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.5.5": version "7.22.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== @@ -305,11 +313,16 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.22.5": +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.22.5", "@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + "@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" @@ -334,7 +347,7 @@ "@babel/traverse" "^7.15.0" "@babel/types" "^7.15.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.22.13": +"@babel/highlight@^7.10.4": version "7.22.13" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.13.tgz#9cda839e5d3be9ca9e8c26b6dd69e7548f0cbf16" integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ== @@ -343,6 +356,16 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@babel/highlight@^7.22.13", "@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/parser@^7.1.0", "@babel/parser@^7.11.5", "@babel/parser@^7.12.3", "@babel/parser@^7.15.0", "@babel/parser@^7.16.4", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" @@ -1096,13 +1119,20 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.19.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.20.7", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.22.11" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.11.tgz#7a9ba3bbe406ad6f9e8dd4da2ece453eb23a77a4" integrity sha512-ee7jVNlWN09+KftVOu9n7S8gQzD/Z6hN/I8VBRXW4P1+Xe7kJGXMwu8vds4aGIMHZnNbdpSWCfZZtinytpcAvA== dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.19.0", "@babel/runtime@^7.21.0": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" + integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.10.4", "@babel/template@^7.14.5", "@babel/template@^7.22.15", "@babel/template@^7.3.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" @@ -2082,11 +2112,11 @@ integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ== "@mapbox/polyline@^1.1.0", "@mapbox/polyline@^1.1.1": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@mapbox/polyline/-/polyline-1.2.0.tgz#11f7481968a83bd9dde36273a50b8037af24a86b" - integrity sha512-sIIi9clVZiTmXYqbXpSAoG+ZLsvQn7j9FJLqiNOG85KnXN8tz11MEhuW2M7NDEDIKi4hIMaSI1CKwH8oLuVxPQ== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@mapbox/polyline/-/polyline-1.2.1.tgz#1eecce5e8c0d9e6dfc718b225e8e9f03591ea636" + integrity sha512-sn0V18O3OzW4RCcPoUIVDWvEGQaBNH9a0y5lgqrf5hUycyw1CzrhEoxV5irzrMNXKCkw1xRsZXcaVbsVZggHXA== dependencies: - meow "^6.1.1" + meow "^9.0.0" "@mapbox/tiny-sdf@^2.0.4": version "2.0.5" @@ -2383,12 +2413,12 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" - integrity sha512-d/yTKEnXqrw9pXhSvCERT+wLFa077Xr4wEFu4pYB+WYoZFflNxuTuAXXjm268HS/d0kjNndkjSMkxaKk6AjsvA== +"@opentripplanner/base-map@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-4.0.0.tgz#56ffa1d833673282cc3a0b7a17f388fc5dbd31e3" + integrity sha512-pWTKXxnzUQk43woPMc40uYfGIcGqHV8GoCvRwrIu2pqNw7QAV4rxjZfca0pm5hnbbJ+G83sRzYboILEbEUwMcw== dependencies: - "@opentripplanner/map-popup" "^3.1.0" + "@opentripplanner/building-blocks" "^1.2.2" mapbox-gl "npm:empty-npm-package@1.0.0" maplibre-gl "^2.1.9" react-map-gl "^7.0.15" @@ -2403,24 +2433,29 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" +"@opentripplanner/building-blocks@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-2.0.0.tgz#8282c01dff7db5c7e809f6ea91cb52df559a2f9d" + integrity sha512-N07rDaZL8fp552eI9/0j1udKjc0uOpvO0Wv1P19Ge0a4roques463MJgWJ026fbopRCi3uwbc/gYTlh4/ske9A== + "@opentripplanner/building-blocks@^1.0.3": version "1.1.0" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== -"@opentripplanner/building-blocks@^1.2.2", "@opentripplanner/building-blocks@^1.2.3": +"@opentripplanner/building-blocks@^1.2.2": version "1.2.3" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@^11.4.0": - version "11.4.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" - integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== +"@opentripplanner/core-utils@12.0.0": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" + integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/geocoder" "^3.0.2" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" @@ -2432,9 +2467,9 @@ qs "^6.9.1" "@opentripplanner/core-utils@^11.4.4": - version "11.4.5" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.5.tgz#f568f5f60f153f0bd74fe47ed3134851067b0064" - integrity sha512-uYaVqZXZoRRVks05KdGMTIeGEC7ItKJvexZqKsEbZMjnnMphHRndv4aSDXM19iL7ynoau7JXjYfYEny1HDp7ig== + version "11.5.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.5.0.tgz#b0aaa7724bb44fadc71c7027fe9eacac09e4e042" + integrity sha512-kRn50DSnET6t8Zdwx5hoGz6ZwOegvq70Ovxs6shgJJRKuEj5tEhkPyuqY+LndTG8NWuZj9Ql9Vb4Va7kZbHAvA== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" @@ -2449,10 +2484,10 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/endpoints-overlay@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.4.tgz#f81088bce83236344dfa4a51b2efe00092a5c87a" - integrity sha512-VLRZArhoRQ38aafc/w986Uv1lnq/WLJOgBqnpvuUbLhLR/qHU9h5X3wg3jgwf2GA0BIn03Z99VJbCkGfkyd0LA== +"@opentripplanner/endpoints-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-3.0.0.tgz#17bb943f5bf2b8571cb808b12b5a2185fd18196a" + integrity sha512-st6vfLRCBzVollYS4nIXghbjApDq73lcExo7hZh60DCVSGESSZA9jsNE6ff0HmvhYHdag9QV9zbZOFuNxPIrng== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/building-blocks" "^1.2.2" @@ -2461,10 +2496,10 @@ "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" -"@opentripplanner/from-to-location-picker@^2.1.12", "@opentripplanner/from-to-location-picker@^2.1.13": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-2.1.13.tgz#d13acd582929175c676cd4303a6cdc6e1c289d99" - integrity sha512-6/7+wYQuuQhnGvxkDQcvoACdmuwUL1BlPqBIUFwyBpkdJ1VQGZiUSAAZTxXdY1Fv/p5mKR1vRsvZgtSPhcxgcg== +"@opentripplanner/from-to-location-picker@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-3.0.0.tgz#048a596c2f854825e0058e03dac67dcad7eb5864" + integrity sha512-jRXaY9jKg+PXUL7Z2SkHRyO88xG1t7iG3U449LPiCm/6flxsY+Wlxg+nyMsAP5gQMjOU0wsGLdH83lGgrpSF4A== dependencies: "@opentripplanner/location-icon" "^1.4.1" flat "^5.0.2" @@ -2477,17 +2512,6 @@ "@opentripplanner/location-icon" "^1.4.1" flat "^5.0.2" -"@opentripplanner/geocoder@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.1.tgz#834960bc52f515e1223346a8002fb847674d33bc" - integrity sha512-+LHTqY8pHmPE39IjVev5T5baa+BohEyvsLwVwFB2bYWzM+m/RgAJ188uBcDzXKdqk5y3dZR9ZODYVMtrvIiKzQ== - dependencies: - "@conveyal/geocoder-arcgis-geojson" "^0.0.3" - "@conveyal/lonlat" "^1.4.1" - "@leeoniya/ufuzzy" "^1.0.14" - isomorphic-mapzen-search "^1.6.1" - lodash.memoize "^4.1.2" - "@opentripplanner/geocoder@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" @@ -2504,7 +2528,15 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA== -"@opentripplanner/icons@^2.0.12", "@opentripplanner/icons@^2.0.13": +"@opentripplanner/icons@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-3.0.0.tgz#f7293fd4dd2625eace3a4c82ecd573d6000d85d3" + integrity sha512-naSCdCsPwSyEiP7Vf6oN6dpgwpFIkeQFXfTJG7lp1Dg9emLTAYzRx/f+45e9Bh0zP0aA4DsN4VgHBQllyu82qQ== + dependencies: + "@opentripplanner/core-utils" "^11.4.4" + prop-types "^15.7.2" + +"@opentripplanner/icons@^2.0.12": version "2.0.13" resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.13.tgz#45c4c16d8f208cff73811941f2def0fa23f87780" integrity sha512-1oEPCmFuyS88bJZ2U9eFlEw2kQ0ZZW+wOI1dggr0omJDD6L+nVNQJ6TUtosNHYL1S35Jpx4aSQEG3iwwlXOHMg== @@ -2512,7 +2544,25 @@ "@opentripplanner/core-utils" "^11.4.4" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@^5.3.6", "@opentripplanner/itinerary-body@^5.3.7": +"@opentripplanner/itinerary-body@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-6.0.0.tgz#e261bcccd0d7a786f7f17be987a52ba1dc940229" + integrity sha512-j79byCefyEZuomvDlvBZJVZJ92+X6U4ivth3M62RKGmw1x8qW4nsbEKnzeQxXzGJcy3M+91eeIpcJnj98KHlRw== + dependencies: + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/humanize-distance" "^1.2.0" + "@opentripplanner/icons" "^2.0.12" + "@opentripplanner/location-icon" "^1.4.1" + "@styled-icons/fa-solid" "^10.34.0" + "@styled-icons/foundation" "^10.34.0" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + flat "^5.0.2" + react-animate-height "^3.0.4" + react-resize-detector "^4.2.1" + string-similarity "^4.0.4" + +"@opentripplanner/itinerary-body@^5.3.6": version "5.3.7" resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.7.tgz#e32437f804defc19aef23685e45c0a363ac8bc31" integrity sha512-ZnbxI78WsY6/Ynl3QY026JqimGG+gqXcN8ZEXY/BPMrNhSul27HgFFT2Flo37Fnc5gN2+jE8LsR1yxq05H3kvQ== @@ -2530,10 +2580,10 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" -"@opentripplanner/location-field@^2.0.24": - version "2.0.24" - resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.24.tgz#32e7109142bd754d28bd28ebbdf68d4e5ef4c812" - integrity sha512-fOAyanDnLLHC39kHG6kMSY6i09n4l0KSVQACFoosGZgUcJmz5CUCMl0/x3RszIwh3g2wqxKh6fagh4V56YEpfQ== +"@opentripplanner/location-field@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-3.0.0.tgz#a6f8743290cf088bcd589cf8e6b0d07a651b704a" + integrity sha512-wPb9l5pvSeocZ45K1E3Zeb4hDjJtP9tw/S0MQ3HXYEQSf+700n4CWXVXYReYJXJYriOzge5/2whjUPGTlJckWw== dependencies: "@conveyal/geocoder-arcgis-geojson" "^0.0.3" "@opentripplanner/core-utils" "^11.4.4" @@ -2551,16 +2601,18 @@ "@styled-icons/fa-regular" "^10.34.0" "@styled-icons/fa-solid" "^10.34.0" -"@opentripplanner/map-popup@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.1.1.tgz#54f081162d328cc4bb0e89562f9ea200e29e01a1" - integrity sha512-yWBIPuYGw7biaRNIpglQm5+opZ+D5QQgXHLhKnYaCR0eNijjl9cx34lGXdyKPXt26S6MiyJZXL81uc6w6CnQ3A== +"@opentripplanner/map-popup@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-5.0.0.tgz#cf360845704ed54222c8bf19581ed1253d3dcf14" + integrity sha512-cuIzZm/cZbjY2tAVLSDpBK63efR+YsEsXVPBx4VAHlGhJoY1yooipFlq+3/51VSsFOJPp6gcsKaizfdICDJlYA== dependencies: - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/from-to-location-picker" "^2.1.12" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/from-to-location-picker" "^2.1.14" flat "^5.0.2" -"@opentripplanner/map-popup@^4.0.0", "@opentripplanner/map-popup@^4.0.2": +"@opentripplanner/map-popup@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-4.0.2.tgz#367ab7ce69d16d319988bb48d8f6d2db762623c7" integrity sha512-RlHv9GE3Bk3++PwBcaPcALr6rZ+2AxY6Uj6W71AnLqz+wbeQO5rM3eEP99r0Sg1K3pAY0hXljBkVwKiUWhwxbQ== @@ -2571,33 +2623,33 @@ "@opentripplanner/from-to-location-picker" "^2.1.14" flat "^5.0.2" -"@opentripplanner/otp2-tile-overlay@^1.0.17": - version "1.0.17" - resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-1.0.17.tgz#0e63bcb956778bbab6bd42d282aa9f5416881b74" - integrity sha512-mgMHprVVOXdzgU0D/50be57TeuEp1RP+b7xH/3Xt+rj0mF1PY+5GgLMuEul+1WqbzFwAefrmi9KRMs3MYJArrg== +"@opentripplanner/otp2-tile-overlay@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-2.0.0.tgz#6af1a9113a8baaebb226a5e747e8e523f6da249b" + integrity sha512-Yc0VsfxS6xIw4+1i9lpvQyCXobkTubZWYYu+6bDWkk77D4J4WaSoWE/qWT39vc2/h1ZY4afUZL59d7kc8V0PLg== dependencies: "@opentripplanner/map-popup" "^4.0.0" -"@opentripplanner/park-and-ride-overlay@^2.0.9": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-2.0.9.tgz#0efe2bf8a7595b56c4da6396e89db5f04e4b3ec8" - integrity sha512-ekf6kcCgMVTzXDMY3Ed8qclaL3YY2/1BrArdpRY8DxciGWmE1HKOW90Vf1aP18aLrwcW9kpvv1Kdbl60tY6mCQ== +"@opentripplanner/park-and-ride-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-3.0.0.tgz#7139d5358bc8e5f68f1574e9225a3bcfb57993be" + integrity sha512-MLalzHhXSZ1yAwW9cyMVoUUQPMGktTTPFbhgEB/Ft4fX/TJAIH1sQHsKoaeGE0+48Kxg4M49zPoeNujr9RIeGA== dependencies: - "@opentripplanner/base-map" "^3.2.0" - "@opentripplanner/from-to-location-picker" "^2.1.13" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/from-to-location-picker" "^2.1.14" -"@opentripplanner/printable-itinerary@^2.0.23": - version "2.0.23" - resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.23.tgz#31f11e0e22bb9f223c4c1d8fa97c6eea18496cfa" - integrity sha512-Cb5SX7ts0rX0P1XSStjqbTITP5ueWlDe1b7U4KMaRNqEOaK2tELEyb/qZGo9kMpXTT/17jmEQZsKHQj43C5Eyg== +"@opentripplanner/printable-itinerary@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-3.0.0.tgz#7f4438b18cbd767ede74b2a3b7e3ad6ab1ec936b" + integrity sha512-/P7HtzXPu0yP6ZnfHl1DQFTVgEx+YplLxs43jd7rnXc0PUvsVyAsmp4oI3TDG8tStMD9pKsVLOCBNLUacoXo1Q== dependencies: "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/itinerary-body" "^5.3.6" -"@opentripplanner/route-viewer-overlay@^2.0.17": - version "2.0.17" - resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-2.0.17.tgz#f34686fd965cf39650a10f64df599e7aca468415" - integrity sha512-3UTTLxHhaMg4iKP4oJlobvUCbvC/TjCW6ss8PxxC3UurwiMeSFNVkaWGLElPc9YoKg0QqKxrIY7zq0WClIPa6g== +"@opentripplanner/route-viewer-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-3.0.0.tgz#d307af1fb734f113627a82f816bf4683a7d9a860" + integrity sha512-Kbgs+gkzOKNEoXG2ImoUBekET5olMc8sGo9ltb7tgTg8ZuBcq3woMID7b3+n3DDdvqdHLExg5T68gkip1Eu/QQ== dependencies: "@mapbox/polyline" "^1.1.0" "@opentripplanner/base-map" "^3.2.2" @@ -2615,38 +2667,38 @@ glob-promise "^4.2.2" js-yaml "^4.1.0" -"@opentripplanner/stop-viewer-overlay@^2.0.10": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-2.0.10.tgz#0749fe7ffb28dac7a6925ed7c663e2fdd5156f3b" - integrity sha512-rFmaqQ7uJ+ZE80O6fveiNxlEVSJW5PwFSMh1B9pN0HaVTB1U27+yKbIMMuP7GtWve31mPy+PaWYXDW3hMlsi8A== +"@opentripplanner/stop-viewer-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-3.0.0.tgz#69dc8af797ab9a202954137b6ea68bcaa45cc4ff" + integrity sha512-1OnLhP9QcOnAe1qwSrjLXsFsMtqx7tBullcl/CgT5kYA/aXLKNiQ7zGeMrfbALOXhU51v74gtmMEAwW1EB1pcw== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" -"@opentripplanner/stops-overlay@^5.3.3": - version "5.3.3" - resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.3.3.tgz#711dd9316de93ac6c959dc3191d31884dc0a9589" - integrity sha512-GYADErZLIG3KPJ4OiigWkyHaGrWJ/wiCenH0RTbQ5J0XbYrenUIlWBsI5kpQNZPGBXocvF77sOTOUM8gex1AUA== +"@opentripplanner/stops-overlay@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-6.0.0.tgz#97186a2ce82284e2632967a4666294ad04d092db" + integrity sha512-zGpCc2PWpHDn1VGu9zdLfRIfde9sNAMN6ElHkLQq/67ylrQ7R1jIzi9K1O2X/ZPAEtfH5VOYa/y/A1drNlN3gw== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/from-to-location-picker" "^2.1.14" "@opentripplanner/map-popup" "^4.0.0" flat "^5.0.2" -"@opentripplanner/transit-vehicle-overlay@^4.0.13": - version "4.0.13" - resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.13.tgz#6f66c7c6a27d2473353b7c8c14acc8c540fb01ad" - integrity sha512-Sh3c3+q2dIhFZP5uyhPboyLSsTv8unVsPYKjFWVJaK19z6wN8KqFVmSqWysrcEnooRJd+D4+4erQiUbabomDLQ== +"@opentripplanner/transit-vehicle-overlay@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-5.0.0.tgz#1a3ea04abce38d65a21a9eaad8c5e0ac19a41100" + integrity sha512-N0vM89xozWTbbb63pBeZEZIbdlbgnP2K0qNJZ0vk87clJU0T7RxBtq/sdftBQ6CzB86AjXCCxfitCZH9HOD7/A== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/icons" "^2.0.12" flat "^5.0.2" -"@opentripplanner/transitive-overlay@3.0.22": - version "3.0.22" - resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.22.tgz#631096b12e08671e5da05ffe1c0a0e01331750a4" - integrity sha512-Ix3+2qz1+iSbeLnMfd4tU+0AUU1LDjq4y8cTzfKHayqHe0pzHpYY9Ib2zrXbvog7Mav/Jozn2ycL27R4UgzQaA== +"@opentripplanner/transitive-overlay@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-4.0.0.tgz#1a0c41dd4a22704b74da105ef67c0ac63624c335" + integrity sha512-kFKRbKGeIKNDx2t21HaPXsOOkG+qlnHgXN8lbTZRxpfy+EIV3ZeoH72/ymWuiHdLnxUORHBAjhacQh+2fryc4A== dependencies: "@mapbox/polyline" "^1.1.1" "@opentripplanner/base-map" "^3.2.2" @@ -2660,24 +2712,24 @@ "@turf/midpoint" "^6.5.0" lodash.isequal "^4.5.0" -"@opentripplanner/trip-details@^5.0.15": - version "5.0.15" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.15.tgz#73cfd7427aed49af53fec4ded9de7d17b0ed5377" - integrity sha512-1OfCEju90PXGH9DVy2dbBk8Jz8/8zSJ35/OCgodenGT3FyokQPoJsQhPjr6MPIIYMTyAdUSDT9C372thA+rU2Q== +"@opentripplanner/trip-details@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-6.0.0.tgz#60958ca14910f865125d20db8ec2eeba6d2c7362" + integrity sha512-BzUAsSpuSWzVMRW6vhiZblrg0Sq7Tnar17jjgvTvIhzv0yUUyrW5jUxlGIPPk11UUJ5WrPZmkfQasF9z8xk5BQ== dependencies: "@opentripplanner/core-utils" "^11.4.4" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.7.0-alpha.5": - version "3.7.0-alpha.5" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.7.0-alpha.5.tgz#326b501807fda4a5b5630d57641ed3a48e2c56f8" - integrity sha512-WrKXIUOmutvZBRdOsJmzprf2AUIOFhcpR/AYI8ev8HmrQeETEbOdWzOlhUr9E9jaPb6+St2Bs6XuHcOtlgWNgw== +"@opentripplanner/trip-form@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-4.0.0.tgz#27b36a0504e46cfda1cdf50c971b5cea03de8ae2" + integrity sha512-Cg8SlAVN8M+qoWpz8jAkwuqllIPgrL2PVewTPuDPsIQ8i5B7xo5KKE3TPo7cQUM+jE6WEshpvv0FIdMF+NAlNg== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/building-blocks" "^1.0.3" - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.4.4" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" "@styled-icons/fa-regular" "^10.37.0" @@ -2688,10 +2740,10 @@ react-indiana-drag-scroll "^2.0.1" react-inlinesvg "^2.3.0" -"@opentripplanner/trip-viewer-overlay@^2.0.10": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-2.0.10.tgz#2c0809b2d54da4d57d0a0683a4739e29cb13a326" - integrity sha512-7M9l7fF8shtD/566bci+zEkPncf/L+ZWIYAl5gnIgrBxwLagN/+E2zkoDebYamGFGb236FXpvTS30i1BJzhcPA== +"@opentripplanner/trip-viewer-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-3.0.0.tgz#a56263863aba87a3608d4dbed0cf839333cf99d0" + integrity sha512-64qNLUxkL6ow8T1FghdKDp13KH96djjYAo6hHTAeZYHZuu7gxffRD1GmrDJVeyk0+DixjKdiNhAZ9mOCtAgK/w== dependencies: "@mapbox/polyline" "^1.1.0" "@opentripplanner/base-map" "^3.2.2" @@ -2702,10 +2754,10 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.2.tgz#1373d738479568d880a3b13670b0ec53a1a75bd5" integrity sha512-2qDcKOrsLoXdwjRAdi4xcdDUsZGTnwBM+vfEf8TTuuWSnA+WYav3ldlMB4sugxIdLaVKXlOfe3F5lCEh9jAHWA== -"@opentripplanner/vehicle-rental-overlay@^2.1.9": - version "2.1.9" - resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-2.1.9.tgz#c373e1400874a00f473be0f029b28e0944652c88" - integrity sha512-VYWqnuk5j1yHF/zH5NEqDIVjsSbIsIgiCK6SaYtQHOBwszWauIubpqviTBASAcY72JfKE36AQfGjPuYILd9oTw== +"@opentripplanner/vehicle-rental-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-3.0.0.tgz#68e2a6c117fa3af485f375685c24a557762c6bb6" + integrity sha512-Yt6l6fEX+5O1jJ4z2NpbA0rib2tARxKdE3nTUFaBORBSq/NFfa2vZMk3EBXIrtzC3/GRabqluJU8sDaMGfkvvw== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" @@ -3136,11 +3188,11 @@ "@styled-icons/styled-icon" "^10.7.0" "@styled-icons/styled-icon@^10.7.0": - version "10.7.0" - resolved "https://registry.yarnpkg.com/@styled-icons/styled-icon/-/styled-icon-10.7.0.tgz#d6960e719b8567c8d0d3a87c40fb6f5b4952a228" - integrity sha512-SCrhCfRyoY8DY7gUkpz+B0RqUg/n1Zaqrr2+YKmK/AyeNfCcoHuP4R9N4H0p/NA1l7PTU10ZkAWSLi68phnAjw== + version "10.7.1" + resolved "https://registry.yarnpkg.com/@styled-icons/styled-icon/-/styled-icon-10.7.1.tgz#da04b80751e126756f98a5485b3b0dd9b52c9aba" + integrity sha512-WLYaeMTMhMkSxE+v+of+r2ovIk0tceDGfv8iqWHRMxvbm+6zxngVcQ4ELx6Zt/LFxqckmmoAdvo6ehiiYj6I6A== dependencies: - "@babel/runtime" "^7.19.0" + "@babel/runtime" "^7.20.7" "@surma/rollup-plugin-off-main-thread@^1.1.1": version "1.4.2" @@ -3596,9 +3648,9 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/node@*", "@types/node@14", "@types/node@14 || 16 || 17": version "14.18.21" @@ -3611,9 +3663,9 @@ integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== "@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/object-hash@^3.0.5": version "3.0.5" @@ -5826,9 +5878,9 @@ chownr@^2.0.0: integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== chroma-js@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.4.2.tgz#dffc214ed0c11fa8eefca2c36651d8e57cbfb2b0" - integrity sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A== + version "2.6.0" + resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.6.0.tgz#578743dd359698a75067a19fa5571dec54d0b70b" + integrity sha512-BLHvCB9s8Z1EV4ethr6xnkl/P2YRFOGqfgvuMG/MyCbZPrTA+NeiByY6XvgF0zP4/2deU2CXnWyMa3zu1LqQ3A== chrome-trace-event@^1.0.2: version "1.0.3" @@ -9257,7 +9309,12 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== -graphql@^16.6.0, graphql@^16.8.1: +graphql@^16.6.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" + integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== + +graphql@^16.8.1: version "16.8.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== @@ -9352,9 +9409,9 @@ has-property-descriptors@^1.0.2: es-define-property "^1.0.0" has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" @@ -9426,10 +9483,10 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== +hasown@^2.0.0, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" @@ -10116,13 +10173,20 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.0.0, is-core-module@^2.13.0, is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.6.0: +is-core-module@^2.0.0, is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.6.0: version "2.13.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== + dependencies: + hasown "^2.0.2" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -12401,30 +12465,31 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -meow@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.1.tgz#1ad64c4b76b2a24dfb2f635fddcadf320d251467" - integrity sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg== +meow@^8.0.0: + version "8.1.2" + resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" + integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== dependencies: "@types/minimist" "^1.2.0" camelcase-keys "^6.2.2" decamelize-keys "^1.1.0" hard-rejection "^2.1.0" - minimist-options "^4.0.2" - normalize-package-data "^2.5.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.0" read-pkg-up "^7.0.1" redent "^3.0.0" trim-newlines "^3.0.0" - type-fest "^0.13.1" - yargs-parser "^18.1.3" + type-fest "^0.18.0" + yargs-parser "^20.2.3" -meow@^8.0.0: - version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" - integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== +meow@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-9.0.0.tgz#cd9510bc5cac9dee7d03c73ee1f9ad959f4ea364" + integrity sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ== dependencies: "@types/minimist" "^1.2.0" camelcase-keys "^6.2.2" + decamelize "^1.2.0" decamelize-keys "^1.1.0" hard-rejection "^2.1.0" minimist-options "4.1.0" @@ -12590,7 +12655,7 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimist-options@4.1.0, minimist-options@^4.0.2: +minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== @@ -13294,11 +13359,16 @@ object-hash@^1.3.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== -object-inspect@^1.11.0, object-inspect@^1.13.1, object-inspect@^1.6.0, object-inspect@^1.7.0: +object-inspect@^1.11.0, object-inspect@^1.6.0, object-inspect@^1.7.0: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" @@ -15770,9 +15840,9 @@ regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== regenerator-transform@^0.14.2: version "0.14.5" @@ -16047,7 +16117,7 @@ resolve@1.18.1: is-core-module "^2.0.0" path-parse "^1.0.6" -resolve@^1.1.5, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.8.1: +resolve@^1.1.5, resolve@^1.1.6, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.8.1: version "1.22.4" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== @@ -16056,6 +16126,15 @@ resolve@^1.1.5, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11. path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.10.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^2.0.0-next.3: version "2.0.0-next.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" @@ -16906,9 +16985,9 @@ spdx-correct@^3.0.0: spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== spdx-expression-parse@^3.0.0: version "3.0.1" @@ -16919,9 +16998,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + version "3.0.20" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz#e44ed19ed318dd1e5888f93325cee800f0f51b89" + integrity sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw== spdy-transport@^3.0.0: version "3.0.0" @@ -17980,11 +18059,6 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - type-fest@^0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" @@ -19047,7 +19121,7 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^18.1.2, yargs-parser@^18.1.3: +yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== From 4ff7e504ee7ac742f01bd43fa65530c8f25bc3db Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:54:32 -0400 Subject: [PATCH 128/162] refactor(apiV2): Pass mobility profile param to OTP based on config. --- example-config.yml | 3 +++ lib/actions/apiV2.js | 7 +++++-- package.json | 2 +- yarn.lock | 10 +++++----- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/example-config.yml b/example-config.yml index c24e1265d..b8470663a 100644 --- a/example-config.yml +++ b/example-config.yml @@ -15,6 +15,9 @@ api: # If your OTP server is at a path other than "/otp" (usually due to a proxy) # Then you can set the OPTIONAL property basePath. The default is "/otp" basePath: /otp + ### Custom GraphQL plan query to override the default one (it still needs to include expected variables). + # planQuery: | + # query Plan() port: 8080 v2: true diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 2a38c1061..13e7407b7 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -924,6 +924,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) { return function (dispatch, getState) { const state = getState() const { config, currentQuery, modeSettingDefinitions } = state.otp + const { planQuery } = config.api const { loggedInUser } = state.user const persistenceMode = getPersistenceMode(config.persistence) const activeItinerary = @@ -999,7 +1000,6 @@ export function routingQuery(searchId = null, updateSearchInReducer) { }, date, from: currentQuery.from, - mobilityProfile: loggedInUser?.mobilityProfile?.mobilityMode, modes: modes || activeModes, modeSettings, time, @@ -1009,6 +1009,9 @@ export function routingQuery(searchId = null, updateSearchInReducer) { ...currentQuery, numItineraries: numItineraries || getDefaultNumItineraries(config) } + if (config.mobilityProfile) { + baseQuery.mobilityProfile = loggedInUser?.mobilityProfile?.mobilityMode + } // Generate combinations if the modes for query are not specified in the query // FIXME: BICYCLE_RENT does not appear in this list unless TRANSIT is also enabled. // This is likely due to the fact that BICYCLE_RENT is treated as a transit submode. @@ -1032,7 +1035,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) { const query = generateOtp2Query(combo) dispatch( createGraphQLQueryAction( - query.query, + planQuery || query.query, query.variables, (response) => { const dispatchedRoutingResponse = routingResponse(response) diff --git a/package.json b/package.json index a94fba861..596e5e849 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@floating-ui/react": "^0.19.2", "@opentripplanner/base-map": "^3.2.2", "@opentripplanner/building-blocks": "^1.2.3", - "@opentripplanner/core-utils": "11.4.3-mobility-profile", + "@opentripplanner/core-utils": "11.4.4", "@opentripplanner/endpoints-overlay": "^2.1.4", "@opentripplanner/from-to-location-picker": "^2.1.14", "@opentripplanner/geocoder": "^3.0.2", diff --git a/yarn.lock b/yarn.lock index 86208d8b8..ec7c4aab4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2408,14 +2408,14 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@11.4.3-mobility-profile": - version "11.4.3-mobility-profile" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.3-mobility-profile.tgz#b1d5675c6c1f85a3454234b720059efa03ad6ed2" - integrity sha512-+6IjMwXCUZHNmTLnZZ+u23Awtm2v4DcRVmkyxy8m8Dd5GxB9tMxXBhvvwxuzD2KV6Wf4tk4j+HqiAf8gW0Dfbg== +"@opentripplanner/core-utils@11.4.4": + version "11.4.4" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.4.tgz#11c1be91a5e90afda4fc265831c761d3e044d933" + integrity sha512-WKhOuG7Q+Yxdm+P5MPmJyXndx+JUtGn44GTeilOnUqDdO8lTLTvqqt0hYeEWjA77jWP0u8tG7fAAsft8IZn2cg== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/geocoder" "^3.0.2" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" From df10d08d76467ab139a47550c913891ddda2e0b7 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 25 Sep 2024 11:43:50 -0500 Subject: [PATCH 129/162] fix unit tests --- .../viewers/__snapshots__/nearby-view.js.snap | 1154 ++++++++--------- .../stop-schedule-viewer.ts.snap | 6 +- yarn.lock | 191 +-- 3 files changed, 647 insertions(+), 704 deletions(-) diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 3f82632bd..36c414905 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -46,7 +46,7 @@ exports[`components > viewers > nearby view renders nothing on a blank page 1`] className="nearby-view base-color-bg" >
                                                                viewers > nearby view renders nothing on a blank page 1`] } >
                                                                  viewers > nearby view renders proper scooter dates 1`] = ` className="nearby-view base-color-bg" >
                                                                  viewers > nearby view renders proper scooter dates 1`] = ` } >
                                                                    viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                    viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    Roosevelt Station - Bay 2 @@ -10036,7 +10036,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                      viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                    • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                            viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                            Roosevelt @@ -16883,7 +16883,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                            • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    Roosevelt Station - Bay 1 @@ -26397,7 +26397,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                    • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="988" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = `

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = `

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = `

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = `

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = `

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              Roosevelt Station Bay 5 - Bay 5 @@ -35949,7 +35949,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                              viewers > nearby view renders proper scooter dates 1`] = `

                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                              • viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="984" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                      viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                      Roosevelt @@ -43780,7 +43780,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                      viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                      • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                          Roosevelt Station - Bay 3 @@ -51332,7 +51332,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                          • viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                        NE 65th St & 14th Ave NE @@ -62499,7 +62499,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                        • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > stop viewer should render with initial stop id a > viewers > stop viewer should render with initial stop id a

                                                                                                                              Date: Wed, 25 Sep 2024 12:10:05 -0500 Subject: [PATCH 130/162] Update percy tests --- percy/percy.test.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/percy/percy.test.js b/percy/percy.test.js index 52fdcdb63..1b355e40f 100644 --- a/percy/percy.test.js +++ b/percy/percy.test.js @@ -192,14 +192,12 @@ async function executeTest(page, isMobile, isCallTaker) { await page.waitForTimeout(1000) // wait extra time for all results to load if (!isMobile) { - await page.hover('label[title="Transit"]') - await page.waitForTimeout(200) - await percySnapshotWithWait( - page, - 'Metro Transit-Walk Itinerary Desktop with Mode Selector Expanded' - ) - // Hover something else to unhover the mode selector. - await page.hover('#plan-trip') + await page.click('#open-advanced-settings-button') + await page.waitForTimeout(500) + await percySnapshotWithWait(page, 'Metro Advanced Settings Open') + // Close advanced settings + await page.click('#close-advanced-settings-button') + await page.waitForTimeout(500) } else { await percySnapshotWithWait(page, 'Metro Transit-Walk Itinerary Mobile') } From a3343d462078e0ab511310b8662a89c4f4d70b20 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:15:57 -0500 Subject: [PATCH 131/162] fix percy tests --- percy/percy.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/percy/percy.test.js b/percy/percy.test.js index 1b355e40f..6e8e8b1e6 100644 --- a/percy/percy.test.js +++ b/percy/percy.test.js @@ -145,7 +145,7 @@ async function executeTest(page, isMobile, isCallTaker) { // Close advanced settings await page.click('#close-advanced-settings-button') - + await page.waitForTimeout(500) // Delete both origin and destination await page.click('.from-form-control') From fb98775d5ece3b30d6ceea82a4a5ca2edbfcde8f Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 25 Sep 2024 12:21:52 -0700 Subject: [PATCH 132/162] address PR cleanup --- example-config.yml | 2 ++ lib/components/form/date-time-modal.tsx | 37 ++++++++++++------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/example-config.yml b/example-config.yml index 968e9fae2..7fc8ed198 100644 --- a/example-config.yml +++ b/example-config.yml @@ -111,6 +111,8 @@ persistence: # iconType: 'car' # iconUrl: '' # href: '' + +### These settings are only used for the field trip features. dateTime: timeFormat: h:mm a dateFormat: MM/dd/yyyy diff --git a/lib/components/form/date-time-modal.tsx b/lib/components/form/date-time-modal.tsx index bf11a0806..1f0e13557 100644 --- a/lib/components/form/date-time-modal.tsx +++ b/lib/components/form/date-time-modal.tsx @@ -1,12 +1,10 @@ -// TODO: TypeScript with props. -/* eslint-disable react/prop-types */ import { connect } from 'react-redux' import coreUtils from '@opentripplanner/core-utils' import React, { useCallback } from 'react' +import * as formActions from '../../actions/form' import { AppConfig } from '../../util/config-types' import { AppReduxState, FilterType, SortType } from '../../util/state-types' -import { setQueryParam } from '../../actions/form' import { StyledDateTimeSelector } from './styled' import { updateItineraryFilter } from '../../actions/narrative' @@ -34,24 +32,25 @@ const DepartArriveTypeMap: Record< NOW: 'DURATION' } -function DateTimeModal(props: Props) { - const { - config, - date, - dateFormatLegacy, - departArrive, - setQueryParam, - sort, - time, - timeFormatLegacy, - updateItineraryFilter - } = props +function DateTimeModal({ + config, + date, + dateFormatLegacy, + departArrive, + setQueryParam, + sort, + time, + timeFormatLegacy, + updateItineraryFilter +}: Props) { const { homeTimezone, isTouchScreenOnDesktop } = config const touchClassName = isTouchScreenOnDesktop ? 'with-desktop-touchscreen' : '' const syncSortWithDepartArrive = config?.itinerary?.syncSortWithDepartArrive + // Note the side effect that this will resort the results of a previous query + // if the user changes the depart/arrive setting before the query is run. const setQueryParamMiddleware = useCallback( (params: any) => { if (syncSortWithDepartArrive) { @@ -76,7 +75,7 @@ function DateTimeModal(props: Props) { departArrive={departArrive} onQueryParamChange={setQueryParamMiddleware} time={time} - // These props below are for Safari on MacOS, and legacy browsers + // These props below are for legacy browsers // that don't support ``. // These props are not relevant in modern browsers, // where `` already @@ -98,19 +97,19 @@ const mapStateToProps = (state: AppReduxState) => { config, date, // This prop is for legacy browsers (see render method above). - // @ts-expect-error Msimatched config types + // @ts-expect-error Mismatched config types dateFormatLegacy: coreUtils.time.getDateFormat(config), departArrive, sort, time, // This prop is for legacy browsers (see render method above). - // @ts-expect-error Msimatched config types + // @ts-expect-error Mismatched config types timeFormatLegacy: coreUtils.time.getTimeFormat(config) } } const mapDispatchToProps = { - setQueryParam, + setQueryParam: formActions.setQueryParam, updateItineraryFilter } From 70c1925ea354297262b84ec0bbc8fef239f0adbe Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 25 Sep 2024 12:33:50 -0700 Subject: [PATCH 133/162] Merge branch 'dev' into sync-sort-departarrive --- .../viewers/__snapshots__/nearby-view.js.snap | 1407 ++++++++++------- .../stop-schedule-viewer.ts.snap | 6 +- example-config.yml | 3 + i18n/en-US.yml | 8 + i18n/fr.yml | 8 + lib/components/app/batch-routing-panel.tsx | 206 ++- .../form/advanced-settings-button.tsx | 29 + .../form/advanced-settings-panel.tsx | 285 ++++ lib/components/form/batch-settings.tsx | 222 +-- lib/components/form/batch-styled.ts | 2 + lib/components/form/form.css | 4 +- lib/components/form/styled.ts | 75 + lib/components/form/util.tsx | 115 ++ lib/components/map/default-map.tsx | 28 +- lib/components/map/point-popup.tsx | 2 +- lib/components/mobile/batch-search-screen.tsx | 155 +- lib/components/mobile/mobile.css | 13 +- lib/components/util/prefersReducedMotion.tsx | 9 + lib/components/util/types.ts | 2 + lib/components/viewers/pattern-row.tsx | 12 +- lib/components/viewers/viewers.css | 10 +- lib/util/config-types.ts | 5 + lib/util/state-types.ts | 2 + package.json | 44 +- percy/percy.test.js | 25 +- yarn.lock | 227 +-- 26 files changed, 1888 insertions(+), 1016 deletions(-) create mode 100644 lib/components/form/advanced-settings-button.tsx create mode 100644 lib/components/form/advanced-settings-panel.tsx create mode 100644 lib/components/form/util.tsx create mode 100644 lib/components/util/prefersReducedMotion.tsx diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 3d4a9501a..41b77e69d 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -46,7 +46,7 @@ exports[`components > viewers > nearby view renders nothing on a blank page 1`] className="nearby-view base-color-bg" >
                                                                                                                              viewers > nearby view renders nothing on a blank page 1`] } >
                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` className="nearby-view base-color-bg" >
                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` } >
                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  Roosevelt Station - Bay 2 @@ -10036,7 +10036,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                  • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Loyal Heights Greenwood" > - Loyal Heights Greenwood + + components.NearbyView.headsign +

                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Downtown Seattle Fremont" > - Downtown Seattle Fremont + + components.NearbyView.headsign +

                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Roosevelt Station Sand Point" > - Roosevelt Station Sand Point + + components.NearbyView.headsign +

                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                          Roosevelt @@ -16883,7 +16910,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                          • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Angle Lake" > - Angle Lake + + components.NearbyView.headsign +

                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Northgate" > - Northgate + + components.NearbyView.headsign +

                                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Capitol Hill" > - Capitol Hill + + components.NearbyView.headsign +

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  Roosevelt Station - Bay 1 @@ -26397,7 +26451,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                                  • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Roosevelt Station" > - University District Roosevelt Station + + components.NearbyView.headsign +

                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Sand Point East Green Lake" > - Sand Point East Green Lake + + components.NearbyView.headsign +

                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Sand Point" > - University District Sand Point + + components.NearbyView.headsign +

                                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="988" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Madrona Special" > - Madrona Special + + components.NearbyView.headsign +

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            Roosevelt Station Bay 5 - Bay 5 @@ -35949,7 +36039,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                                            • viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Roosevelt" > - University District Roosevelt + + components.NearbyView.headsign +

                                                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` } title="University District Maple Leaf" > - University District Maple Leaf + + components.NearbyView.headsign +

                                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="984" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Downtown Seattle Special" > - Downtown Seattle Special + + components.NearbyView.headsign +

                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                    Roosevelt @@ -43780,7 +43897,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                                                    • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Northgate" > - Northgate + + components.NearbyView.headsign +

                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                        Roosevelt Station - Bay 3 @@ -51332,7 +51458,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                                                        • viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Bothell" > - Bothell + + components.NearbyView.headsign +

                                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Northgate Station Roosevelt Station" > - Northgate Station Roosevelt Station + + components.NearbyView.headsign +

                                                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Woodinville" > - Woodinville + + components.NearbyView.headsign +

                                                                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Jackson Park Maple Leaf" > - Jackson Park Maple Leaf + + components.NearbyView.headsign +

                                                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Kenmore P&R Roosevelt Station" > - Kenmore P&R Roosevelt Station + + components.NearbyView.headsign +

                                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Kenmore P&R" > - Kenmore P&R + + components.NearbyView.headsign +

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      NE 65th St & 14th Ave NE @@ -62499,7 +62679,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = `

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                                                                                                                                                      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Loyal Heights Greenwood" > - Loyal Heights Greenwood + + components.NearbyView.headsign +

                                                                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Downtown Seattle Fremont" > - Downtown Seattle Fremont + + components.NearbyView.headsign +

                                                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = ` } title="Roosevelt Station Sand Point" > - Roosevelt Station Sand Point + + components.NearbyView.headsign +

                                                                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > stop viewer should render with initial stop id a > viewers > stop viewer should render with initial stop id a

                                                                                                                                                                                      - @@ -357,6 +364,7 @@ components: distanceAway: "{localizedDistanceString} away" error: An error occurred loading nearby amenities. header: Nearby View + headsign: "{destination}" nearbyListIntro: List of {count} nearby entities. nothingNearby: There are no places nearby. spacesAvailable: "{spacesAvailable} empty spaces available" diff --git a/i18n/fr.yml b/i18n/fr.yml index 082b0e96a..741ad9f2c 100644 --- a/i18n/fr.yml +++ b/i18n/fr.yml @@ -209,8 +209,15 @@ components: BatchRoutingPanel: shortTitle: Planifier un trajet BatchSearchScreen: + advancedHeader: Préférences avancées header: Votre trajet + modeOptions: Choix du mode modeSelectorLabel: Sélectionnez un mode de déplacement + moreOptions: Plus d'options + saveAndReturn: Enregistrer et fermer + saved: Enregistré + submodeSelectorLabel: Sélectionnez vos modes et sous-modes de déplacement + tripOptions: Options concernant le trajet BatchSettings: destination: destination invalidModeSelection: >- @@ -376,6 +383,7 @@ components: distanceAway: à {localizedDistanceString} error: Erreur lors du chargement des services à proximité. header: À proximité + headsign: "{destination}" nearbyListIntro: Liste de {count} entités à proximité. nothingNearby: Aucun lieu à proximité. spacesAvailable: "{spacesAvailable} emplacements libres disponibles" diff --git a/lib/components/app/batch-routing-panel.tsx b/lib/components/app/batch-routing-panel.tsx index c1321091e..5c6a69c73 100644 --- a/lib/components/app/batch-routing-panel.tsx +++ b/lib/components/app/batch-routing-panel.tsx @@ -1,9 +1,17 @@ import { connect } from 'react-redux' +import { CSSTransition, TransitionGroup } from 'react-transition-group' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' import React, { Component, FormEvent } from 'react' +import { + advancedPanelClassName, + mainPanelClassName, + transitionDuration, + TransitionStyles +} from '../form/styled' import { getActiveSearch, getShowUserSettings } from '../../util/state' import { getPersistenceMode } from '../../util/user' +import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import InvisibleA11yLabel from '../util/invisible-a11y-label' import LocationField from '../form/connected-location-field' @@ -15,6 +23,7 @@ import ViewerContainer from '../viewers/viewer-container' interface Props { activeSearch: any intl: IntlShape + mainPanelContent: number mobile?: boolean showUserSettings: boolean } @@ -24,7 +33,43 @@ interface Props { */ class BatchRoutingPanel extends Component { state = { - planTripClicked: false + closeAdvancedSettingsWithDelay: false, + planTripClicked: false, + showAdvancedModeSettings: false + } + + _advancedSettingRef = React.createRef() + _mainPanelContentRef = React.createRef() + _itinerariesAndUserRef = React.createRef() + + componentDidUpdate(prevProps: Readonly): void { + // Close the advanced mode settings if we navigate to another page + if ( + prevProps.mainPanelContent === null && + this.props.mainPanelContent !== null && + this.state.showAdvancedModeSettings + ) { + this.setState({ + showAdvancedModeSettings: false + }) + } + } + + openAdvancedSettings = () => { + this.setState({ + closeAdvancedSettingsWithDelay: false, + showAdvancedModeSettings: true + }) + } + + closeAdvancedSettings = () => { + this.setState({ showAdvancedModeSettings: false }) + } + + setCloseAdvancedSettingsWithDelay = () => { + this.setState({ + closeAdvancedSettingsWithDelay: true + }) } handleSubmit = (e: FormEvent) => e.preventDefault() @@ -44,6 +89,11 @@ class BatchRoutingPanel extends Component { id: 'common.searchForms.click' }) + /* If there is a save button in advanced preferences, add a transition delay to allow + the saved state to be displayed to users */ + const transitionDelay = this.state.closeAdvancedSettingsWithDelay ? 300 : 0 + const transitionDurationWithDelay = transitionDuration + transitionDelay + return ( { height: '100%' }} > - -

                                                                                                                                                                                      - -

                                                                                                                                                                                      -
                                                                                                                                                                                      -
                                                                                                                                                                                      - - + {!this.state.showAdvancedModeSettings && ( + +

                                                                                                                                                                                      + +

                                                                                                                                                                                      +
                                                                                                                                                                                      + )} + + + {this.state.showAdvancedModeSettings && ( + + + )} - isRequired - locationType="from" - selfValidate={planTripClicked} - showClearButton={!mobile} - /> - +
                                                                                                                                                                                      + + + +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + +
                                                                                                                                                                                      + )} - isRequired - locationType="to" - selfValidate={planTripClicked} - showClearButton={!mobile} - /> -
                                                                                                                                                                                      - -
                                                                                                                                                                                      -
                                                                                                                                                                                      - - - {!activeSearch && showUserSettings && ( - - )} -
                                                                                                                                                                                      - -
                                                                                                                                                                                      + + + + {!this.state.showAdvancedModeSettings && ( + +
                                                                                                                                                                                      + {!activeSearch && showUserSettings && ( + + )} +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      + )} +
                                                                                                                                                                                      +
                                                                                                                                                                                      ) } @@ -115,8 +222,11 @@ const mapStateToProps = (state: any) => { getShowUserSettings(state) && (state.user.loggedInUser?.hasConsentedToTerms || getPersistenceMode(state.otp.config.persistence).isLocalStorage) + const { mainPanelContent } = state.otp.ui + return { activeSearch: getActiveSearch(state), + mainPanelContent, showUserSettings } } diff --git a/lib/components/form/advanced-settings-button.tsx b/lib/components/form/advanced-settings-button.tsx new file mode 100644 index 000000000..0449dc85d --- /dev/null +++ b/lib/components/form/advanced-settings-button.tsx @@ -0,0 +1,29 @@ +import { ArrowRight } from '@styled-icons/fa-solid' +import { FormattedMessage } from 'react-intl' + +import { grey } from '../util/colors' +import React from 'react' +import styled from 'styled-components' + +interface Props { + onClick: () => void +} + +const StyledTransparentButton = styled.button` + align-items: center; + background: transparent; + border: none; + color: ${grey[800]}; + display: flex; + gap: 7px; + margin-bottom: 5px; +` + +const AdvancedSettingsButton = ({ onClick }: Props): JSX.Element => ( + + + + +) + +export default AdvancedSettingsButton diff --git a/lib/components/form/advanced-settings-panel.tsx b/lib/components/form/advanced-settings-panel.tsx new file mode 100644 index 000000000..ea085d017 --- /dev/null +++ b/lib/components/form/advanced-settings-panel.tsx @@ -0,0 +1,285 @@ +import { + addSettingsToButton, + AdvancedModeSubsettingsContainer, + ModeSettingRenderer, + populateSettingWithValue +} from '@opentripplanner/trip-form' +import { ArrowLeft } from '@styled-icons/fa-solid/ArrowLeft' +import { Check } from '@styled-icons/boxicons-regular' +import { connect } from 'react-redux' +import { decodeQueryParams, DelimitedArrayParam } from 'serialize-query-params' +import { FormattedMessage, useIntl } from 'react-intl' +import { invisibleCss } from '@opentripplanner/trip-form/lib/MetroModeSelector' +import { + ModeButtonDefinition, + ModeSetting, + ModeSettingValues +} from '@opentripplanner/types' +import React, { RefObject, useCallback, useContext, useState } from 'react' +import styled from 'styled-components' + +import * as formActions from '../../actions/form' +import { AppReduxState } from '../../util/state-types' +import { blue, getBaseColor } from '../util/colors' +import { ComponentContext } from '../../util/contexts' +import { generateModeSettingValues } from '../../util/api' + +import { + addCustomSettingLabels, + addModeButtonIcon, + onSettingsUpdate, + pipe, + populateSettingWithIcon, + setModeButton +} from './util' +import { setModeButtonEnabled } from './batch-settings' +import { styledCheckboxCss } from './styled' +import DateTimeModal from './date-time-modal' + +const PanelOverlay = styled.div` + height: 100%; + left: 0; + overflow-y: auto; + padding: 1.5em; + position: absolute; + top: 0; + width: 100%; + z-index: 100; +` + +const GlobalSettingsContainer = styled.div` + display: flex; + flex-direction: column; + gap: 13px; + margin-bottom: 2em; + + ${styledCheckboxCss} +` + +const CloseButton = styled.button` + background: transparent; + border: none; +` + +const HeaderContainer = styled.div` + align-items: center; + display: flex; + gap: 10px; + height: 30px; +` + +const Subheader = styled.h2` + ${invisibleCss} +` + +const ReturnToTripPlanButton = styled.button` + align-items: center; + background-color: var(--main-base-color, ${blue[900]}); + border: 0; + color: white; + display: flex; + font-weight: 700; + gap: 5px; + height: 51px; + justify-content: center; + margin-top: 2em; + width: 100%; + + svg { + margin-bottom: 7px; + } +` + +const DtSelectorContainer = styled.div` + margin: 2em 0; + + .date-time-modal { + padding: 0; + + .main-panel { + margin: 0; + + button { + padding: 6px 0; + } + + .date-time-selector { + margin: 15px 0; + } + } + } +` + +const AdvancedSettingsPanel = ({ + closeAdvancedSettings, + enabledModeButtons, + innerRef, + modeButtonOptions, + modeSettingDefinitions, + modeSettingValues, + saveAndReturnButton, + setCloseAdvancedSettingsWithDelay, + setQueryParam +}: { + closeAdvancedSettings: () => void + enabledModeButtons: string[] + innerRef: RefObject + modeButtonOptions: ModeButtonDefinition[] + modeSettingDefinitions: ModeSetting[] + modeSettingValues: ModeSettingValues + saveAndReturnButton?: boolean + setCloseAdvancedSettingsWithDelay: () => void + setQueryParam: (evt: any) => void +}): JSX.Element => { + const [closingBySave, setClosingBySave] = useState(false) + const baseColor = getBaseColor() + const accentColor = baseColor || blue[900] + + const intl = useIntl() + const closeButtonText = intl.formatMessage({ + id: 'components.BatchSearchScreen.saveAndReturn' + }) + const headerText = intl.formatMessage({ + id: 'components.BatchSearchScreen.advancedHeader' + }) + + // @ts-expect-error Context not typed + const { ModeIcon } = useContext(ComponentContext) + + const processSettings = (settings: ModeSetting[]) => + settings.map( + pipe( + populateSettingWithIcon(ModeIcon), + populateSettingWithValue(modeSettingValues), + addCustomSettingLabels(intl) + ) + ) + + const globalSettings = modeSettingDefinitions.filter((x) => !x.applicableMode) + const processedGlobalSettings = processSettings(globalSettings) + + const globalSettingsComponents = processedGlobalSettings.map( + (setting: ModeSetting) => ( + + ) + ) + + const processedModeSettings = processSettings(modeSettingDefinitions) + const processedModeButtons = modeButtonOptions.map( + pipe( + addModeButtonIcon(ModeIcon), + addSettingsToButton(processedModeSettings), + setModeButtonEnabled(enabledModeButtons) + ) + ) + + const onSaveAndReturnClick = useCallback(async () => { + await setCloseAdvancedSettingsWithDelay() + setClosingBySave(true) + closeAdvancedSettings() + }, [closeAdvancedSettings, setCloseAdvancedSettingsWithDelay]) + + return ( + + + { + closeAdvancedSettings() + }} + title={closeButtonText} + > + + +

                                                                                                                                                                                      {headerText}

                                                                                                                                                                                      +
                                                                                                                                                                                      + + + + {processedGlobalSettings.length > 0 && ( + <> + + + + + {globalSettingsComponents} + + + )} + + + + + {saveAndReturnButton && ( + + {closingBySave ? ( + <> + + + + ) : ( + + )} + + )} +
                                                                                                                                                                                      + ) +} + +const queryParamConfig = { modeButtons: DelimitedArrayParam } + +const mapStateToProps = (state: AppReduxState) => { + const urlSearchParams = new URLSearchParams(state.router.location.search) + const { modes } = state.otp.config + const modeSettingValues = generateModeSettingValues( + urlSearchParams, + state.otp.modeSettingDefinitions || [], + modes?.initialState?.modeSettingValues || {} + ) + const saveAndReturnButton = + state.otp.config?.advancedSettingsPanel?.saveAndReturnButton + return { + currentQuery: state.otp.currentQuery, + // TODO: Duplicated in apiv2.js + enabledModeButtons: + decodeQueryParams(queryParamConfig, { + modeButtons: urlSearchParams.get('modeButtons') + })?.modeButtons?.filter((mb): mb is string => mb !== null) || + modes?.initialState?.enabledModeButtons || + [], + modeButtonOptions: modes?.modeButtons || [], + modeSettingDefinitions: state.otp?.modeSettingDefinitions || [], + modeSettingValues, + saveAndReturnButton + } +} + +const mapDispatchToProps = { + setQueryParam: formActions.setQueryParam, + updateQueryTimeIfLeavingNow: formActions.updateQueryTimeIfLeavingNow +} + +export default connect( + mapStateToProps, + mapDispatchToProps +)(AdvancedSettingsPanel) diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx index 63e748973..23bd13a6c 100644 --- a/lib/components/form/batch-settings.tsx +++ b/lib/components/form/batch-settings.tsx @@ -1,19 +1,7 @@ -import { - addSettingsToButton, - MetroModeSelector, - populateSettingWithValue -} from '@opentripplanner/trip-form' import { connect } from 'react-redux' -import { - decodeQueryParams, - DelimitedArrayParam, - encodeQueryParams -} from 'use-query-params' -import { - ModeButtonDefinition, - ModeSetting, - ModeSettingValues -} from '@opentripplanner/types' +import { decodeQueryParams } from 'use-query-params' +import { MetroModeSelector } from '@opentripplanner/trip-form' +import { ModeButtonDefinition } from '@opentripplanner/types' import { Search } from '@styled-icons/fa-solid/Search' import { SyncAlt } from '@styled-icons/fa-solid/SyncAlt' import { useIntl } from 'react-intl' @@ -22,22 +10,26 @@ import React, { useCallback, useContext, useState } from 'react' import * as apiActions from '../../actions/api' import * as formActions from '../../actions/form' import { ComponentContext } from '../../util/contexts' -import { generateModeSettingValues } from '../../util/api' import { getActiveSearch, hasValidLocation } from '../../util/state' import { getBaseColor, getDarkenedBaseColor } from '../util/colors' -import { getFormattedMode } from '../../util/i18n' -import { RoutingQueryCallResult } from '../../actions/api-constants' import { StyledIconWrapper } from '../util/styledIcon' +import { + addModeButtonIcon, + alertUserTripPlan, + modesQueryParamConfig, + onSettingsUpdate, + pipe, + setModeButton +} from './util' import { MainSettingsRow, ModeSelectorContainer, PlanTripButton } from './batch-styled' +import AdvancedSettingsButton from './advanced-settings-button' import DateTimeButton from './date-time-button' -const queryParamConfig = { modeButtons: DelimitedArrayParam } - // TYPESCRIPT TODO: better types type Props = { activeSearch: any @@ -45,18 +37,11 @@ type Props = { enabledModeButtons: string[] fillModeIcons?: boolean modeButtonOptions: ModeButtonDefinition[] - modeSettingDefinitions: ModeSetting[] - modeSettingValues: ModeSettingValues onPlanTripClick: () => void + openAdvancedSettings: () => void routingQuery: any setQueryParam: (evt: any) => void spacedOutModeSelector?: boolean - updateQueryTimeIfLeavingNow: () => void -} - -// This method is used to daisy-chain a series of functions together on a given value -function pipe(...fns: Array<(arg: T) => T>) { - return (value: T) => fns.reduce((acc, fn) => fn(acc), value) } export function setModeButtonEnabled(enabledKeys: string[]) { @@ -77,174 +62,37 @@ function BatchSettings({ enabledModeButtons, fillModeIcons, modeButtonOptions, - modeSettingDefinitions, - modeSettingValues, onPlanTripClick, + openAdvancedSettings, routingQuery, setQueryParam, - spacedOutModeSelector, - updateQueryTimeIfLeavingNow + spacedOutModeSelector }: Props) { const intl = useIntl() // Whether the date/time selector is open const [dateTimeOpen, setDateTimeOpen] = useState(false) - // Whether the mode selector has a popup open - const [modeSelectorPopup, setModeSelectorPopup] = useState(false) - // @ts-expect-error Context not typed const { ModeIcon } = useContext(ComponentContext) - const addModeButtonIcon = useCallback( - (def: ModeButtonDefinition) => ({ - ...def, - Icon: function ModeButtonIcon() { - return - } - }), - [ModeIcon] - ) - - const populateSettingWithIcon = useCallback( - (msd: ModeSetting) => ({ - ...msd, - icon: - }), - [ModeIcon] - ) - - const addCustomSettingLabels = useCallback( - (msd: ModeSetting) => { - let modeLabel - // If we're using route mode overrides, make sure we're using the custom mode name - if (msd.type === 'SUBMODE') { - modeLabel = msd.overrideMode || msd.addTransportMode.mode - return { - ...msd, - label: getFormattedMode(modeLabel, intl) - } - } - return msd - }, - [intl] - ) - - const processedModeSettings = modeSettingDefinitions.map( - pipe( - populateSettingWithIcon, - populateSettingWithValue(modeSettingValues), - addCustomSettingLabels - ) - ) - const processedModeButtons = modeButtonOptions.map( - pipe( - addModeButtonIcon, - addSettingsToButton(processedModeSettings), - setModeButtonEnabled(enabledModeButtons) - ) + pipe(addModeButtonIcon(ModeIcon), setModeButtonEnabled(enabledModeButtons)) ) const _planTrip = useCallback(() => { - // Check for any validation issues in query. - const issues = [] - if (!hasValidLocation(currentQuery, 'from')) { - issues.push(intl.formatMessage({ id: 'components.BatchSettings.origin' })) - } - if (!hasValidLocation(currentQuery, 'to')) { - issues.push( - intl.formatMessage({ id: 'components.BatchSettings.destination' }) - ) - } - onPlanTripClick && onPlanTripClick() - if (issues.length > 0) { - // TODO: replace with less obtrusive validation. - window.alert( - intl.formatMessage( - { id: 'components.BatchSettings.validationMessage' }, - { issues: intl.formatList(issues, { type: 'conjunction' }) } - ) - ) - return - } - - // Plan trip. - updateQueryTimeIfLeavingNow() - const routingQueryResult = routingQuery() - - // If mode combination is not valid (i.e. produced no query), alert the user. - if (routingQueryResult === RoutingQueryCallResult.INVALID_MODE_SELECTION) { - window.alert( - intl.formatMessage({ - id: 'components.BatchSettings.invalidModeSelection' - }) - ) - } - }, [ - currentQuery, - intl, - onPlanTripClick, - routingQuery, - updateQueryTimeIfLeavingNow - ]) - - /** - * Stores parameters in both the Redux `currentQuery` and URL - * @param params Params to store - */ - const _onSettingsUpdate = useCallback( - (params: any) => { - setQueryParam({ queryParamData: params, ...params }) - }, - [setQueryParam] - ) - - const _toggleModeButton = useCallback( - (buttonId: string, newState: boolean) => { - let newButtons - if (newState) { - newButtons = [...enabledModeButtons, buttonId] - } else { - newButtons = enabledModeButtons.filter((c) => c !== buttonId) - } - - // encodeQueryParams serializes the mode buttons for the URL - // to get nice looking URL params and consistency - _onSettingsUpdate( - encodeQueryParams(queryParamConfig, { modeButtons: newButtons }) - ) - }, - [enabledModeButtons, _onSettingsUpdate] - ) - - /** - * Check whether the mode selector is showing a popup. - */ - const checkModeSelectorPopup = useCallback(() => { - const modeSelectorPopup = document.querySelector( - '.metro-mode-selector div[role="dialog"]' - ) - setModeSelectorPopup(!!modeSelectorPopup) - }, [setModeSelectorPopup]) + alertUserTripPlan(intl, currentQuery, onPlanTripClick, routingQuery) + }, [currentQuery, intl, onPlanTripClick, routingQuery]) const baseColor = getBaseColor() const accentColor = getDarkenedBaseColor() return ( - - - + + + + { const urlSearchParams = new URLSearchParams(state.router.location.search) - const modeSettingValues = generateModeSettingValues( - urlSearchParams, - state.otp?.modeSettingDefinitions || [], - state.otp.config.modes?.initialState?.modeSettingValues - ) + const { modes } = state.otp.config return { activeSearch: getActiveSearch(state), currentQuery: state.otp.currentQuery, // TODO: Duplicated in apiv2.js enabledModeButtons: - decodeQueryParams(queryParamConfig, { + decodeQueryParams(modesQueryParamConfig, { modeButtons: urlSearchParams.get('modeButtons') })?.modeButtons || - state.otp.config?.modes?.initialState?.enabledModeButtons || + modes?.initialState?.enabledModeButtons || {}, fillModeIcons: state.otp.config.itinerary?.fillModeIcons, - modeButtonOptions: state.otp.config?.modes?.modeButtons || [], - modeSettingDefinitions: state.otp?.modeSettingDefinitions || [], - modeSettingValues, - spacedOutModeSelector: state.otp?.config?.modes?.spacedOut + modeButtonOptions: modes?.modeButtons || [], + spacedOutModeSelector: modes?.spacedOut } } const mapDispatchToProps = { routingQuery: apiActions.routingQuery, - setQueryParam: formActions.setQueryParam, - updateQueryTimeIfLeavingNow: formActions.updateQueryTimeIfLeavingNow + setQueryParam: formActions.setQueryParam } export default connect(mapStateToProps, mapDispatchToProps)(BatchSettings) diff --git a/lib/components/form/batch-styled.ts b/lib/components/form/batch-styled.ts index 2283f3b9e..4fe5d9da5 100644 --- a/lib/components/form/batch-styled.ts +++ b/lib/components/form/batch-styled.ts @@ -65,6 +65,8 @@ export const ModeSelectorContainer = styled.div<{ squashed?: boolean }>` align-items: flex-start; display: flex; float: right; + justify-content: space-between; + width: 100%; ${PlanTripButton} { border-bottom-left-radius: ${(props) => (props.squashed ? 0 : 'invalid')}; diff --git a/lib/components/form/form.css b/lib/components/form/form.css index 7ef399d67..9f694e155 100644 --- a/lib/components/form/form.css +++ b/lib/components/form/form.css @@ -93,14 +93,14 @@ position: absolute; top: 22px; right: 32px; - z-index: 100000; + z-index: 99; } .otp .switch-button-container-mobile { position: absolute; top: 32px; right: 45px; - z-index: 100000; + z-index: 99; } /* Settings Selector Panel */ diff --git a/lib/components/form/styled.ts b/lib/components/form/styled.ts index 06e9449f7..5033db42f 100644 --- a/lib/components/form/styled.ts +++ b/lib/components/form/styled.ts @@ -5,6 +5,7 @@ import { Styled as TripFormClasses } from '@opentripplanner/trip-form' import { Input, MenuItemLi } from '@opentripplanner/location-field/lib/styled' +import { prefersReducedMotion } from '../util/prefersReducedMotion' import LocationField from '@opentripplanner/location-field' import styled, { css } from 'styled-components' @@ -230,3 +231,77 @@ export const StyledLocationField = styled(LocationField)` } } ` + +export const advancedPanelClassName = 'advanced-panel' +export const mainPanelClassName = 'main-panel' +export const transitionDuration = prefersReducedMotion ? 0 : 175 + +const wipeOffset = 7 + +const transitionMixin = css` + transition: all ${transitionDuration}ms ease-in-out; +` + +const wipeOutMixin = (offset: number) => css` + opacity: 0; + transform: translateX(${offset}px); +` +const wipeInMixin = css` + opacity: 1; +` + +export const TransitionStyles = styled.div<{ transitionDelay: number }>` + display: contents; + .${advancedPanelClassName}-enter { + ${wipeOutMixin(wipeOffset)} + } + .${advancedPanelClassName}-enter-done { + ${wipeInMixin} + ${transitionMixin} + } + + .${advancedPanelClassName}-exit { + ${wipeInMixin} + } + + .${advancedPanelClassName}-exit-active { + ${wipeOutMixin(wipeOffset)} + ${transitionMixin} + transition-delay: ${(props) => props.transitionDelay}ms; + } + + .${mainPanelClassName}-enter { + ${wipeOutMixin(-wipeOffset)} + } + .${mainPanelClassName}-enter-done { + ${wipeInMixin} + ${transitionMixin} + } + + .${mainPanelClassName}-exit { + ${wipeInMixin} + } + + .${mainPanelClassName}-exit-active { + ${wipeOutMixin(-wipeOffset)} + ${transitionMixin} + } +` +export const styledCheckboxCss = css` + div { + align-items: center; + justify-content: space-between; + + label { + margin-bottom: 0; + } + input[type='checkbox'] { + margin-top: 0; + order: 2; + + &:focus-visible + label { + outline: 1px solid blue; + } + } + } +` diff --git a/lib/components/form/util.tsx b/lib/components/form/util.tsx new file mode 100644 index 000000000..85dd3107d --- /dev/null +++ b/lib/components/form/util.tsx @@ -0,0 +1,115 @@ +import { DelimitedArrayParam, encodeQueryParams } from 'serialize-query-params' +import { IntlShape } from 'react-intl' +import { ModeButtonDefinition, ModeSetting } from '@opentripplanner/types' +import React from 'react' + +import { getFormattedMode } from '../../util/i18n' +import { hasValidLocation } from '../../util/state' +import { QueryParamChangeHandler } from '../util/types' +import { RoutingQueryCallResult } from '../../actions/api-constants' +import { updateQueryTimeIfLeavingNow } from '../../actions/form' + +// This method is used to daisy-chain a series of functions together on a given value +export function pipe(...fns: Array<(arg: T) => T>) { + return (value: T) => fns.reduce((acc, fn) => fn(acc), value) +} + +export const modesQueryParamConfig = { modeButtons: DelimitedArrayParam } + +export const populateSettingWithIcon = + (ModeIcon: React.ComponentType<{ mode?: string; width?: number }>) => + // eslint-disable-next-line react/display-name + (modeSetting: ModeSetting): ModeSetting => ({ + ...modeSetting, + icon: + }) + +export const addModeButtonIcon = + (ModeIcon: React.ComponentType<{ mode?: string; width?: number }>) => + (def: ModeButtonDefinition): ModeButtonDefinition => ({ + ...def, + Icon: function ModeButtonIcon() { + return + } + }) + +export const addCustomSettingLabels = + (intl: IntlShape) => + (modeSetting: ModeSetting): ModeSetting => { + // If we're using route mode overrides, make sure we're using the custom mode name + if (modeSetting.type === 'SUBMODE') { + const modeLabel = + modeSetting.overrideMode || modeSetting.addTransportMode.mode + return { + ...modeSetting, + label: getFormattedMode(modeLabel, intl) + } + } + return modeSetting + } + +/** + * Stores parameters in both the Redux `currentQuery` and URL + * @param params Params to store + */ +export const onSettingsUpdate = + (setQueryParam: QueryParamChangeHandler) => + (params: any): void => { + setQueryParam({ queryParamData: params, ...params }) + } + +export const setModeButton = + (enabledModeButtons: string[], updateHandler: (params: any) => void) => + (buttonId: string, newState: boolean): void => { + const newButtons = newState + ? [...enabledModeButtons, buttonId] + : enabledModeButtons.filter((c) => c !== buttonId) + + // encodeQueryParams serializes the mode buttons for the URL + // to get nice looking URL params and consistency + updateHandler( + encodeQueryParams(modesQueryParamConfig, { modeButtons: newButtons }) + ) + } + +export const alertUserTripPlan = ( + intl: IntlShape, + currentQuery: any, + onPlanTripClick: () => void, + routingQuery: () => any +): void => { + // Check for any validation issues in query. + const issues: string[] = [] + if (!hasValidLocation(currentQuery, 'from')) { + issues.push(intl.formatMessage({ id: 'components.BatchSettings.origin' })) + } + if (!hasValidLocation(currentQuery, 'to')) { + issues.push( + intl.formatMessage({ id: 'components.BatchSettings.destination' }) + ) + } + onPlanTripClick() + if (issues.length > 0) { + // TODO: replace with less obtrusive validation. + window.alert( + intl.formatMessage( + { id: 'components.BatchSettings.validationMessage' }, + { issues: intl.formatList(issues, { type: 'conjunction' }) } + ) + ) + return + } + + // Plan trip. + updateQueryTimeIfLeavingNow() + const routingQueryResult = routingQuery() + + // If mode combination is not valid (i.e. produced no query), alert the user. + if (routingQueryResult === RoutingQueryCallResult.INVALID_MODE_SELECTION) { + window.alert( + intl.formatMessage({ + id: 'components.BatchSettings.invalidModeSelection' + }) + ) + } +} diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 6c50d1899..38d7570e4 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -267,7 +267,8 @@ class DefaultMap extends Component { setLocation, setViewedStop, vehicleRentalQuery, - vehicleRentalStations + vehicleRentalStations, + viewedRouteStops } = this.props const { getCustomMapOverlays, getTransitiveRouteLabel, ModeIcon } = this.context @@ -405,7 +406,7 @@ class DefaultMap extends Component { vectorTilesEndpoint, setLocation, setViewedStop, - null, + viewedRouteStops, config.companies ) default: @@ -428,6 +429,26 @@ class DefaultMap extends Component { const mapStateToProps = (state) => { const activeSearch = getActiveSearch(state) + const viewedRoute = state.otp?.ui?.viewedRoute?.routeId + const nearbyViewerActive = + state.otp.ui.mainPanelContent === MainPanelContent.NEARBY_VIEW + + const viewedRoutePatterns = Object.entries( + state.otp?.transitIndex?.routes?.[viewedRoute]?.patterns || {} + ) + const viewedRouteStops = + viewedRoute && !nearbyViewerActive + ? // Ensure we don't have duplicates + Array.from( + new Set( + // Generate a list of every stop id the pattern stops at + viewedRoutePatterns.reduce((acc, cur) => { + // Convert pattern object to list of the pattern's stops + return [...cur?.[1]?.stops.map((s) => s.id), ...acc] + }, []) + ) + ) + : null return { bikeRentalStations: state.otp.overlay.bikeRental.stations, @@ -439,7 +460,8 @@ const mapStateToProps = (state) => { state.otp.ui.mainPanelContent === MainPanelContent.NEARBY_VIEW, pending: activeSearch ? Boolean(activeSearch.pending) : false, query: state.otp.currentQuery, - vehicleRentalStations: state.otp.overlay.vehicleRental.stations + vehicleRentalStations: state.otp.overlay.vehicleRental.stations, + viewedRouteStops } } diff --git a/lib/components/map/point-popup.tsx b/lib/components/map/point-popup.tsx index d7121b34b..071901434 100644 --- a/lib/components/map/point-popup.tsx +++ b/lib/components/map/point-popup.tsx @@ -82,7 +82,7 @@ function MapPopup({ // Override inline style supplied by react-map-gl to accommodate long "plan a trip" translations. style={{ maxWidth: '260px', width: '260px' }} > - + {typeof popupName === 'string' && popupName.split(',').length > 3 diff --git a/lib/components/mobile/batch-search-screen.tsx b/lib/components/mobile/batch-search-screen.tsx index 930112a88..c24b4dacb 100644 --- a/lib/components/mobile/batch-search-screen.tsx +++ b/lib/components/mobile/batch-search-screen.tsx @@ -1,9 +1,18 @@ import { connect } from 'react-redux' +import { CSSTransition, TransitionGroup } from 'react-transition-group' import { injectIntl, IntlShape } from 'react-intl' import React, { Component } from 'react' +import styled from 'styled-components' import * as uiActions from '../../actions/ui' +import { + advancedPanelClassName, + mainPanelClassName, + transitionDuration, + TransitionStyles +} from '../form/styled' import { MobileScreens } from '../../actions/ui-constants' +import AdvancedSettingsPanel from '../form/advanced-settings-panel' import BatchSettings from '../form/batch-settings' import DefaultMap from '../map/default-map' import LocationField from '../form/connected-location-field' @@ -14,6 +23,25 @@ import MobileNavigationBar from './navigation-bar' const { SET_FROM_LOCATION, SET_TO_LOCATION } = MobileScreens +const MobileSearchSettings = styled.div<{ + advancedPanelOpen: boolean + transitionDelay: number + transitionDuration: number +}>` + background: white; + box-shadow: 3px 0px 12px #00000052; + height: ${(props) => + props.advancedPanelOpen ? 'calc(100% - 50px)' : '230px'}; + left: 0; + position: fixed; + right: 0; + top: 50px; + transition: ${(props) => `all ${props.transitionDuration}ms ease`}; + transition-delay: ${(props) => props.transitionDelay}ms; + /* Must appear under the 'hamburger' dropdown which has z-index of 1000. */ + z-index: 999; +` + interface Props { intl: IntlShape map: React.ReactElement @@ -22,20 +50,45 @@ interface Props { class BatchSearchScreen extends Component { state = { - planTripClicked: false + closeAdvancedSettingsWithDelay: false, + planTripClicked: false, + showAdvancedModeSettings: false } _fromFieldClicked = () => this.props.setMobileScreen(SET_FROM_LOCATION) _toFieldClicked = () => this.props.setMobileScreen(SET_TO_LOCATION) + _mainPanelContentRef = React.createRef() + _advancedSettingRef = React.createRef() + handlePlanTripClick = () => { this.setState({ planTripClicked: true }) } + openAdvancedSettings = () => { + this.setState({ + closeAdvancedSettingsWithDelay: false, + showAdvancedModeSettings: true + }) + } + + closeAdvancedSettings = () => { + this.setState({ showAdvancedModeSettings: false }) + } + + setCloseAdvancedSettingsWithDelay = () => { + this.setState({ + closeAdvancedSettingsWithDelay: true + }) + } + render() { const { intl } = this.props - const { planTripClicked } = this.state + const { planTripClicked, showAdvancedModeSettings } = this.state + + const transitionDelay = this.state.closeAdvancedSettingsWithDelay ? 300 : 0 + const transitionDurationWithDelay = transitionDuration + transitionDelay return ( { })} />
                                                                                                                                                                                      -
                                                                                                                                                                                      - - -
                                                                                                                                                                                      - -
                                                                                                                                                                                      - -
                                                                                                                                                                                      + + + + {/* Unfortunately we can't use a ternary operator here because it is cancelling out the CSSTransition animations. */} + {!showAdvancedModeSettings && ( + +
                                                                                                                                                                                      + + +
                                                                                                                                                                                      + +
                                                                                                                                                                                      + +
                                                                                                                                                                                      +
                                                                                                                                                                                      + )} + {showAdvancedModeSettings && ( + + + + )} +
                                                                                                                                                                                      +
                                                                                                                                                                                      +
                                                                                                                                                                                      diff --git a/lib/components/mobile/mobile.css b/lib/components/mobile/mobile.css index b0b6fb3db..b1197cfbd 100644 --- a/lib/components/mobile/mobile.css +++ b/lib/components/mobile/mobile.css @@ -121,20 +121,9 @@ /* Batch routing search screen */ -.otp.mobile .batch-search-settings { - position: fixed; - top: 50px; - left: 0; - right: 0; - height: 216px; - /* Must appear under the 'hamburger' dropdown which has z-index of 1000. */ - z-index: 999; - box-shadow: 3px 0px 12px #00000052; -} - .otp.mobile .batch-search-map { position: fixed; - top: 266px; + top: 282px; left: 0; right: 0; bottom: 0; diff --git a/lib/components/util/prefersReducedMotion.tsx b/lib/components/util/prefersReducedMotion.tsx new file mode 100644 index 000000000..69e13b7d4 --- /dev/null +++ b/lib/components/util/prefersReducedMotion.tsx @@ -0,0 +1,9 @@ +/** + * Identifies whether the user's machine has "reduced motion" enabled + * in their local settings. If reduced motion is on, the app should + * show as few animations & transitions as possible. + * @returns boolean reflecting whether user prefers reduced motion + */ +export const prefersReducedMotion = window.matchMedia( + '(prefers-reduced-motion: reduce)' +).matches diff --git a/lib/components/util/types.ts b/lib/components/util/types.ts index 9b21030fa..83bcd7930 100644 --- a/lib/components/util/types.ts +++ b/lib/components/util/types.ts @@ -108,3 +108,5 @@ export type ZoomToPlaceHandler = ( place?: { lat: number; lon: number }, zoom?: number ) => void + +export type QueryParamChangeHandler = (event: any) => void diff --git a/lib/components/viewers/pattern-row.tsx b/lib/components/viewers/pattern-row.tsx index 73bc22006..4f87a8c7a 100644 --- a/lib/components/viewers/pattern-row.tsx +++ b/lib/components/viewers/pattern-row.tsx @@ -1,5 +1,6 @@ import { Calendar } from '@styled-icons/fa-regular' import { format, utcToZonedTime } from 'date-fns-tz' +import { FormattedMessage } from 'react-intl' import { getMostReadableTextColor } from '@opentripplanner/core-utils/lib/route' import { isSameDay } from 'date-fns' import React, { useContext } from 'react' @@ -108,8 +109,15 @@ const PatternRow = ({ {pattern.route.longName} )} - {extractHeadsignFromPattern(pattern) || - (pattern.route.longName !== routeName && pattern.route.longName)} +

                                                                                                                                                                                      {/* next departure preview (only shows up to 3 entries) */} diff --git a/lib/components/viewers/viewers.css b/lib/components/viewers/viewers.css index 31e260402..1ea4637a9 100644 --- a/lib/components/viewers/viewers.css +++ b/lib/components/viewers/viewers.css @@ -60,12 +60,18 @@ } .otp .trip-viewer .header-text, -.otp .route-viewer .header-text { - display: contents; +.otp .route-viewer .header-text, +.otp .advanced-settings .header-text { font-weight: 700; font-size: 24px; margin: 0; } + +.otp .trip-viewer .header-text, +.otp .route-viewer .header-text { + display: contents; +} + .otp .route-viewer .header-text.route-expanded { display: flex; align-items: center; diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index d44980640..3f71126cb 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -339,6 +339,10 @@ export interface TransitOperatorConfig extends TransitOperator { routeIcons?: boolean } +export interface AdvancedSettingsPanelConfig { + saveAndReturnButton?: boolean +} + /** Route Viewer config */ export interface RouteViewerConfig { /** Whether to hide the route linear shape inside a flex zone of that route. */ @@ -367,6 +371,7 @@ export interface DateTimeConfig { /** The main application configuration object */ export interface AppConfig { accessibilityScore?: AccessibilityScoreConfig + advancedSettingsPanel?: AdvancedSettingsPanelConfig api: ApiConfig // Optional on declaration, populated with defaults in reducer if not configured. autoPlan?: boolean | AutoPlanConfig diff --git a/lib/util/state-types.ts b/lib/util/state-types.ts index 05b89d3cc..4c5c70a3b 100644 --- a/lib/util/state-types.ts +++ b/lib/util/state-types.ts @@ -5,6 +5,7 @@ import { MonitoredTrip, User } from '../components/user/types' +import { ModeSetting } from '@opentripplanner/types' import { AppConfig } from './config-types' @@ -15,6 +16,7 @@ export interface OtpState { currentQuery: any filter: FilterType location: any + modeSettingDefinitions: ModeSetting[] overlay: any serviceTimeRange?: { end: number diff --git a/package.json b/package.json index 5b4a1881e..34e1e7c8f 100644 --- a/package.json +++ b/package.json @@ -42,34 +42,35 @@ "@bugsnag/js": "^7.17.0", "@bugsnag/plugin-react": "^7.17.0", "@floating-ui/react": "^0.19.2", - "@opentripplanner/base-map": "^3.2.2", - "@opentripplanner/building-blocks": "^1.2.3", - "@opentripplanner/core-utils": "^11.4.4", - "@opentripplanner/endpoints-overlay": "^2.1.4", - "@opentripplanner/from-to-location-picker": "^2.1.14", + "@opentripplanner/base-map": "4.0.0", + "@opentripplanner/building-blocks": "2.0.0", + "@opentripplanner/core-utils": "12.0.0", + "@opentripplanner/endpoints-overlay": "3.0.0", + "@opentripplanner/from-to-location-picker": "3.0.0", "@opentripplanner/geocoder": "^3.0.2", "@opentripplanner/humanize-distance": "^1.2.0", - "@opentripplanner/icons": "^2.0.13", - "@opentripplanner/itinerary-body": "^5.3.7", - "@opentripplanner/location-field": "^2.0.24", + "@opentripplanner/icons": "3.0.0", + "@opentripplanner/itinerary-body": "6.0.0", + "@opentripplanner/location-field": "3.0.0", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "^4.0.2", - "@opentripplanner/otp2-tile-overlay": "^1.0.17", - "@opentripplanner/park-and-ride-overlay": "^2.0.9", - "@opentripplanner/printable-itinerary": "^2.0.23", - "@opentripplanner/route-viewer-overlay": "^2.0.17", - "@opentripplanner/stop-viewer-overlay": "^2.0.10", - "@opentripplanner/stops-overlay": "^5.3.3", - "@opentripplanner/transit-vehicle-overlay": "^4.0.13", - "@opentripplanner/transitive-overlay": "3.0.22", - "@opentripplanner/trip-details": "^5.0.15", - "@opentripplanner/trip-form": "^3.6.4", - "@opentripplanner/trip-viewer-overlay": "^2.0.10", - "@opentripplanner/vehicle-rental-overlay": "^2.1.9", + "@opentripplanner/map-popup": "5.0.0", + "@opentripplanner/otp2-tile-overlay": "2.0.0", + "@opentripplanner/park-and-ride-overlay": "3.0.0", + "@opentripplanner/printable-itinerary": "3.0.0", + "@opentripplanner/route-viewer-overlay": "3.0.0", + "@opentripplanner/stop-viewer-overlay": "3.0.0", + "@opentripplanner/stops-overlay": "6.0.0", + "@opentripplanner/transit-vehicle-overlay": "5.0.0", + "@opentripplanner/transitive-overlay": "4.0.0", + "@opentripplanner/trip-details": "6.0.0", + "@opentripplanner/trip-form": "4.0.0", + "@opentripplanner/trip-viewer-overlay": "3.0.0", + "@opentripplanner/vehicle-rental-overlay": "3.0.0", "@styled-icons/fa-regular": "^10.34.0", "@styled-icons/fa-solid": "^10.34.0", "@turf/centroid": "^6.5.0", "@turf/helpers": "^6.5.0", + "@types/react-transition-group": "^4.4.10", "blob-stream": "^0.1.3", "bootstrap": "^3.3.7", "bowser": "^1.9.3", @@ -118,6 +119,7 @@ "react-router-dom": "^5.3.4", "react-select": "^3.1.0", "react-sliding-pane": "^7.0.0", + "react-transition-group": "^4.4.5", "redux": "^4.0.4", "redux-actions": "^1.2.1", "redux-logger": "^2.7.4", diff --git a/percy/percy.test.js b/percy/percy.test.js index c4ac7142e..6e8e8b1e6 100644 --- a/percy/percy.test.js +++ b/percy/percy.test.js @@ -133,16 +133,19 @@ async function executeTest(page, isMobile, isCallTaker) { await page.keyboard.press('Escape') await page.waitForTimeout(200) - // Check submode selector (this will have no effect on mock query) - await page.hover('label[title="Transit"]') + // Open advanced settings and wait for animation + await page.click('#open-advanced-settings-button') await page.waitForTimeout(500) + + // Check submode selector (this will have no effect on mock query) await page.click('#id-query-param-tram') // Enable accessible routing (this will have no effect on mock query) - await page.hover('label[title="Transit"]') - await page.waitForTimeout(500) await page.click('#id-query-param-wheelchair') + // Close advanced settings + await page.click('#close-advanced-settings-button') + await page.waitForTimeout(500) // Delete both origin and destination await page.click('.from-form-control') @@ -189,14 +192,12 @@ async function executeTest(page, isMobile, isCallTaker) { await page.waitForTimeout(1000) // wait extra time for all results to load if (!isMobile) { - await page.hover('label[title="Transit"]') - await page.waitForTimeout(200) - await percySnapshotWithWait( - page, - 'Metro Transit-Walk Itinerary Desktop with Mode Selector Expanded' - ) - // Hover something else to unhover the mode selector. - await page.hover('#plan-trip') + await page.click('#open-advanced-settings-button') + await page.waitForTimeout(500) + await percySnapshotWithWait(page, 'Metro Advanced Settings Open') + // Close advanced settings + await page.click('#close-advanced-settings-button') + await page.waitForTimeout(500) } else { await percySnapshotWithWait(page, 'Metro Transit-Walk Itinerary Mobile') } diff --git a/yarn.lock b/yarn.lock index 930fe34b0..599332b3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,12 +2383,12 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" - integrity sha512-d/yTKEnXqrw9pXhSvCERT+wLFa077Xr4wEFu4pYB+WYoZFflNxuTuAXXjm268HS/d0kjNndkjSMkxaKk6AjsvA== +"@opentripplanner/base-map@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-4.0.0.tgz#56ffa1d833673282cc3a0b7a17f388fc5dbd31e3" + integrity sha512-pWTKXxnzUQk43woPMc40uYfGIcGqHV8GoCvRwrIu2pqNw7QAV4rxjZfca0pm5hnbbJ+G83sRzYboILEbEUwMcw== dependencies: - "@opentripplanner/map-popup" "^3.1.0" + "@opentripplanner/building-blocks" "^1.2.2" mapbox-gl "npm:empty-npm-package@1.0.0" maplibre-gl "^2.1.9" react-map-gl "^7.0.15" @@ -2403,19 +2403,24 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@^1.2.2", "@opentripplanner/building-blocks@^1.2.3": +"@opentripplanner/building-blocks@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-2.0.0.tgz#8282c01dff7db5c7e809f6ea91cb52df559a2f9d" + integrity sha512-N07rDaZL8fp552eI9/0j1udKjc0uOpvO0Wv1P19Ge0a4roques463MJgWJ026fbopRCi3uwbc/gYTlh4/ske9A== + +"@opentripplanner/building-blocks@^1.0.3", "@opentripplanner/building-blocks@^1.2.2": version "1.2.3" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@^11.4.0": - version "11.4.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" - integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== +"@opentripplanner/core-utils@12.0.0": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" + integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/geocoder" "^3.0.2" "@styled-icons/foundation" "^10.34.0" "@turf/along" "^6.0.1" chroma-js "^2.4.2" @@ -2444,10 +2449,10 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/endpoints-overlay@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.4.tgz#f81088bce83236344dfa4a51b2efe00092a5c87a" - integrity sha512-VLRZArhoRQ38aafc/w986Uv1lnq/WLJOgBqnpvuUbLhLR/qHU9h5X3wg3jgwf2GA0BIn03Z99VJbCkGfkyd0LA== +"@opentripplanner/endpoints-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-3.0.0.tgz#17bb943f5bf2b8571cb808b12b5a2185fd18196a" + integrity sha512-st6vfLRCBzVollYS4nIXghbjApDq73lcExo7hZh60DCVSGESSZA9jsNE6ff0HmvhYHdag9QV9zbZOFuNxPIrng== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/building-blocks" "^1.2.2" @@ -2456,10 +2461,10 @@ "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" -"@opentripplanner/from-to-location-picker@^2.1.12", "@opentripplanner/from-to-location-picker@^2.1.13": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-2.1.13.tgz#d13acd582929175c676cd4303a6cdc6e1c289d99" - integrity sha512-6/7+wYQuuQhnGvxkDQcvoACdmuwUL1BlPqBIUFwyBpkdJ1VQGZiUSAAZTxXdY1Fv/p5mKR1vRsvZgtSPhcxgcg== +"@opentripplanner/from-to-location-picker@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-3.0.0.tgz#048a596c2f854825e0058e03dac67dcad7eb5864" + integrity sha512-jRXaY9jKg+PXUL7Z2SkHRyO88xG1t7iG3U449LPiCm/6flxsY+Wlxg+nyMsAP5gQMjOU0wsGLdH83lGgrpSF4A== dependencies: "@opentripplanner/location-icon" "^1.4.1" flat "^5.0.2" @@ -2472,17 +2477,6 @@ "@opentripplanner/location-icon" "^1.4.1" flat "^5.0.2" -"@opentripplanner/geocoder@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.1.tgz#834960bc52f515e1223346a8002fb847674d33bc" - integrity sha512-+LHTqY8pHmPE39IjVev5T5baa+BohEyvsLwVwFB2bYWzM+m/RgAJ188uBcDzXKdqk5y3dZR9ZODYVMtrvIiKzQ== - dependencies: - "@conveyal/geocoder-arcgis-geojson" "^0.0.3" - "@conveyal/lonlat" "^1.4.1" - "@leeoniya/ufuzzy" "^1.0.14" - isomorphic-mapzen-search "^1.6.1" - lodash.memoize "^4.1.2" - "@opentripplanner/geocoder@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.2.tgz#2c7618947d1d9b082bd39d037327c9cf23282782" @@ -2499,7 +2493,15 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA== -"@opentripplanner/icons@^2.0.12", "@opentripplanner/icons@^2.0.13": +"@opentripplanner/icons@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-3.0.0.tgz#f7293fd4dd2625eace3a4c82ecd573d6000d85d3" + integrity sha512-naSCdCsPwSyEiP7Vf6oN6dpgwpFIkeQFXfTJG7lp1Dg9emLTAYzRx/f+45e9Bh0zP0aA4DsN4VgHBQllyu82qQ== + dependencies: + "@opentripplanner/core-utils" "^11.4.4" + prop-types "^15.7.2" + +"@opentripplanner/icons@^2.0.12": version "2.0.13" resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.13.tgz#45c4c16d8f208cff73811941f2def0fa23f87780" integrity sha512-1oEPCmFuyS88bJZ2U9eFlEw2kQ0ZZW+wOI1dggr0omJDD6L+nVNQJ6TUtosNHYL1S35Jpx4aSQEG3iwwlXOHMg== @@ -2507,7 +2509,25 @@ "@opentripplanner/core-utils" "^11.4.4" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@^5.3.6", "@opentripplanner/itinerary-body@^5.3.7": +"@opentripplanner/itinerary-body@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-6.0.0.tgz#e261bcccd0d7a786f7f17be987a52ba1dc940229" + integrity sha512-j79byCefyEZuomvDlvBZJVZJ92+X6U4ivth3M62RKGmw1x8qW4nsbEKnzeQxXzGJcy3M+91eeIpcJnj98KHlRw== + dependencies: + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/humanize-distance" "^1.2.0" + "@opentripplanner/icons" "^2.0.12" + "@opentripplanner/location-icon" "^1.4.1" + "@styled-icons/fa-solid" "^10.34.0" + "@styled-icons/foundation" "^10.34.0" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + flat "^5.0.2" + react-animate-height "^3.0.4" + react-resize-detector "^4.2.1" + string-similarity "^4.0.4" + +"@opentripplanner/itinerary-body@^5.3.6": version "5.3.7" resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.7.tgz#e32437f804defc19aef23685e45c0a363ac8bc31" integrity sha512-ZnbxI78WsY6/Ynl3QY026JqimGG+gqXcN8ZEXY/BPMrNhSul27HgFFT2Flo37Fnc5gN2+jE8LsR1yxq05H3kvQ== @@ -2525,10 +2545,10 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" -"@opentripplanner/location-field@^2.0.24": - version "2.0.24" - resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.24.tgz#32e7109142bd754d28bd28ebbdf68d4e5ef4c812" - integrity sha512-fOAyanDnLLHC39kHG6kMSY6i09n4l0KSVQACFoosGZgUcJmz5CUCMl0/x3RszIwh3g2wqxKh6fagh4V56YEpfQ== +"@opentripplanner/location-field@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-3.0.0.tgz#a6f8743290cf088bcd589cf8e6b0d07a651b704a" + integrity sha512-wPb9l5pvSeocZ45K1E3Zeb4hDjJtP9tw/S0MQ3HXYEQSf+700n4CWXVXYReYJXJYriOzge5/2whjUPGTlJckWw== dependencies: "@conveyal/geocoder-arcgis-geojson" "^0.0.3" "@opentripplanner/core-utils" "^11.4.4" @@ -2546,16 +2566,18 @@ "@styled-icons/fa-regular" "^10.34.0" "@styled-icons/fa-solid" "^10.34.0" -"@opentripplanner/map-popup@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.1.1.tgz#54f081162d328cc4bb0e89562f9ea200e29e01a1" - integrity sha512-yWBIPuYGw7biaRNIpglQm5+opZ+D5QQgXHLhKnYaCR0eNijjl9cx34lGXdyKPXt26S6MiyJZXL81uc6w6CnQ3A== +"@opentripplanner/map-popup@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-5.0.0.tgz#cf360845704ed54222c8bf19581ed1253d3dcf14" + integrity sha512-cuIzZm/cZbjY2tAVLSDpBK63efR+YsEsXVPBx4VAHlGhJoY1yooipFlq+3/51VSsFOJPp6gcsKaizfdICDJlYA== dependencies: - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/from-to-location-picker" "^2.1.12" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/from-to-location-picker" "^2.1.14" flat "^5.0.2" -"@opentripplanner/map-popup@^4.0.0", "@opentripplanner/map-popup@^4.0.2": +"@opentripplanner/map-popup@^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-4.0.2.tgz#367ab7ce69d16d319988bb48d8f6d2db762623c7" integrity sha512-RlHv9GE3Bk3++PwBcaPcALr6rZ+2AxY6Uj6W71AnLqz+wbeQO5rM3eEP99r0Sg1K3pAY0hXljBkVwKiUWhwxbQ== @@ -2566,33 +2588,33 @@ "@opentripplanner/from-to-location-picker" "^2.1.14" flat "^5.0.2" -"@opentripplanner/otp2-tile-overlay@^1.0.17": - version "1.0.17" - resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-1.0.17.tgz#0e63bcb956778bbab6bd42d282aa9f5416881b74" - integrity sha512-mgMHprVVOXdzgU0D/50be57TeuEp1RP+b7xH/3Xt+rj0mF1PY+5GgLMuEul+1WqbzFwAefrmi9KRMs3MYJArrg== +"@opentripplanner/otp2-tile-overlay@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-2.0.0.tgz#6af1a9113a8baaebb226a5e747e8e523f6da249b" + integrity sha512-Yc0VsfxS6xIw4+1i9lpvQyCXobkTubZWYYu+6bDWkk77D4J4WaSoWE/qWT39vc2/h1ZY4afUZL59d7kc8V0PLg== dependencies: "@opentripplanner/map-popup" "^4.0.0" -"@opentripplanner/park-and-ride-overlay@^2.0.9": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-2.0.9.tgz#0efe2bf8a7595b56c4da6396e89db5f04e4b3ec8" - integrity sha512-ekf6kcCgMVTzXDMY3Ed8qclaL3YY2/1BrArdpRY8DxciGWmE1HKOW90Vf1aP18aLrwcW9kpvv1Kdbl60tY6mCQ== +"@opentripplanner/park-and-ride-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/park-and-ride-overlay/-/park-and-ride-overlay-3.0.0.tgz#7139d5358bc8e5f68f1574e9225a3bcfb57993be" + integrity sha512-MLalzHhXSZ1yAwW9cyMVoUUQPMGktTTPFbhgEB/Ft4fX/TJAIH1sQHsKoaeGE0+48Kxg4M49zPoeNujr9RIeGA== dependencies: - "@opentripplanner/base-map" "^3.2.0" - "@opentripplanner/from-to-location-picker" "^2.1.13" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/from-to-location-picker" "^2.1.14" -"@opentripplanner/printable-itinerary@^2.0.23": - version "2.0.23" - resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.23.tgz#31f11e0e22bb9f223c4c1d8fa97c6eea18496cfa" - integrity sha512-Cb5SX7ts0rX0P1XSStjqbTITP5ueWlDe1b7U4KMaRNqEOaK2tELEyb/qZGo9kMpXTT/17jmEQZsKHQj43C5Eyg== +"@opentripplanner/printable-itinerary@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-3.0.0.tgz#7f4438b18cbd767ede74b2a3b7e3ad6ab1ec936b" + integrity sha512-/P7HtzXPu0yP6ZnfHl1DQFTVgEx+YplLxs43jd7rnXc0PUvsVyAsmp4oI3TDG8tStMD9pKsVLOCBNLUacoXo1Q== dependencies: "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/itinerary-body" "^5.3.6" -"@opentripplanner/route-viewer-overlay@^2.0.17": - version "2.0.17" - resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-2.0.17.tgz#f34686fd965cf39650a10f64df599e7aca468415" - integrity sha512-3UTTLxHhaMg4iKP4oJlobvUCbvC/TjCW6ss8PxxC3UurwiMeSFNVkaWGLElPc9YoKg0QqKxrIY7zq0WClIPa6g== +"@opentripplanner/route-viewer-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/route-viewer-overlay/-/route-viewer-overlay-3.0.0.tgz#d307af1fb734f113627a82f816bf4683a7d9a860" + integrity sha512-Kbgs+gkzOKNEoXG2ImoUBekET5olMc8sGo9ltb7tgTg8ZuBcq3woMID7b3+n3DDdvqdHLExg5T68gkip1Eu/QQ== dependencies: "@mapbox/polyline" "^1.1.0" "@opentripplanner/base-map" "^3.2.2" @@ -2610,38 +2632,38 @@ glob-promise "^4.2.2" js-yaml "^4.1.0" -"@opentripplanner/stop-viewer-overlay@^2.0.10": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-2.0.10.tgz#0749fe7ffb28dac7a6925ed7c663e2fdd5156f3b" - integrity sha512-rFmaqQ7uJ+ZE80O6fveiNxlEVSJW5PwFSMh1B9pN0HaVTB1U27+yKbIMMuP7GtWve31mPy+PaWYXDW3hMlsi8A== +"@opentripplanner/stop-viewer-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/stop-viewer-overlay/-/stop-viewer-overlay-3.0.0.tgz#69dc8af797ab9a202954137b6ea68bcaa45cc4ff" + integrity sha512-1OnLhP9QcOnAe1qwSrjLXsFsMtqx7tBullcl/CgT5kYA/aXLKNiQ7zGeMrfbALOXhU51v74gtmMEAwW1EB1pcw== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" -"@opentripplanner/stops-overlay@^5.3.3": - version "5.3.3" - resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.3.3.tgz#711dd9316de93ac6c959dc3191d31884dc0a9589" - integrity sha512-GYADErZLIG3KPJ4OiigWkyHaGrWJ/wiCenH0RTbQ5J0XbYrenUIlWBsI5kpQNZPGBXocvF77sOTOUM8gex1AUA== +"@opentripplanner/stops-overlay@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-6.0.0.tgz#97186a2ce82284e2632967a4666294ad04d092db" + integrity sha512-zGpCc2PWpHDn1VGu9zdLfRIfde9sNAMN6ElHkLQq/67ylrQ7R1jIzi9K1O2X/ZPAEtfH5VOYa/y/A1drNlN3gw== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/from-to-location-picker" "^2.1.14" "@opentripplanner/map-popup" "^4.0.0" flat "^5.0.2" -"@opentripplanner/transit-vehicle-overlay@^4.0.13": - version "4.0.13" - resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.13.tgz#6f66c7c6a27d2473353b7c8c14acc8c540fb01ad" - integrity sha512-Sh3c3+q2dIhFZP5uyhPboyLSsTv8unVsPYKjFWVJaK19z6wN8KqFVmSqWysrcEnooRJd+D4+4erQiUbabomDLQ== +"@opentripplanner/transit-vehicle-overlay@5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-5.0.0.tgz#1a3ea04abce38d65a21a9eaad8c5e0ac19a41100" + integrity sha512-N0vM89xozWTbbb63pBeZEZIbdlbgnP2K0qNJZ0vk87clJU0T7RxBtq/sdftBQ6CzB86AjXCCxfitCZH9HOD7/A== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" "@opentripplanner/icons" "^2.0.12" flat "^5.0.2" -"@opentripplanner/transitive-overlay@3.0.22": - version "3.0.22" - resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-3.0.22.tgz#631096b12e08671e5da05ffe1c0a0e01331750a4" - integrity sha512-Ix3+2qz1+iSbeLnMfd4tU+0AUU1LDjq4y8cTzfKHayqHe0pzHpYY9Ib2zrXbvog7Mav/Jozn2ycL27R4UgzQaA== +"@opentripplanner/transitive-overlay@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/transitive-overlay/-/transitive-overlay-4.0.0.tgz#1a0c41dd4a22704b74da105ef67c0ac63624c335" + integrity sha512-kFKRbKGeIKNDx2t21HaPXsOOkG+qlnHgXN8lbTZRxpfy+EIV3ZeoH72/ymWuiHdLnxUORHBAjhacQh+2fryc4A== dependencies: "@mapbox/polyline" "^1.1.1" "@opentripplanner/base-map" "^3.2.2" @@ -2655,22 +2677,23 @@ "@turf/midpoint" "^6.5.0" lodash.isequal "^4.5.0" -"@opentripplanner/trip-details@^5.0.15": - version "5.0.15" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.15.tgz#73cfd7427aed49af53fec4ded9de7d17b0ed5377" - integrity sha512-1OfCEju90PXGH9DVy2dbBk8Jz8/8zSJ35/OCgodenGT3FyokQPoJsQhPjr6MPIIYMTyAdUSDT9C372thA+rU2Q== +"@opentripplanner/trip-details@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-6.0.0.tgz#60958ca14910f865125d20db8ec2eeba6d2c7362" + integrity sha512-BzUAsSpuSWzVMRW6vhiZblrg0Sq7Tnar17jjgvTvIhzv0yUUyrW5jUxlGIPPk11UUJ5WrPZmkfQasF9z8xk5BQ== dependencies: "@opentripplanner/core-utils" "^11.4.4" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.4.tgz#e741bb190dbea845c826d0021618daf568cc3df7" - integrity sha512-wnoJyI8jR3DbtTmg//FWWy+yhd6Yej843XxSnnGCuBhZjUnvC9aYffKa/FI1W9s8Xw+tJ7DsZ9wADiSOWEjmwA== +"@opentripplanner/trip-form@4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-4.0.0.tgz#27b36a0504e46cfda1cdf50c971b5cea03de8ae2" + integrity sha512-Cg8SlAVN8M+qoWpz8jAkwuqllIPgrL2PVewTPuDPsIQ8i5B7xo5KKE3TPo7cQUM+jE6WEshpvv0FIdMF+NAlNg== dependencies: "@floating-ui/react" "^0.19.2" + "@opentripplanner/building-blocks" "^1.0.3" "@opentripplanner/core-utils" "^11.4.4" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" @@ -2678,13 +2701,14 @@ "@styled-icons/fa-solid" "^10.37.0" date-fns "^2.28.0" flat "^5.0.2" + react-animate-height "^3.0.4" react-indiana-drag-scroll "^2.0.1" react-inlinesvg "^2.3.0" -"@opentripplanner/trip-viewer-overlay@^2.0.10": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-2.0.10.tgz#2c0809b2d54da4d57d0a0683a4739e29cb13a326" - integrity sha512-7M9l7fF8shtD/566bci+zEkPncf/L+ZWIYAl5gnIgrBxwLagN/+E2zkoDebYamGFGb236FXpvTS30i1BJzhcPA== +"@opentripplanner/trip-viewer-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-viewer-overlay/-/trip-viewer-overlay-3.0.0.tgz#a56263863aba87a3608d4dbed0cf839333cf99d0" + integrity sha512-64qNLUxkL6ow8T1FghdKDp13KH96djjYAo6hHTAeZYHZuu7gxffRD1GmrDJVeyk0+DixjKdiNhAZ9mOCtAgK/w== dependencies: "@mapbox/polyline" "^1.1.0" "@opentripplanner/base-map" "^3.2.2" @@ -2695,10 +2719,10 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.2.tgz#1373d738479568d880a3b13670b0ec53a1a75bd5" integrity sha512-2qDcKOrsLoXdwjRAdi4xcdDUsZGTnwBM+vfEf8TTuuWSnA+WYav3ldlMB4sugxIdLaVKXlOfe3F5lCEh9jAHWA== -"@opentripplanner/vehicle-rental-overlay@^2.1.9": - version "2.1.9" - resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-2.1.9.tgz#c373e1400874a00f473be0f029b28e0944652c88" - integrity sha512-VYWqnuk5j1yHF/zH5NEqDIVjsSbIsIgiCK6SaYtQHOBwszWauIubpqviTBASAcY72JfKE36AQfGjPuYILd9oTw== +"@opentripplanner/vehicle-rental-overlay@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/vehicle-rental-overlay/-/vehicle-rental-overlay-3.0.0.tgz#68e2a6c117fa3af485f375685c24a557762c6bb6" + integrity sha512-Yt6l6fEX+5O1jJ4z2NpbA0rib2tARxKdE3nTUFaBORBSq/NFfa2vZMk3EBXIrtzC3/GRabqluJU8sDaMGfkvvw== dependencies: "@opentripplanner/base-map" "^3.2.2" "@opentripplanner/core-utils" "^11.4.4" @@ -3677,6 +3701,13 @@ "@types/history" "^4.7.11" "@types/react" "*" +"@types/react-transition-group@^4.4.10": + version "4.4.11" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz#d963253a611d757de01ebb241143b1017d5d63d5" + integrity sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@17": version "17.0.38" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.38.tgz#f24249fefd89357d5fa71f739a686b8d7c7202bd" @@ -15526,6 +15557,16 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-transition-group@^4.4.5: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react@<17.0.0: version "16.14.0" resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" From d6f1a8cd2e12701265c4778f1015e8f55de70724 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 25 Sep 2024 12:36:59 -0700 Subject: [PATCH 134/162] more cleanup --- lib/components/form/date-time-modal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/components/form/date-time-modal.tsx b/lib/components/form/date-time-modal.tsx index 1f0e13557..e9f31407b 100644 --- a/lib/components/form/date-time-modal.tsx +++ b/lib/components/form/date-time-modal.tsx @@ -3,11 +3,11 @@ import coreUtils from '@opentripplanner/core-utils' import React, { useCallback } from 'react' import * as formActions from '../../actions/form' +import * as narrativeActions from '../../actions/narrative' import { AppConfig } from '../../util/config-types' import { AppReduxState, FilterType, SortType } from '../../util/state-types' import { StyledDateTimeSelector } from './styled' -import { updateItineraryFilter } from '../../actions/narrative' type Props = { config: AppConfig @@ -110,7 +110,7 @@ const mapStateToProps = (state: AppReduxState) => { const mapDispatchToProps = { setQueryParam: formActions.setQueryParam, - updateItineraryFilter + updateItineraryFilter: narrativeActions.updateItineraryFilter } export default connect(mapStateToProps, mapDispatchToProps)(DateTimeModal) From fe78a8aa399b8ad6fd269a855298334fe68bdb74 Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Wed, 25 Sep 2024 12:53:56 -0700 Subject: [PATCH 135/162] pr review cleanup --- lib/actions/field-trip.js | 2 +- .../narrative/default/default-itinerary.js | 2 +- .../narrative/line-itin/LegIconWithA11y.tsx | 14 ++++++-------- .../narrative/line-itin/realtime-time-column.tsx | 2 +- lib/components/narrative/narrative-itineraries.js | 2 +- lib/util/itinerary.tsx | 2 +- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/actions/field-trip.js b/lib/actions/field-trip.js index 28c008e69..6522acb3b 100644 --- a/lib/actions/field-trip.js +++ b/lib/actions/field-trip.js @@ -712,7 +712,7 @@ function checkValidityAndCapacity(state, request) { // check each individual trip to see if there aren't any trips in this // itinerary that are already in use by another field trip itinerary.legs - .filter((leg) => isTransitLeg(leg.mode)) + .filter((leg) => isTransitLeg(leg)) .forEach((leg) => { const tripId = leg?.trip?.gtfsId diff --git a/lib/components/narrative/default/default-itinerary.js b/lib/components/narrative/default/default-itinerary.js index bdfdb7b7c..ba67d24da 100644 --- a/lib/components/narrative/default/default-itinerary.js +++ b/lib/components/narrative/default/default-itinerary.js @@ -164,7 +164,7 @@ const ITINERARY_ATTRIBUTES = [ order: 3, render: (itinerary, options) => { const leg = clone(itinerary.legs[0]) - if (isTransitLeg(leg.mode)) { + if (isTransitLeg(leg)) { leg.mode = 'WALK' } diff --git a/lib/components/narrative/line-itin/LegIconWithA11y.tsx b/lib/components/narrative/line-itin/LegIconWithA11y.tsx index 307819393..283fe7ace 100644 --- a/lib/components/narrative/line-itin/LegIconWithA11y.tsx +++ b/lib/components/narrative/line-itin/LegIconWithA11y.tsx @@ -1,14 +1,12 @@ +import { isTransitLeg } from '@opentripplanner/core-utils/lib/itinerary' import { Leg } from '@opentripplanner/types' +import { useIntl } from 'react-intl' +import { ComponentContext } from '../../../util/contexts' import { getFormattedMode } from '../../../util/i18n' -import coreUtils from '@opentripplanner/core-utils' -import InvisibleA11yLabel from '../../util/invisible-a11y-label' - import React, { useContext } from 'react' -import { ComponentContext } from '../../../util/contexts' - -import { useIntl } from 'react-intl' +import InvisibleA11yLabel from '../../util/invisible-a11y-label' type Props = { leg: Leg @@ -19,8 +17,8 @@ const LegIconWithA11y = (props: Props): JSX.Element => { const { LegIcon } = useContext(ComponentContext) const intl = useIntl() const { leg } = props - const { mode, transitLeg } = leg - const ariaLabel = transitLeg ? getFormattedMode(mode, intl) : null + const { mode } = leg + const ariaLabel = isTransitLeg(leg) ? getFormattedMode(mode, intl) : null return ( <> diff --git a/lib/components/narrative/line-itin/realtime-time-column.tsx b/lib/components/narrative/line-itin/realtime-time-column.tsx index 0c5f802f8..303a700d9 100644 --- a/lib/components/narrative/line-itin/realtime-time-column.tsx +++ b/lib/components/narrative/line-itin/realtime-time-column.tsx @@ -36,7 +36,7 @@ function RealtimeTimeColumn({ isDestination, leg }: Props): ReactElement { const isRealtimeTransitLeg = isTransitLeg(leg) && leg.realTime // For non-transit legs show only the scheduled time. - if (!isTransitLeg) { + if (!isTransitLeg(leg)) { return (
                                                                                                                                                                                      diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index 5c7faf9f0..ec55d4636 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -423,7 +423,7 @@ class NarrativeItineraries extends Component { }) // Identify whether an itinerary uses transit & sort into appropriate bucket - const transitLegs = cur.legs.filter((leg) => isTransitLeg(leg.mode)) + const transitLegs = cur.legs.filter((leg) => isTransitLeg(leg)) const modeContainer = transitLegs.length > 0 ? modeItinMap.multi : modeItinMap.single diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index f1d5f4f5a..a8f2d1a2b 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -82,7 +82,7 @@ export function getMinutesUntilItineraryStart(itinerary: Itinerary): number { * Gets the first transit leg of the given itinerary, or null if none found. */ function getFirstTransitLeg(itinerary: Itinerary) { - return itinerary?.legs?.find((leg) => isTransitLeg(leg)) + return itinerary?.legs?.find(isTransitLeg) } /** From 00c786fb005c0e7bb97a3ce72d940d8b95cdddcb Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:09:35 -0500 Subject: [PATCH 136/162] Adds a configuration item that removes the ability to monitor a trip for only one day --- i18n/en-US.yml | 1 + .../user/monitored-trip/saved-trip-screen.js | 39 ++- .../user/monitored-trip/trip-basics-pane.tsx | 241 +++++++++++------- .../util/formatted-validation-error.js | 4 + lib/util/config-types.ts | 1 + 5 files changed, 188 insertions(+), 98 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index 1b13a37da..5df0782de 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -534,6 +534,7 @@ components: SavedTripScreen: itineraryLoaded: Itinerary loaded itineraryLoading: Loading itinerary + selectAtLeastOneDay: Please select at least one day to monitor. tooManyTrips: > You already have reached the maximum of five saved trips. Please remove unused trips from your saved trips, and try again. diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js index 14ab18f8b..d0b7f1c1f 100644 --- a/lib/components/user/monitored-trip/saved-trip-screen.js +++ b/lib/components/user/monitored-trip/saved-trip-screen.js @@ -149,8 +149,14 @@ class SavedTripScreen extends Component { } render() { - const { isCreating, itinerary, loggedInUser, monitoredTrips, pending } = - this.props + const { + disableSingleItineraryDays, + isCreating, + itinerary, + loggedInUser, + monitoredTrips, + pending + } = this.props const isAwaiting = !monitoredTrips || (isCreating && pending) let screenContents @@ -176,7 +182,32 @@ class SavedTripScreen extends Component { // Text constant is used to allow format.js command line tool to keep track of // which IDs are in the code. .notOneOf(otherTripNames, 'trip-name-already-used') - const validationSchema = yup.object(clonedSchemaShape) + const validationSchema = yup + .object(clonedSchemaShape) + // If disableSingleItineraryDays is true, test to see if at least one day checkbox is checked + .test('dayofweek', 'Please select one day', function (obj) { + if ( + obj.monday || + obj.tuesday || + obj.wednesday || + obj.thursday || + obj.friday || + obj.saturday || + obj.sunday || + !disableSingleItineraryDays + ) { + return true + } + + /* Hack: because the selected days values are not grouped, we need to assign this error to one of the + checkboxes so that form validates correctly. Monday makes sure the focus is on the first checkbox. */ + + return new yup.ValidationError( + 'Please select at least one day to monitor', + obj.monday, + 'monday' + ) + }) screenContents = ( { const pending = activeSearch ? Boolean(activeSearch.pending) : false const itineraries = getActiveItineraries(state) || [] const tripId = ownProps.match.params.id + const { disableSingleItineraryDays } = state.otp.config return { activeSearchId: state.otp.activeSearchId, + disableSingleItineraryDays, homeTimezone: state.otp.config.homeTimezone, isCreating: tripId === 'new', itinerary: itineraries[activeItinerary], diff --git a/lib/components/user/monitored-trip/trip-basics-pane.tsx b/lib/components/user/monitored-trip/trip-basics-pane.tsx index 9d98eedd1..a6a810b23 100644 --- a/lib/components/user/monitored-trip/trip-basics-pane.tsx +++ b/lib/components/user/monitored-trip/trip-basics-pane.tsx @@ -46,6 +46,7 @@ type TripBasicsProps = WrappedComponentProps & intl: IntlShape ) => void clearItineraryExistence: () => void + disableSingleItineraryDays: boolean | undefined isCreating: boolean itineraryExistence?: ItineraryExistence } @@ -200,6 +201,99 @@ class TripBasicsPane extends Component { } } + RenderAvailableDays = ({ + errorCheckingTrip, + errorSelectingDays, + finalItineraryExistence, + intl, + isCreating, + monitoredTrip + }: { + errorCheckingTrip: boolean + errorSelectingDays?: 'error' | null + finalItineraryExistence: ItineraryExistence | undefined + intl: IntlShape + isCreating: boolean + monitoredTrip: MonitoredTrip + }) => ( + <> + {errorCheckingTrip && ( + <> + {/* FIXME: Temporary solution until itinerary existence check is fixed. */} +
                                                                                                                                                                                      + + + )} + + <> + {ALL_DAYS.map((day) => { + const isDayDisabled = isDisabled(day, finalItineraryExistence) + const labelClass = isDayDisabled ? 'disabled-day' : '' + const notAvailableText = isDayDisabled + ? intl.formatMessage( + { + id: 'components.TripBasicsPane.tripNotAvailableOnDay' + }, + { + repeatedDay: getFormattedDayOfWeekPlural(day, intl) + } + ) + : '' + + const baseColor = getBaseColor() + return ( + + + + + {notAvailableText} + + ) + })} + + + + + {finalItineraryExistence ? ( + + ) : ( + + } + now={100} + /> + )} + + + {errorSelectingDays && ( + + )} + + + ) + componentDidMount() { // Check itinerary availability (existence) for all days if not already done. const { checkItineraryExistence, intl, values: monitoredTrip } = this.props @@ -220,6 +314,7 @@ class TripBasicsPane extends Component { const { canceled, dirty, + disableSingleItineraryDays, errors, intl, isCreating, @@ -257,6 +352,9 @@ class TripBasicsPane extends Component { const errorCheckingTrip = ALL_DAYS.every((day) => isDisabled(day, finalItineraryExistence) ) + /* Hack: because the selected days checkboxes are not grouped, we need to assign this error to one of the + checkboxes so that the FormikErrorFocus works. */ + const selectOneDayError = errorStates.monday return (
                                                                                                                                                                                      {/* TODO: This component does not block navigation on reload or using the back button. @@ -286,104 +384,55 @@ class TripBasicsPane extends Component { )} - - - - - - - - {errorCheckingTrip && ( + {disableSingleItineraryDays ? ( + + + + + + + ) : ( + + + + + + + + {!isOneTime && ( <> - {/* FIXME: Temporary solution until itinerary existence check is fixed. */} -
                                                                                                                                                                                      - + )} -
                                                                                                                                                                                      - {!isOneTime && ( - <> - - {ALL_DAYS.map((day) => { - const isDayDisabled = isDisabled( - day, - finalItineraryExistence - ) - const labelClass = isDayDisabled ? 'disabled-day' : '' - const notAvailableText = isDayDisabled - ? intl.formatMessage( - { - id: 'components.TripBasicsPane.tripNotAvailableOnDay' - }, - { - repeatedDay: getFormattedDayOfWeekPlural(day, intl) - } - ) - : '' - - const baseColor = getBaseColor() - return ( - - - - - - {notAvailableText} - - - ) - })} - - - {finalItineraryExistence ? ( - - ) : ( - - } - now={100} - /> - )} - - - )} - - - - - {/* Scroll to the trip name/days fields if submitting and there is an error on these fields. */} - -
                                                                                                                                                                                      + + + + + )} + + {/* Scroll to the trip name/days fields if submitting and there is an error on these fields. */} +
                                                                                                                                                                                      ) } @@ -394,7 +443,9 @@ class TripBasicsPane extends Component { const mapStateToProps = (state: AppReduxState) => { const { itineraryExistence } = state.user + const { disableSingleItineraryDays } = state.otp.config return { + disableSingleItineraryDays, itineraryExistence } } diff --git a/lib/components/util/formatted-validation-error.js b/lib/components/util/formatted-validation-error.js index 2bf08ecb2..9b836207f 100644 --- a/lib/components/util/formatted-validation-error.js +++ b/lib/components/util/formatted-validation-error.js @@ -28,6 +28,10 @@ export default function FormattedValidationError({ type }) { return ( ) + case 'select-at-least-one-day': + return ( + + ) default: return null } diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 120bf1bad..8f8d43552 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -375,6 +375,7 @@ export interface AppConfig { bugsnag?: BugsnagConfig co2?: CO2Config companies?: Company[] + disableSingleItineraryDays?: boolean elevationProfile?: boolean extraMenuItems?: AppMenuItemConfig[] geocoder: GeocoderConfig From 122a944b92b90afa7a9b93626c4036e0b60cf76d Mon Sep 17 00:00:00 2001 From: Daniel Heppner Date: Fri, 27 Sep 2024 10:53:11 -0700 Subject: [PATCH 137/162] use shorthand --- lib/actions/field-trip.js | 142 +++++++++--------- .../narrative/narrative-itineraries.js | 2 +- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/lib/actions/field-trip.js b/lib/actions/field-trip.js index 6522acb3b..0b667dbf1 100644 --- a/lib/actions/field-trip.js +++ b/lib/actions/field-trip.js @@ -395,36 +395,34 @@ function makeSaveFieldTripItinerariesData(request, outbound, state) { } const gtfsTripsForItinerary = [] - itinerary.legs - .filter((leg) => isTransitLeg(leg)) - .forEach((leg) => { - let routeName = leg.routeShortName ? `(${leg.routeShortName}) ` : '' - routeName = `${routeName}${leg.routeLongName}` - const gtfsTrip = { - agencyAndId: leg.tripId, - // 'arrive' must be expressed in the agency's timezone - arrive: formatInTz(new Date(leg.endTime), FIELD_TRIP_TIME_FORMAT, { - timeZone: homeTimezone - }), - capacity: getFieldTripGroupCapacityForMode( - fieldTripModuleConfig, - leg.mode - ), - // 'depart' must be expressed in the agency's timezone - depart: formatInTz(new Date(leg.startTime), FIELD_TRIP_TIME_FORMAT, { - timeZone: homeTimezone - }), - fromStopIndex: leg.from.stopIndex, - fromStopName: leg.from.name, - headsign: leg.headsign, - routeName, - toStopIndex: leg.to.stopIndex, - toStopName: leg.to.name, - tripHash: tripHashLookup[leg.tripId] - } - if (leg.tripBlockId) gtfsTrip.blockId = leg.tripBlockId - gtfsTripsForItinerary.push(gtfsTrip) - }) + itinerary.legs.filter(isTransitLeg).forEach((leg) => { + let routeName = leg.routeShortName ? `(${leg.routeShortName}) ` : '' + routeName = `${routeName}${leg.routeLongName}` + const gtfsTrip = { + agencyAndId: leg.tripId, + // 'arrive' must be expressed in the agency's timezone + arrive: formatInTz(new Date(leg.endTime), FIELD_TRIP_TIME_FORMAT, { + timeZone: homeTimezone + }), + capacity: getFieldTripGroupCapacityForMode( + fieldTripModuleConfig, + leg.mode + ), + // 'depart' must be expressed in the agency's timezone + depart: formatInTz(new Date(leg.startTime), FIELD_TRIP_TIME_FORMAT, { + timeZone: homeTimezone + }), + fromStopIndex: leg.from.stopIndex, + fromStopName: leg.from.name, + headsign: leg.headsign, + routeName, + toStopIndex: leg.to.stopIndex, + toStopName: leg.to.name, + tripHash: tripHashLookup[leg.tripId] + } + if (leg.tripBlockId) gtfsTrip.blockId = leg.tripBlockId + gtfsTripsForItinerary.push(gtfsTrip) + }) data.itins.push(itineraryDataToSave) data.gtfsTrips.push(gtfsTripsForItinerary) @@ -711,52 +709,50 @@ function checkValidityAndCapacity(state, request) { // check each individual trip to see if there aren't any trips in this // itinerary that are already in use by another field trip - itinerary.legs - .filter((leg) => isTransitLeg(leg)) - .forEach((leg) => { - const tripId = leg?.trip?.gtfsId - - // this variable is used to track how many other field trips are using a - // particular trip - let capacityInUse = 0 - - // iterate over trips that are already being used by other field trips - // NOTE: In the use case of re-planning trips, there is currently no way - // to discern whether a tripInUse belongs to the current direction of - // the field trip being planned. Therefore, this will result in the - // re-planning of trips avoiding it's own previously planned trips - // that it currently has saved - travelDateTripsInUse.forEach((tripInUse) => { - if (!tripsOverlap(leg, tripHashLookup, tripId, tripInUse)) return - - // ranges overlap! Add number of passengers on this other field trip - // to total capacity in use - capacityInUse += tripInUse.passengers - }) + itinerary.legs.filter(isTransitLeg).forEach((leg) => { + const tripId = leg?.trip?.gtfsId + + // this variable is used to track how many other field trips are using a + // particular trip + let capacityInUse = 0 + + // iterate over trips that are already being used by other field trips + // NOTE: In the use case of re-planning trips, there is currently no way + // to discern whether a tripInUse belongs to the current direction of + // the field trip being planned. Therefore, this will result in the + // re-planning of trips avoiding it's own previously planned trips + // that it currently has saved + travelDateTripsInUse.forEach((tripInUse) => { + if (!tripsOverlap(leg, tripHashLookup, tripId, tripInUse)) return + + // ranges overlap! Add number of passengers on this other field trip + // to total capacity in use + capacityInUse += tripInUse.passengers + }) - // check if the remaining capacity on this trip is enough to allow more - // field trip passengers on board - const legModeCapacity = getFieldTripGroupCapacityForMode( - fieldTripModuleConfig, - leg.mode - ) - let remainingTripCapacity = legModeCapacity - capacityInUse - if (remainingTripCapacity < minimumAllowableRemainingCapacity) { - // This trip is already too "full" to allow any addition field trips - // on board. Ban this trip in future searches and don't use this - // itinerary in final results (set trip and itinerary capacity to 0). - remainingTripCapacity = 0 - } + // check if the remaining capacity on this trip is enough to allow more + // field trip passengers on board + const legModeCapacity = getFieldTripGroupCapacityForMode( + fieldTripModuleConfig, + leg.mode + ) + let remainingTripCapacity = legModeCapacity - capacityInUse + if (remainingTripCapacity < minimumAllowableRemainingCapacity) { + // This trip is already too "full" to allow any addition field trips + // on board. Ban this trip in future searches and don't use this + // itinerary in final results (set trip and itinerary capacity to 0). + remainingTripCapacity = 0 + } - // always ban trips found in itineraries so that subsequent searches - // don't encounter them. - // TODO: a more advanced way of doing things might be to ban trip - // sequences to not find the same exact sequence, but also - // individual trips that are too full. - tripsToBanInSubsequentSearches.push(tripId) + // always ban trips found in itineraries so that subsequent searches + // don't encounter them. + // TODO: a more advanced way of doing things might be to ban trip + // sequences to not find the same exact sequence, but also + // individual trips that are too full. + tripsToBanInSubsequentSearches.push(tripId) - itineraryCapacity = Math.min(itineraryCapacity, remainingTripCapacity) - }) + itineraryCapacity = Math.min(itineraryCapacity, remainingTripCapacity) + }) if (itineraryCapacity > 0) { // itinerary has capacity, add to list and update remaining group size. diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index ec55d4636..e86007221 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -423,7 +423,7 @@ class NarrativeItineraries extends Component { }) // Identify whether an itinerary uses transit & sort into appropriate bucket - const transitLegs = cur.legs.filter((leg) => isTransitLeg(leg)) + const transitLegs = cur.legs.filter(isTransitLeg) const modeContainer = transitLegs.length > 0 ? modeItinMap.multi : modeItinMap.single From 63233a8f4b586c3cb02ffc6016b053aad5b4488e Mon Sep 17 00:00:00 2001 From: Amy Corson <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 27 Sep 2024 15:17:10 -0500 Subject: [PATCH 138/162] Update lib/components/user/monitored-trip/trip-basics-pane.tsx Co-authored-by: Binh Dam <56846598+binh-dam-ibigroup@users.noreply.github.com> --- lib/components/user/monitored-trip/trip-basics-pane.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/user/monitored-trip/trip-basics-pane.tsx b/lib/components/user/monitored-trip/trip-basics-pane.tsx index a6a810b23..28561000c 100644 --- a/lib/components/user/monitored-trip/trip-basics-pane.tsx +++ b/lib/components/user/monitored-trip/trip-basics-pane.tsx @@ -46,7 +46,7 @@ type TripBasicsProps = WrappedComponentProps & intl: IntlShape ) => void clearItineraryExistence: () => void - disableSingleItineraryDays: boolean | undefined + disableSingleItineraryDays?: boolean isCreating: boolean itineraryExistence?: ItineraryExistence } From 5b0b98662afc215373192ea41086301bef40e224 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:52:11 -0500 Subject: [PATCH 139/162] refactor: code cleanup --- example-config.yml | 2 + .../user/monitored-trip/trip-basics-pane.tsx | 192 +++++++++--------- 2 files changed, 96 insertions(+), 98 deletions(-) diff --git a/example-config.yml b/example-config.yml index 0312aa3ac..79a242954 100644 --- a/example-config.yml +++ b/example-config.yml @@ -436,6 +436,8 @@ itinerary: advancedSettingsPanel: # Show button in advanced panel that allows users to save and return saveAndReturnButton: true +# Prevent users from selecting a single day for saving trips. +disableSingleItineraryDays: false # The transitOperators key is a list of transit operators that can be used to # order transit agencies when sorting by route. Also, this can optionally diff --git a/lib/components/user/monitored-trip/trip-basics-pane.tsx b/lib/components/user/monitored-trip/trip-basics-pane.tsx index 28561000c..1fe2e9ac7 100644 --- a/lib/components/user/monitored-trip/trip-basics-pane.tsx +++ b/lib/components/user/monitored-trip/trip-basics-pane.tsx @@ -9,7 +9,7 @@ import { Radio } from 'react-bootstrap' import { Field, FormikProps } from 'formik' -import { FormattedMessage, injectIntl } from 'react-intl' +import { FormattedMessage, injectIntl, useIntl } from 'react-intl' import { Prompt } from 'react-router' // @ts-expect-error FormikErrorFocus does not support TypeScript yet. import FormikErrorFocus from 'formik-error-focus' @@ -133,6 +133,97 @@ function isDisabled(day: string, itineraryExistence?: ItineraryExistence) { return itineraryExistence && !itineraryExistence[day]?.valid } +const RenderAvailableDays = ({ + errorCheckingTrip, + errorSelectingDays, + finalItineraryExistence, + isCreating, + monitoredTrip +}: { + errorCheckingTrip: boolean + errorSelectingDays?: 'error' | null + finalItineraryExistence: ItineraryExistence | undefined + isCreating: boolean + monitoredTrip: MonitoredTrip +}) => { + const intl = useIntl() + const baseColor = getBaseColor() + return ( + <> + {errorCheckingTrip && ( + <> + {/* FIXME: Temporary solution until itinerary existence check is fixed. */} +
                                                                                                                                                                                      + + + )} + + {ALL_DAYS.map((day) => { + const isDayDisabled = isDisabled(day, finalItineraryExistence) + const labelClass = isDayDisabled ? 'disabled-day' : '' + const notAvailableText = isDayDisabled + ? intl.formatMessage( + { + id: 'components.TripBasicsPane.tripNotAvailableOnDay' + }, + { + repeatedDay: getFormattedDayOfWeekPlural(day, intl) + } + ) + : '' + + return ( + + + + + {notAvailableText} + + ) + })} + + + {finalItineraryExistence ? ( + + ) : ( + + } + now={100} + /> + )} + + + {errorSelectingDays && ( + + )} + + + ) +} + /** * This component shows summary information for a trip * and lets the user edit the trip name and day. @@ -201,99 +292,6 @@ class TripBasicsPane extends Component { } } - RenderAvailableDays = ({ - errorCheckingTrip, - errorSelectingDays, - finalItineraryExistence, - intl, - isCreating, - monitoredTrip - }: { - errorCheckingTrip: boolean - errorSelectingDays?: 'error' | null - finalItineraryExistence: ItineraryExistence | undefined - intl: IntlShape - isCreating: boolean - monitoredTrip: MonitoredTrip - }) => ( - <> - {errorCheckingTrip && ( - <> - {/* FIXME: Temporary solution until itinerary existence check is fixed. */} -
                                                                                                                                                                                      - - - )} - - <> - {ALL_DAYS.map((day) => { - const isDayDisabled = isDisabled(day, finalItineraryExistence) - const labelClass = isDayDisabled ? 'disabled-day' : '' - const notAvailableText = isDayDisabled - ? intl.formatMessage( - { - id: 'components.TripBasicsPane.tripNotAvailableOnDay' - }, - { - repeatedDay: getFormattedDayOfWeekPlural(day, intl) - } - ) - : '' - - const baseColor = getBaseColor() - return ( - - - - - {notAvailableText} - - ) - })} - - - - - {finalItineraryExistence ? ( - - ) : ( - - } - now={100} - /> - )} - - - {errorSelectingDays && ( - - )} - - - ) - componentDidMount() { // Check itinerary availability (existence) for all days if not already done. const { checkItineraryExistence, intl, values: monitoredTrip } = this.props @@ -389,11 +387,10 @@ class TripBasicsPane extends Component { - @@ -413,10 +410,9 @@ class TripBasicsPane extends Component { {!isOneTime && ( <> - From ebdf73a0e2fc43430767cb53857e2c9d0f309442 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:23:09 -0400 Subject: [PATCH 140/162] chore(i18n): Add matching FR text --- i18n/fr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/fr.yml b/i18n/fr.yml index 741ad9f2c..5f0f2187f 100644 --- a/i18n/fr.yml +++ b/i18n/fr.yml @@ -559,6 +559,7 @@ components: SavedTripScreen: itineraryLoaded: Trajet chargé itineraryLoading: Chargement du trajet + selectAtLeastOneDay: Veuillez choisir au moins un jour pour le suivi. tooManyTrips: > Vous avez déjà atteint le nombre maximum de 5 trajets enregistrés. Veuillez supprimer les trajets enregistrés qui sont inutilisés, puis From 4c3c5d57ed79a898ea2e77b17119c1c22338cca6 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Mon, 30 Sep 2024 15:09:44 -0500 Subject: [PATCH 141/162] clean up prop types --- lib/components/user/monitored-trip/trip-basics-pane.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/user/monitored-trip/trip-basics-pane.tsx b/lib/components/user/monitored-trip/trip-basics-pane.tsx index 1fe2e9ac7..dafafcd00 100644 --- a/lib/components/user/monitored-trip/trip-basics-pane.tsx +++ b/lib/components/user/monitored-trip/trip-basics-pane.tsx @@ -142,7 +142,7 @@ const RenderAvailableDays = ({ }: { errorCheckingTrip: boolean errorSelectingDays?: 'error' | null - finalItineraryExistence: ItineraryExistence | undefined + finalItineraryExistence?: ItineraryExistence isCreating: boolean monitoredTrip: MonitoredTrip }) => { From 650f390cae06ac0f521de63638ee6a8570585b02 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:46:54 -0400 Subject: [PATCH 142/162] refactor(TripPreviewLayoutBase): Extract common component between print and preview layouts --- lib/components/app/print-layout.tsx | 126 +++----------- .../app/trip-preview-layout-base.tsx | 131 +++++++++++++++ lib/components/app/trip-preview-layout.tsx | 158 ++++-------------- 3 files changed, 181 insertions(+), 234 deletions(-) create mode 100644 lib/components/app/trip-preview-layout-base.tsx diff --git a/lib/components/app/print-layout.tsx b/lib/components/app/print-layout.tsx index d0365f015..2610eac90 100644 --- a/lib/components/app/print-layout.tsx +++ b/lib/components/app/print-layout.tsx @@ -1,65 +1,30 @@ -import { Button } from 'react-bootstrap' import { connect } from 'react-redux' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' import { Itinerary } from '@opentripplanner/types' -import { Map } from '@styled-icons/fa-solid/Map' -import { Print } from '@styled-icons/fa-solid/Print' -import { Times } from '@styled-icons/fa-solid/Times' -// @ts-expect-error not typescripted yet -import PrintableItinerary from '@opentripplanner/printable-itinerary' import React, { Component } from 'react' import * as apiActions from '../../actions/api' import * as formActions from '../../actions/form' -import { - addPrintViewClassToRootHtml, - clearClassFromRootHtml -} from '../../util/print' -import { ComponentContext } from '../../util/contexts' +import { AppReduxState } from '../../util/state-types' import { getActiveItinerary, getActiveSearch } from '../../util/state' -import { IconWithText } from '../util/styledIcon' import { summarizeQuery } from '../form/user-settings-i18n' +import { User } from '../user/types' import DefaultMap from '../map/default-map' -import PageTitle from '../util/page-title' -import SpanWithSpace from '../util/span-with-space' -import TripDetails from '../narrative/connected-trip-details' + +import TripPreviewLayoutBase from './trip-preview-layout-base' type Props = { // TODO: Typescript activeSearch type activeSearch: any - // TODO: Typescript config type - config: any currentQuery: any intl: IntlShape itinerary: Itinerary location?: { search?: string } parseUrlQueryString: (params?: any, source?: string) => any - // TODO: Typescript user type - user: any -} - -type State = { - mapVisible?: boolean + user: User } -class PrintLayout extends Component { - static contextType = ComponentContext - - constructor(props: Props) { - super(props) - this.state = { - mapVisible: true - } - } - - _toggleMap = () => { - this.setState({ mapVisible: !this.state.mapVisible }) - } - - _print = () => { - window.print() - } - +class PrintLayout extends Component { _close = () => { window.location.replace(String(window.location).replace('print/', '')) } @@ -67,9 +32,8 @@ class PrintLayout extends Component { componentDidMount() { const { itinerary, location, parseUrlQueryString } = this.props - // Add print-view class to html tag to ensure that iOS scroll fix only applies - // to non-print views. - addPrintViewClassToRootHtml() + console.log(itinerary, location) + // Parse the URL query parameters, if present if (!itinerary && location && location.search) { parseUrlQueryString() @@ -78,72 +42,27 @@ class PrintLayout extends Component { // TODO: use currentQuery to pan/zoom to the correct part of the map } - componentWillUnmount() { - clearClassFromRootHtml() - } - render() { - const { activeSearch, config, intl, itinerary, user } = this.props - const { LegIcon } = this.context + const { activeSearch, intl, itinerary, user } = this.props const printVerb = intl.formatMessage({ id: 'common.forms.print' }) return ( -
                                                                                                                                                                                      - - {/* The header bar, including the Toggle Map and Print buttons */} -
                                                                                                                                                                                      -
                                                                                                                                                                                      - - - - - - - -
                                                                                                                                                                                      - -
                                                                                                                                                                                      - - {/* The map, if visible */} - {this.state.mapVisible && ( + } + itinerary={itinerary} + mapElement={
                                                                                                                                                                                      {/* FIXME: Improve reframing/setting map bounds when itinerary is received. */}
                                                                                                                                                                                      - )} - - {/* The main itinerary body */} - {itinerary && ( - <> - - - - )} -
                                                                                                                                                                                      + } + onClose={this._close} + subTitle={ + activeSearch && + summarizeQuery(activeSearch.query, intl, user.savedLocations) + } + title={printVerb} + /> ) } } @@ -151,13 +70,12 @@ class PrintLayout extends Component { // connect to the redux store // TODO: Typescript state -const mapStateToProps = (state: any) => { +const mapStateToProps = (state: AppReduxState) => { const activeSearch = getActiveSearch(state) const { localUser, loggedInUser } = state.user const user = loggedInUser || localUser return { activeSearch, - config: state.otp.config, currentQuery: state.otp.currentQuery, itinerary: getActiveItinerary(state) as Itinerary, user diff --git a/lib/components/app/trip-preview-layout-base.tsx b/lib/components/app/trip-preview-layout-base.tsx new file mode 100644 index 000000000..d7738f80f --- /dev/null +++ b/lib/components/app/trip-preview-layout-base.tsx @@ -0,0 +1,131 @@ +import { Button } from 'react-bootstrap' +import { connect } from 'react-redux' +import { FormattedMessage } from 'react-intl' +import { Itinerary } from '@opentripplanner/types' +import { Map } from '@styled-icons/fa-solid/Map' +import { Print } from '@styled-icons/fa-solid/Print' +import { Times } from '@styled-icons/fa-solid/Times' +// @ts-expect-error not typescripted yet +import PrintableItinerary from '@opentripplanner/printable-itinerary' +import React, { Component, ReactNode } from 'react' + +import { + addPrintViewClassToRootHtml, + clearClassFromRootHtml +} from '../../util/print' +import { AppConfig } from '../../util/config-types' +import { AppReduxState } from '../../util/state-types' +import { ComponentContext } from '../../util/contexts' +import { IconWithText } from '../util/styledIcon' +import PageTitle from '../util/page-title' +import SpanWithSpace from '../util/span-with-space' +import TripDetails from '../narrative/connected-trip-details' + +type Props = { + config: AppConfig + header?: ReactNode + itinerary?: Itinerary + mapElement?: ReactNode + onClose?: () => void + subTitle: string + title: string +} + +type State = { + mapVisible?: boolean +} + +class TripPreviewLayoutBase extends Component { + static contextType = ComponentContext + + constructor(props: Props) { + super(props) + this.state = { + mapVisible: true + } + } + + _toggleMap = () => { + this.setState({ mapVisible: !this.state.mapVisible }) + } + + _print = () => { + window.print() + } + + componentDidUpdate() { + // Add print-view class to html tag to ensure that iOS scroll fix only applies + // to non-print views. + addPrintViewClassToRootHtml() + } + + componentWillUnmount() { + clearClassFromRootHtml() + } + + render() { + const { config, itinerary, mapElement, onClose, subTitle, title } = + this.props + const { LegIcon } = this.context + + return ( +
                                                                                                                                                                                      + + {/* The header bar, including the Toggle Map and Print buttons */} +
                                                                                                                                                                                      +
                                                                                                                                                                                      + + + + + + + {onClose && ( + + )} +
                                                                                                                                                                                      + {title} +
                                                                                                                                                                                      + + {/* The map, if visible */} + {this.state.mapVisible && mapElement} + + {/* The main itinerary body */} + {itinerary && ( + <> + + + + )} +
                                                                                                                                                                                      + ) + } +} + +// connect to the redux store + +const mapStateToProps = (state: AppReduxState) => ({ + config: state.otp.config +}) + +export default connect(mapStateToProps)(TripPreviewLayoutBase) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index 7b0e92d4d..c3c9ffa31 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -1,41 +1,20 @@ -import { Button } from 'react-bootstrap' import { connect } from 'react-redux' -import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' -import { Map } from '@styled-icons/fa-solid/Map' -import { Print } from '@styled-icons/fa-solid/Print' import { RouteComponentProps } from 'react-router' +import { useIntl } from 'react-intl' import { withAuthenticationRequired } from '@auth0/auth0-react' -// @ts-expect-error not typescripted yet -import PrintableItinerary from '@opentripplanner/printable-itinerary' -import React, { Component } from 'react' +import React from 'react' import styled from 'styled-components' -import { - addPrintViewClassToRootHtml, - clearClassFromRootHtml -} from '../../util/print' -import { AppConfig } from '../../util/config-types' import { AppReduxState } from '../../util/state-types' -import { ComponentContext } from '../../util/contexts' -import { IconWithText } from '../util/styledIcon' import { MonitoredTrip } from '../user/types' import { RETURN_TO_CURRENT_ROUTE } from '../../util/ui' -import AwaitingScreen from '../user/awaiting-screen' -import PageTitle from '../util/page-title' import SimpleMap from '../map/simple-map' -import SpanWithSpace from '../util/span-with-space' -import TripDetails from '../narrative/connected-trip-details' import withLoggedInUserSupport from '../user/with-logged-in-user-support' -type Props = { - config: AppConfig - intl: IntlShape - monitoredTrips?: MonitoredTrip[] | null - tripId: string -} +import TripPreviewLayoutBase from './trip-preview-layout-base' -type State = { - mapVisible?: boolean +type Props = { + monitoredTrip?: MonitoredTrip } const MapContainer = styled.div` @@ -48,108 +27,29 @@ const MapContainer = styled.div` } ` -class TripPreviewLayout extends Component { - static contextType = ComponentContext - - constructor(props: Props) { - super(props) - this.state = { - mapVisible: true - } - } - - /** - * Gets the trip to view from the props. - */ - _getTripToEdit = (): MonitoredTrip | undefined => { - const { monitoredTrips, tripId } = this.props - return monitoredTrips?.find((trip) => trip.id === tripId) - } - - _toggleMap = () => { - this.setState({ mapVisible: !this.state.mapVisible }) - } - - _print = () => { - window.print() - } - - componentDidUpdate() { - // Add print-view class to html tag to ensure that iOS scroll fix only applies - // to non-print views. - addPrintViewClassToRootHtml() - - // TODO: use currentQuery to pan/zoom to the correct part of the map - } - - componentWillUnmount() { - clearClassFromRootHtml() - } - - render() { - const { config, intl } = this.props - const { LegIcon } = this.context - const printVerb = intl.formatMessage({ id: 'common.forms.print' }) - const previewTripText = intl.formatMessage({ - id: 'components.TripPreviewLayout.previewTrip' - }) - const monitoredTrip = this._getTripToEdit() - const isAwaiting = !monitoredTrip - if (isAwaiting) { - // Flash an indication while the selected and saved user trips are being loaded. - return - } - - const itinerary = - monitoredTrip.journeyState?.matchingItinerary || monitoredTrip.itinerary - - return ( -
                                                                                                                                                                                      - - {/* The header bar, including the Toggle Map and Print buttons */} -
                                                                                                                                                                                      -
                                                                                                                                                                                      - - - - - - -
                                                                                                                                                                                      - {previewTripText} -
                                                                                                                                                                                      - - {/* The map, if visible */} - {this.state.mapVisible && ( +const TripPreviewLayout = ({ monitoredTrip }: Props) => { + const intl = useIntl() + const previewTripText = intl.formatMessage({ + id: 'components.TripPreviewLayout.previewTrip' + }) + const itinerary = + monitoredTrip?.journeyState?.matchingItinerary || monitoredTrip?.itinerary + + return ( + - )} - - {/* The main itinerary body */} - {itinerary && ( - <> - - - - )} -
                                                                                                                                                                                      - ) - } + ) + } + subTitle={monitoredTrip?.tripName} + title={previewTripText} + /> + ) } // connect to the redux store @@ -158,19 +58,17 @@ const mapStateToProps = ( state: AppReduxState, ownProps: Props & RouteComponentProps<{ id: string }> ) => { - const { loggedInUserMonitoredTrips: monitoredTrips } = state.user + const { loggedInUserMonitoredTrips: trips } = state.user const tripId = ownProps.match.params.id return { - config: state.otp.config, - monitoredTrips, - tripId + monitoredTrip: trips?.find((trip) => trip.id === tripId) } } export default withLoggedInUserSupport( withAuthenticationRequired( - connect(mapStateToProps)(injectIntl(TripPreviewLayout)), + connect(mapStateToProps)(TripPreviewLayout), RETURN_TO_CURRENT_ROUTE ), true From c5b622ef562b191ab11bddc4bec66d4570bcc9b4 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:52:23 -0400 Subject: [PATCH 143/162] refactor(SimpleMap): Add checks for null itinerary --- lib/components/app/trip-preview-layout.tsx | 8 +++----- lib/components/map/simple-map.tsx | 22 ++++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/components/app/trip-preview-layout.tsx b/lib/components/app/trip-preview-layout.tsx index c3c9ffa31..f00ff4d4c 100644 --- a/lib/components/app/trip-preview-layout.tsx +++ b/lib/components/app/trip-preview-layout.tsx @@ -40,11 +40,9 @@ const TripPreviewLayout = ({ monitoredTrip }: Props) => { header={previewTripText} itinerary={itinerary} mapElement={ - itinerary && ( - - - - ) + + + } subTitle={monitoredTrip?.tripName} title={previewTripText} diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index a62aca608..c0eebb708 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -15,7 +15,7 @@ import { ComponentContext } from '../../util/contexts' interface Props { config: AppConfig - itinerary: Itinerary + itinerary?: Itinerary } function noop() { @@ -37,7 +37,7 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { } = config.map || {} const baseLayerUrls = baseLayers?.map((bl) => bl.url) const { disableFlexArc } = transitive || {} - const { legs } = itinerary + const { legs = [] } = itinerary || {} return ( { toLocation={legs[legs.length - 1]?.to} /> - + {itinerary && ( + + )} Date: Tue, 1 Oct 2024 18:43:43 -0400 Subject: [PATCH 144/162] refactor(TripPreviewLayoutBase): Fix types --- lib/components/app/trip-preview-layout-base.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/components/app/trip-preview-layout-base.tsx b/lib/components/app/trip-preview-layout-base.tsx index d7738f80f..7fbe12bca 100644 --- a/lib/components/app/trip-preview-layout-base.tsx +++ b/lib/components/app/trip-preview-layout-base.tsx @@ -27,7 +27,7 @@ type Props = { itinerary?: Itinerary mapElement?: ReactNode onClose?: () => void - subTitle: string + subTitle?: string title: string } @@ -64,8 +64,14 @@ class TripPreviewLayoutBase extends Component { } render() { - const { config, itinerary, mapElement, onClose, subTitle, title } = - this.props + const { + config, + itinerary, + mapElement, + onClose, + subTitle = '', + title + } = this.props const { LegIcon } = this.context return ( From 2db92844849bf2a7ef4ea8b80f640572258b3208 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:59:47 -0400 Subject: [PATCH 145/162] refactor: Remove unused code and tweak comments --- lib/components/app/print-layout.tsx | 7 ------- lib/components/map/simple-map.tsx | 1 + 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/components/app/print-layout.tsx b/lib/components/app/print-layout.tsx index 2610eac90..7d8b2fd4e 100644 --- a/lib/components/app/print-layout.tsx +++ b/lib/components/app/print-layout.tsx @@ -16,7 +16,6 @@ import TripPreviewLayoutBase from './trip-preview-layout-base' type Props = { // TODO: Typescript activeSearch type activeSearch: any - currentQuery: any intl: IntlShape itinerary: Itinerary location?: { search?: string } @@ -32,14 +31,10 @@ class PrintLayout extends Component { componentDidMount() { const { itinerary, location, parseUrlQueryString } = this.props - console.log(itinerary, location) - // Parse the URL query parameters, if present if (!itinerary && location && location.search) { parseUrlQueryString() } - - // TODO: use currentQuery to pan/zoom to the correct part of the map } render() { @@ -69,14 +64,12 @@ class PrintLayout extends Component { // connect to the redux store -// TODO: Typescript state const mapStateToProps = (state: AppReduxState) => { const activeSearch = getActiveSearch(state) const { localUser, loggedInUser } = state.user const user = loggedInUser || localUser return { activeSearch, - currentQuery: state.otp.currentQuery, itinerary: getActiveItinerary(state) as Itinerary, user } diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index c0eebb708..446a11fbb 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -22,6 +22,7 @@ function noop() { return null } +/** Renders an optional itinerary with a given config. */ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { const intl = useIntl() // @ts-expect-error ComponentContext not typed yet. From 57234328e7b0f443cb28d40d7968d9da49e2e295 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:11:38 -0400 Subject: [PATCH 146/162] refactor(TripPreviewLayoutBase): Actually render header prop --- lib/components/app/trip-preview-layout-base.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/components/app/trip-preview-layout-base.tsx b/lib/components/app/trip-preview-layout-base.tsx index 7fbe12bca..14fbf080b 100644 --- a/lib/components/app/trip-preview-layout-base.tsx +++ b/lib/components/app/trip-preview-layout-base.tsx @@ -66,6 +66,7 @@ class TripPreviewLayoutBase extends Component { render() { const { config, + header, itinerary, mapElement, onClose, @@ -106,7 +107,7 @@ class TripPreviewLayoutBase extends Component { )}
                                                                                                                                                                                      - {title} + {header}
                                                                                                                                                                                      {/* The map, if visible */} From 0a12a22b3c23450667d10de606e7c8ca9372d69c Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:47:28 -0500 Subject: [PATCH 147/162] Update OTP-UI packages to pass operator logos --- package.json | 4 ++-- yarn.lock | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 34e1e7c8f..f463f2b18 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,8 @@ "@opentripplanner/itinerary-body": "6.0.0", "@opentripplanner/location-field": "3.0.0", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "5.0.0", - "@opentripplanner/otp2-tile-overlay": "2.0.0", + "@opentripplanner/map-popup": "5.1.0", + "@opentripplanner/otp2-tile-overlay": "2.1.0", "@opentripplanner/park-and-ride-overlay": "3.0.0", "@opentripplanner/printable-itinerary": "3.0.0", "@opentripplanner/route-viewer-overlay": "3.0.0", diff --git a/yarn.lock b/yarn.lock index 599332b3e..2176c6e5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,7 +2383,7 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@4.0.0": +"@opentripplanner/base-map@4.0.0", "@opentripplanner/base-map@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-4.0.0.tgz#56ffa1d833673282cc3a0b7a17f388fc5dbd31e3" integrity sha512-pWTKXxnzUQk43woPMc40uYfGIcGqHV8GoCvRwrIu2pqNw7QAV4rxjZfca0pm5hnbbJ+G83sRzYboILEbEUwMcw== @@ -2403,7 +2403,7 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@2.0.0": +"@opentripplanner/building-blocks@2.0.0", "@opentripplanner/building-blocks@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-2.0.0.tgz#8282c01dff7db5c7e809f6ea91cb52df559a2f9d" integrity sha512-N07rDaZL8fp552eI9/0j1udKjc0uOpvO0Wv1P19Ge0a4roques463MJgWJ026fbopRCi3uwbc/gYTlh4/ske9A== @@ -2413,7 +2413,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@12.0.0": +"@opentripplanner/core-utils@12.0.0", "@opentripplanner/core-utils@^12.0.0": version "12.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== @@ -2461,7 +2461,7 @@ "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" -"@opentripplanner/from-to-location-picker@3.0.0": +"@opentripplanner/from-to-location-picker@3.0.0", "@opentripplanner/from-to-location-picker@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-3.0.0.tgz#048a596c2f854825e0058e03dac67dcad7eb5864" integrity sha512-jRXaY9jKg+PXUL7Z2SkHRyO88xG1t7iG3U449LPiCm/6flxsY+Wlxg+nyMsAP5gQMjOU0wsGLdH83lGgrpSF4A== @@ -2566,15 +2566,15 @@ "@styled-icons/fa-regular" "^10.34.0" "@styled-icons/fa-solid" "^10.34.0" -"@opentripplanner/map-popup@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-5.0.0.tgz#cf360845704ed54222c8bf19581ed1253d3dcf14" - integrity sha512-cuIzZm/cZbjY2tAVLSDpBK63efR+YsEsXVPBx4VAHlGhJoY1yooipFlq+3/51VSsFOJPp6gcsKaizfdICDJlYA== +"@opentripplanner/map-popup@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-5.1.0.tgz#cf6374bf7b69af69c026ec414a84719078c56e9e" + integrity sha512-EShoMyFZa7Zb2ZZrJhEsJfuCAvs2jfQe5QstU+AEk5Jm1zc8LzU6PsXmizQ/RMVi6zIYLhlBoZ3u458tTA3VQA== dependencies: - "@opentripplanner/base-map" "^3.2.2" - "@opentripplanner/building-blocks" "^1.2.2" - "@opentripplanner/core-utils" "^11.4.4" - "@opentripplanner/from-to-location-picker" "^2.1.14" + "@opentripplanner/base-map" "^4.0.0" + "@opentripplanner/building-blocks" "^2.0.0" + "@opentripplanner/core-utils" "^12.0.0" + "@opentripplanner/from-to-location-picker" "^3.0.0" flat "^5.0.2" "@opentripplanner/map-popup@^4.0.0": @@ -2588,12 +2588,23 @@ "@opentripplanner/from-to-location-picker" "^2.1.14" flat "^5.0.2" -"@opentripplanner/otp2-tile-overlay@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-2.0.0.tgz#6af1a9113a8baaebb226a5e747e8e523f6da249b" - integrity sha512-Yc0VsfxS6xIw4+1i9lpvQyCXobkTubZWYYu+6bDWkk77D4J4WaSoWE/qWT39vc2/h1ZY4afUZL59d7kc8V0PLg== +"@opentripplanner/map-popup@^v3.2.0-alpha.1": + version "3.2.0-alpha.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.2.0-alpha.1.tgz#dcad38c103500f7c5ad3c632398204849ed5885e" + integrity sha512-Z0RsyC7wkYU/aOLYQFsJI5tBhzooEE/sQZROX2WODkDWAv4Qfj95ppS8pvNkpoZ0N4fioFcj5aM2VGXVMSy0EA== dependencies: - "@opentripplanner/map-popup" "^4.0.0" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/from-to-location-picker" "^2.1.14" + flat "^5.0.2" + +"@opentripplanner/otp2-tile-overlay@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-2.1.0.tgz#745cb6c80dbde767a0b5ac7b0b866193a18ec984" + integrity sha512-gkKS5OT/Ayc/987vcdSkFcGSH/YyvEBN9bZFWBHKRN5nbRykBRZu2GNFVfN5ITLoshrFw+YasIk9omfTKVJtRg== + dependencies: + "@opentripplanner/map-popup" "^v3.2.0-alpha.1" "@opentripplanner/park-and-ride-overlay@3.0.0": version "3.0.0" From 0ec86c4b8889636f959db9ebabdcea650bb918a0 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 2 Oct 2024 09:51:19 -0500 Subject: [PATCH 148/162] Update snapshots --- .../viewers/__snapshots__/nearby-view.js.snap | 3735 ++++++++++++++++- 1 file changed, 3715 insertions(+), 20 deletions(-) diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 41b77e69d..52b08c691 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -4232,7 +4232,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + Roosevelt Station - Bay 2 @@ -16898,8 +17465,374 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + Roosevelt @@ -20031,7 +20964,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + Roosevelt Station - Bay 1 @@ -30979,7 +32556,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + Roosevelt Station Bay 5 - Bay 5 @@ -39165,7 +41108,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + Roosevelt @@ -51446,8 +53930,652 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + Roosevelt Station - Bay 3 @@ -57739,7 +60867,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      + NE 65th St & 14th Ave NE From 3370a9a70f4226fab884d1893b7d9e44686eed56 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Thu, 3 Oct 2024 10:47:50 -0400 Subject: [PATCH 149/162] chore(deps): update otp-ui --- package.json | 6 +++--- yarn.lock | 59 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 34e1e7c8f..7b69da5c0 100644 --- a/package.json +++ b/package.json @@ -50,11 +50,11 @@ "@opentripplanner/geocoder": "^3.0.2", "@opentripplanner/humanize-distance": "^1.2.0", "@opentripplanner/icons": "3.0.0", - "@opentripplanner/itinerary-body": "6.0.0", + "@opentripplanner/itinerary-body": "6.0.1", "@opentripplanner/location-field": "3.0.0", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "5.0.0", - "@opentripplanner/otp2-tile-overlay": "2.0.0", + "@opentripplanner/map-popup": "5.1.0", + "@opentripplanner/otp2-tile-overlay": "2.1.0", "@opentripplanner/park-and-ride-overlay": "3.0.0", "@opentripplanner/printable-itinerary": "3.0.0", "@opentripplanner/route-viewer-overlay": "3.0.0", diff --git a/yarn.lock b/yarn.lock index 599332b3e..1a65ef7a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,7 +2383,7 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@4.0.0": +"@opentripplanner/base-map@4.0.0", "@opentripplanner/base-map@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-4.0.0.tgz#56ffa1d833673282cc3a0b7a17f388fc5dbd31e3" integrity sha512-pWTKXxnzUQk43woPMc40uYfGIcGqHV8GoCvRwrIu2pqNw7QAV4rxjZfca0pm5hnbbJ+G83sRzYboILEbEUwMcw== @@ -2403,7 +2403,7 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@2.0.0": +"@opentripplanner/building-blocks@2.0.0", "@opentripplanner/building-blocks@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-2.0.0.tgz#8282c01dff7db5c7e809f6ea91cb52df559a2f9d" integrity sha512-N07rDaZL8fp552eI9/0j1udKjc0uOpvO0Wv1P19Ge0a4roques463MJgWJ026fbopRCi3uwbc/gYTlh4/ske9A== @@ -2413,7 +2413,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@12.0.0": +"@opentripplanner/core-utils@12.0.0", "@opentripplanner/core-utils@^12.0.0": version "12.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== @@ -2461,7 +2461,7 @@ "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" -"@opentripplanner/from-to-location-picker@3.0.0": +"@opentripplanner/from-to-location-picker@3.0.0", "@opentripplanner/from-to-location-picker@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-3.0.0.tgz#048a596c2f854825e0058e03dac67dcad7eb5864" integrity sha512-jRXaY9jKg+PXUL7Z2SkHRyO88xG1t7iG3U449LPiCm/6flxsY+Wlxg+nyMsAP5gQMjOU0wsGLdH83lGgrpSF4A== @@ -2493,7 +2493,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA== -"@opentripplanner/icons@3.0.0": +"@opentripplanner/icons@3.0.0", "@opentripplanner/icons@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-3.0.0.tgz#f7293fd4dd2625eace3a4c82ecd573d6000d85d3" integrity sha512-naSCdCsPwSyEiP7Vf6oN6dpgwpFIkeQFXfTJG7lp1Dg9emLTAYzRx/f+45e9Bh0zP0aA4DsN4VgHBQllyu82qQ== @@ -2509,14 +2509,14 @@ "@opentripplanner/core-utils" "^11.4.4" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-6.0.0.tgz#e261bcccd0d7a786f7f17be987a52ba1dc940229" - integrity sha512-j79byCefyEZuomvDlvBZJVZJ92+X6U4ivth3M62RKGmw1x8qW4nsbEKnzeQxXzGJcy3M+91eeIpcJnj98KHlRw== +"@opentripplanner/itinerary-body@6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-6.0.1.tgz#74139536b34083af5b324fb94e69be267ea6bbeb" + integrity sha512-6Z+ZEW28MwtteOwZZUjkPkTnYQ0Aq1lMpfKMZW7F+OD6hfKhFBUx4NLMExTffXHswXQ3faYaHScOHxpalX73UQ== dependencies: - "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/core-utils" "^12.0.0" "@opentripplanner/humanize-distance" "^1.2.0" - "@opentripplanner/icons" "^2.0.12" + "@opentripplanner/icons" "^3.0.0" "@opentripplanner/location-icon" "^1.4.1" "@styled-icons/fa-solid" "^10.34.0" "@styled-icons/foundation" "^10.34.0" @@ -2566,15 +2566,15 @@ "@styled-icons/fa-regular" "^10.34.0" "@styled-icons/fa-solid" "^10.34.0" -"@opentripplanner/map-popup@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-5.0.0.tgz#cf360845704ed54222c8bf19581ed1253d3dcf14" - integrity sha512-cuIzZm/cZbjY2tAVLSDpBK63efR+YsEsXVPBx4VAHlGhJoY1yooipFlq+3/51VSsFOJPp6gcsKaizfdICDJlYA== +"@opentripplanner/map-popup@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-5.1.0.tgz#cf6374bf7b69af69c026ec414a84719078c56e9e" + integrity sha512-EShoMyFZa7Zb2ZZrJhEsJfuCAvs2jfQe5QstU+AEk5Jm1zc8LzU6PsXmizQ/RMVi6zIYLhlBoZ3u458tTA3VQA== dependencies: - "@opentripplanner/base-map" "^3.2.2" - "@opentripplanner/building-blocks" "^1.2.2" - "@opentripplanner/core-utils" "^11.4.4" - "@opentripplanner/from-to-location-picker" "^2.1.14" + "@opentripplanner/base-map" "^4.0.0" + "@opentripplanner/building-blocks" "^2.0.0" + "@opentripplanner/core-utils" "^12.0.0" + "@opentripplanner/from-to-location-picker" "^3.0.0" flat "^5.0.2" "@opentripplanner/map-popup@^4.0.0": @@ -2588,12 +2588,23 @@ "@opentripplanner/from-to-location-picker" "^2.1.14" flat "^5.0.2" -"@opentripplanner/otp2-tile-overlay@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-2.0.0.tgz#6af1a9113a8baaebb226a5e747e8e523f6da249b" - integrity sha512-Yc0VsfxS6xIw4+1i9lpvQyCXobkTubZWYYu+6bDWkk77D4J4WaSoWE/qWT39vc2/h1ZY4afUZL59d7kc8V0PLg== +"@opentripplanner/map-popup@^v3.2.0-alpha.1": + version "3.2.0-alpha.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.2.0-alpha.1.tgz#dcad38c103500f7c5ad3c632398204849ed5885e" + integrity sha512-Z0RsyC7wkYU/aOLYQFsJI5tBhzooEE/sQZROX2WODkDWAv4Qfj95ppS8pvNkpoZ0N4fioFcj5aM2VGXVMSy0EA== dependencies: - "@opentripplanner/map-popup" "^4.0.0" + "@opentripplanner/base-map" "^3.2.2" + "@opentripplanner/building-blocks" "^1.2.2" + "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/from-to-location-picker" "^2.1.14" + flat "^5.0.2" + +"@opentripplanner/otp2-tile-overlay@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/otp2-tile-overlay/-/otp2-tile-overlay-2.1.0.tgz#745cb6c80dbde767a0b5ac7b0b866193a18ec984" + integrity sha512-gkKS5OT/Ayc/987vcdSkFcGSH/YyvEBN9bZFWBHKRN5nbRykBRZu2GNFVfN5ITLoshrFw+YasIk9omfTKVJtRg== + dependencies: + "@opentripplanner/map-popup" "^v3.2.0-alpha.1" "@opentripplanner/park-and-ride-overlay@3.0.0": version "3.0.0" From 84d2e4ea27468c8fe868b2e146016e6a447c6ef0 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:26:45 -0500 Subject: [PATCH 150/162] Cleanup transit operator icons --- lib/components/map/default-map.tsx | 4 +-- .../util/connected-transit-operator-icons.tsx | 30 +++++++---------- lib/components/util/operator-logo.tsx | 33 ++++++++----------- .../util/transit-operator-icons.tsx | 10 ++---- 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/lib/components/map/default-map.tsx b/lib/components/map/default-map.tsx index 3cb14fbde..b2e7b899f 100644 --- a/lib/components/map/default-map.tsx +++ b/lib/components/map/default-map.tsx @@ -24,6 +24,7 @@ import { MainPanelContent } from '../../actions/ui-constants' import { setLocation, setMapPopupLocationAndGeocode } from '../../actions/map' import { setViewedStop } from '../../actions/ui' import { updateOverlayVisibility } from '../../actions/config' +import TransitOperatorIcons from '../util/connected-transit-operator-icons' import ElevationPointMarker from './elevation-point-marker' import EndpointsOverlay from './connected-endpoints-overlay' @@ -36,7 +37,6 @@ import RoutePreviewOverlay from './route-preview-overlay' import RouteViewerOverlay from './connected-route-viewer-overlay' import StopsOverlay from './connected-stops-overlay' import TransitiveOverlay from './connected-transitive-overlay' -import TransitOperatorLogos from '../util/connected-transit-operator-icons' import TransitVehicleOverlay from './connected-transit-vehicle-overlay' import TripViewerOverlay from './connected-trip-viewer-overlay' import VehicleRentalOverlay from './connected-vehicle-rental-overlay' @@ -164,7 +164,7 @@ class DefaultMap extends Component { onlyRequestForOperators: true, stopId }) - return + return } /** diff --git a/lib/components/util/connected-transit-operator-icons.tsx b/lib/components/util/connected-transit-operator-icons.tsx index 64b804e53..0475e54e4 100644 --- a/lib/components/util/connected-transit-operator-icons.tsx +++ b/lib/components/util/connected-transit-operator-icons.tsx @@ -1,6 +1,6 @@ import { connect } from 'react-redux' import { TransitOperator } from '@opentripplanner/types' -import React, { Component } from 'react' +import React from 'react' import { AppReduxState } from '../../util/state-types' import { FETCH_STATUS } from '../../util/constants' @@ -13,34 +13,26 @@ interface Props { transitOperators: TransitOperator[] } -class ConnectedTransitOperatorLogos extends Component { - render() { - const loading = this.props.stopData?.fetchStatus === FETCH_STATUS.FETCHING - return ( - - ) - } +function TransitOperatorIcons({ stopData, transitOperators }: Props) { + const loading = stopData?.fetchStatus === FETCH_STATUS.FETCHING + return ( + + ) } -const mapDispatchToProps = {} - const mapStateToProps = ( state: AppReduxState, ownProps: Props & { stopId: string } ) => { const stops = state.otp.transitIndex.stops - // clean this up return { stopData: stops?.[ownProps.stopId], transitOperators: state.otp.config.transitOperators || [] } } -export default connect( - mapStateToProps, - mapDispatchToProps -)(ConnectedTransitOperatorLogos) +export default connect(mapStateToProps)(TransitOperatorIcons) diff --git a/lib/components/util/operator-logo.tsx b/lib/components/util/operator-logo.tsx index e7000faa0..e40c121ca 100644 --- a/lib/components/util/operator-logo.tsx +++ b/lib/components/util/operator-logo.tsx @@ -6,35 +6,28 @@ const OperatorImg = styled.img<{ marginRight?: number; maxHeight?: number }>` &:not(:last-of-type) { margin-right: 0.5ch; } - margin-right: ${(props) => props.marginRight && props.marginRight}ch; - max-height: ${(props) => props.maxHeight && props.maxHeight}em; - // Make sure icons stay square - max-width: ${(props) => props.maxHeight && props.maxHeight}em; width: 25px; ` +const StyledOperatorImg = styled(OperatorImg)` + margin-right: 0.5ch; + max-height: 1em; + // Make sure icons stay square + max-width: 1em; +` + type Props = { alt?: string - marginRight?: number - maxHeight?: number operator?: TransitOperator + styled?: boolean } -const OperatorLogo = ({ - alt, - marginRight, - maxHeight, - operator -}: Props): JSX.Element | null => { +const OperatorLogo = ({ alt, operator, styled }: Props): JSX.Element | null => { if (!operator?.logo) return null - return ( - - ) + if (styled) + return + + return } export default OperatorLogo diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx index 1f008b2ef..377f8cf38 100644 --- a/lib/components/util/transit-operator-icons.tsx +++ b/lib/components/util/transit-operator-icons.tsx @@ -31,12 +31,7 @@ const Operator = ({ operator }: { operator?: TransitOperator }) => { operator.name ? operator.name.replace(/\s+/g, '-').toLowerCase() : '' } > - + ) : ( // If operator exists but logo is missing, @@ -55,13 +50,12 @@ const TransitOperatorLogos = ({ transitOperators }: { loading?: boolean - stopData: StopData | undefined + stopData?: StopData transitOperators?: TransitOperator[] }): JSX.Element => { const agencies = (stopData && stopData.stoptimesForPatterns?.reduce>((prev, cur) => { - // @ts-expect-error The agency type is not yet compatible with OTP2 const agencyGtfsId = cur.pattern.route.agency?.gtfsId return agencyGtfsId ? prev.add(agencyGtfsId) : prev }, new Set())) || From a883518ec82cb3837633548f9404027b51489d55 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:04:33 -0500 Subject: [PATCH 151/162] Whoops add back the @ts-expect-error --- lib/components/util/transit-operator-icons.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/components/util/transit-operator-icons.tsx b/lib/components/util/transit-operator-icons.tsx index 377f8cf38..7f40fe11c 100644 --- a/lib/components/util/transit-operator-icons.tsx +++ b/lib/components/util/transit-operator-icons.tsx @@ -56,6 +56,7 @@ const TransitOperatorLogos = ({ const agencies = (stopData && stopData.stoptimesForPatterns?.reduce>((prev, cur) => { + // @ts-expect-error The agency type is not yet compatible with OTP2 const agencyGtfsId = cur.pattern.route.agency?.gtfsId return agencyGtfsId ? prev.add(agencyGtfsId) : prev }, new Set())) || From 6bea334a9a8b1be85c2d40429d6fd5ce4a1a0c51 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:16:54 -0500 Subject: [PATCH 152/162] Update snapshots --- .../viewers/__snapshots__/nearby-view.js.snap | 228 +++++++++--------- .../stop-schedule-viewer.ts.snap | 2 +- 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 52b08c691..ac5bc3bee 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -12231,7 +12231,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                                        1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                            viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                                          1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                                                                                                                                                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                                                1. viewers > nearby view renders proper scooter dates 1`] = ` className="departure-times" >

                                                                                                                                                                                                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                                                                                                                                                                                                  Date: Fri, 4 Oct 2024 14:42:57 -0500 Subject: [PATCH 153/162] fix: add curly braces to conditional --- lib/components/util/operator-logo.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/components/util/operator-logo.tsx b/lib/components/util/operator-logo.tsx index e40c121ca..f88f6d51a 100644 --- a/lib/components/util/operator-logo.tsx +++ b/lib/components/util/operator-logo.tsx @@ -24,8 +24,9 @@ type Props = { const OperatorLogo = ({ alt, operator, styled }: Props): JSX.Element | null => { if (!operator?.logo) return null - if (styled) + if (styled) { return + } return } From d82715415e51b06d6ef623ccba6bd129bb3032aa Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:46:12 -0400 Subject: [PATCH 154/162] style(SimpleMap): Apply code style feedback. --- lib/components/map/simple-map.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index 446a11fbb..960e6b532 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -33,7 +33,7 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { initLon = 0, initZoom, maxZoom, - navigationControlPosition, + navigationControlPosition = 'bottom-right', transitive } = config.map || {} const baseLayerUrls = baseLayers?.map((bl) => bl.url) @@ -42,9 +42,7 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { return ( 1 ? baseLayerUrls : baseLayerUrls?.[0] - } + baseLayer={baseLayerUrls?.length > 1 ? baseLayerUrls : baseLayerUrls?.[0]} center={[initLat, initLon]} mapLibreProps={{ reuseMaps: true }} maxZoom={maxZoom} @@ -52,6 +50,7 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { > @@ -67,9 +66,7 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { /> )} - + ) } From 6b97adfe7801db2275fc6358dd7248bdc9e64def Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:54:25 -0400 Subject: [PATCH 155/162] refactor(SimpleMap): Fix types --- lib/components/map/simple-map.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index 960e6b532..25040c268 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -42,7 +42,9 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { return ( 1 ? baseLayerUrls : baseLayerUrls?.[0]} + baseLayer={ + (baseLayerUrls?.length || 0) > 1 ? baseLayerUrls : baseLayerUrls?.[0] + } center={[initLat, initLon]} mapLibreProps={{ reuseMaps: true }} maxZoom={maxZoom} From 83cadc9952112d9040f39768c5e7cd45577ba0cf Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:38:38 -0400 Subject: [PATCH 156/162] refactor(SimpleMap): Remove EndpointOverlay handler after updating OTP-UI pkg. --- lib/components/map/simple-map.tsx | 6 ------ package.json | 2 +- yarn.lock | 20 ++++++++++---------- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/lib/components/map/simple-map.tsx b/lib/components/map/simple-map.tsx index 25040c268..f9312a9a4 100644 --- a/lib/components/map/simple-map.tsx +++ b/lib/components/map/simple-map.tsx @@ -18,10 +18,6 @@ interface Props { itinerary?: Itinerary } -function noop() { - return null -} - /** Renders an optional itinerary with a given config. */ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { const intl = useIntl() @@ -52,8 +48,6 @@ const SimpleMap = ({ config, itinerary }: Props): JSX.Element => { > diff --git a/package.json b/package.json index 34e1e7c8f..63a43c1fa 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@opentripplanner/base-map": "4.0.0", "@opentripplanner/building-blocks": "2.0.0", "@opentripplanner/core-utils": "12.0.0", - "@opentripplanner/endpoints-overlay": "3.0.0", + "@opentripplanner/endpoints-overlay": "3.0.1", "@opentripplanner/from-to-location-picker": "3.0.0", "@opentripplanner/geocoder": "^3.0.2", "@opentripplanner/humanize-distance": "^1.2.0", diff --git a/yarn.lock b/yarn.lock index 599332b3e..c96260c70 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,7 +2383,7 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@4.0.0": +"@opentripplanner/base-map@4.0.0", "@opentripplanner/base-map@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-4.0.0.tgz#56ffa1d833673282cc3a0b7a17f388fc5dbd31e3" integrity sha512-pWTKXxnzUQk43woPMc40uYfGIcGqHV8GoCvRwrIu2pqNw7QAV4rxjZfca0pm5hnbbJ+G83sRzYboILEbEUwMcw== @@ -2403,7 +2403,7 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@2.0.0": +"@opentripplanner/building-blocks@2.0.0", "@opentripplanner/building-blocks@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-2.0.0.tgz#8282c01dff7db5c7e809f6ea91cb52df559a2f9d" integrity sha512-N07rDaZL8fp552eI9/0j1udKjc0uOpvO0Wv1P19Ge0a4roques463MJgWJ026fbopRCi3uwbc/gYTlh4/ske9A== @@ -2413,7 +2413,7 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@12.0.0": +"@opentripplanner/core-utils@12.0.0", "@opentripplanner/core-utils@^12.0.0": version "12.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== @@ -2449,14 +2449,14 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/endpoints-overlay@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-3.0.0.tgz#17bb943f5bf2b8571cb808b12b5a2185fd18196a" - integrity sha512-st6vfLRCBzVollYS4nIXghbjApDq73lcExo7hZh60DCVSGESSZA9jsNE6ff0HmvhYHdag9QV9zbZOFuNxPIrng== +"@opentripplanner/endpoints-overlay@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-3.0.1.tgz#b6b8e2f08ae41fbaad475fc0f0fe3e72d7d36463" + integrity sha512-X3T0GM8U+VU/mOOSNUgj6fVcjAKMeciKFYnQNbKiNgNeDHa5JltwvtXsM4x3wCLP2xAF6jH/HTWJmYmsfLPlAw== dependencies: - "@opentripplanner/base-map" "^3.2.2" - "@opentripplanner/building-blocks" "^1.2.2" - "@opentripplanner/core-utils" "^11.4.4" + "@opentripplanner/base-map" "^4.0.0" + "@opentripplanner/building-blocks" "^2.0.0" + "@opentripplanner/core-utils" "^12.0.0" "@opentripplanner/location-icon" "^1.4.1" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" From ad9ce17e1ba97fbd3377eb2fd6aaa7daeea55423 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:54:17 -0400 Subject: [PATCH 157/162] chore(deps): Update core-utils to 12.0.1. --- package.json | 2 +- yarn.lock | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7b69da5c0..e7ed5b415 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@floating-ui/react": "^0.19.2", "@opentripplanner/base-map": "4.0.0", "@opentripplanner/building-blocks": "2.0.0", - "@opentripplanner/core-utils": "12.0.0", + "@opentripplanner/core-utils": "12.0.1", "@opentripplanner/endpoints-overlay": "3.0.0", "@opentripplanner/from-to-location-picker": "3.0.0", "@opentripplanner/geocoder": "^3.0.2", diff --git a/yarn.lock b/yarn.lock index 1a65ef7a9..3385bc918 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2413,10 +2413,10 @@ resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.2.3.tgz#404e8f9038867d66d55f51adf8855b1326c51ed5" integrity sha512-I0AxiZrTZu+e7+av4u0tHW2ijqpxH0AkLHrhf75BHf1Ep2FOGxaul/v+8UT18mNYiM5eHNstOX3XiXaDjtCUaw== -"@opentripplanner/core-utils@12.0.0", "@opentripplanner/core-utils@^12.0.0": - version "12.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" - integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== +"@opentripplanner/core-utils@12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.1.tgz#2bafb78133393213b4943c76fec5d46436c0fb6d" + integrity sha512-QUTxEcpiOnbqaoiu6RQngTLlQHjSHO4PCMJqR9IRiaei08FnlTx2jgpvIaRla6u7tRNr12YCzptc37+a10ryww== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" @@ -2449,6 +2449,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@^12.0.0": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0.tgz#cc40af92620b207f4dce817d08f99def0cdaea7a" + integrity sha512-udLF8XU+k7gxZ+yyyw7ASz6/4D540zYIv8a9GbUL61TF8HmgGhcMk3XOgBnm5jdOukuaNNpOFE4J3oJc5QsSBQ== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.0" + "@opentripplanner/geocoder" "^3.0.2" + "@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@3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-3.0.0.tgz#17bb943f5bf2b8571cb808b12b5a2185fd18196a" From 01e6e8e357ed6843eba7fadf6cc90d37cf1f46dc Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:58:36 -0400 Subject: [PATCH 158/162] ci: Add --no-sandbox arg to a11y/percy tests. --- a11y/a11y.test.js | 2 +- percy/percy.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/a11y/a11y.test.js b/a11y/a11y.test.js index 255b0c23a..c1823caf9 100644 --- a/a11y/a11y.test.js +++ b/a11y/a11y.test.js @@ -58,7 +58,7 @@ beforeAll(async () => { }) // Web security is disabled to allow requests to the mock OTP server browser = await puppeteer.launch({ - args: ['--disable-web-security'] + args: ['--disable-web-security', '--no-sandbox'] }) }) diff --git a/percy/percy.test.js b/percy/percy.test.js index 6e8e8b1e6..37433032d 100644 --- a/percy/percy.test.js +++ b/percy/percy.test.js @@ -71,7 +71,7 @@ beforeAll(async () => { // Web security is disabled to allow requests to the mock OTP server browser = await puppeteer.launch({ - args: ['--disable-web-security'] + args: ['--disable-web-security', '--no-sandbox'] //, headless: false }) } catch (error) { From 788f1cbe3ebb4e0338af3eb3bebf5629fc0a81d0 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 16 Oct 2024 16:57:53 -0400 Subject: [PATCH 159/162] chore(deps): Add webpack raw-loader --- package.json | 1 + yarn.lock | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/package.json b/package.json index 77e39c1eb..707a514ca 100644 --- a/package.json +++ b/package.json @@ -195,6 +195,7 @@ "pinst": "^2.1.6", "prettier": "^2.3.2", "puppeteer": "^10.2.0", + "raw-loader": "^4.0.2", "react-refresh": "^0.10.0", "react-scripts": "^4.0.3", "redux-mock-store": "^1.5.3", diff --git a/yarn.lock b/yarn.lock index d4f948996..fc46f8d41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15166,6 +15166,14 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +raw-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" From 9d606badea84376bc41ce958ca23b72ec800b81d Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:00:34 -0400 Subject: [PATCH 160/162] build(craco): Include local graphql file in build. --- craco.config.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/craco.config.js b/craco.config.js index 283dc3350..f156dcfe1 100644 --- a/craco.config.js +++ b/craco.config.js @@ -48,6 +48,8 @@ module.exports = { findBackwardsCompatibleEnvVar('JS_CONFIG') backwardsCompatibleEnv.HTML_FILE = findBackwardsCompatibleEnvVar('HTML_FILE') + backwardsCompatibleEnv.PLAN_QUERY_RESOURCE_URI = + findBackwardsCompatibleEnvVar('PLAN_QUERY_RESOURCE_URI') backwardsCompatibleEnv.CUSTOM_CSS = findBackwardsCompatibleEnvVar('CUSTOM_CSS') @@ -65,6 +67,13 @@ module.exports = { } addBeforeLoader(webpackConfig, loaderByName('file-loader'), yamlLoader) + // Support YAML + const graphqlLoader = { + loader: ['raw-loader'], + test: /\.graphql$/ + } + addBeforeLoader(webpackConfig, loaderByName('file-loader'), graphqlLoader) + // Support webfonts (for font awesome) const webfontLoader = { loader: ['url-loader'], @@ -82,7 +91,7 @@ module.exports = { loader.exclude = /node_modules/ }) - // Gather the CSS, HTML, YAML, and JS override files. + // Gather the CSS, HTML, YAML, GraphQL, and JS override files. const CUSTOM_CSS = (process.env && process.env.CUSTOM_CSS) || backwardsCompatibleEnv.CUSTOM_CSS || @@ -91,6 +100,22 @@ module.exports = { (process.env && process.env.HTML_FILE) || backwardsCompatibleEnv.HTML_FILE || 'lib/index.tpl.html' + // resolve the custom GraphQL file. If it is present, copy the file to a + // temporary folder within this project so that it can be bundled and loaded at runtime. + let customPlanGraphQLFile = './planQuery.graphql' + const PLAN_QUERY_RESOURCE_URI = + (process.env && process.env.PLAN_QUERY_RESOURCE_URI) || + backwardsCompatibleEnv.PLAN_QUERY_RESOURCE_URI || + 'node_modules/@opentripplanner/core-utils/src/planQuery.graphql' + if (PLAN_QUERY_RESOURCE_URI) { + const splitPath = PLAN_QUERY_RESOURCE_URI.split(path.sep) + customPlanGraphQLFile = `../tmp/${splitPath[splitPath.length - 1]}` + // copy location is relative to root, while js file for app is relative to lib + fs.copySync( + PLAN_QUERY_RESOURCE_URI, + `./tmp/${splitPath[splitPath.length - 1]}` + ) + } const YAML_CONFIG = (process.env && process.env.YAML_CONFIG) || backwardsCompatibleEnv.YAML_CONFIG || @@ -143,6 +168,7 @@ module.exports = { new webpack.DefinePlugin({ CSS: JSON.stringify(CUSTOM_CSS), JS_CONFIG: JSON.stringify(customJsFile), + PLAN_QUERY_RESOURCE: JSON.stringify(customPlanGraphQLFile), // Optionally override the default config files with some other // files. YAML_CONFIG: JSON.stringify(YAML_CONFIG) From 1f44061c26b07fc9a2dd263744aaa7fa77db7947 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:19:45 -0400 Subject: [PATCH 161/162] feat(main): Use plan GraphQL template from config --- lib/main.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/main.js b/lib/main.js index 780584e27..33e36c552 100644 --- a/lib/main.js +++ b/lib/main.js @@ -34,6 +34,18 @@ import(CSS) // eslint-disable-next-line no-undef const otpConfig = require(YAML_CONFIG) +// Loads a JavaScript file which is set in the webpack section of the craco.config.js file. +// This setting is defined from a custom environment setting passed into webpack or +// defaults to ./config.js +// defined in webpack config: +// The JS_CONFIG variable is passed to this file by webpack's `DefinePlugin` that replaces the variable +// with its content at compile time (like C's `#define` preprocessor directive). +// eslint-disable-next-line no-undef +const jsConfig = require(JS_CONFIG).configure(otpConfig) + +// Plug the plan query into the config (if available) +otpConfig.api.planQuery = jsConfig.planQuery + const history = createHashHistory() const middleware = [ From c403cf051f48bbc6cac0026d3c03a09a66e46a4e Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:30:28 -0400 Subject: [PATCH 162/162] chore(example-config): Remove custom plan query --- example-config.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/example-config.yml b/example-config.yml index 6ad279aae..79a242954 100644 --- a/example-config.yml +++ b/example-config.yml @@ -15,9 +15,6 @@ api: # If your OTP server is at a path other than "/otp" (usually due to a proxy) # Then you can set the OPTIONAL property basePath. The default is "/otp" basePath: /otp - ### Custom GraphQL plan query to override the default one (it still needs to include expected variables). - # planQuery: | - # query Plan() port: 8080 v2: true