diff --git a/i18n/en-US.yml b/i18n/en-US.yml index 2bdc3c2df..19ccbedb5 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -377,6 +377,7 @@ components: selectCost: Cost selectDepartureTime: Departure time selectDuration: Duration + selectFare: Transit fare selectWalkTime: Walk time sortResults: Sort results viewAll: View all options diff --git a/lib/components/util/sortOptions.ts b/lib/components/util/sortOptions.ts index 54ac217d3..f71cf479e 100644 --- a/lib/components/util/sortOptions.ts +++ b/lib/components/util/sortOptions.ts @@ -12,7 +12,8 @@ export const sortOptions = ( 'ARRIVALTIME', 'WALKTIME', 'COST', - 'DEPARTURETIME' + 'DEPARTURETIME', + 'FARE' ] ): SortOptionEntry[] => { const sortOptionsArray: SortOptionEntry[] = [ @@ -51,6 +52,12 @@ export const sortOptions = ( id: 'components.NarrativeItinerariesHeader.selectCost' }), value: 'COST' + }, + { + text: intl.formatMessage({ + id: 'components.NarrativeItinerariesHeader.selectFare' + }), + value: 'FARE' } ] diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index ed70eda01..dc94a3b51 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -264,6 +264,7 @@ export type ItinerarySortOption = | 'WALKTIME' | 'COST' | 'DEPARTURETIME' + | 'FARE' export interface ItineraryCostWeights { driveReluctance: number diff --git a/lib/util/itinerary.tsx b/lib/util/itinerary.tsx index 1ac8cd142..1e355a481 100644 --- a/lib/util/itinerary.tsx +++ b/lib/util/itinerary.tsx @@ -48,6 +48,7 @@ export interface ItineraryWithCO2Info extends Itinerary { export interface ItineraryWithSortingCosts extends Itinerary { rank: number totalFare: number + transitFare?: number } export interface ItineraryFareSummary { @@ -453,10 +454,12 @@ export function addSortingCosts( totalFareResult === null ? Number.MAX_VALUE : totalFareResult const rank = calculateItineraryCost(itinerary, config) + const transitFare = getFare(itinerary).transitFare return { ...itinerary, rank, - totalFare + totalFare, + transitFare } } diff --git a/lib/util/state.js b/lib/util/state.js index 1d31785ce..c3b436042 100644 --- a/lib/util/state.js +++ b/lib/util/state.js @@ -33,6 +33,16 @@ export function getActiveSearch(state) { return state.otp.searches[state.otp.activeSearchId] } +function compareItineraryFare(a, b) { + // If both fares are not defined, they are equal. + if (a === undefined && b === undefined) return 0 + // If one fare is not defined, the other is greater. + if (a === undefined) return 1 + if (b === undefined) return -1 + // If both fares are defined, compare them. + return a - b +} + /** * Array sort function for itineraries (in batch routing context) that attempts * to sort based on the type/direction specified. @@ -50,6 +60,8 @@ export function sortItineraries(type, direction, a, b, config) { return dirFactor * (a.duration - b.duration) case 'COST': return dirFactor * (a.totalFare - b.totalFare) + case 'FARE': + return dirFactor * compareItineraryFare(a.transitFare, b.transitFare) default: if (type !== 'BEST') console.warn(`Sort (${type}) not supported. Defaulting to BEST.`)