diff --git a/front/public/locales/en/operationalStudies/manageTrainSchedule.json b/front/public/locales/en/operationalStudies/manageTrainSchedule.json index 45c6572c79f..ef6e0947af7 100644 --- a/front/public/locales/en/operationalStudies/manageTrainSchedule.json +++ b/front/public/locales/en/operationalStudies/manageTrainSchedule.json @@ -91,6 +91,7 @@ "pathfinding": "Path search", "pathfindingDone": "Pathfinding done.", "pathfindingError": "An error occurred in pathfinding: {{errorMessage}}.", + "InvalidTrainScheduleStep": "At least one of the waypoints could not be recognized", "pathfindingInProgress": "Pathfinding in progress…", "pathfindingMissingParams": "Missing parameters for pathfinding: {{missingElements}}.", "pathfindingMissingParamsSimple": "Missing information for the search", diff --git a/front/public/locales/fr/operationalStudies/manageTrainSchedule.json b/front/public/locales/fr/operationalStudies/manageTrainSchedule.json index 1a7b6f70463..c7d1eac9065 100644 --- a/front/public/locales/fr/operationalStudies/manageTrainSchedule.json +++ b/front/public/locales/fr/operationalStudies/manageTrainSchedule.json @@ -91,6 +91,7 @@ "pathfinding": "Recherche d’itinéraire", "pathfindingDone": "Recherche d'itinéraire terminée.", "pathfindingError": "Erreur dans la recherche d’itinéraire : {{errorMessage}}.", + "InvalidTrainScheduleStep": "Au moins un des points de passage n'a pas été reconnu", "pathfindingInProgress": "Recherche d’itinéraire en cours…", "pathfindingMissingParams": "Éléments manquants pour la recherche : {{missingElements}}.", "pathfindingMissingParamsSimple": "Informations manquantes pour la recherche", diff --git a/front/src/modules/pathfinding/components/Pathfinding/Pathfinding.tsx b/front/src/modules/pathfinding/components/Pathfinding/Pathfinding.tsx index 18cf6b00ded..b36ab2662cd 100644 --- a/front/src/modules/pathfinding/components/Pathfinding/Pathfinding.tsx +++ b/front/src/modules/pathfinding/components/Pathfinding/Pathfinding.tsx @@ -1,3 +1,5 @@ +import { useEffect } from 'react'; + import { Alert, CheckCircle, Stop } from '@osrd-project/ui-icons'; import cx from 'classnames'; import { isEqual } from 'lodash'; @@ -10,6 +12,7 @@ import infraLogo from 'assets/pictures/components/tracks.svg'; import { Spinner } from 'common/Loaders'; import { useOsrdConfSelectors } from 'common/osrdContext'; import { usePathfinding } from 'modules/pathfinding/hooks/usePathfinding'; +import { isPathStepInvalid } from 'modules/pathfinding/utils'; import { useStoreDataForRollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector/useStoreDataForRollingStockSelector'; import { conditionalStringConcat, formatKmValue } from 'utils/strings'; @@ -23,13 +26,16 @@ type PathfindingProps = { const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) => { const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); - const { getOrigin, getDestination } = useOsrdConfSelectors(); + const { getOrigin, getDestination, getPathSteps } = useOsrdConfSelectors(); + const pathSteps = useSelector(getPathSteps); + const hasInvalidPathStep = pathSteps.some((pathStep) => isPathStepInvalid(pathStep)); const origin = useSelector(getOrigin, isEqual); const destination = useSelector(getDestination, isEqual); const { rollingStock } = useStoreDataForRollingStockSelector(); const { pathfindingState, + pathfindingDispatch, infraInfos: { infra, reloadCount }, } = usePathfinding(setPathProperties, pathProperties); @@ -61,7 +67,8 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) => !pathfindingState.running && pathfindingState.done && origin && - destination && ( + destination && + !hasInvalidPathStep && (
@@ -83,7 +90,7 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) =>
) : ( <> - {pathfindingState.error && ( + {(pathfindingState.error || hasInvalidPathStep) && (
- {t('pathfindingError', { errorMessage: t(pathfindingState.error) })} + {hasInvalidPathStep + ? t('InvalidTrainScheduleStep') + : t('pathfindingError', { errorMessage: t(pathfindingState.error) })}
)} diff --git a/front/src/modules/pathfinding/hooks/usePathfinding.ts b/front/src/modules/pathfinding/hooks/usePathfinding.ts index 72f68893177..c9d26089106 100644 --- a/front/src/modules/pathfinding/hooks/usePathfinding.ts +++ b/front/src/modules/pathfinding/hooks/usePathfinding.ts @@ -6,7 +6,6 @@ import { useSelector } from 'react-redux'; import type { ManageTrainSchedulePathProperties } from 'applications/operationalStudies/types'; import type { - PathfindingInputError, PostInfraByInfraIdPathPropertiesApiArg, PostInfraByInfraIdPathfindingBlocksApiArg, RollingStockWithLiveries, @@ -18,7 +17,6 @@ import type { PathfindingAction, PathfindingState } from 'modules/pathfinding/ty import { formatSuggestedOperationalPoints, getPathfindingQuery, - matchPathStepAndOp, upsertPathStepsInOPs, } from 'modules/pathfinding/utils'; import { useStoreDataForRollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector/useStoreDataForRollingStockSelector'; @@ -181,18 +179,7 @@ export const usePathfinding = ( const generatePathfindingParams = (): PostInfraByInfraIdPathfindingBlocksApiArg | null => { setPathProperties?.(undefined); - - const filteredPathSteps = pathSteps.filter( - (step) => step !== null && step.coordinates !== null && !step.isInvalid - ); - - return getPathfindingQuery({ - infraId, - rollingStock, - origin, - destination, - pathSteps: filteredPathSteps, - }); + return getPathfindingQuery({ infraId, rollingStock, origin, destination, pathSteps }); }; useEffect(() => { @@ -219,36 +206,7 @@ export const usePathfinding = ( }, }); } - }, [origin?.id, destination?.id, rollingStock]); - - const handleInvalidPathItems = ( - steps: (PathStep | null)[], - invalidPathItems: Extract['items'] - ) => { - // TODO: we currently only handle invalid pathSteps with trigram. We will have to do it for trackOffset, opId and uic too. - const invalidTrigrams = invalidPathItems - .map((item) => { - if ('trigram' in item.path_item) { - return item.path_item.trigram; - } - return null; - }) - .filter((trigram): trigram is string => trigram !== null); - if (invalidTrigrams.length > 0) { - const updatedPathSteps = steps.map((step) => { - if (step && 'trigram' in step && invalidTrigrams.includes(step.trigram)) { - return { ...step, isInvalid: true }; - } - return step; - }); - - dispatch(updatePathSteps({ pathSteps: updatedPathSteps })); - pathfindingDispatch({ type: 'PATHFINDING_FINISHED' }); - pathfindingDispatch({ type: 'PATHFINDING_PARAM_CHANGED' }); - } else { - dispatch(setFailure({ name: t('pathfindingError'), message: t('missingPathSteps') })); - } - }; + }, [origin, destination, rollingStock]); useEffect(() => { const startPathFinding = async () => { @@ -271,13 +229,8 @@ export const usePathfinding = ( pathfindingResult.status === 'failure' && pathfindingResult.failed_status === 'pathfinding_not_found' && pathfindingResult.error_type === 'incompatible_constraints'; - if ( - pathfindingResult.status === 'failure' && - pathfindingResult.failed_status === 'pathfinding_input_error' && - pathfindingResult.error_type === 'invalid_path_items' - ) { - handleInvalidPathItems(pathSteps, pathfindingResult.items); - } else if (pathfindingResult.status === 'success' || incompatibleConstraintsCheck) { + + if (pathfindingResult.status === 'success' || incompatibleConstraintsCheck) { const pathResult = pathfindingResult.status === 'success' ? pathfindingResult @@ -303,8 +256,9 @@ export const usePathfinding = ( // We update existing pathsteps with coordinates, positionOnPath and kp corresponding to the new pathfinding result const updatedPathSteps: (PathStep | null)[] = pathSteps.map((step, i) => { if (!step) return step; - const correspondingOp = suggestedOperationalPoints.find((suggestedOp) => - matchPathStepAndOp(step, suggestedOp) + const correspondingOp = suggestedOperationalPoints.find( + (suggestedOp) => + 'uic' in step && suggestedOp.uic === step.uic && suggestedOp.ch === step.ch ); const theoreticalMargin = i === 0 ? '0%' : step.theoreticalMargin;