digitransit-ui/app/component/AlertList.js
Vesa Meskanen 2e0f247550 fix: close disruption modal when user clicks a link
User will then see the linked stop/route view.
2024-06-24 14:48:53 +03:00

140 lines
3.9 KiB
JavaScript

/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
import cx from 'classnames';
import connectToStores from 'fluxible-addons-react/connectToStores';
import PropTypes from 'prop-types';
import React from 'react';
import { FormattedMessage } from 'react-intl';
import AlertRow from './AlertRow';
import {
alertCompare,
getEntitiesOfType,
isAlertValid,
} from '../util/alertUtils';
import { alertShape } from '../util/shapes';
import withBreakpoint from '../util/withBreakpoint';
import { AlertEntityType, AlertSeverityLevelType } from '../constants';
const AlertList = ({
cancelations,
currentTime,
disableScrolling,
serviceAlerts,
showLinks,
breakpoint,
onClickLink,
}) => {
const validAlerts = serviceAlerts.filter(alert =>
isAlertValid(alert, currentTime),
);
const validCancelations = cancelations.filter(cancelation =>
isAlertValid(cancelation, currentTime),
);
if (validAlerts.length === 0 && validCancelations.length === 0) {
return (
<div className="no-alerts-container" tabIndex="0" aria-live="polite">
<FormattedMessage
id="disruption-info-no-alerts"
defaultMessage="No known disruptions or diversions."
/>
</div>
);
}
// Cancelations should be between non-info alerts and info alerts
const alertsSorted = [
...validAlerts
.filter(alert => alert.alertSeverityLevel !== AlertSeverityLevelType.Info)
.sort(alertCompare),
...validCancelations.sort(alertCompare),
...validAlerts
.filter(alert => alert.alertSeverityLevel === AlertSeverityLevelType.Info)
.sort(alertCompare),
];
return (
<div className="alerts-content-wrapper">
<div
className={cx('alerts-list-wrapper', {
'bp-large': breakpoint === 'large',
})}
aria-live="polite"
>
<div
className={cx('alerts-list', {
'momentum-scroll': !disableScrolling,
})}
>
{alertsSorted.map(
(
{
alertDescriptionText,
alertHeaderText,
entities,
alertSeverityLevel,
alertUrl,
effectiveStartDate,
effectiveEndDate,
feed,
},
i,
) => {
const entityType =
getEntitiesOfType(entities, AlertEntityType.Stop).length > 0
? 'stop'
: 'route';
return (
<AlertRow
currentTime={currentTime}
description={alertDescriptionText}
endTime={effectiveEndDate}
entities={entities}
feed={feed}
header={alertHeaderText}
// eslint-disable-next-line react/no-array-index-key
key={`alert-${entityType}-${alertSeverityLevel}-${i}`}
severityLevel={alertSeverityLevel}
showLinks={showLinks}
startTime={effectiveStartDate}
url={alertUrl}
index={i}
onClickLink={onClickLink}
/>
);
},
)}
</div>
</div>
</div>
);
};
AlertList.propTypes = {
cancelations: PropTypes.arrayOf(alertShape),
currentTime: PropTypes.PropTypes.number.isRequired,
disableScrolling: PropTypes.bool,
serviceAlerts: PropTypes.arrayOf(alertShape),
showLinks: PropTypes.bool,
breakpoint: PropTypes.string,
onClickLink: PropTypes.func,
};
AlertList.defaultProps = {
cancelations: [],
disableScrolling: false,
serviceAlerts: [],
showLinks: false,
breakpoint: undefined,
onClickLink: undefined,
};
const connectedComponent = connectToStores(
withBreakpoint(AlertList),
['TimeStore', 'PreferencesStore'],
context => ({
currentTime: context.getStore('TimeStore').getCurrentTime(),
}),
);
export { connectedComponent as default, AlertList as Component };