Skip to content

Commit

Permalink
front: display new warnings in stdcm
Browse files Browse the repository at this point in the history
Display a warning if the infra is loading or if the user launches a request when some waypoints do not have a location

Signed-off-by: Clara Ni <[email protected]>
  • Loading branch information
clarani committed Oct 11, 2024
1 parent 9072683 commit f2e834f
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 26 deletions.
2 changes: 2 additions & 0 deletions front/public/locales/en/stdcm.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
"stdcmComputation": "Search for a train path",
"stdcmErrors": {
"bothPointAreScheduled": "The calculation cannot take into account both an origin and a destination schedule. You have to choose one or the other:",
"infraNotLoaded": "Infrastructure is loading",
"missingLocation": "Missing location",
"noPaths": "Incompatibility with other train paths.",
"noResults": "No path found",
"noScheduledPoint": "The calculation requires either the origin or destination schedule.",
Expand Down
2 changes: 2 additions & 0 deletions front/public/locales/fr/stdcm.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
"stdcmComputation": "Recherche de sillon",
"stdcmErrors": {
"bothPointAreScheduled": "Le calcul ne peut pas prendre en compte à la fois un horaire d'origine et un horaire de destination. Il faut choisir l'un ou l'autre :",
"infraNotLoaded": "Infrastructure en cours de chargement",
"missingLocation": "Localisation manquante",
"noPaths": "Incompatibilité avec d'autres sillons.",
"noResults": "Aucun sillon trouvé",
"noScheduledPoint": "Le calcul a besoin de l'horaire d'origine ou de celui de la destination.",
Expand Down
5 changes: 5 additions & 0 deletions front/scripts/i18n-checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const IGNORE_MISSING: RegExp[] = [
/translation:unspecified/,
// key used by upsertMapWaypointsInOperationalPoints
/translation:requestedPoint/,
// key used by checkStdcmConfigErrors
/translation:arriveAt/,
/translation:departureTime/,
/translation:destinationTime/,
/translation:leaveAt/,
];
const IGNORE_UNUSED: RegExp[] = [
/.*-generated$/,
Expand Down
53 changes: 34 additions & 19 deletions front/src/applications/stdcmV2/components/StdcmConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { useEffect, useState } from 'react';

import { Button } from '@osrd-project/ui-core';
import cx from 'classnames';
import { compact } from 'lodash';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';

import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
import useInfraStatus from 'modules/pathfinding/hooks/useInfraStatus';
import { Map } from 'modules/trainschedule/components/ManageTrainSchedule';
import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf';
import { useAppDispatch } from 'store';
import { extractHHMM } from 'utils/date';

import StdcmConsist from './StdcmConsist';
import StdcmDestination from './StdcmDestination';
Expand Down Expand Up @@ -47,6 +48,7 @@ const StdcmConfig = ({
}: StdcmConfigProps) => {
const { t } = useTranslation('stdcm');

const { infra } = useInfraStatus();
const dispatch = useAppDispatch();
const {
updateGridMarginAfter,
Expand All @@ -56,15 +58,16 @@ const StdcmConfig = ({
updateDestinationArrivalType,
} = useOsrdConfActions() as StdcmConfSliceActions;

const { getOrigin, getDestination, getProjectID, getScenarioID, getStudyID } =
const { getOrigin, getDestination, getPathSteps, getProjectID, getScenarioID, getStudyID } =
useOsrdConfSelectors();
const origin = useSelector(getOrigin);
const pathSteps = useSelector(getPathSteps);
const destination = useSelector(getDestination);
const projectID = useSelector(getProjectID);
const studyID = useSelector(getStudyID);
const scenarioID = useSelector(getScenarioID);

const pathfinding = useStaticPathfinding();
const pathfinding = useStaticPathfinding(infra);

const [formErrors, setFormErrors] = useState<StdcmConfigErrors>();

Expand All @@ -77,8 +80,19 @@ const StdcmConfig = ({
};

const startSimulation = () => {
if (pathfinding?.status === 'success' && !formErrors) {
const isPathfindingFailed = !!pathfinding && pathfinding.status !== 'success';
const formErrorsStatus = checkStdcmConfigErrors(
isPathfindingFailed,
origin,
destination,
compact(pathSteps),
t
);
if (pathfinding?.status === 'success' && !formErrorsStatus) {
launchStdcmRequest();
} else {
console.error('The form is not valid:', { pathfinding, formErrorsStatus });
setFormErrors(formErrorsStatus);
}
};

Expand All @@ -91,22 +105,15 @@ const StdcmConfig = ({

useEffect(() => {
const isPathfindingFailed = !!pathfinding && pathfinding.status !== 'success';
let formErrorsStatus = checkStdcmConfigErrors(isPathfindingFailed, origin, destination);
if (formErrorsStatus?.errorType === StdcmConfigErrorTypes.BOTH_POINT_SCHEDULED) {
formErrorsStatus = {
...formErrorsStatus,
errorDetails: {
originTime: origin?.arrival
? t('leaveAt', { time: extractHHMM(origin.arrival) })
: t('departureTime'),
destinationTime: destination?.arrival
? t('arriveAt', { time: extractHHMM(destination.arrival) })
: t('destinationTime'),
},
};
}
const formErrorsStatus = checkStdcmConfigErrors(
isPathfindingFailed,
origin,
destination,
[],
t
);
setFormErrors(formErrorsStatus);
}, [origin, destination, pathfinding]);
}, [origin, pathSteps, destination, pathfinding]);

// TODO: DROP STDCMV1: set those values by default in the store when <StdcmAllowances/> is not used anymore.
useEffect(() => {
Expand All @@ -117,6 +124,14 @@ const StdcmConfig = ({
}
}, [isDebugMode]);

useEffect(() => {
if (!infra || infra.state === 'CACHED') {
setFormErrors(undefined);
} else {
setFormErrors({ errorType: StdcmConfigErrorTypes.INFRA_NOT_LOADED });
}
}, [infra]);

return (
<div className="stdcm-v2__body">
{isDebugMode && (
Expand Down
17 changes: 15 additions & 2 deletions front/src/applications/stdcmV2/components/StdcmWarningBox.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Button } from '@osrd-project/ui-core';
import { Alert } from '@osrd-project/ui-icons';
import cx from 'classnames';
import { useTranslation } from 'react-i18next';

import type { StdcmConfigErrorTypes, StdcmConfigErrors } from '../types';
import { StdcmConfigErrorTypes, type StdcmConfigErrors } from '../types';

const SHORT_TEXT_ERRORS = [
StdcmConfigErrorTypes.INFRA_NOT_LOADED,
StdcmConfigErrorTypes.MISSING_LOCATION,
];

type StdcmWarningBoxProps = {
errorInfos: {
Expand All @@ -24,7 +30,14 @@ const StdcmWarningBox = ({
<span>
<Alert variant="fill" />
</span>
<p className="mb-0 text-justify">{t(`stdcmErrors.${errorType}`)}</p>
<p
className={cx('mb-0', {
'text-center': SHORT_TEXT_ERRORS.includes(errorType),
'text-justify': !SHORT_TEXT_ERRORS.includes(errorType),
})}
>
{t(`stdcmErrors.${errorType}`)}
</p>
{errorType === 'bothPointAreScheduled' && errorDetails && (
<div className="stdcm-warning-buttons">
<Button
Expand Down
10 changes: 6 additions & 4 deletions front/src/applications/stdcmV2/hooks/useStaticPathfinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import { useEffect, useMemo, useState } from 'react';
import { compact } from 'lodash';
import { useSelector } from 'react-redux';

import { osrdEditoastApi, type PathfindingResult } from 'common/api/osrdEditoastApi';
import {
osrdEditoastApi,
type InfraWithState,
type PathfindingResult,
} from 'common/api/osrdEditoastApi';
import { useOsrdConfSelectors } from 'common/osrdContext';
import useInfraStatus from 'modules/pathfinding/hooks/useInfraStatus';
import usePathProperties from 'modules/pathfinding/hooks/usePathProperties';
import { getPathfindingQuery } from 'modules/pathfinding/utils';
import { useStoreDataForRollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector/useStoreDataForRollingStockSelector';

const useStaticPathfinding = () => {
const useStaticPathfinding = (infra?: InfraWithState) => {
const { getPathSteps } = useOsrdConfSelectors();

const { infra } = useInfraStatus();
const pathSteps = useSelector(getPathSteps);
const { rollingStock } = useStoreDataForRollingStockSelector();

Expand Down
2 changes: 2 additions & 0 deletions front/src/applications/stdcmV2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export enum ArrivalTimeTypes {
}

export enum StdcmConfigErrorTypes {
INFRA_NOT_LOADED = 'infraNotLoaded',
MISSING_LOCATION = 'missingLocation',
PATHFINDING_FAILED = 'pathfindingFailed',
BOTH_POINT_SCHEDULED = 'bothPointAreScheduled',
NO_SCHEDULED_POINT = 'noScheduledPoint',
Expand Down
19 changes: 18 additions & 1 deletion front/src/applications/stdcmV2/utils/checkStdcmConfigErrors.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { TFunction } from 'i18next';

import type { PathStep } from 'reducers/osrdconf/types';
import { extractHHMM } from 'utils/date';

import { StdcmConfigErrorTypes, ArrivalTimeTypes, type StdcmConfigErrors } from '../types';

const checkStdcmConfigErrors = (
pathfindingStateError: boolean,
origin: PathStep | null,
destination: PathStep | null
destination: PathStep | null,
pathSteps: PathStep[],
t: TFunction
): StdcmConfigErrors | undefined => {
const isOneOpPointMissing = !origin || !destination;
if (isOneOpPointMissing) {
Expand All @@ -16,6 +21,10 @@ const checkStdcmConfigErrors = (
return { errorType: StdcmConfigErrorTypes.PATHFINDING_FAILED };
}

if (pathSteps.some((step) => 'uic' in step && step.uic === -1)) {
return { errorType: StdcmConfigErrorTypes.MISSING_LOCATION };
}

const areBothPointsASAP =
origin.arrivalType === ArrivalTimeTypes.ASAP &&
destination.arrivalType === ArrivalTimeTypes.ASAP;
Expand All @@ -31,6 +40,14 @@ const checkStdcmConfigErrors = (
if (areBothPointsScheduled) {
return {
errorType: StdcmConfigErrorTypes.BOTH_POINT_SCHEDULED,
errorDetails: {
originTime: origin?.arrival
? t('leaveAt', { time: extractHHMM(origin.arrival) })
: t('departureTime'),
destinationTime: destination?.arrival
? t('arriveAt', { time: extractHHMM(destination.arrival) })
: t('destinationTime'),
},
};
}

Expand Down

0 comments on commit f2e834f

Please sign in to comment.