Skip to content

Commit 283f73c

Browse files
committed
Create view for stop listing
1 parent 05924ae commit 283f73c

File tree

4 files changed

+429
-1
lines changed

4 files changed

+429
-1
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { DateTime } from 'luxon';
2+
import { FC } from 'react';
3+
import { useTranslation } from 'react-i18next';
4+
import { Link } from 'react-router';
5+
import { Path, routeDetails } from '../../../../../router/routeDetails';
6+
import { mapLngLatToPoint } from '../../../../../utils';
7+
import {
8+
LocatorActionButton,
9+
OpenDetailsPage,
10+
ShowOnMap,
11+
} from '../../../components';
12+
import { StopTableRow } from '../../../search';
13+
import { StopSearchRow } from '../../../search/types';
14+
import { LocatableStop } from '../../../types/LocatableStop';
15+
16+
const testIds = {
17+
stopAreaHeader: 'TerminalDetailsPage::stopAreaHeader',
18+
};
19+
20+
type StopAreaSectionProps = {
21+
readonly privateCode: string;
22+
readonly name: string;
23+
readonly stops: ReadonlyArray<StopSearchRow>;
24+
readonly observationDate: DateTime;
25+
};
26+
27+
type StopAreaHeaderProps = {
28+
readonly privateCode: string;
29+
readonly name: string;
30+
readonly observationDate: DateTime;
31+
};
32+
33+
type StopRowProps = {
34+
readonly stop: StopSearchRow;
35+
readonly observationDate: DateTime;
36+
};
37+
38+
const StopAreaHeader: FC<StopAreaHeaderProps> = ({
39+
privateCode,
40+
name,
41+
observationDate,
42+
}) => {
43+
const { t } = useTranslation();
44+
return (
45+
<h3 className="mb-2 font-bold">
46+
<Link
47+
to={routeDetails[Path.stopAreaDetails].getLink(privateCode, {
48+
observationDate,
49+
})}
50+
title={t('accessibility:stopAreas.showStopAreaDetails', {
51+
areaLabel: name,
52+
})}
53+
data-testid={testIds.stopAreaHeader}
54+
>
55+
<span>{name}</span>
56+
<i className="icon-open-in-new ml-1" aria-hidden="true" />
57+
</Link>
58+
</h3>
59+
);
60+
};
61+
62+
const StopRow: FC<StopRowProps> = ({ stop, observationDate }) => {
63+
const locatableStop: LocatableStop = {
64+
label: stop.label,
65+
netextId: stop.quay.netexId ?? null,
66+
location: mapLngLatToPoint(stop.measured_location.coordinates),
67+
};
68+
return (
69+
<StopTableRow
70+
key={stop.scheduled_stop_point_id}
71+
actionButtons={<LocatorActionButton stop={locatableStop} />}
72+
menuItems={[
73+
<OpenDetailsPage key="OpenDetailsPage" stop={locatableStop} />,
74+
<ShowOnMap key="ShowOnMap" stop={locatableStop} />,
75+
]}
76+
observationDate={observationDate}
77+
stop={stop}
78+
/>
79+
);
80+
};
81+
82+
export const StopAreaSection: FC<StopAreaSectionProps> = ({
83+
privateCode,
84+
name,
85+
stops,
86+
observationDate,
87+
}) => {
88+
return (
89+
<div className="mt-4" data-testid="TerminalDetailsPage::stopAreaSection">
90+
<StopAreaHeader
91+
privateCode={privateCode}
92+
name={name}
93+
observationDate={observationDate}
94+
/>
95+
<table
96+
className="w-full border-x border-x-light-grey"
97+
data-testid="TerminalDetailsPage::stopAreaStopsTable"
98+
>
99+
<tbody>
100+
{stops.map((stop) => (
101+
<StopRow
102+
key={stop.scheduled_stop_point_id}
103+
stop={stop}
104+
observationDate={observationDate}
105+
/>
106+
))}
107+
</tbody>
108+
</table>
109+
</div>
110+
);
111+
};
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { FC, useMemo } from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
import { MemberStopQuayDetailsFragment } from '../../../../../generated/graphql';
4+
import { useObservationDateQueryParam } from '../../../../../hooks';
5+
import { EnrichedParentStopPlace } from '../../../../../types';
6+
import { StopSearchRow } from '../../../search/types';
7+
import { StopAreaSection } from './StopAreaSection';
8+
9+
const testIds = {
10+
stopsTitle: 'TerminalDetailsPage::stopsTitle',
11+
};
12+
13+
type StopsProps = {
14+
readonly terminal: EnrichedParentStopPlace;
15+
};
16+
17+
type StopAreaData = {
18+
readonly id: string;
19+
readonly name: string;
20+
readonly privateCode: string;
21+
readonly stops: ReadonlyArray<StopSearchRow>;
22+
};
23+
24+
function toStopSearchRow(
25+
quay: MemberStopQuayDetailsFragment | null | undefined,
26+
): StopSearchRow | null {
27+
const ssp = quay?.scheduled_stop_point;
28+
if (!ssp) {
29+
return null;
30+
}
31+
return {
32+
...ssp,
33+
quay: {
34+
netexId: quay?.id ?? null,
35+
nameFin: quay?.description?.value ?? null,
36+
nameSwe: null,
37+
},
38+
} as StopSearchRow;
39+
}
40+
41+
function mapChildrenToStopAreas(
42+
terminal: EnrichedParentStopPlace,
43+
): ReadonlyArray<StopAreaData> {
44+
const children = terminal.children ?? [];
45+
const sections = children.map((child) => ({
46+
id: child?.id ?? '',
47+
privateCode: child?.privateCode?.value ?? '',
48+
name: child?.name?.value ?? '',
49+
stops: (child?.quays ?? [])
50+
.map(toStopSearchRow)
51+
.filter((row): row is StopSearchRow => row !== null),
52+
}));
53+
54+
sections.toSorted((a, b) => a.name.localeCompare(b.name));
55+
56+
return sections;
57+
}
58+
59+
export const StopsListSection: FC<StopsProps> = ({ terminal }) => {
60+
const { t } = useTranslation();
61+
62+
const { observationDate } = useObservationDateQueryParam({
63+
initialize: false,
64+
});
65+
66+
const stopAreas = useMemo(() => mapChildrenToStopAreas(terminal), [terminal]);
67+
68+
return (
69+
<>
70+
<h2 data-testid={testIds.stopsTitle}>
71+
{t('terminalDetails.stops.title')}
72+
</h2>
73+
{stopAreas.map((section) => (
74+
<StopAreaSection
75+
key={section.id}
76+
privateCode={section.privateCode}
77+
name={section.name}
78+
stops={section.stops}
79+
observationDate={observationDate}
80+
/>
81+
))}
82+
</>
83+
);
84+
};

ui/src/components/stop-registry/terminals/useGetTerminalDetails.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ const GQL_GET_PARENT_STOP_PLACE_DETAILS = gql`
9393
name {
9494
value
9595
}
96+
privateCode {
97+
value
98+
}
9699
quays {
97100
...member_stop_quay_details
98101
}
@@ -101,6 +104,13 @@ const GQL_GET_PARENT_STOP_PLACE_DETAILS = gql`
101104
fragment member_stop_quay_details on stop_registry_Quay {
102105
id
103106
publicCode
107+
description {
108+
lang
109+
value
110+
}
111+
scheduled_stop_point {
112+
...scheduled_stop_point_detail_fields
113+
}
104114
keyValues {
105115
key
106116
values

0 commit comments

Comments
 (0)