Skip to content

Commit 4982d5f

Browse files
committed
Merge branch 'next' into snackbar-refactoring
2 parents f5fccdd + f11704f commit 4982d5f

File tree

326 files changed

+17933
-11423
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

326 files changed

+17933
-11423
lines changed

app/action/ViaPointActions.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ export function addViaPoint(actionContext, val) {
55
export function setViaPoints(actionContext, points) {
66
actionContext.dispatch('setViaPoints', points);
77
}
8+
9+
export function deleteViaPoint(actionContext, val) {
10+
actionContext.dispatch('deleteViaPoint', val);
11+
}

app/component/AppBar.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { matchShape } from 'found';
55
import { userShape, configShape } from '../util/shapes';
66
import Icon from './Icon';
77
import { addAnalyticsEvent } from '../util/analyticsUtils';
8-
import DisruptionInfo from './DisruptionInfo';
98
import MainMenuContainer from './MainMenuContainer';
109
import MessageBar from './MessageBar';
1110
import LogoSmall from './LogoSmall';
@@ -17,7 +16,6 @@ export default function AppBar(
1716
{ config, intl, match, getStore },
1817
) {
1918
const { location } = match;
20-
const [disruptionInfoOpen, setDisruptionInfoOpen] = useState(false);
2119
const [menuOpen, setMenuOpen] = useState(
2220
window.sessionStorage.menuOpen === 'true',
2321
);
@@ -35,14 +33,8 @@ export default function AppBar(
3533
setMenuOpen(newState);
3634
};
3735

38-
const toggleDisruptionInfo = newState => {
39-
setDisruptionInfoOpen(newState);
40-
setMenuOpen(false);
41-
};
42-
4336
return (
4437
<>
45-
{disruptionInfoOpen && <DisruptionInfo setOpen={toggleDisruptionInfo} />}
4638
{config.NODE_ENV !== 'test' && <MessageBar breakpoint={breakpoint} />}
4739
<nav className={`top-bar ${breakpoint !== 'large' ? 'mobile' : ''}`}>
4840
<section className="title">
@@ -86,12 +78,11 @@ export default function AppBar(
8678
isMobile
8779
/>
8880
))}
89-
{!disruptionInfoOpen && menuOpen && (
81+
{menuOpen && (
9082
<MainMenuContainer
9183
homeUrl={homeUrl}
9284
closeMenu={() => setMenuOpenWithAnalytics(false)}
9385
breakpoint={breakpoint}
94-
setDisruptionInfoOpen={setDisruptionInfoOpen}
9586
/>
9687
)}
9788
{config.mainMenu.show ? (

app/component/Badge.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import cx from 'classnames';
4+
import { FormattedMessage } from 'react-intl';
5+
import capitalize from 'lodash/capitalize';
6+
import Icon from './Icon';
7+
import { AlertSeverityLevelType } from '../constants';
8+
9+
const DISRUPTION_BADGE_PREFIX = 'disruption-badge-';
10+
11+
function variantValidator(props, propName, componentName) {
12+
if (!Object.values(AlertSeverityLevelType).includes(props[propName])) {
13+
return new Error(
14+
`Invalid prop \`${propName}: ${props[propName]}\` supplied to ${componentName}.`,
15+
);
16+
}
17+
return null;
18+
}
19+
20+
const getIcon = variant => {
21+
switch (true) {
22+
case [AlertSeverityLevelType.Info, AlertSeverityLevelType.Unknown].includes(
23+
variant,
24+
): {
25+
return <Icon img="icon_info-circled" className="info" />;
26+
}
27+
case variant === 'success': {
28+
return <Icon img="icon_check" className="success" />;
29+
}
30+
case [
31+
AlertSeverityLevelType.Warning,
32+
AlertSeverityLevelType.Severe,
33+
].includes(variant): {
34+
return <Icon img="icon_caution_white_exclamation" className="danger" />;
35+
}
36+
default:
37+
return null;
38+
}
39+
};
40+
41+
export default function Badge({
42+
label,
43+
showIcon,
44+
variant,
45+
className,
46+
...rest
47+
}) {
48+
return (
49+
<div
50+
{...rest}
51+
className={cx('badge tag-bold', variant.toLowerCase(), className)}
52+
>
53+
{showIcon && getIcon(variant)}
54+
<FormattedMessage
55+
id={`${DISRUPTION_BADGE_PREFIX}${label.toLowerCase()}`}
56+
defaultMessage={capitalize(label.toLowerCase()).replace(/_/g, ' ')}
57+
/>
58+
</div>
59+
);
60+
}
61+
62+
Badge.propTypes = {
63+
label: PropTypes.string,
64+
showIcon: PropTypes.bool,
65+
variant: variantValidator,
66+
className: PropTypes.string,
67+
};
68+
Badge.defaultProps = {
69+
label: undefined,
70+
variant: 'info',
71+
showIcon: false,
72+
className: undefined,
73+
};

app/component/Card.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import PropTypes from 'prop-types';
2-
import React from 'react';
2+
import React, { forwardRef } from 'react';
33
import cx from 'classnames';
44

5-
export default function Card({ className, children }) {
6-
return <div className={cx('card', className)}>{children}</div>;
7-
}
5+
const Card = forwardRef(({ className, children, ...rest }, ref) => {
6+
return (
7+
<div ref={ref} className={cx('card', className)} {...rest}>
8+
{children}
9+
</div>
10+
);
11+
});
812

913
Card.displayName = 'Card';
1014

@@ -14,3 +18,5 @@ Card.propTypes = {
1418
};
1519

1620
Card.defaultProps = { className: undefined };
21+
22+
export default Card;

app/component/DesktopView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default function DesktopView({
1616
}) {
1717
return (
1818
<div className="desktop">
19-
<div className="main-content" role="main">
19+
<div className="main-content" role="main" id="main-content">
2020
{bckBtnVisible && (
2121
<div className="desktop-title h1">
2222
<BackButton title={title} fallback={bckBtnFallback} />

app/component/Disclaimer.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import React, { useState } from 'react';
2+
import { FormattedMessage } from 'react-intl';
3+
import PropTypes from 'prop-types';
4+
import Icon from './Icon';
5+
import { useDeepLink } from '../util/vehicleRentalUtils';
6+
import { useConfigContext } from '../configurations/ConfigContext';
7+
import { useTranslationsContext } from '../util/useTranslationsContext';
8+
9+
export default function Disclaimer({
10+
header,
11+
headerId,
12+
text,
13+
textId,
14+
linkLabel,
15+
linkLabelId,
16+
values,
17+
href,
18+
useLinkButton,
19+
closable,
20+
onClose, // hook e.g. for remembering closing
21+
}) {
22+
const { colors } = useConfigContext();
23+
const intl = useTranslationsContext();
24+
25+
const [showCard, setShowCard] = useState(true);
26+
27+
const handleClose = () => {
28+
setShowCard(false);
29+
if (onClose) {
30+
onClose();
31+
}
32+
};
33+
34+
const onClick = href?.startsWith('http')
35+
? () => {
36+
window.open(href, '_blank', 'noopener,noreferrer');
37+
}
38+
: () => useDeepLink(href, window.location.href);
39+
40+
if (!showCard) {
41+
return null;
42+
}
43+
const hdr = headerId ? (
44+
<FormattedMessage id={headerId} values={values} />
45+
) : (
46+
header
47+
);
48+
const txt = textId ? <FormattedMessage id={textId} values={values} /> : text;
49+
const label = linkLabelId ? (
50+
<FormattedMessage id={linkLabelId} values={values} />
51+
) : (
52+
linkLabel
53+
);
54+
55+
return (
56+
<div className="disclaimer-container">
57+
<Icon className="info" img="icon_info" />
58+
<div className="disclaimer">
59+
<div className="disclaimer-header">
60+
{hdr && <h3>{hdr}</h3>}
61+
{closable && (
62+
<button
63+
className="disclaimer-close"
64+
aria-label={intl.formatMessage({ id: 'close' })}
65+
onClick={handleClose}
66+
type="button"
67+
>
68+
<Icon color={colors.primary} img="icon_close" />
69+
</button>
70+
)}
71+
</div>
72+
{txt}
73+
{href && useLinkButton && (
74+
<button
75+
type="button"
76+
className="external-link-button"
77+
onClick={e => {
78+
e.stopPropagation();
79+
onClick(e);
80+
}}
81+
>
82+
{label}
83+
</button>
84+
)}
85+
{href && !useLinkButton && (
86+
<a
87+
className="external-link"
88+
href={href}
89+
target="_blank"
90+
rel="noreferrer"
91+
>
92+
{label}
93+
<Icon className="arrow" img="icon_arrow-collapse--right" />
94+
</a>
95+
)}
96+
</div>
97+
</div>
98+
);
99+
}
100+
101+
Disclaimer.propTypes = {
102+
header: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
103+
headerId: PropTypes.string,
104+
text: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
105+
textId: PropTypes.string,
106+
linkLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
107+
linkLabelId: PropTypes.string,
108+
values: PropTypes.objectOf(PropTypes.string),
109+
href: PropTypes.string,
110+
useLinkButton: PropTypes.bool,
111+
closable: PropTypes.bool,
112+
onClose: PropTypes.func,
113+
};
114+
115+
Disclaimer.defaultProps = {
116+
header: null,
117+
headerId: undefined,
118+
text: null,
119+
textId: undefined,
120+
linkLabel: null,
121+
linkLabelId: undefined,
122+
values: {},
123+
href: undefined,
124+
useLinkButton: false,
125+
closable: false,
126+
onClose: undefined,
127+
};

app/component/DisruptionBannerAlert.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useState } from 'react';
33
import cx from 'classnames';
44
import { intlShape } from 'react-intl';
55
import { configShape, alertShape } from '../util/shapes';
6-
6+
import { TRAFFICNOW } from '../util/path';
77
import Icon from './Icon';
88
import TruncatedMessage from './TruncatedMessage';
99
import { mapAlertSource } from '../util/alertUtils';
@@ -75,9 +75,7 @@ const DisruptionBannerAlert = (
7575
<a
7676
className="disruption-info-content"
7777
onClick={e => e.stopPropagation()}
78-
href={`${config.URL.ROOTLINK}/${
79-
language === 'fi' ? '' : `${language}/`
80-
}${config.trafficNowLink[language]}`}
78+
href={`/${TRAFFICNOW}`}
8179
>
8280
{message}
8381
</a>

app/component/DisruptionInfo.js

Lines changed: 0 additions & 75 deletions
This file was deleted.

app/component/DisruptionInfoButton.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ function DisruptionInfoButton(props, { config }) {
1313
className="cursor-pointer disruption-info noborder"
1414
onClick={props.openDisruptionInfo}
1515
>
16-
<FormattedMessage
17-
id="disruptions-and-diversions"
18-
defaultMessage="Disruptions and diversions"
19-
/>
16+
<FormattedMessage id="traffic-now-long" defaultMessage="Services now" />
2017
{props.viewer?.alerts?.length > 0 && (
2118
<Icon
2219
img="icon_caution_white_exclamation"

0 commit comments

Comments
 (0)