diff --git a/front/public/locales/en/stdcm-simulation-report-sheet.json b/front/public/locales/en/stdcm-simulation-report-sheet.json index ac95f72cad8..5e87860e816 100644 --- a/front/public/locales/en/stdcm-simulation-report-sheet.json +++ b/front/public/locales/en/stdcm-simulation-report-sheet.json @@ -18,6 +18,7 @@ "passageStop": "passage", "refEngine": "Ref. engine", "referenceEngine": "reference engine", + "simulationStopType": "Type d'arrêt", "requestedRoute": "requested route", "scheduledArrival": "scheduled arrival on {{date}} at {{time}}", "scheduledDeparture": "scheduled departure on {{date}} at {{time}}", @@ -25,7 +26,7 @@ "simulation": "Simulation", "speedLimitByTag": "speed limit by tag", "startStop": "start", - "stdcm": "ST DCM", + "stdcm": "LMR", "stdcmCreation": "short term path creation", "stopType": "motif", "towedMaterial": "towed material", diff --git a/front/public/locales/fr/stdcm-simulation-report-sheet.json b/front/public/locales/fr/stdcm-simulation-report-sheet.json index 870f6689932..42b192900f4 100644 --- a/front/public/locales/fr/stdcm-simulation-report-sheet.json +++ b/front/public/locales/fr/stdcm-simulation-report-sheet.json @@ -18,6 +18,7 @@ "passageStop": "passage", "refEngine": "Engin de réf.", "referenceEngine": "engin de référence", + "simulationStopType": "Type d'arrêt", "requestedRoute": "parcours demandé", "scheduledArrival": "arrivée prévue le {{date}} à {{time}}", "scheduledDeparture": "départ prévu le {{date}} à {{time}}", @@ -25,7 +26,7 @@ "simulation": "Simulation", "speedLimitByTag": "code de composition", "startStop": "départ", - "stdcm": "ST DCM", + "stdcm": "LMR", "stdcmCreation": "Création de sillon de dernière minute", "stopType": "motif", "towedMaterial": "matériel remorqué", diff --git a/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx b/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx index dd1627faeec..b372e6cf3f0 100644 --- a/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx +++ b/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx @@ -12,7 +12,7 @@ import { capitalizeFirstLetter } from 'utils/strings'; import { secToMin } from 'utils/timeManipulation'; import styles from './SimulationReportStyleSheet'; -import type { SimulationReportSheetProps } from '../../types'; +import type { SimulationReportSheetProps, StdcmResultsOperationalPoint } from '../../types'; import { getStopDurationTime } from '../../utils/formatSimulationReportSheet'; const getSecondaryCode = ({ location }: StdcmPathStep) => location!.secondary_code; @@ -52,6 +52,20 @@ const SimulationReportSheet = ({ const convoyLength = consist?.totalLength ?? rollingStock.length; const convoyMaxSpeed = consist?.maxSpeed ?? msToKmh(rollingStock.max_speed); + const getStopTypeLabel = ( + isFirstStep: boolean, + isLastStep: boolean, + step: StdcmResultsOperationalPoint + ) => { + if (isFirstStep || isLastStep) { + return t('serviceStop'); + } + if (step?.stopType) { + return capitalizeFirstLetter(t(`stdcm:trainPath.stopType.${step.stopType}`)); + } + return ''; + }; + return ( @@ -291,6 +305,9 @@ const SimulationReportSheet = ({ {t('referenceEngine')} + + {t('simulationStopType')} + {operationalPointsList.map((step, index) => { const isFirstStep = index === 0; @@ -399,6 +416,11 @@ const SimulationReportSheet = ({ {!isFirstStep ? '=' : rollingStock.metadata?.reference} + + + {getStopTypeLabel(isFirstStep, isLastStep, step)} + + ); })} diff --git a/front/src/applications/stdcm/components/StdcmResults/StdcmResults.tsx b/front/src/applications/stdcm/components/StdcmResults/StdcmResults.tsx index f37abe5a018..85920b4cd5e 100644 --- a/front/src/applications/stdcm/components/StdcmResults/StdcmResults.tsx +++ b/front/src/applications/stdcm/components/StdcmResults/StdcmResults.tsx @@ -65,6 +65,7 @@ const StcdmResults = ({ return getOperationalPointsWithTimes( outputs.pathProperties?.suggestedOperationalPoints || [], outputs.results.simulation, + outputs.results.simulationPathSteps, outputs.results.departure_time ); }, [outputs]); diff --git a/front/src/applications/stdcm/types.ts b/front/src/applications/stdcm/types.ts index 035a6b1f1a5..f820f8d3758 100644 --- a/front/src/applications/stdcm/types.ts +++ b/front/src/applications/stdcm/types.ts @@ -70,6 +70,7 @@ export type StdcmResultsOperationalPoint = { duration: number; stopEndTime: string; trackName?: string; + stopType?: string; }; export type StdcmResults = { diff --git a/front/src/applications/stdcm/utils/formatSimulationReportSheet.ts b/front/src/applications/stdcm/utils/formatSimulationReportSheet.ts index 81e380e0df0..890f015ebfd 100644 --- a/front/src/applications/stdcm/utils/formatSimulationReportSheet.ts +++ b/front/src/applications/stdcm/utils/formatSimulationReportSheet.ts @@ -1,6 +1,8 @@ import type { SimulationResponse } from 'common/api/osrdEditoastApi'; +import { matchPathStepAndOp } from 'modules/pathfinding/utils'; import { interpolateValue } from 'modules/simulationResult/SimulationResultExport/utils'; import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types'; +import type { StdcmPathStep } from 'reducers/osrdconf/types'; import type { StdcmResultsOperationalPoint } from '../types'; @@ -106,6 +108,7 @@ export function getStopDurationBetweenTwoPositions( export function getOperationalPointsWithTimes( operationalPoints: SuggestedOP[], simulation: Extract, + pathSteps: StdcmPathStep[], departureTime: string ): StdcmResultsOperationalPoint[] { const { positions, times } = simulation.final_output; @@ -129,6 +132,15 @@ export function getOperationalPointsWithTimes( const durationToString = secondsToTimeString(durationInSeconds); const stopEndTime = computeStopDepartureTime(formattedTime, durationToString); + // Find the corresponding stopType from pathSteps + const correspondingStep = pathSteps.find( + (step) => step.location && matchPathStepAndOp(step.location, op) + ); + let stopType; + if (correspondingStep) { + stopType = !correspondingStep.isVia ? 'serviceStop' : correspondingStep.stopType; + } + return { opId: op.opId!, positionOnPath: op.positionOnPath, @@ -138,6 +150,7 @@ export function getOperationalPointsWithTimes( duration: durationInSeconds, stopEndTime, trackName: op.metadata?.trackName, + stopType, }; }); diff --git a/front/src/modules/pathfinding/utils.ts b/front/src/modules/pathfinding/utils.ts index 022e70dc658..97d2f46cd9d 100644 --- a/front/src/modules/pathfinding/utils.ts +++ b/front/src/modules/pathfinding/utils.ts @@ -43,7 +43,7 @@ export const formatSuggestedOperationalPoints = ( })); export const matchPathStepAndOp = ( - step: PathStep, + step: PathItemLocation, op: Pick ) => { if ('operational_point' in step) { diff --git a/front/src/reducers/osrdconf/stdcmConf/index.ts b/front/src/reducers/osrdconf/stdcmConf/index.ts index be8576ee1e5..ba172262715 100644 --- a/front/src/reducers/osrdconf/stdcmConf/index.ts +++ b/front/src/reducers/osrdconf/stdcmConf/index.ts @@ -55,6 +55,7 @@ export const stdcmConfSlice = createSlice({ state.totalMass = stdcmConfInitialState.totalMass; state.maxSpeed = stdcmConfInitialState.maxSpeed; state.speedLimitByTag = stdcmConfInitialState.speedLimitByTag; + state.linkedTrains = stdcmConfInitialState.linkedTrains; }, updateTotalMass( state: Draft, @@ -167,6 +168,18 @@ export const stdcmConfSlice = createSlice({ (pathStep) => pathStep.id !== action.payload ); }, + resetLinkedPathResults( + state: Draft, + action: PayloadAction + ) { + const extremityPathStep = action.payload; + + if (extremityPathStep === 'destination') { + state.linkedTrains.anteriorTrain = undefined; + } else { + state.linkedTrains.posteriorTrain = undefined; + } + }, updateLinkedTrainExtremity( state: Draft, action: PayloadAction<{