diff --git a/app/component/itinerary/BicycleLeg.js b/app/component/itinerary/BicycleLeg.js index c2e287d1c3..6af19bb363 100644 --- a/app/component/itinerary/BicycleLeg.js +++ b/app/component/itinerary/BicycleLeg.js @@ -276,6 +276,12 @@ export default function BicycleLeg( to={`/${PREFIX_STOPS}/${fromStop.gtfsId}`} > {origin} + {leg.isViaPoint && ( + + )} */}
+ {leg.isViaPoint && ( + + )} {/* TODO */} {/* {bikePark && (
{address} + {props.leg.isViaPoint && ( + + )} {props.leg.from.stop && (
+ {props.leg.isViaPoint && ( + + )} {props.carPark && ( {` ${name}`}
+ {isViaPoint && ( + + )} 0 && + (leg.intermediatePlace || connectsFromViaPoint(leg, intermediatePlaces)) ) { intermediateSlack += legTime(leg.start) - legTime(compressedLegs[i - 1].end); // calculate time spent at each intermediate place @@ -364,8 +364,9 @@ const Itinerary = ( const isNextLegLast = i + 1 === compressedLegs.length - 1; const shouldRenderLastLeg = isNextLegLast && lastLegLength < renderBarThreshold; - const previousLeg = compressedLegs[i - 1]; - const nextLeg = compressedLegs[i + 1]; + const previousLeg = i > 0 ? compressedLegs[i - 1] : null; + const nextLeg = + i < compressedLegs.length - 1 ? compressedLegs[i + 1] : null; let legLength = relativeLength(endMs - startMs); const longName = !leg?.route?.shortName || leg?.route?.shortName.length > 5; diff --git a/app/component/itinerary/Legs.js b/app/component/itinerary/Legs.js index ebd5bd9c04..7ec01cff54 100644 --- a/app/component/itinerary/Legs.js +++ b/app/component/itinerary/Legs.js @@ -1,6 +1,7 @@ /* eslint-disable react/no-array-index-key */ import PropTypes from 'prop-types'; import React from 'react'; +import { matchShape } from 'found'; import { configShape, fareShape, @@ -25,12 +26,14 @@ import { isCallAgencyLeg, isLegOnFoot, legTime, + markViaPoints, getBoardingLeg, } from '../../util/legUtils'; import { getRouteMode } from '../../util/modeUtils'; import { addAnalyticsEvent } from '../../util/analyticsUtils'; import Profile from './Profile'; import BikeParkLeg from './BikeParkLeg'; +import { getIntermediatePlaces } from '../../util/otpStrings'; const stopCode = stop => stop && stop.code && ; @@ -53,7 +56,10 @@ export default class Legs extends React.Component { relayEnvironment: relayShape, }; - static contextTypes = { config: configShape }; + static contextTypes = { + config: configShape, + match: matchShape, + }; static defaultProps = { fares: [], @@ -95,7 +101,10 @@ export default class Legs extends React.Component { } = this.props; const { waitThreshold } = this.context.config.itinerary; - const compressedLegs = compressLegs(itinerary.legs, true).map(leg => ({ + const { location } = this.context.match; + const intermediatePlaces = getIntermediatePlaces(location.query); + const itineraryLegs = markViaPoints(itinerary.legs, intermediatePlaces); + const compressedLegs = compressLegs(itineraryLegs, true).map(leg => ({ showBikeBoardingInformation, showCarBoardingInformation, ...leg, @@ -163,10 +172,15 @@ export default class Legs extends React.Component { !isNextLegInterlining && leg.to.stop ) { + const waitLegProps = { ...leg }; + if (nextLeg && nextLeg.isViaPoint) { + waitLegProps.isViaPoint = true; + nextLeg.isViaPoint = false; + } waitLeg = ( @@ -478,6 +479,12 @@ class TransitLeg extends React.Component { to={`/${PREFIX_STOPS}/${leg.from.stop.gtfsId}`} > {leg.from.name} + {leg.isViaPoint && ( + + )} {leg.to.name} + {leg.isViaPoint && ( + + )} {returnNotice || leg[toOrFrom].name} + {leg.isViaPoint && ( + + )} {leg[toOrFrom].stop && ( = 0) { + array.splice(index, 1); + return true; + } + return false; +} + +function isViaPointMatch(stop, viaPoints) { + return ( + stop && + (includesAndRemove(viaPoints, stop.gtfsId) || + (stop.parentStation && + includesAndRemove(viaPoints, stop.parentStation.gtfsId))) + ); +} + /** * Adds intermediate: true to legs if their start point should have a via point * marker, possibly splitting legs in case the via point belongs in the middle. + * Once a via point is used, it is not matched again. * * @param originalLegs Leg objects from graphql query * @param viaPlaces Location objects (otpToLocation) from query parameter @@ -245,27 +265,14 @@ function syntheticEndpoint(originalEndpoint, place) { export function splitLegsAtViaPoints(originalLegs, viaPlaces) { const splitLegs = []; // Once a via place is matched, it is used and will not match again. - function includesAndRemove(array, id) { - const index = array.indexOf(id); - if (index >= 0) { - array.splice(index, 1); - return true; - } - return false; - } const viaPoints = viaPlaces.map(p => p.gtfsId); - const isViaPointMatch = stop => - stop && - (includesAndRemove(viaPoints, stop.gtfsId) || - (stop.parentStation && - includesAndRemove(viaPoints, stop.parentStation.gtfsId))); let nextLegStartsWithIntermediate = false; originalLegs.forEach(originalLeg => { const leg = { ...originalLeg }; const { intermediatePlaces } = leg; if ( nextLegStartsWithIntermediate || - (leg.transitLeg && isViaPointMatch(leg.from.stop)) + (leg.transitLeg && isViaPointMatch(leg.from.stop, viaPoints)) ) { leg.intermediatePlace = true; nextLegStartsWithIntermediate = false; @@ -274,7 +281,7 @@ export function splitLegsAtViaPoints(originalLegs, viaPlaces) { let start = 0; let lastSplit = -1; intermediatePlaces.forEach((place, i) => { - if (isViaPointMatch(place.stop)) { + if (isViaPointMatch(place.stop, viaPoints)) { const leftLeg = { ...leg, to: syntheticEndpoint(leg.to, place), @@ -297,12 +304,50 @@ export function splitLegsAtViaPoints(originalLegs, viaPlaces) { } } splitLegs.push(leg); - if (leg.transitLeg && isViaPointMatch(leg.to.stop)) { + if (leg.transitLeg && isViaPointMatch(leg.to.stop, viaPoints)) { nextLegStartsWithIntermediate = true; } }); return splitLegs; } + +/** + * Mark via points to legs and possible intermediatePlaces in them. Once a via + * point is matched, it is not used again. Used for expanded view of the + * itinerary. + * + * @param originalLegs Leg objects from graphql query + * @param viaPlaces Location objects (otpToLocation) from query parameter + * @returns {*[]} + */ +export function markViaPoints(originalLegs, viaPlaces) { + const legs = []; + const viaPoints = viaPlaces.map(p => p.gtfsId); + originalLegs.forEach(leg => { + const isViaPoint = isViaPointMatch(leg.from.stop, viaPoints); + if (leg.intermediatePlaces) { + const intermediatePlaces = []; + leg.intermediatePlaces.forEach(place => { + intermediatePlaces.push({ + ...place, + isViaPoint: isViaPointMatch(place.stop, viaPoints), + }); + }); + legs.push({ + ...leg, + intermediatePlaces, + isViaPoint, + }); + } else { + legs.push({ + ...leg, + isViaPoint, + }); + } + }); + return legs; +} + /** * Compresses the incoming legs (affects only legs with mode BICYCLE, WALK or CITYBIKE). These are combined * so that the person will be walking their bicycle and there won't be multiple similar legs diff --git a/digitransit-component/packages/digitransit-component-autosuggest-panel/package.json b/digitransit-component/packages/digitransit-component-autosuggest-panel/package.json index b63ef30e10..83906a0c68 100644 --- a/digitransit-component/packages/digitransit-component-autosuggest-panel/package.json +++ b/digitransit-component/packages/digitransit-component-autosuggest-panel/package.json @@ -1,6 +1,6 @@ { "name": "@digitransit-component/digitransit-component-autosuggest-panel", - "version": "4.0.1", + "version": "4.0.2", "description": "digitransit-component autosuggest-panel module", "main": "index.js", "files": [ diff --git a/digitransit-component/packages/digitransit-component-autosuggest-panel/src/index.js b/digitransit-component/packages/digitransit-component-autosuggest-panel/src/index.js index 22b77f8e7c..e23723165f 100644 --- a/digitransit-component/packages/digitransit-component-autosuggest-panel/src/index.js +++ b/digitransit-component/packages/digitransit-component-autosuggest-panel/src/index.js @@ -521,6 +521,7 @@ class DTAutosuggestPanel extends React.Component { list={viaPoints} handle={`.${styles['viapoint-before']}`} animation={200} + disabled={viaPoints.length <= 1} setList={items => { const newViaPoints = items.filter(vp => !isViaPointEmpty(vp)); if (newViaPoints.length > 0) { @@ -537,9 +538,15 @@ class DTAutosuggestPanel extends React.Component {
1 ? { cursor: 'move' } : {}} > - + {viaPoints.length > 1 && ( + + )}
4, })} - enabled={showViapointControl} + enabled={showViapointControl && viaPoints.length === 0} onClick={() => this.handleAddViaPointClick()} onKeyPress={e => isKeyboardSelectionEvent(e) && this.handleAddViaPointClick() diff --git a/digitransit-component/packages/digitransit-component/package.json b/digitransit-component/packages/digitransit-component/package.json index fcd0eea585..2d37bc240e 100644 --- a/digitransit-component/packages/digitransit-component/package.json +++ b/digitransit-component/packages/digitransit-component/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@digitransit-component/digitransit-component-autosuggest": "^3.0.1", - "@digitransit-component/digitransit-component-autosuggest-panel": "^4.0.1", + "@digitransit-component/digitransit-component-autosuggest-panel": "^4.0.2", "@digitransit-component/digitransit-component-control-panel": "^2.0.0", "@digitransit-component/digitransit-component-favourite-bar": "2.0.5", "@digitransit-component/digitransit-component-favourite-editing-modal": "^2.0.2", diff --git a/yarn.lock b/yarn.lock index d8c2d7e8d6..e374c5bebb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1968,7 +1968,7 @@ __metadata: languageName: unknown linkType: soft -"@digitransit-component/digitransit-component-autosuggest-panel@^4.0.1, @digitransit-component/digitransit-component-autosuggest-panel@workspace:digitransit-component/packages/digitransit-component-autosuggest-panel": +"@digitransit-component/digitransit-component-autosuggest-panel@^4.0.2, @digitransit-component/digitransit-component-autosuggest-panel@workspace:digitransit-component/packages/digitransit-component-autosuggest-panel": version: 0.0.0-use.local resolution: "@digitransit-component/digitransit-component-autosuggest-panel@workspace:digitransit-component/packages/digitransit-component-autosuggest-panel" peerDependencies: @@ -2167,7 +2167,7 @@ __metadata: resolution: "@digitransit-component/digitransit-component@workspace:digitransit-component/packages/digitransit-component" dependencies: "@digitransit-component/digitransit-component-autosuggest": ^3.0.1 - "@digitransit-component/digitransit-component-autosuggest-panel": ^4.0.1 + "@digitransit-component/digitransit-component-autosuggest-panel": ^4.0.2 "@digitransit-component/digitransit-component-control-panel": ^2.0.0 "@digitransit-component/digitransit-component-favourite-bar": 2.0.5 "@digitransit-component/digitransit-component-favourite-editing-modal": ^2.0.2