From b41838d9ca107f94073ca5c6637ad890f99ebc59 Mon Sep 17 00:00:00 2001 From: SharglutDev Date: Mon, 2 Sep 2024 17:27:34 +0200 Subject: [PATCH] front: manchette: display waypoints added with map click --- front/public/locales/en/simulation.json | 1 + front/public/locales/fr/simulation.json | 1 + .../hooks/useScenarioData.ts | 6 ++ .../views/v2/ScenarioV2.tsx | 2 + .../views/v2/SimulationResultsV2.tsx | 4 ++ .../useGetProjectedTrainOperationalPoints.ts | 64 +++++++++++++++---- 6 files changed, 67 insertions(+), 11 deletions(-) diff --git a/front/public/locales/en/simulation.json b/front/public/locales/en/simulation.json index 5cd0bf57f69..91d4df4cdbe 100644 --- a/front/public/locales/en/simulation.json +++ b/front/public/locales/en/simulation.json @@ -34,6 +34,7 @@ "used": "used" }, "projectionInProgress": "Projection in progress: {{ count }}/{{ total }} trains", + "requestedPoint": "requested point ({{ count }})", "reset": "Reset the chart", "resetTimer": "Reset timer", "rotate": "Rotate the chart", diff --git a/front/public/locales/fr/simulation.json b/front/public/locales/fr/simulation.json index e12a14187db..fd140ae9047 100644 --- a/front/public/locales/fr/simulation.json +++ b/front/public/locales/fr/simulation.json @@ -34,6 +34,7 @@ "used": "utilisée" }, "projectionInProgress": "Projection en cours: {{ count }}/{{ total }} trains", + "requestedPoint": "point demandé ({{ count }})", "reset": "Réinitialiser le graphique", "resetTimer": "Réinitialiser le compteur", "rotate": "Pivoter le graphique", diff --git a/front/src/applications/operationalStudies/hooks/useScenarioData.ts b/front/src/applications/operationalStudies/hooks/useScenarioData.ts index 85ceb24e768..01d6ccf206b 100644 --- a/front/src/applications/operationalStudies/hooks/useScenarioData.ts +++ b/front/src/applications/operationalStudies/hooks/useScenarioData.ts @@ -92,6 +92,11 @@ const useScenarioData = () => { [projectedTrainsById] ); + const trainScheduleUsedForProjection = useMemo( + () => trainSchedules?.find((trainSchedule) => trainSchedule.id === trainIdUsedForProjection), + [trainIdUsedForProjection, trainSchedules] + ); + useEffect(() => { if (!rawTrainSchedules) { setTrainSchedules(undefined); @@ -193,6 +198,7 @@ const useScenarioData = () => { infra: { infra, isInfraLoaded, reloadCount }, trainScheduleSummaries, trainSchedules, + trainScheduleUsedForProjection, trainIdUsedForProjection, projectedTrains, simulationResults, diff --git a/front/src/applications/operationalStudies/views/v2/ScenarioV2.tsx b/front/src/applications/operationalStudies/views/v2/ScenarioV2.tsx index 8c6d9fc442c..5d30d7bd19f 100644 --- a/front/src/applications/operationalStudies/views/v2/ScenarioV2.tsx +++ b/front/src/applications/operationalStudies/views/v2/ScenarioV2.tsx @@ -97,6 +97,7 @@ const Scenario = () => { infra: { infra, isInfraLoaded, reloadCount }, trainScheduleSummaries, trainSchedules, + trainScheduleUsedForProjection, trainIdUsedForProjection, projectedTrains, simulationResults, @@ -308,6 +309,7 @@ const Scenario = () => { collapsedTimetable={collapsedTimetable} spaceTimeData={projectedTrains} simulationResults={simulationResults} + trainScheduleUsedForProjection={trainScheduleUsedForProjection} trainIdUsedForProjection={trainIdUsedForProjection} infraId={infraId} timetableTrainNb={timetable.train_ids.length} diff --git a/front/src/applications/operationalStudies/views/v2/SimulationResultsV2.tsx b/front/src/applications/operationalStudies/views/v2/SimulationResultsV2.tsx index 22ca872af3c..3b5ebf0d45d 100644 --- a/front/src/applications/operationalStudies/views/v2/SimulationResultsV2.tsx +++ b/front/src/applications/operationalStudies/views/v2/SimulationResultsV2.tsx @@ -8,6 +8,7 @@ import { useSelector } from 'react-redux'; import { Rnd } from 'react-rnd'; import type { SimulationResults, TrainSpaceTimeData } from 'applications/operationalStudies/types'; +import type { TrainScheduleResult } from 'common/api/osrdEditoastApi'; import SimulationWarpedMap from 'common/Map/WarpedMap/SimulationWarpedMap'; import { getScaleDomainFromValuesV2 } from 'modules/simulationResult/components/ChartHelpers/getScaleDomainFromValues'; import SimulationResultsMapV2 from 'modules/simulationResult/components/SimulationResultsMapV2'; @@ -33,6 +34,7 @@ type SimulationResultsV2Props = { collapsedTimetable: boolean; spaceTimeData?: TrainSpaceTimeData[]; infraId?: number; + trainScheduleUsedForProjection?: TrainScheduleResult; trainIdUsedForProjection?: number; simulationResults: SimulationResults; timetableTrainNb: number; @@ -42,6 +44,7 @@ const SimulationResultsV2 = ({ collapsedTimetable, spaceTimeData, infraId, + trainScheduleUsedForProjection, trainIdUsedForProjection, simulationResults: { selectedTrainSchedule, @@ -88,6 +91,7 @@ const SimulationResultsV2 = ({ ); const projectedOperationalPoints = useGetProjectedTrainOperationalPoints( + trainScheduleUsedForProjection, trainIdUsedForProjection, infraId ); diff --git a/front/src/modules/simulationResult/components/SpaceTimeChart/useGetProjectedTrainOperationalPoints.ts b/front/src/modules/simulationResult/components/SpaceTimeChart/useGetProjectedTrainOperationalPoints.ts index 1e235bcb6d0..8964b3621fe 100644 --- a/front/src/modules/simulationResult/components/SpaceTimeChart/useGetProjectedTrainOperationalPoints.ts +++ b/front/src/modules/simulationResult/components/SpaceTimeChart/useGetProjectedTrainOperationalPoints.ts @@ -1,24 +1,29 @@ import { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + import { STDCM_TRAIN_ID } from 'applications/stdcm/consts'; import { osrdEditoastApi, type PathProperties, - type PostInfraByInfraIdPathPropertiesApiArg, + type TrainScheduleResult, } from 'common/api/osrdEditoastApi'; +import { addElementAtIndex } from 'utils/array'; const useGetProjectedTrainOperationalPoints = ( + trainScheduleUsedForProjection?: TrainScheduleResult, trainIdUsedForProjection?: number, infraId?: number ) => { + const { t } = useTranslation('simulation'); const [operationalPoints, setOperationalPoints] = useState< NonNullable >([]); const { data: pathfindingResult } = osrdEditoastApi.endpoints.getTrainScheduleByIdPath.useQuery( { - id: trainIdUsedForProjection as number, - infraId: infraId as number, + id: trainIdUsedForProjection!, + infraId: infraId!, }, { skip: !trainIdUsedForProjection || !infraId || trainIdUsedForProjection === STDCM_TRAIN_ID, @@ -30,23 +35,60 @@ const useGetProjectedTrainOperationalPoints = ( useEffect(() => { const getOperationalPoints = async () => { - if (infraId && pathfindingResult && pathfindingResult.status === 'success') { - const pathPropertiesParams: PostInfraByInfraIdPathPropertiesApiArg = { + if (infraId && trainScheduleUsedForProjection && pathfindingResult?.status === 'success') { + const { operational_points } = await postPathProperties({ infraId, props: ['operational_points'], pathPropertiesInput: { track_section_ranges: pathfindingResult.track_section_ranges, }, - }; - const { operational_points } = await postPathProperties(pathPropertiesParams).unwrap(); + }).unwrap(); + + let operationalPointsWithAllWaypoints = operational_points!; + + // Check if there are vias added by map click and insert them in the operational points + let waypointCounter = 1; + + trainScheduleUsedForProjection.path.forEach((step, i) => { + if (!('track' in step)) return; + + const positionOnPath = pathfindingResult.path_item_positions[i]; + const indexToInsert = operationalPointsWithAllWaypoints.findIndex( + (op) => op.position >= positionOnPath + ); + + const formattedStep: NonNullable[number] = { + id: step.id, + extensions: { + identifier: { + name: t('requestedPoint', { count: waypointCounter }), + uic: 0, + }, + }, + part: { track: step.track, position: step.offset }, + position: positionOnPath, + }; + + waypointCounter += 1; + + // If we can't find any op position greater than the current step position, we add it at the end + if (indexToInsert === -1) { + operationalPointsWithAllWaypoints.push(formattedStep); + return; + } + + operationalPointsWithAllWaypoints = addElementAtIndex( + operationalPointsWithAllWaypoints, + indexToInsert, + formattedStep + ); + }); - setOperationalPoints( - operational_points as NonNullable - ); + setOperationalPoints(operationalPointsWithAllWaypoints); } }; getOperationalPoints(); - }, [pathfindingResult, infraId]); + }, [pathfindingResult, infraId, t]); return operationalPoints; };