diff --git a/front/public/locales/en/stdcm.json b/front/public/locales/en/stdcm.json index 31172b49e02..7403826a81c 100644 --- a/front/public/locales/en/stdcm.json +++ b/front/public/locales/en/stdcm.json @@ -90,6 +90,8 @@ "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", + "invalidOriginTime": "Origin departure time is invalid", + "invalidDestinationTime": "Destination arrival time is invalid", "missingLocation": "Missing location", "noPaths": "Incompatibility with other train paths.", "noResults": "No path found", diff --git a/front/public/locales/fr/stdcm.json b/front/public/locales/fr/stdcm.json index 30a085dd736..56112b494b7 100644 --- a/front/public/locales/fr/stdcm.json +++ b/front/public/locales/fr/stdcm.json @@ -78,7 +78,7 @@ "helpUs": "Aidez-nous à améliorer ST DCM", "other": "Autre", "reason": "Cette simulation ne répond pas à vos besoin car ...", - "startIncompatible": "Heure départ incompatible", + "startIncompatible": "Heure de départ incompatible", "unqualifiedDriver": "Conducteur non habilité" } }, @@ -90,6 +90,8 @@ "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", + "invalidOriginTime": "L'heure de départ de l'origine est invalide", + "invalidDestinationTime": "L'heure d'arrivée de la destination est invalide", "missingLocation": "Localisation manquante", "noPaths": "Incompatibilité avec d'autres sillons.", "noResults": "Aucun sillon trouvé", diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmConfig.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmConfig.tsx index b330b391b03..36a0d9b3574 100644 --- a/front/src/applications/stdcm/components/StdcmForm/StdcmConfig.tsx +++ b/front/src/applications/stdcm/components/StdcmForm/StdcmConfig.tsx @@ -61,6 +61,7 @@ const StdcmConfig = ({ getProjectID, getScenarioID, getStudyID, + getSearchDatetimeWindow, } = useOsrdConfSelectors() as StdcmConfSelectors; const origin = useSelector(getStdcmOrigin); const pathSteps = useSelector(getStdcmPathSteps); @@ -68,6 +69,7 @@ const StdcmConfig = ({ const projectID = useSelector(getProjectID); const studyID = useSelector(getStudyID); const scenarioID = useSelector(getScenarioID); + const searchDatetimeWindow = useSelector(getSearchDatetimeWindow); const pathfinding = useStaticPathfinding(infra); const formRef = useRef(null); @@ -80,7 +82,13 @@ const StdcmConfig = ({ const startSimulation = () => { const isPathfindingFailed = !!pathfinding && pathfinding.status !== 'success'; - const formErrorsStatus = checkStdcmConfigErrors(isPathfindingFailed, pathSteps, t); + const formErrorsStatus = checkStdcmConfigErrors( + isPathfindingFailed, + pathSteps, + t, + searchDatetimeWindow, + { simulationStarting: true } + ); if (pathfinding?.status === 'success' && !formErrorsStatus) { launchStdcmRequest(); } else { @@ -106,7 +114,8 @@ const StdcmConfig = ({ const formErrorsStatus = checkStdcmConfigErrors( pathfinding.status !== 'success', pathSteps, - t + t, + searchDatetimeWindow ); setFormErrors(formErrorsStatus); } diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmDestination.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmDestination.tsx index 31e0a185904..c925e61eb7b 100644 --- a/front/src/applications/stdcm/components/StdcmForm/StdcmDestination.tsx +++ b/front/src/applications/stdcm/components/StdcmForm/StdcmDestination.tsx @@ -37,6 +37,7 @@ const StdcmDestination = ({ disabled = false }: StdcmConfigCardProps) => { ); const onArrivalChange = ({ date, hours, minutes }: ScheduleConstraint) => { + console.log('change date', date, hours, minutes); date.setHours(hours, minutes); dispatch( updateStdcmPathStep({ diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmOpSchedule.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmOpSchedule.tsx index 06890423654..614d5f7c200 100644 --- a/front/src/applications/stdcm/components/StdcmForm/StdcmOpSchedule.tsx +++ b/front/src/applications/stdcm/components/StdcmForm/StdcmOpSchedule.tsx @@ -166,6 +166,8 @@ const StdcmOpSchedule = ({ disabled={disabled} value={arrivalTime} readOnly={false} + // statusWithMessage={ + // } />
void; removeDestinationArrivalTime: () => void; }; const StdcmWarningBox = ({ - errorInfos: { errorType, errorDetails }, + errorInfos, removeOriginArrivalTime, removeDestinationArrivalTime, }: StdcmWarningBoxProps) => { @@ -32,23 +29,23 @@ const StdcmWarningBox = ({

- {t(`stdcmErrors.${errorType}`)} + {t(`stdcmErrors.${errorInfos.errorType}`)}

- {errorType === 'bothPointAreScheduled' && errorDetails && ( + {errorInfos.errorType === 'bothPointAreScheduled' && (
)} diff --git a/front/src/applications/stdcm/types.ts b/front/src/applications/stdcm/types.ts index 746ce92658d..b5234c060e0 100644 --- a/front/src/applications/stdcm/types.ts +++ b/front/src/applications/stdcm/types.ts @@ -160,12 +160,18 @@ export enum StdcmConfigErrorTypes { PATHFINDING_FAILED = 'pathfindingFailed', BOTH_POINT_SCHEDULED = 'bothPointAreScheduled', NO_SCHEDULED_POINT = 'noScheduledPoint', + INVALID_ORIGIN_TIME = 'invalidOriginTime', + INVALID_DESTINATION_TIME = 'invalidDestinationTime', } -export type StdcmConfigErrors = { - errorType: StdcmConfigErrorTypes; - errorDetails?: { originTime: string; destinationTime: string }; -}; +export type StdcmConfigErrors = + | { + errorType: Exclude; + } + | { + errorType: StdcmConfigErrorTypes.BOTH_POINT_SCHEDULED; + errorDetails: { originTime: string; destinationTime: string }; + }; export type ScheduleConstraint = { date: Date; diff --git a/front/src/applications/stdcm/utils/checkStdcmConfigErrors.ts b/front/src/applications/stdcm/utils/checkStdcmConfigErrors.ts index 279a2422f53..feca7381c99 100644 --- a/front/src/applications/stdcm/utils/checkStdcmConfigErrors.ts +++ b/front/src/applications/stdcm/utils/checkStdcmConfigErrors.ts @@ -1,14 +1,16 @@ import type { TFunction } from 'i18next'; import type { StdcmPathStep } from 'reducers/osrdconf/types'; -import { dateToHHMMSS } from 'utils/date'; +import { dateToHHMMSS, isArrivalDateInSearchTimeWindow } from 'utils/date'; import { StdcmConfigErrorTypes, ArrivalTimeTypes, type StdcmConfigErrors } from '../types'; const checkStdcmConfigErrors = ( pathfindingStateError: boolean, pathSteps: StdcmPathStep[], - t: TFunction + t: TFunction, + searchDatetimeWindow?: { begin: Date; end: Date }, + { simulationStarting = false }: { simulationStarting?: boolean } = {} ): StdcmConfigErrors | undefined => { if (pathSteps.some((step) => !step.location)) { return { errorType: StdcmConfigErrorTypes.MISSING_LOCATION }; @@ -27,6 +29,33 @@ const checkStdcmConfigErrors = ( return { errorType: StdcmConfigErrorTypes.PATHFINDING_FAILED }; } + console.log( + 'origin', + origin.arrival, + !origin.arrival || isArrivalDateInSearchTimeWindow(origin.arrival, searchDatetimeWindow) + ); + + if ( + simulationStarting && + origin.arrivalType === ArrivalTimeTypes.PRECISE_TIME && + (!origin.arrival || isArrivalDateInSearchTimeWindow(origin.arrival, searchDatetimeWindow)) + ) { + return { + errorType: StdcmConfigErrorTypes.INVALID_ORIGIN_TIME, + }; + } + + if ( + simulationStarting && + destination.arrivalType === ArrivalTimeTypes.PRECISE_TIME && + (!destination.arrival || + isArrivalDateInSearchTimeWindow(destination.arrival, searchDatetimeWindow)) + ) { + return { + errorType: StdcmConfigErrorTypes.INVALID_DESTINATION_TIME, + }; + } + const isOriginRespectDestinationSchedule = origin.arrivalType === ArrivalTimeTypes.RESPECT_DESTINATION_SCHEDULE;