Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show passenger information messages on station and train pages #18

Merged
merged 25 commits into from
Sep 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
85e8582
Show passenger information messages on station and train pages
viliket Sep 10, 2023
5020739
Improve passenger information messages with junaan.fi as info source
viliket Sep 10, 2023
5ddad3a
Follow delivery rules when displaying passenger information messages
viliket Sep 14, 2023
a5b573d
Merge branch 'main' into passenger-information-messages
viliket Sep 15, 2023
7fd6952
Fix wrong imports
viliket Sep 15, 2023
1cf1c58
Check message relevance primarily from video and then from audio
viliket Sep 15, 2023
bc6660a
Fix time zone handling when handling dates in delivery rules
viliket Sep 16, 2023
37e2ad7
Improve PassengerInformationMessagesDialog opening and closing
viliket Sep 16, 2023
418f759
Ignore messages with unsupported deliveryRules type
viliket Sep 16, 2023
46fcf8f
Add tests for getPassengerInformationMessagesByStation
viliket Sep 16, 2023
bdfca09
Merge branch 'main' into passenger-information-messages
viliket Sep 16, 2023
e0703d4
Remove unused imports
viliket Sep 17, 2023
e1776bf
Simplify isWithinTimeSpan logic
viliket Sep 17, 2023
c999985
Add more tests for special cases
viliket Sep 17, 2023
2fb4560
Fix code quality issues
viliket Sep 17, 2023
4710f51
Merge branch 'main' into passenger-information-messages
viliket Sep 17, 2023
6b803de
Reduce code duplication in passengerInformationMessages.test.ts
viliket Sep 17, 2023
1a96ce9
Improve usePassengerInformationMessages data fetching
viliket Sep 21, 2023
5350052
Add check for overall passenger message validity
viliket Sep 21, 2023
452318a
Fix issues usePassengerInformationMessages tests and code style
viliket Sep 21, 2023
b4f85fa
Change default refetch interval to 20 seconds
viliket Sep 21, 2023
9abb916
Simplify creating search params in usePassengerInformationMessages
viliket Sep 21, 2023
28efb3a
Change default refetch interval to 10s and use 20s in pages
viliket Sep 21, 2023
5851713
Simplify logic of getting passenger message for current language
viliket Sep 22, 2023
105460a
Improve tests for getPassengerInformationMessageForLanguage
viliket Sep 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"track": "Track",
"station": "Station",
"canceled": "Canceled",
"alerts": "Alerts",
"page_not_found": "Page could not be found.",
"train_current_composition": "Current composition",
"train_composition_change_from_to_station_text": "These train units continue from {{from}} to {{to}}",
Expand Down
1 change: 1 addition & 0 deletions public/locales/fi/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"track": "Raide",
"station": "Asema",
"canceled": "Peruttu",
"alerts": "Tiedotteet",
"page_not_found": "Etsimääsi sivua ei löytynyt.",
"train_current_composition": "Nykyinen kokoonpano",
"train_composition_change_from_to_station_text": "Nämä junayksiköt jatkavat asemalta {{from}} asemalle {{to}}",
Expand Down
48 changes: 48 additions & 0 deletions src/components/PassengerInformationMessageAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Alert, ButtonBase } from '@mui/material';
import { useTranslation } from 'react-i18next';

import {
getPassengerInformationMessageForLanguage,
PassengerInformationMessage,
} from '../utils/passengerInformationMessages';

type PassengerInformationMessageAlertProps = {
onClick: () => void;
passengerInformationMessages: PassengerInformationMessage[];
};

const PassengerInformationMessageAlert = ({
onClick,
passengerInformationMessages,
}: PassengerInformationMessageAlertProps) => {
const { i18n } = useTranslation();

if (passengerInformationMessages.length === 0) return null;

const firstMessage = passengerInformationMessages[0];

return (
<ButtonBase
onClick={onClick}
sx={{
width: '100%',
textAlign: 'left',
'&:focus-visible': {
outline: 'auto 1px',
},
}}
>
<Alert severity="info" sx={{ width: '100%' }}>
{getPassengerInformationMessageForLanguage(
firstMessage,
i18n.resolvedLanguage
)}
{passengerInformationMessages.length > 1 && (
<strong> + {passengerInformationMessages.length - 1}</strong>
)}
</Alert>
</ButtonBase>
);
};

export default PassengerInformationMessageAlert;
49 changes: 49 additions & 0 deletions src/components/PassengerInformationMessagesDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Alert, DialogActions, DialogContent } from '@mui/material';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import { useTranslation } from 'react-i18next';

import {
getPassengerInformationMessageForLanguage,
PassengerInformationMessage,
} from '../utils/passengerInformationMessages';

type PassengerInformationMessagesDialogProps = {
onClose: () => void;
open: boolean;
passengerInformationMessages:
| PassengerInformationMessage[]
| null
| undefined;
};

const PassengerInformationMessagesDialog = (
props: PassengerInformationMessagesDialogProps
) => {
const { onClose, open, passengerInformationMessages } = props;
const { i18n } = useTranslation();
const { t } = useTranslation();

const handleClose = () => {
onClose();
};

return (
<Dialog onClose={handleClose} open={open}>
<DialogTitle>{t('alerts')}</DialogTitle>
<DialogContent>
{passengerInformationMessages?.map((m) => (
<Alert key={m.id} severity="info" sx={{ mb: 1 }}>
{getPassengerInformationMessageForLanguage(
m,
i18n.resolvedLanguage
)}
</Alert>
))}
</DialogContent>
<DialogActions sx={{ justifyContent: 'space-evenly' }}></DialogActions>
</Dialog>
);
};

