Skip to content

Commit 2ed63ae

Browse files
committed
Merge branch 'v3' into next
2 parents dc4369b + 7ece7ff commit 2ed63ae

21 files changed

Lines changed: 267 additions & 81 deletions

File tree

.github/workflows/dev-pipeline.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,36 @@ jobs:
239239
name: sbom-artifact
240240
path: ${{ github.repository }}-${{ github.sha }}.json
241241

242+
- name: 'Az CLI login for central SBOM server'
243+
uses: azure/login@v3
244+
with:
245+
client-id: ${{ secrets.SBOM_CLIENT_ID }}
246+
tenant-id: ${{ secrets.SBOM_TENANT_ID }}
247+
subscription-id: ${{ secrets.SBOM_SUBSCRIPTION_ID }}
248+
249+
- name: 'Send SBOM to central SBOM server'
250+
if: github.ref == 'refs/heads/v3'
251+
run: >-
252+
az storage blob upload
253+
--account-name ${{ secrets.SBOM_STORAGE_ACCOUNT_NAME }}
254+
--container-name sbom-ingest
255+
--file ${{ github.repository }}-${{ github.sha }}.json
256+
--name ${{ secrets.SBOM_ENV_KEY_DEV_V3 }}/${{ github.sha }}.json
257+
--auth-mode login
258+
--overwrite true
259+
260+
- name: 'Send SBOM to central SBOM server'
261+
if: github.ref == 'refs/heads/next'
262+
run: >-
263+
az storage blob upload
264+
--account-name ${{ secrets.SBOM_STORAGE_ACCOUNT_NAME }}
265+
--container-name sbom-ingest
266+
--file ${{ github.repository }}-${{ github.sha }}.json
267+
--name ${{ secrets.SBOM_ENV_KEY_DEV_NEXT }}/${{ github.sha }}.json
268+
--auth-mode login
269+
--overwrite true
270+
271+
242272
# This is only done when pushing to v3
243273
publish-npm:
244274
if: github.ref == 'refs/heads/v3'

