From 51ca633c5bff37b0f5890348bea6882d98a41a29 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:10:02 -0400 Subject: [PATCH 1/8] fix(narrative-itineraries): Make sure leg alernateRoutes available on earliest itin. --- .../narrative/narrative-itineraries.js | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index 2f37581e1..aa78d24a1 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -44,11 +44,16 @@ import NarrativeItinerariesErrors from './narrative-itineraries-errors' import NarrativeItinerariesHeader from './narrative-itineraries-header' function doMergeItineraries(itineraries) { - const mergedItineraries = itineraries - .reduce((prev, cur, curIndex) => { + // Order itineraries by start time. + // This is because alternate routes are only added to the first non-duplicate itinerary, + // and we show alternate routes for the first (i.e. earliest) non-duplicate itinerary found. + const sortedItineraries = sortStartTimes([...itineraries]) + const mergedItineraries = sortedItineraries + .reduce((prev, cur) => { const updatedItineraries = clone(prev) const updatedItinerary = clone(cur) - updatedItinerary.index = curIndex + // Sorting itineraries above requires to find the index in the original array. + updatedItinerary.index = itineraries.indexOf(cur) const duplicateIndex = updatedItineraries.findIndex((itin) => itinerariesAreEqual(itin, cur) @@ -91,15 +96,16 @@ function doMergeItineraries(itineraries) { // This map catches those and stores the alternate routes so they can be displayed duplicateItin.legs = duplicateItin.legs.map((leg, index) => { const newLeg = clone(leg) - if (leg?.routeId !== cur.legs[index]?.routeId) { + const curLeg = cur.legs[index] + const curLegRouteId = curLeg?.routeId + if (curLegRouteId && leg?.routeId && leg?.routeId !== curLegRouteId) { if (!newLeg.alternateRoutes) { newLeg.alternateRoutes = {} } - const { routeId } = cur.legs?.[index] - newLeg.alternateRoutes[routeId] = { + newLeg.alternateRoutes[curLegRouteId] = { // We save the entire leg to the alternateRoutes object so in // the future, we can draw the leg on the map as an alternate route - ...cur.legs?.[index] + ...curLeg } } return newLeg From fb7f0be2473dc59455c098887d0d4fc3ca8ddd60 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:33:58 -0400 Subject: [PATCH 2/8] fix(create-otp-reducer): Unset the visible itin when setting the active itin. --- lib/reducers/create-otp-reducer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js index bc866f3ea..7b5f1f8e3 100644 --- a/lib/reducers/create-otp-reducer.js +++ b/lib/reducers/create-otp-reducer.js @@ -464,7 +464,8 @@ function createOtpReducer(config) { [state.activeSearchId]: { activeItinerary: { $set: action.payload.index }, activeLeg: { $set: null }, - activeStep: { $set: null } + activeStep: { $set: null }, + visibleItinerary: { $set: null } } } }) From 52ed414b5a4ad0d3033d566bfacc03336fdf3974 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:34:50 -0400 Subject: [PATCH 3/8] refactor(metro-itinerary): Remove unused import. --- lib/components/narrative/metro/metro-itinerary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/narrative/metro/metro-itinerary.tsx b/lib/components/narrative/metro/metro-itinerary.tsx index e86a593e3..274b8816c 100644 --- a/lib/components/narrative/metro/metro-itinerary.tsx +++ b/lib/components/narrative/metro/metro-itinerary.tsx @@ -28,7 +28,7 @@ import ItineraryBody from '../line-itin/connected-itinerary-body' import NarrativeItinerary from '../narrative-itinerary' import SimpleRealtimeAnnotation from '../simple-realtime-annotation' -import { getFirstTransitLegStop, getFlexAttirbutes } from './attribute-utils' +import { getFlexAttirbutes } from './attribute-utils' import DepartureTimesList, { SetActiveItineraryHandler } from './departure-times-list' From 841feb5977e50b636f723aac8db7441836b94c01 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:11:49 -0400 Subject: [PATCH 4/8] fix(narrative-itineraries): Find earliest itin of a group without pre-sorting itins This preserves the itinerary sort feature. --- .../narrative/narrative-itineraries.js | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index aa78d24a1..ee61416c9 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -44,16 +44,11 @@ import NarrativeItinerariesErrors from './narrative-itineraries-errors' import NarrativeItinerariesHeader from './narrative-itineraries-header' function doMergeItineraries(itineraries) { - // Order itineraries by start time. - // This is because alternate routes are only added to the first non-duplicate itinerary, - // and we show alternate routes for the first (i.e. earliest) non-duplicate itinerary found. - const sortedItineraries = sortStartTimes([...itineraries]) - const mergedItineraries = sortedItineraries - .reduce((prev, cur) => { + const mergedItineraries = itineraries + .reduce((prev, cur, curIndex) => { const updatedItineraries = clone(prev) const updatedItinerary = clone(cur) - // Sorting itineraries above requires to find the index in the original array. - updatedItinerary.index = itineraries.indexOf(cur) + updatedItinerary.index = curIndex const duplicateIndex = updatedItineraries.findIndex((itin) => itinerariesAreEqual(itin, cur) @@ -65,10 +60,23 @@ function doMergeItineraries(itineraries) { // Only process itineraries less than 24 hours in the future differenceInDays(updatedItinerary.startTime, Date.now()) < 1 ) { - const duplicateItin = updatedItineraries[duplicateIndex] + const duplicateFoundItin = updatedItineraries[duplicateIndex] // TODO: MERGE ROUTE NAMES - // Add only new start time to existing itinerary + // Add only new start time to existing itinerary. + // The existing itinerary is the earliest between + // this itinerary (updatedItinerary) and duplicateItin. + // This is because alternate routes are only added to the first non-duplicate itinerary, + // and we show alternate routes for the first (i.e. earliest) non-duplicate itinerary found. + let duplicateItin = duplicateFoundItin + let itinCopyToAdd = updatedItinerary + if (duplicateFoundItin.startTime > updatedItinerary.startTime) { + duplicateItin = updatedItinerary + duplicateItin.startTimes = duplicateFoundItin.allStartTimes + updatedItineraries[duplicateIndex] = updatedItinerary + itinCopyToAdd = duplicateFoundItin + } + if (!duplicateItin.allStartTimes) { duplicateItin.allStartTimes = [ { @@ -82,13 +90,14 @@ function doMergeItineraries(itineraries) { // the uniqueness feature of Set, but unfortunately objects are never equal if ( !duplicateItin.allStartTimes.find( - (time) => getFirstLegStartTime(time.legs) === cur.startTime + (time) => + getFirstLegStartTime(time.legs) === itinCopyToAdd.startTime ) ) { duplicateItin.allStartTimes.push({ - itinerary: updatedItinerary, - legs: cur.legs, - realtime: firstTransitLegIsRealtime(cur) + itinerary: itinCopyToAdd, + legs: itinCopyToAdd.legs, + realtime: firstTransitLegIsRealtime(itinCopyToAdd) }) } @@ -96,7 +105,7 @@ function doMergeItineraries(itineraries) { // This map catches those and stores the alternate routes so they can be displayed duplicateItin.legs = duplicateItin.legs.map((leg, index) => { const newLeg = clone(leg) - const curLeg = cur.legs[index] + const curLeg = itinCopyToAdd.legs[index] const curLegRouteId = curLeg?.routeId if (curLegRouteId && leg?.routeId && leg?.routeId !== curLegRouteId) { if (!newLeg.alternateRoutes) { From 2040a8fc7b08e49352fa973dd1669e5ac2564004 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:23:23 -0400 Subject: [PATCH 5/8] refactor(attribute-utils): Fix typo in flex function name. --- lib/components/narrative/metro/attribute-utils.tsx | 2 +- lib/components/narrative/metro/metro-itinerary.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/components/narrative/metro/attribute-utils.tsx b/lib/components/narrative/metro/attribute-utils.tsx index 36a12b90b..c48afd0c8 100644 --- a/lib/components/narrative/metro/attribute-utils.tsx +++ b/lib/components/narrative/metro/attribute-utils.tsx @@ -9,7 +9,7 @@ export const getFirstTransitLegStop = ( itinerary.legs?.find((leg: Leg) => leg?.from?.vertexType === 'TRANSIT')?.from ?.name -export const getFlexAttirbutes = ( +export const getFlexAttributes = ( itinerary: Itinerary ): { isCallAhead: boolean diff --git a/lib/components/narrative/metro/metro-itinerary.tsx b/lib/components/narrative/metro/metro-itinerary.tsx index 274b8816c..26ffa98a6 100644 --- a/lib/components/narrative/metro/metro-itinerary.tsx +++ b/lib/components/narrative/metro/metro-itinerary.tsx @@ -28,7 +28,7 @@ import ItineraryBody from '../line-itin/connected-itinerary-body' import NarrativeItinerary from '../narrative-itinerary' import SimpleRealtimeAnnotation from '../simple-realtime-annotation' -import { getFlexAttirbutes } from './attribute-utils' +import { getFlexAttributes } from './attribute-utils' import DepartureTimesList, { SetActiveItineraryHandler } from './departure-times-list' @@ -266,7 +266,7 @@ class MetroItinerary extends NarrativeItinerary { const { SvgIcon } = this.context const { isCallAhead, isContinuousDropoff, isFlexItinerary, phone } = - getFlexAttirbutes(itinerary) + getFlexAttributes(itinerary) const { fareCurrency, transitFare } = getFare(itinerary, defaultFareType) From 370dadf3c9999a2ec9ce3a7d724837090bf9b3ad Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 23 Aug 2023 16:30:38 -0400 Subject: [PATCH 6/8] refactor(narrative-itineraries): Extract makeStartTime method. --- .../narrative/narrative-itineraries.js | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index ee61416c9..d5a7b0f2f 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -43,6 +43,15 @@ import Loading from './loading' import NarrativeItinerariesErrors from './narrative-itineraries-errors' import NarrativeItinerariesHeader from './narrative-itineraries-header' +/** Creates a start time object for the given itinerary. */ +function makeStartTime(itinerary) { + return { + itinerary, + legs: itinerary.legs, + realtime: firstTransitLegIsRealtime(itinerary) + } +} + function doMergeItineraries(itineraries) { const mergedItineraries = itineraries .reduce((prev, cur, curIndex) => { @@ -78,13 +87,7 @@ function doMergeItineraries(itineraries) { } if (!duplicateItin.allStartTimes) { - duplicateItin.allStartTimes = [ - { - itinerary: duplicateItin, - legs: duplicateItin.legs, - realtime: firstTransitLegIsRealtime(duplicateItin) - } - ] + duplicateItin.allStartTimes = [makeStartTime(duplicateItin)] } // Only add new time if it doesn't already exist. It would be better to use // the uniqueness feature of Set, but unfortunately objects are never equal @@ -94,11 +97,7 @@ function doMergeItineraries(itineraries) { getFirstLegStartTime(time.legs) === itinCopyToAdd.startTime ) ) { - duplicateItin.allStartTimes.push({ - itinerary: itinCopyToAdd, - legs: itinCopyToAdd.legs, - realtime: firstTransitLegIsRealtime(itinCopyToAdd) - }) + duplicateItin.allStartTimes.push(makeStartTime(itinCopyToAdd)) } // Some legs will be the same, but have a different route From 257cac2f40ce5533e1d11b34c5efe731b4f16372 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:17:12 -0400 Subject: [PATCH 7/8] fix(metro-itinerary): Display all routes in dashed lines on mouse leave. --- lib/components/narrative/metro/metro-itinerary.tsx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/components/narrative/metro/metro-itinerary.tsx b/lib/components/narrative/metro/metro-itinerary.tsx index 26ffa98a6..4e65c966d 100644 --- a/lib/components/narrative/metro/metro-itinerary.tsx +++ b/lib/components/narrative/metro/metro-itinerary.tsx @@ -202,23 +202,17 @@ class MetroItinerary extends NarrativeItinerary { static ModesAndRoutes = MetroItineraryRoutes _onMouseEnter = () => { - const { active, index, setVisibleItinerary, visibleItinerary } = this.props + const { active, index, setVisibleItinerary, visible } = this.props // Set this itinerary as visible if not already visible. - const visibleNotSet = - visibleItinerary === null || visibleItinerary === undefined - const isVisible = - visibleItinerary === index || (active === index && visibleNotSet) + const isVisible = visible || active === index if (typeof setVisibleItinerary === 'function' && !isVisible) { setVisibleItinerary({ index }) } } _onMouseLeave = () => { - const { index, setVisibleItinerary, visibleItinerary } = this.props - if ( - typeof setVisibleItinerary === 'function' && - visibleItinerary === index - ) { + const { setVisibleItinerary, visible } = this.props + if (typeof setVisibleItinerary === 'function' && visible) { setVisibleItinerary({ index: null }) } } From 91055c878240cf7c722e8cd97e72bc4fcdfdace6 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 29 Aug 2023 09:51:28 -0400 Subject: [PATCH 8/8] refactor(metro-itinerary): Update interpretation of active. --- lib/components/narrative/metro/metro-itinerary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/components/narrative/metro/metro-itinerary.tsx b/lib/components/narrative/metro/metro-itinerary.tsx index 4e65c966d..cbd0f7194 100644 --- a/lib/components/narrative/metro/metro-itinerary.tsx +++ b/lib/components/narrative/metro/metro-itinerary.tsx @@ -204,7 +204,7 @@ class MetroItinerary extends NarrativeItinerary { _onMouseEnter = () => { const { active, index, setVisibleItinerary, visible } = this.props // Set this itinerary as visible if not already visible. - const isVisible = visible || active === index + const isVisible = visible || active if (typeof setVisibleItinerary === 'function' && !isVisible) { setVisibleItinerary({ index }) }