From ffec4f3685b4dfae31d0fd59e0df8978fc020bcc Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Mon, 6 Jan 2025 16:25:10 -0600 Subject: [PATCH 1/8] feat(connected-endpoints-overlay): Pass nearby to endpoint overlay --- .../map/connected-endpoints-overlay.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/components/map/connected-endpoints-overlay.tsx b/lib/components/map/connected-endpoints-overlay.tsx index acbc0a23e..f4925c2e2 100644 --- a/lib/components/map/connected-endpoints-overlay.tsx +++ b/lib/components/map/connected-endpoints-overlay.tsx @@ -1,6 +1,6 @@ import { connect } from 'react-redux' import { IntlShape, useIntl } from 'react-intl' -import { UserLocationAndType } from '@opentripplanner/types' +import { Location, UserLocationAndType } from '@opentripplanner/types' import EndpointsOverlay from '@opentripplanner/endpoints-overlay' import React, { ComponentProps, useCallback } from 'react' @@ -13,16 +13,19 @@ import { } from '../../actions/user' import { getActiveSearch, getShowUserSettings } from '../../util/state' import { setLocation } from '../../actions/map' +import { setViewedStop } from '../../actions/ui' import { toastOnPlaceSaved } from '../util/toasts' type Props = ComponentProps & { forgetPlace: (place: string, intl: IntlShape) => void rememberPlace: (arg: UserLocationAndType, intl: IntlShape) => number + setViewedStop: (arg: Location) => void } const ConnectedEndpointsOverlay = ({ forgetPlace, rememberPlace, + setViewedStop, ...otherProps }: Props): JSX.Element => { const intl = useIntl() @@ -33,6 +36,8 @@ const ConnectedEndpointsOverlay = ({ [forgetPlace, intl] ) + const { fromLocation, toLocation } = otherProps + const _rememberPlace = useCallback( async (placeTypeLocation) => { const result = await rememberPlace(placeTypeLocation, intl) @@ -47,6 +52,12 @@ const ConnectedEndpointsOverlay = ({ {...otherProps} forgetPlace={_forgetPlace} rememberPlace={_rememberPlace} + viewNearbyDestination={() => { + toLocation && setViewedStop(toLocation) + }} + viewNearbyOrigin={() => { + fromLocation && setViewedStop(fromLocation) + }} /> ) } @@ -89,7 +100,8 @@ const mapDispatchToProps = { clearLocation, forgetPlace, rememberPlace, - setLocation + setLocation, + setViewedStop } export default connect( From f5294aed778430d37b2ac72a0f5424a50dd1edb4 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Tue, 7 Jan 2025 16:41:23 -0600 Subject: [PATCH 2/8] add config item "sortPatternsByVehicleCount" --- example-config.yml | 2 + lib/components/viewers/route-details.tsx | 64 +++++++++++++++++------- lib/util/config-types.ts | 2 + 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/example-config.yml b/example-config.yml index a7e100230..97befc4df 100644 --- a/example-config.yml +++ b/example-config.yml @@ -674,6 +674,8 @@ disableSingleItineraryDays: false # # Whether to render routes within flex zones of a route's patterns. If set to true, # # routes will not be rendered within flex zones. # hideRouteShapesWithinFlexZones: true +# # Setting to sort routes by the number of vehicles on each pattern +# sortRoutePatternsByVehicleCount: true # # Disable vehicle highlight if necessary (e.g. custom or inverted icons) # vehicleIconHighlight: true # # Customize vehicle icon padding (the default iconPadding is 2px in otp-ui) diff --git a/lib/components/viewers/route-details.tsx b/lib/components/viewers/route-details.tsx index 5e8afbfad..a50470be4 100644 --- a/lib/components/viewers/route-details.tsx +++ b/lib/components/viewers/route-details.tsx @@ -47,6 +47,11 @@ const PatternSelectDropdown = styled(Dropdown)` span.caret { color: #333; } + + ul li button span { + width: 100%; + display: block; + } ` interface Props { @@ -57,6 +62,7 @@ interface Props { setHoveredStop: (id: string | null) => void setViewedRoute: SetViewedRouteHandler setViewedStop: SetViewedStopHandler + sortPatternsByVehicleCount: boolean } class RouteDetails extends Component { @@ -87,7 +93,14 @@ class RouteDetails extends Component { } render() { - const { intl, operator, patternId, route, setHoveredStop } = this.props + const { + intl, + operator, + patternId, + route, + setHoveredStop, + sortPatternsByVehicleCount + } = this.props const { agency, patterns = {}, shortName, url } = route const pattern = patterns[patternId] @@ -95,25 +108,29 @@ class RouteDetails extends Component { const routeColor = getRouteColorBasedOnSettings(operator, route) - const headsigns = extractMainHeadsigns( + const unsortedHeadsigns = extractMainHeadsigns( patterns, shortName, this._editHeadsign - ).sort((a, b) => { - // sort by number of vehicles on that pattern - const aVehicleCount = - route.vehicles?.filter((vehicle) => vehicle.patternId === a.id) - .length || 0 - const bVehicleCount = - route.vehicles?.filter((vehicle) => vehicle.patternId === b.id) - .length || 0 - - // if both have the same count, sort by pattern geometry length - if (aVehicleCount === bVehicleCount) { - return b.geometryLength - a.geometryLength - } - return bVehicleCount - aVehicleCount - }) + ) + + const headsigns = sortPatternsByVehicleCount + ? unsortedHeadsigns.sort((a, b) => { + // sort by number of vehicles on that pattern + const aVehicleCount = + route.vehicles?.filter((vehicle) => vehicle.patternId === a.id) + .length || 0 + const bVehicleCount = + route.vehicles?.filter((vehicle) => vehicle.patternId === b.id) + .length || 0 + + // if both have the same count, sort by pattern geometry length + if (aVehicleCount === bVehicleCount) { + return b.geometryLength - a.geometryLength + } + return bVehicleCount - aVehicleCount + }) + : unsortedHeadsigns const patternSelectLabel = intl.formatMessage({ id: 'components.RouteDetails.selectADirection' @@ -231,6 +248,14 @@ class RouteDetails extends Component { } } +const mapStateToProps = (state: any) => { + const { sortRoutePatternsByVehicleCount } = state.otp.config.routeViewer + + return { + sortPatternsByVehicleCount: sortRoutePatternsByVehicleCount !== false + } +} + // connect to redux store const mapDispatchToProps = { setHoveredStop: uiActions.setHoveredStop, @@ -238,4 +263,7 @@ const mapDispatchToProps = { setViewedStop: uiActions.setViewedStop } -export default connect(null, mapDispatchToProps)(injectIntl(RouteDetails)) +export default connect( + mapStateToProps, + mapDispatchToProps +)(injectIntl(RouteDetails)) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 93f00ce26..64a6ff3f4 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -362,6 +362,8 @@ export interface RouteViewerConfig { maxRealtimeVehicleAge?: number /** Use OTP date limiting to only show current service week in list */ onlyShowCurrentServiceWeek?: boolean + /** Setting to sort routes by the number of vehicles on each pattern */ + sortRoutePatternsByVehicleCount?: boolean /** Disable vehicle highlight if necessary (e.g. custom or inverted icons) */ vehicleIconHighlight?: boolean /** Customize vehicle icon padding (the default iconPadding is 2px in otp-ui) */ From f8fc89c0406eba8e68d111432249d6b35723f6fd Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Tue, 7 Jan 2025 16:42:06 -0600 Subject: [PATCH 3/8] Fix spacing dropdown on pattern header --- lib/components/viewers/styled.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/components/viewers/styled.ts b/lib/components/viewers/styled.ts index 8a870a84e..9c9815dbf 100644 --- a/lib/components/viewers/styled.ts +++ b/lib/components/viewers/styled.ts @@ -36,8 +36,7 @@ export const PatternContainer = styled.div` background-color: inherit; color: inherit; display: flex; - gap: 16px; - justify-content: flex-start; + justify-content: space-between; margin: 0; padding: 8px; @@ -48,7 +47,7 @@ export const PatternContainer = styled.div` // Styling for SortResultsDropdown & > span { - width: 85%; + width: 80%; button#headsign-selector-label { align-items: center; From e74a07db98671852acfe2a3d9b106143b6fc9405 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Wed, 8 Jan 2025 11:03:42 -0600 Subject: [PATCH 4/8] Update to reflect otp-ui changes --- lib/components/map/connected-endpoints-overlay.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/components/map/connected-endpoints-overlay.tsx b/lib/components/map/connected-endpoints-overlay.tsx index f4925c2e2..c86b4d4af 100644 --- a/lib/components/map/connected-endpoints-overlay.tsx +++ b/lib/components/map/connected-endpoints-overlay.tsx @@ -36,8 +36,6 @@ const ConnectedEndpointsOverlay = ({ [forgetPlace, intl] ) - const { fromLocation, toLocation } = otherProps - const _rememberPlace = useCallback( async (placeTypeLocation) => { const result = await rememberPlace(placeTypeLocation, intl) @@ -52,12 +50,7 @@ const ConnectedEndpointsOverlay = ({ {...otherProps} forgetPlace={_forgetPlace} rememberPlace={_rememberPlace} - viewNearbyDestination={() => { - toLocation && setViewedStop(toLocation) - }} - viewNearbyOrigin={() => { - fromLocation && setViewedStop(fromLocation) - }} + setViewNearby={setViewedStop} /> ) } From e3401b6b1f280009f3bf4d465929a04a5406c601 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Wed, 8 Jan 2025 11:08:53 -0600 Subject: [PATCH 5/8] account for undefined route viewer config --- lib/components/viewers/route-details.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/components/viewers/route-details.tsx b/lib/components/viewers/route-details.tsx index a50470be4..639d23ffb 100644 --- a/lib/components/viewers/route-details.tsx +++ b/lib/components/viewers/route-details.tsx @@ -249,7 +249,8 @@ class RouteDetails extends Component { } const mapStateToProps = (state: any) => { - const { sortRoutePatternsByVehicleCount } = state.otp.config.routeViewer + const sortRoutePatternsByVehicleCount = + state.otp?.config?.routeViewer?.sortRoutePatternsByVehicleCount return { sortPatternsByVehicleCount: sortRoutePatternsByVehicleCount !== false From 334d86af79d4799eaaaef7220767a4e260c186fc Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Thu, 9 Jan 2025 10:16:09 -0600 Subject: [PATCH 6/8] Simplify sort code --- lib/components/viewers/route-details.tsx | 35 +++++++++++------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/lib/components/viewers/route-details.tsx b/lib/components/viewers/route-details.tsx index 639d23ffb..c9cbcfdd2 100644 --- a/lib/components/viewers/route-details.tsx +++ b/lib/components/viewers/route-details.tsx @@ -108,29 +108,26 @@ class RouteDetails extends Component { const routeColor = getRouteColorBasedOnSettings(operator, route) - const unsortedHeadsigns = extractMainHeadsigns( + const headsigns = extractMainHeadsigns( patterns, shortName, this._editHeadsign - ) - - const headsigns = sortPatternsByVehicleCount - ? unsortedHeadsigns.sort((a, b) => { - // sort by number of vehicles on that pattern - const aVehicleCount = - route.vehicles?.filter((vehicle) => vehicle.patternId === a.id) - .length || 0 - const bVehicleCount = - route.vehicles?.filter((vehicle) => vehicle.patternId === b.id) - .length || 0 + ).sort((a, b) => { + if (!sortPatternsByVehicleCount) return 0 + // sort by number of vehicles on that pattern + const aVehicleCount = + route.vehicles?.filter((vehicle) => vehicle.patternId === a.id) + .length || 0 + const bVehicleCount = + route.vehicles?.filter((vehicle) => vehicle.patternId === b.id) + .length || 0 - // if both have the same count, sort by pattern geometry length - if (aVehicleCount === bVehicleCount) { - return b.geometryLength - a.geometryLength - } - return bVehicleCount - aVehicleCount - }) - : unsortedHeadsigns + // if both have the same count, sort by pattern geometry length + if (aVehicleCount === bVehicleCount) { + return b.geometryLength - a.geometryLength + } + return bVehicleCount - aVehicleCount + }) const patternSelectLabel = intl.formatMessage({ id: 'components.RouteDetails.selectADirection' From ba29c136c5785e7e706c513bba7398edec41e831 Mon Sep 17 00:00:00 2001 From: amy-corson-ibigroup Date: Wed, 15 Jan 2025 10:37:51 -0600 Subject: [PATCH 7/8] Update endpoint-overlay package --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f211c743e..1d9c35894 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@opentripplanner/base-map": "4.0.0", "@opentripplanner/building-blocks": "2.1.0", "@opentripplanner/core-utils": "12.0.1", - "@opentripplanner/endpoints-overlay": "3.0.1", + "@opentripplanner/endpoints-overlay": "3.1.0", "@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 1f29a0b0f..3d9ff499c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2451,10 +2451,10 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@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== +"@opentripplanner/endpoints-overlay@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-3.1.0.tgz#92ad54ed9445385e25c2a968f700945ae4fc9315" + integrity sha512-FxQrd/nDIP9Tq5yfMFVgWx0QIXmy64y521r6yFCNsY/rBLSAtnLCVMLNUW+bCtdo3IUpeSpqshJDLYHHDHpa/g== dependencies: "@opentripplanner/base-map" "^4.0.0" "@opentripplanner/building-blocks" "^2.0.0" From 2a409124dc44883d2e5220ee68d961d7575e7d19 Mon Sep 17 00:00:00 2001 From: Amy Corson <115499534+amy-corson-ibigroup@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:50:00 -0600 Subject: [PATCH 8/8] fix state typing in route-details --- lib/components/viewers/route-details.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/components/viewers/route-details.tsx b/lib/components/viewers/route-details.tsx index c9cbcfdd2..e7c4dac02 100644 --- a/lib/components/viewers/route-details.tsx +++ b/lib/components/viewers/route-details.tsx @@ -7,6 +7,7 @@ import React, { Component } from 'react' import styled from 'styled-components' import * as uiActions from '../../actions/ui' +import { AppReduxState } from '../../util/state-types' import { DEFAULT_ROUTE_COLOR } from '../util/colors' import { extractMainHeadsigns, PatternSummary } from '../../util/pattern-viewer' import { getOperatorName } from '../../util/state' @@ -245,9 +246,9 @@ class RouteDetails extends Component { } } -const mapStateToProps = (state: any) => { +const mapStateToProps = (state: AppReduxState) => { const sortRoutePatternsByVehicleCount = - state.otp?.config?.routeViewer?.sortRoutePatternsByVehicleCount + state.otp.config.routeViewer?.sortRoutePatternsByVehicleCount return { sortPatternsByVehicleCount: sortRoutePatternsByVehicleCount !== false