Skip to content

Commit

Permalink
Merge pull request #2810 from HSLdevcom/DT-3029
Browse files Browse the repository at this point in the history
DT-3029: info icon for service alerts
  • Loading branch information
vesameskanen authored May 29, 2019
2 parents 482f773 + 4c53826 commit 40b4c31
Show file tree
Hide file tree
Showing 40 changed files with 1,115 additions and 338 deletions.
38 changes: 22 additions & 16 deletions app/component/AlertList.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ const AlertList = ({
showExpired,
serviceAlerts,
}) => {
const currentTimeUnix = currentTime.unix ? currentTime.unix() : currentTime;

const getRoute = alert => alert.route || {};
const getMode = alert => getRoute(alert).mode;
const getShortName = alert => getRoute(alert).shortName;
Expand All @@ -55,16 +53,24 @@ const AlertList = ({

const uniqueAlerts = uniqBy(
[
...(Array.isArray(cancelations) ? cancelations : []),
...(Array.isArray(serviceAlerts) ? serviceAlerts : []),
...(Array.isArray(cancelations)
? cancelations.map(cancelation => ({
...cancelation,
severityLevel: AlertSeverityLevelType.Warning,
expired: !isAlertValid(cancelation, currentTime, {
isFutureValid: true,
}),
}))
: []),
...(Array.isArray(serviceAlerts)
? serviceAlerts.map(alert => ({
...alert,
expired: !isAlertValid(alert, currentTime),
}))
: []),
],
getUniqueId,
)
.map(alert => ({
...alert,
expired: !isAlertValid(alert, currentTimeUnix),
}))
.filter(alert => (showExpired ? true : !alert.expired));
).filter(alert => (showExpired ? true : !alert.expired));

if (uniqueAlerts.length === 0) {
return (
Expand Down Expand Up @@ -112,7 +118,7 @@ const AlertList = ({
) => (
<RouteAlertsRow
color={color ? `#${color}` : null}
currentTime={currentTimeUnix}
currentTime={currentTime}
description={description}
endTime={endTime}
expired={expired}
Expand Down Expand Up @@ -148,10 +154,7 @@ const alertShape = PropTypes.shape({
});

AlertList.propTypes = {
currentTime: PropTypes.oneOfType([
PropTypes.shape({ unix: PropTypes.func.isRequired }),
PropTypes.number,
]).isRequired,
currentTime: PropTypes.PropTypes.number.isRequired,
cancelations: PropTypes.arrayOf(alertShape),
serviceAlerts: PropTypes.arrayOf(alertShape),
showExpired: PropTypes.bool,
Expand Down Expand Up @@ -275,7 +278,10 @@ const connectedComponent = connectToStores(
AlertList,
['TimeStore'],
context => ({
currentTime: context.getStore('TimeStore').getCurrentTime(),
currentTime: context
.getStore('TimeStore')
.getCurrentTime()
.unix(),
}),
);

Expand Down
1 change: 0 additions & 1 deletion app/component/BicycleRentalStationRowContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ const BicycleRentalStationRow = ({ distance, station }, { config, intl }) => {
icon={isOff ? `${networkIcon}_off` : networkIcon}
mode={isOff ? 'citybike_off' : 'citybike'}
text={station.stationId}
hasDisruption={false}
/>
</td>
<td className="td-bikestation" colSpan="1">
Expand Down
7 changes: 4 additions & 3 deletions app/component/Departure.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import {
} from './ExampleData';

function Departure({
alertSeverityLevel,
canceled,
className,
currentTime,
departure,
hasDisruption,
isArrival,
isLastStop,
showPlatformCode,
Expand All @@ -47,8 +47,8 @@ function Departure({
/>
)}
<RouteNumberContainer
alertSeverityLevel={alertSeverityLevel}
route={departure.pattern.route}
hasDisruption={hasDisruption}
isCallAgency={isCallAgencyDeparture(departure)}
fadeLong
/>
Expand Down Expand Up @@ -127,9 +127,9 @@ Departure.description = () => (
Departure.displayName = 'Departure';

Departure.propTypes = {
alertSeverityLevel: PropTypes.string,
canceled: PropTypes.bool,
className: PropTypes.string,
hasDisruption: PropTypes.bool,
currentTime: PropTypes.number.isRequired,
departure: PropTypes.shape({
headsign: PropTypes.string,
Expand All @@ -155,6 +155,7 @@ Departure.propTypes = {
};

Departure.defaultProps = {
alertSeverityLevel: undefined,
showPlatformCode: false,
};

Expand Down
61 changes: 36 additions & 25 deletions app/component/DepartureListContainer.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import cx from 'classnames';
import get from 'lodash/get';
import moment from 'moment';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Relay from 'react-relay/classic';
import filter from 'lodash/filter';
import moment from 'moment';
import { Link } from 'react-router';
import cx from 'classnames';

import Departure from './Departure';
import { RouteAlertsQuery } from '../util/alertQueries';
import {
getActiveAlertSeverityLevel,
patternIdPredicate,
} from '../util/alertUtils';
import { isBrowser } from '../util/browser';
import { PREFIX_ROUTES } from '../util/path';

const hasActiveDisruption = (t, alerts) =>
filter(
alerts,
alert => alert.effectiveStartDate < t && t < alert.effectiveEndDate,
).length > 0;

const asDepartures = stoptimes =>
!stoptimes
? []
Expand All @@ -39,14 +39,18 @@ const asDepartures = stoptimes =>
: stoptime.scheduledDeparture);
const stoptimeTime = isArrival ? arrivalTime : departureTime;

const { pattern } = stoptime.trip;
return {
alerts: get(pattern, 'route.alerts', []).filter(alert =>
patternIdPredicate(alert, get(pattern, 'code', undefined)),
),
canceled,
isArrival,
isLastStop,
stoptime: stoptimeTime,
stop: stoptime.stop,
realtime: stoptime.realtime,
pattern: stoptime.trip.pattern,
pattern,
headsign: stoptime.stopHeadsign,
trip: stoptime.trip,
pickupType: stoptime.pickupType,
Expand Down Expand Up @@ -80,7 +84,8 @@ class DepartureListContainer extends Component {

render() {
const departureObjs = [];
const { currentTime } = this.props;
const { currentTime, limit, isTerminal, stoptimes } = this.props;

let currentDate = moment
.unix(currentTime)
.startOf('day')
Expand All @@ -91,10 +96,10 @@ class DepartureListContainer extends Component {
.startOf('day')
.unix();

const departures = asDepartures(this.props.stoptimes)
.filter(departure => !(this.props.isTerminal && departure.isArrival))
const departures = asDepartures(stoptimes)
.filter(departure => !(isTerminal && departure.isArrival))
.filter(departure => currentTime < departure.stoptime)
.slice(0, this.props.limit);
.slice(0, limit);

departures.forEach(departure => {
if (departure.stoptime >= tomorrow) {
Expand All @@ -117,18 +122,21 @@ class DepartureListContainer extends Component {

const id = `${departure.pattern.code}:${departure.stoptime}`;

const classes = {
disruption: hasActiveDisruption(departure.stoptime, departure.alerts),
};

const alertSeverityLevel = getActiveAlertSeverityLevel(
departure.alerts,
currentTime,
);
const departureObj = (
<Departure
alertSeverityLevel={alertSeverityLevel}
key={id}
departure={departure}
showStop={this.props.showStops}
currentTime={currentTime}
hasDisruption={classes.disruption}
className={cx(classes, this.props.rowClasses)}
className={cx(
{ disruption: !!alertSeverityLevel },
this.props.rowClasses,
)}
canceled={departure.canceled}
isArrival={departure.isArrival}
isLastStop={departure.isLastStop}
Expand Down Expand Up @@ -163,7 +171,7 @@ class DepartureListContainer extends Component {
}
}

export default Relay.createContainer(DepartureListContainer, {
const containerComponent = Relay.createContainer(DepartureListContainer, {
fragments: {
stoptimes: () => Relay.QL`
fragment on Stoptime @relay(plural:true) {
Expand All @@ -182,10 +190,6 @@ export default Relay.createContainer(DepartureListContainer, {
platformCode
}
trip {
alerts {
effectiveStartDate
effectiveEndDate
}
gtfsId
tripHeadsign
stops {
Expand All @@ -201,6 +205,7 @@ export default Relay.createContainer(DepartureListContainer, {
agency {
name
}
${RouteAlertsQuery}
}
code
}
Expand All @@ -209,3 +214,9 @@ export default Relay.createContainer(DepartureListContainer, {
`,
},
});

export {
containerComponent as default,
DepartureListContainer as Component,
asDepartures,
};
44 changes: 28 additions & 16 deletions app/component/FavouriteRouteListContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import Relay from 'react-relay/classic';
import connectToStores from 'fluxible-addons-react/connectToStores';

import NextDeparturesList from './NextDeparturesList';
import { RouteAlertsQuery } from '../util/alertQueries';
import {
getActiveAlertSeverityLevel,
patternIdPredicate,
} from '../util/alertUtils';
import { getDistanceToNearestStop } from '../util/geo-utils';

export const getNextDepartures = (routes, lat, lon) => {
export const getNextDepartures = (routes, lat, lon, currentTime) => {
const nextDepartures = [];
const seenDepartures = {};

Expand All @@ -13,9 +18,14 @@ export const getNextDepartures = (routes, lat, lon) => {
return;
}

const hasDisruption = route.alerts.length > 0;

route.patterns.forEach(pattern => {
const patternAlerts =
Array.isArray(route.alerts) &&
route.alerts.filter(alert => patternIdPredicate(alert, pattern.code));
const alertSeverityLevel = getActiveAlertSeverityLevel(
patternAlerts || [],
currentTime,
);
const closest = getDistanceToNearestStop(lat, lon, pattern.stops);
closest.stop.stoptimes
.filter(stoptime => {
Expand All @@ -35,9 +45,9 @@ export const getNextDepartures = (routes, lat, lon) => {
})
.forEach(stoptime => {
nextDepartures.push({
alertSeverityLevel,
distance: closest.distance,
stoptime,
hasDisruption,
});
});
});
Expand All @@ -50,23 +60,29 @@ export const getNextDepartures = (routes, lat, lon) => {
const FavouriteRouteListContainer = connectToStores(
NextDeparturesList,
['TimeStore'],
(context, { routes, origin }) => ({
currentTime: context
(context, { routes, origin }) => {
const currentTime = context
.getStore('TimeStore')
.getCurrentTime()
.unix(),
departures: getNextDepartures(routes, origin.lat, origin.lon),
}),
.unix();
return {
currentTime,
departures: getNextDepartures(
routes,
origin.lat,
origin.lon,
currentTime,
),
};
},
);

// TODO: Add filtering in stoptimesForPatterns for route gtfsId
export default Relay.createContainer(FavouriteRouteListContainer, {
fragments: {
routes: () => Relay.QL`
fragment on Route @relay(plural:true) {
alerts {
id
}
${RouteAlertsQuery}
patterns {
headsign
stops {
Expand All @@ -92,10 +108,6 @@ export default Relay.createContainer(FavouriteRouteListContainer, {
realtime
serviceDay
}
pattern {
headsign
route { gtfsId }
}
}
}
}
Expand Down
11 changes: 8 additions & 3 deletions app/component/FavouritesTabLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import Icon from './Icon';
import IconWithCaution from './IconWithCaution';

export default function FavouritesTabLabel({
hasDisruption,
alertSeverityLevel,
classes,
onClick,
}) {
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role, jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events
<li className={classes} onClick={onClick} role="button">
{hasDisruption ? (
{alertSeverityLevel ? (
<IconWithCaution
alertSeverityLevel={alertSeverityLevel}
className="prefix-icon favourites-icon"
img="icon-icon_star"
/>
Expand All @@ -26,7 +27,11 @@ export default function FavouritesTabLabel({
}

FavouritesTabLabel.propTypes = {
hasDisruption: PropTypes.bool,
alertSeverityLevel: PropTypes.string,
classes: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
};

FavouritesTabLabel.defaultProps = {
alertSeverityLevel: undefined,
};
Loading

0 comments on commit 40b4c31

Please sign in to comment.