app/component/itinerary/SettingsButton.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import PropTypes from 'prop-types';
22
import React, { useState, useCallback, useRef } from 'react';
3+
import cx from 'classnames';
34
import { FormattedMessage, useIntl } from 'react-intl';
45
import Icon from '../Icon';
56
import { isKeyboardSelectionEvent } from '../../util/browser';
@@ -36,19 +37,22 @@ export default function SettingsButton({ onToggleClick }) {
3637
const dismissPopover = useCallback(() => {
3738
// wait 1 second before dismissing to allow user to see the popover disappearing
3839
const timeoutId = setTimeout(() => {
40+
setDialogState(dismissTarget);
3941
if (dismissTarget === 'setting-change-acknowledged') {
4042
setSettingChangeInfoDismissed(true);
4143
} else {
4244
setPersonalizationInfoDismissed(true);
4345
}
44-
setDialogState(dismissTarget);
4546
}, 1000);
4647
return () => clearTimeout(timeoutId);
4748
}, []);
4849

4950
let personalizationPopover;
5051
const personalizationEnabled = isPersonalizationEnabled(config, settings);
51-
if (!isPersonalizationInfoDismissed && config.personalization) {
52+
if (
53+
!getDialogState('personalization-acknowledged', config) &&
54+
config.personalization
55+
) {
5256
personalizationPopover = personalizationEnabled ? (
5357
<div>
5458
<div className="popover-header">
@@ -94,7 +98,14 @@ export default function SettingsButton({ onToggleClick }) {
9498
onKeyPress={e => isKeyboardSelectionEvent(e) && onToggleClick()}
9599
aria-label={label}
96100
title={label}
97-
className="noborder cursor-pointer open-advanced-settings-window-button"
101+
className={cx(
102+
'noborder',
103+
'cursor-pointer',
104+
'open-advanced-settings-window-button',
105+
{
106+
'highlight-z-index': personalizationPopover,
107+
},
108+
)}
98109
>
99110
<div className="icon-holder">
100111
<Icon img="icon_settings" />

app/component/itinerary/TransitLeg.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const filterNextLegs = l => {
7070

7171
export default function TransitLeg({
7272
leg,
73-
interliningLegs,
73+
interliningLegs = [],
7474
index,
7575
mode,
7676
focusAction,

app/component/itinerary/search-settings.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@
209209
border-radius: 999px;
210210
background: #fff;
211211
position: relative;
212+
}
213+
214+
.highlight-z-index {
212215
z-index: 1004;
213216
}
214217

app/component/trafficnow/DisruptionBadge.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const getIcon = variant => {
2525
return <Icon img="icon_info-circled" className="info" />;
2626
}
2727
case variant === AlertSeverityLevelType.Warning: {
28-
return <Icon img="icon_alert-circled" className="warning" />;
28+
return <Icon img="icon_caution_white_exclamation" className="warning" />;
2929
}
3030
case variant === AlertSeverityLevelType.Severe: {
3131
return <Icon img="icon_caution_white_exclamation" className="danger" />;

app/component/trafficnow/TrafficNow.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import Filters from './filters/Filters';
1717
import { FilterContextProvider } from './filters/FiltersContext';
1818
import FiltersModal from './filters/FiltersModal';
1919

20+
// defines the scroll position at which a drop shadow is applied to the header button on mobile
21+
const HEADER_HEIGHT = 320;
22+
2023
const TrafficNow = () => {
2124
const {
2225
match: {
@@ -38,6 +41,16 @@ const TrafficNow = () => {
3841
const isMobileCanceledTripsView = !!mode && mobile;
3942
const isDetailsView = !!alertId;
4043

44+
const [top, setTop] = useState(true);
45+
46+
useEffect(() => {
47+
const scrollHandler = () => {
48+
setTop(window.scrollY <= HEADER_HEIGHT);
49+
};
50+
window.addEventListener('scroll', scrollHandler);
51+
return () => window.removeEventListener('scroll', scrollHandler);
52+
}, []);
53+
4154
return (
4255
<div className="traffic-now design-system">
4356
{!isMobileCanceledTripsView && !(isDetailsView && mobile) && (
@@ -84,7 +97,12 @@ const TrafficNow = () => {
8497
<Filters />
8598
</div>
8699
) : (
87-
<div className="traffic-now__filters-button-container">
100+
<div
101+
className={cx(
102+
'traffic-now__filters-button-container',
103+
!top && 'scrolled',
104+
)}
105+
>
88106
<FiltersModal
89107
isOpen={showFiltersModal}
90108
onClose={() => setShowFiltersModal(false)}

app/component/trafficnow/components/DisruptionStatus.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import { useIntl } from 'react-intl';
4+
import { DateTime } from 'luxon';
45
import Icon from '../../Icon';
56
import { getFormattedTimeDate } from '../../../util/timeUtils';
67
import { useConfigContext } from '../../../configurations/ConfigContext';
@@ -24,9 +25,19 @@ export default function DisruptionStatus({
2425
? active
2526
: now > effectiveStartDate * 1000 && now < effectiveEndDate * 1000;
2627

28+
// We want to hide start year when both dates are the current year
29+
const hideStartYear =
30+
effectiveStartDate &&
31+
effectiveEndDate &&
32+
DateTime.now().year === DateTime.fromSeconds(effectiveStartDate).year &&
33+
DateTime.now().year === DateTime.fromSeconds(effectiveEndDate).year;
34+
2735
const startDate =
2836
effectiveStartDate &&
29-
getFormattedTimeDate(effectiveStartDate * 1000, DATE_FORMAT);
37+
getFormattedTimeDate(
38+
effectiveStartDate * 1000,
39+
hideStartYear ? 'd.L.' : DATE_FORMAT,
40+
);
3041
const endDate =
3142
effectiveEndDate &&
3243
getFormattedTimeDate(effectiveEndDate * 1000, DATE_FORMAT);

app/component/trafficnow/components/RouteBadgeGroup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const RouteBadgeGroup = ({
3232
<div className="badges__group">
3333
<Icon
3434
img={`icon_${mode}`}
35-
className={mode}
35+
className={cx(mode, isStop ? 'stop' : 'route')}
3636
height={2}
3737
width={2}
3838
iconScale={isStop ? STOP_SIGN_ICON_SCALE : NORMAL_ICON_SCALE}

app/component/trafficnow/filters/Filters.js

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from 'react';
22
import { useIntl } from 'react-intl';
33
import Button from '@hsl-fi/button';
44
import PropTypes from 'prop-types';
5-
import cx from 'classnames';
65
import ValidityPeriodFilter from './ValidityPeriodFilter';
76
import { useFilterContext } from './FiltersContext';
87
import { useBreakpoint } from '../../../util/withBreakpoint';
@@ -28,10 +27,6 @@ const Filters = ({ onApplyClick = undefined, onResetClick = () => {} }) => {
2827
id: 'vehicleModes',
2928
Component: VehicleModesFilter,
3029
},
31-
{
32-
id: 'separator-1',
33-
Component: Separator,
34-
},
3530
{
3631
id: 'validityPeriod',
3732
Component: ValidityPeriodFilter,
@@ -53,28 +48,23 @@ const Filters = ({ onApplyClick = undefined, onResetClick = () => {} }) => {
5348
}
5449
};
5550

56-
return (
57-
<form
58-
className={cx('traffic-now__filters', {
59-
'traffic-now__filters-mobile': mobile,
60-
})}
61-
>
62-
{components.map(({ id, Component }) => (
63-
<Component key={id} filterId={id} />
64-
))}
51+
const buttons = (
52+
<>
6553
{onApplyClick && (
6654
<Button
6755
type="button"
6856
size="medium"
6957
fullWidth
7058
variant="blue"
71-
value={intl.formatMessage({ id: 'traffic-now_filters_view-results' })}
59+
value={intl.formatMessage({
60+
id: 'traffic-now_filters_view-results',
61+
})}
7262
onClick={onApplyClick}
7363
/>
7464
)}
7565
<Button
7666
type="button"
77-
size={mobile ? 'medium' : 'small'}
67+
size="medium"
7868
disabled={
7969
JSON.stringify(selectedFilters) === JSON.stringify(DEFAULT_FILTERS)
8070
}
@@ -83,6 +73,24 @@ const Filters = ({ onApplyClick = undefined, onResetClick = () => {} }) => {
8373
value={intl.formatMessage({ id: 'clear-button-label' })}
8474
onClick={handleResetClick}
8575
/>
76+
</>
77+
);
78+
79+
return mobile ? (
80+
<div>
81+
<form className="traffic-now__filters traffic-now__filters-mobile">
82+
{components.map(({ id, Component }) => (
83+
<Component key={id} filterId={id} />
84+
))}
85+
</form>
86+
<div className="traffic-now__filters-form-buttons">{buttons}</div>
87+
</div>
88+
) : (
89+
<form className="traffic-now__filters">
90+
{components.map(({ id, Component }) => (
91+
<Component key={id} filterId={id} />
92+
))}
93+
{buttons}
8694
</form>
8795
);
8896
};

app/component/trafficnow/filters/FiltersModal.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,21 @@ const FiltersModal = ({ isOpen, onClose }) => {
2323
})}
2424
onRequestClose={onClose}
2525
variant="large"
26-
className="traffic-now traffic-now__modal"
26+
className="traffic-now traffic-now__modal design-system"
2727
>
2828
<header className="traffic-now__modal-header bordered">
2929
<FormattedMessage id="filter" defaultMessage="Filter">
30-
{msg => <h3 className="heading-xs">{msg}</h3>}
30+
{msg => (
31+
<h3 className="heading-xs traffic-now__modal-header__label">
32+
{msg}
33+
</h3>
34+
)}
3135
</FormattedMessage>
3236
<button type="button" onClick={onClose}>
3337
<Icon
34-
height={1.5}
35-
width={1.5}
36-
iconScale={0.4}
38+
height={2.1}
39+
width={2.1}
40+
iconScale={0.5}
3741
img="icon_close"
3842
color="#007ac9"
3943
background={<IconBackground shape="circle" color="#ebf6fd" />}

0 commit comments

Comments
 (0)