mirror of
https://github.com/HSLdevcom/digitransit-ui
synced 2025-07-07 19:30:41 +02:00
193 lines
6.6 KiB
JavaScript
193 lines
6.6 KiB
JavaScript
/* eslint-disable no-bitwise */
|
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
/* eslint-disable func-names */
|
|
/* eslint-disable no-param-reassign */
|
|
/* eslint-disable prefer-destructuring */
|
|
import dayRangeAllowedDiff from '@digitransit-util/digitransit-util-day-range-allowed-diff';
|
|
import cloneDeep from 'lodash/cloneDeep';
|
|
import { DateTime } from 'luxon';
|
|
|
|
const DATE_FORMAT = 'yyyyLLdd';
|
|
|
|
/**
|
|
* <DESCRIPTION>
|
|
*
|
|
* @name enrichPatterns
|
|
* @param {object} patterns Array of patterns (result from GraphiQL query)
|
|
* @param {boolean} onlyInFuture Is filtered out today's past trips
|
|
* @param {number} serviceTimeRange How many days shows in UI
|
|
* @returns {Object} enriched pattern
|
|
* @example
|
|
* digitransit-util.enrichPatterns([ { code: 'HSL:3002U:0:02', headsign: 'Kirkkonummi', stops: [{ name: 'Helsinki' }, { name: 'Kirkkonummi' }], tripsForDate: [], activeDates: [{ "day": [ "20200329" ] },{ "day": [ "20200329" ] },{ "day": [ "20200329" ] }, { "day": [ "20200329" ] }] } ], true, 30);
|
|
* //=[ { code: 'HSL:3002U:0:02', headsign: 'Kirkkonummi', stops: [{ name: 'Helsinki' }, { name: 'Kirkkonummi' }], tripsForDate: [], activeDates: ["20200221","20200222","20200228","20200229"], } ]
|
|
*/
|
|
|
|
function makeHash(s) {
|
|
return s.split('').reduce(function (a, b) {
|
|
a = (a << 5) - a + b.charCodeAt(0);
|
|
return a & a;
|
|
}, 0);
|
|
}
|
|
|
|
export default function enrichPatterns(
|
|
patterns,
|
|
onlyInFuture,
|
|
serviceTimeRange,
|
|
) {
|
|
const currentDate = DateTime.now();
|
|
const lastRangeDate = DateTime.now().plus({ days: serviceTimeRange });
|
|
|
|
let futureTrips = cloneDeep(patterns);
|
|
futureTrips.forEach(function (x) {
|
|
if (x.tripsForDate !== undefined) {
|
|
x.tripsForDate = x.tripsForDate.filter(s => s.stoptimes.length > 0);
|
|
x.countTripsForDate = x.tripsForDate.length;
|
|
} else {
|
|
x.tripsForDate = [];
|
|
x.countTripsForDate = 0;
|
|
}
|
|
const uniqueDates = [];
|
|
if (x.activeDates !== undefined) {
|
|
x.activeDates.forEach(function (a) {
|
|
a.day.forEach(function (b) {
|
|
uniqueDates.push(b);
|
|
});
|
|
});
|
|
} else {
|
|
x.activeDates = [];
|
|
}
|
|
x.activeDates = Array.from(new Set(uniqueDates.sort()));
|
|
if (
|
|
x.activeDates.length === 1 &&
|
|
DateTime.fromFormat(x.activeDates[0], DATE_FORMAT) > lastRangeDate
|
|
) {
|
|
x.activeDates = [];
|
|
}
|
|
if (x.stops) {
|
|
const stopNames = x.stops.map(s => s.name);
|
|
x.stopsHash = makeHash(stopNames.join(','));
|
|
}
|
|
});
|
|
|
|
futureTrips = futureTrips.filter(
|
|
f => f.tripsForDate.length > 0 || f.activeDates.length > 0,
|
|
);
|
|
|
|
for (let y = 0; y < futureTrips.length; y++) {
|
|
const actDates = [];
|
|
const dayNumbers = [];
|
|
const minAndMaxDate = [];
|
|
const dayDiff = [];
|
|
const rangeFollowingDays = [];
|
|
futureTrips[y].activeDates.forEach(function diffBetween(item, index, arr) {
|
|
if (!actDates.includes[item]) {
|
|
actDates.push(item);
|
|
}
|
|
const itemDate = DateTime.fromFormat(arr[index], DATE_FORMAT);
|
|
if (index === 0) {
|
|
dayDiff.push(0);
|
|
rangeFollowingDays.push([itemDate.toFormat(DATE_FORMAT), 0]);
|
|
minAndMaxDate[0] = itemDate.toFormat(DATE_FORMAT);
|
|
minAndMaxDate[1] = itemDate.toFormat(DATE_FORMAT);
|
|
} else {
|
|
if (Number(itemDate.toFormat(DATE_FORMAT) < Number(minAndMaxDate[0]))) {
|
|
minAndMaxDate[0] = itemDate.toFormat(DATE_FORMAT);
|
|
}
|
|
if (Number(itemDate.toFormat(DATE_FORMAT) > Number(minAndMaxDate[1]))) {
|
|
minAndMaxDate[1] = itemDate.toFormat(DATE_FORMAT);
|
|
}
|
|
}
|
|
|
|
dayNumbers.push(itemDate.weekday);
|
|
if (arr[index + 1]) {
|
|
const diff = DateTime.fromFormat(arr[index + 1], DATE_FORMAT).diff(
|
|
itemDate,
|
|
'days',
|
|
).days;
|
|
if (diff !== 1) {
|
|
rangeFollowingDays[rangeFollowingDays.length - 1][1] = arr[index];
|
|
rangeFollowingDays.push([arr[index + 1], 0]);
|
|
}
|
|
dayDiff.push(diff);
|
|
}
|
|
|
|
if (index + 1 === dayDiff.length && dayDiff[index] === 1) {
|
|
rangeFollowingDays[rangeFollowingDays.length - 1][1] = arr[index];
|
|
}
|
|
});
|
|
|
|
futureTrips[y].currentDate = currentDate.toFormat(DATE_FORMAT);
|
|
futureTrips[y].lastRangeDate = lastRangeDate.toFormat(DATE_FORMAT);
|
|
futureTrips[y].rangeFollowingDays = rangeFollowingDays;
|
|
futureTrips[y].dayDiff = dayDiff;
|
|
futureTrips[y].activeDates = Array.from(new Set(actDates.sort()));
|
|
futureTrips[y].allowedDiff = dayRangeAllowedDiff(
|
|
dayNumbers,
|
|
currentDate.weekday,
|
|
);
|
|
|
|
if (
|
|
futureTrips[y].rangeFollowingDays.length === 1 &&
|
|
(futureTrips[y].rangeFollowingDays[0][0] ===
|
|
futureTrips[y].rangeFollowingDays[0][1] ||
|
|
futureTrips[y].rangeFollowingDays[0][1] === 0)
|
|
) {
|
|
futureTrips[y].fromDate = futureTrips[y].rangeFollowingDays[0][0];
|
|
futureTrips[y].untilDate = futureTrips[y].rangeFollowingDays[0][0];
|
|
futureTrips[y].rangeFollowingDays[0][1] = 0;
|
|
} else if (
|
|
futureTrips[y].rangeFollowingDays.length === 1 &&
|
|
futureTrips[y].rangeFollowingDays[0][0] !==
|
|
futureTrips[y].rangeFollowingDays[0][1]
|
|
) {
|
|
if (DateTime.fromFormat(minAndMaxDate[0], DATE_FORMAT) > currentDate) {
|
|
futureTrips[y].fromDate = futureTrips[y].rangeFollowingDays[0][0];
|
|
} else {
|
|
futureTrips[y].fromDate = '-';
|
|
}
|
|
if (
|
|
DateTime.fromFormat(
|
|
futureTrips[y].rangeFollowingDays[0][1],
|
|
DATE_FORMAT,
|
|
) < lastRangeDate
|
|
) {
|
|
futureTrips[y].untilDate = futureTrips[y].rangeFollowingDays[0][1];
|
|
} else {
|
|
futureTrips[y].untilDate = '-';
|
|
}
|
|
} else {
|
|
futureTrips[y].fromDate =
|
|
DateTime.fromFormat(minAndMaxDate[0], DATE_FORMAT).minus({
|
|
days: futureTrips[y].allowedDiff,
|
|
}) >= currentDate
|
|
? `${minAndMaxDate[0]}`
|
|
: '-';
|
|
futureTrips[y].untilDate =
|
|
DateTime.fromFormat(minAndMaxDate[1], DATE_FORMAT) < lastRangeDate
|
|
? `${minAndMaxDate[1]}`
|
|
: '-';
|
|
}
|
|
|
|
futureTrips[y].activeDates = futureTrips[y].activeDates.filter(
|
|
ad => DateTime.fromFormat(ad, DATE_FORMAT) >= currentDate === true,
|
|
);
|
|
|
|
futureTrips[y].minAndMaxDate = minAndMaxDate;
|
|
futureTrips[y].inFuture =
|
|
DateTime.now().startOf('week') <
|
|
DateTime.fromFormat(futureTrips[y].minAndMaxDate[0], DATE_FORMAT).startOf(
|
|
'week',
|
|
);
|
|
}
|
|
|
|
futureTrips = futureTrips.filter(
|
|
f => f.tripsForDate.length > 0 || f.activeDates.length > 0,
|
|
);
|
|
|
|
// DT-2531: shows main routes (both directions) if there is no futureTrips
|
|
if (futureTrips.length === 0 && patterns.length > 0) {
|
|
futureTrips = patterns.filter(p => p.code.endsWith(':01'));
|
|
}
|
|
|
|
return futureTrips;
|
|
}
|