export default PassengerInformationMessagesDialog;
35 changes: 35 additions & 0 deletions src/components/TrainInfoContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ import {
useTrainQuery,
Wagon,
} from '../graphql/generated/digitraffic';
import usePassengerInformationMessages from '../hooks/usePassengerInformationMessages';
import { formatEET } from '../utils/date';
import { getPassengerInformationMessagesByStation } from '../utils/passengerInformationMessages';
import { getTrainScheduledDepartureTime } from '../utils/train';

import PassengerInformationMessagesDialog from './PassengerInformationMessagesDialog';
import TrainComposition from './TrainComposition';
import TrainStationTimeline from './TrainStationTimeline';
import TrainWagonDetailsDialog from './TrainWagonDetailsDialog';
Expand All @@ -22,6 +25,8 @@ type TrainInfoContainerProps = {
function TrainInfoContainer({ train }: TrainInfoContainerProps) {
const [wagonDialogOpen, setWagonDialogOpen] = useState(false);
const [selectedWagon, setSelectedWagon] = useState<Wagon | null>(null);
const [selectedStation, setSelectedStation] = useState<string | null>(null);
const [stationAlertDialogOpen, setStationAlertDialogOpen] = useState(false);
const departureDate = train ? getTrainScheduledDepartureTime(train) : null;
const { error, data: realTimeData } = useTrainQuery(
train && departureDate
Expand All @@ -37,6 +42,16 @@ function TrainInfoContainer({ train }: TrainInfoContainerProps) {
}
: { skip: true }
);
const { messages: passengerInformationMessages } =
usePassengerInformationMessages({
skip: !train,
refetchIntervalMs: 20000,
trainNumber: train?.trainNumber,
trainDepartureDate: train?.departureDate,
});
const stationMessages = getPassengerInformationMessagesByStation(
passengerInformationMessages
);

const realTimeTrain = realTimeData?.train?.[0];

Expand All @@ -49,6 +64,15 @@ function TrainInfoContainer({ train }: TrainInfoContainerProps) {
setWagonDialogOpen(true);
};

const handleStationAlertDialogClose = () => {
setStationAlertDialogOpen(false);
};

const handleStationAlertClick = (stationCode: string) => {
setSelectedStation(stationCode);
setStationAlertDialogOpen(true);
};

return (
<>
<Box
Expand Down Expand Up @@ -87,6 +111,8 @@ function TrainInfoContainer({ train }: TrainInfoContainerProps) {
train={train}
realTimeTrain={realTimeTrain}
onWagonClick={handleWagonClick}
onStationAlertClick={handleStationAlertClick}
stationMessages={stationMessages}
/>
{train && (
<TrainWagonDetailsDialog
Expand All @@ -96,6 +122,15 @@ function TrainInfoContainer({ train }: TrainInfoContainerProps) {
onClose={handleWagonDialogClose}
/>
)}
<PassengerInformationMessagesDialog
open={stationAlertDialogOpen}
passengerInformationMessages={
selectedStation && stationMessages?.[selectedStation]
? stationMessages[selectedStation]
: null
}
onClose={handleStationAlertDialogClose}
/>
</>
);
}
Expand Down
15 changes: 15 additions & 0 deletions src/components/TrainStationTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import getTrainCurrentStation from '../utils/getTrainCurrentStation';
import getTrainLatestArrivalRow from '../utils/getTrainLatestArrivalRow';
import getTrainLatestDepartureTimeTableRow from '../utils/getTrainLatestDepartureTimeTableRow';
import getTrainPreviousStation from '../utils/getTrainPreviousStation';
import { PassengerInformationMessage } from '../utils/passengerInformationMessages';
import { getTrainStationName } from '../utils/train';

import PassengerInformationMessageAlert from './PassengerInformationMessageAlert';
import TimelineRouteStopSeparator from './TimelineRouteStopSeparator';
import TimeTableRowTime from './TimeTableRowTime';
import TrainComposition from './TrainComposition';
Expand All @@ -19,12 +21,16 @@ type TrainStationTimelineProps = {
train?: TrainDetailsFragment | null;
realTimeTrain?: TrainDetailsFragment | null;
onWagonClick: (w: Wagon) => void;
onStationAlertClick: (stationCode: string) => void;
stationMessages?: Record<string, PassengerInformationMessage[]>;
};

const TrainStationTimeline = ({
train,
realTimeTrain,
onWagonClick,
onStationAlertClick,
stationMessages,
}: TrainStationTimelineProps) => {
const { t } = useTranslation();

Expand Down Expand Up @@ -101,6 +107,15 @@ const TrainStationTimeline = ({
/>
</div>
)}
{stationMessages &&
stationMessages[station.shortCode]?.length > 0 && (
<PassengerInformationMessageAlert
onClick={() => onStationAlertClick(station.shortCode)}
passengerInformationMessages={
stationMessages[station.shortCode]
}
/>
)}
<Divider />
</Grid>
</Grid>
Expand Down
Loading