From 205ed7423a83571a14b38220c62215afe0278db1 Mon Sep 17 00:00:00 2001 From: Achraf Mohyeddine Date: Mon, 23 Dec 2024 16:42:24 +0100 Subject: [PATCH] front: enhance lmr report sheet and fix linked paths Signed-off-by: Achraf Mohyeddine --- .../en/stdcm-simulation-report-sheet.json | 3 ++- .../fr/stdcm-simulation-report-sheet.json | 3 ++- .../StdcmForm/StdcmLinkedPathSearch.tsx | 15 +++++++++++- .../StdcmResults/SimulationReportSheet.tsx | 24 ++++++++++++++++++- .../components/StdcmResults/StdcmResults.tsx | 1 + .../stdcm/hooks/useLinkedPathSearch.ts | 1 + front/src/applications/stdcm/types.ts | 1 + .../utils/formatSimulationReportSheet.ts | 13 +++++++++- .../src/reducers/osrdconf/stdcmConf/index.ts | 13 ++++++++++ 9 files changed, 69 insertions(+), 5 deletions(-) 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/StdcmForm/StdcmLinkedPathSearch.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmLinkedPathSearch.tsx index 30cde1c5d2f..59e45c58612 100644 --- a/front/src/applications/stdcm/components/StdcmForm/StdcmLinkedPathSearch.tsx +++ b/front/src/applications/stdcm/components/StdcmForm/StdcmLinkedPathSearch.tsx @@ -3,8 +3,11 @@ import { useState, type ReactNode } from 'react'; import { DatePicker, Input } from '@osrd-project/ui-core'; import { Gear } from '@osrd-project/ui-icons'; import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; import useLinkedPathSearch from 'applications/stdcm/hooks/useLinkedPathSearch'; +import { useOsrdConfActions } from 'common/osrdContext'; +import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf'; import StdcmCard from './StdcmCard'; import StdcmDefaultCard from './StdcmDefaultCard'; @@ -29,7 +32,9 @@ const StdcmLinkedPathSearch = ({ linkedOp, }: StdcmLinkedPathSearchProps) => { const { t } = useTranslation('stdcm'); + const dispatch = useDispatch(); const [displayLinkedPathSearch, setShowLinkedPathSearch] = useState(false); + const { resetLinkedPathResults } = useOsrdConfActions() as StdcmConfSliceActions; const { displaySearchButton, @@ -42,8 +47,16 @@ const StdcmLinkedPathSearch = ({ setLinkedPathDate, setTrainNameInput, trainNameInput, + setLinkedPathResults, } = useLinkedPathSearch(); + const handleResetLinkedPathSearch = () => { + setShowLinkedPathSearch(false); + dispatch(resetLinkedPathResults(linkedOp.extremityType)); + setLinkedPathResults([]); + setTrainNameInput(''); + }; + return (
{!displayLinkedPathSearch ? ( @@ -59,7 +72,7 @@ const StdcmLinkedPathSearch = ({ disabled={disabled} name={cardName} title={ - } diff --git a/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx b/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx index 7fd6df3bdb5..acc036abd56 100644 --- a/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx +++ b/front/src/applications/stdcm/components/StdcmResults/SimulationReportSheet.tsx @@ -11,7 +11,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 SimulationReportSheet = ({ @@ -46,6 +46,20 @@ const SimulationReportSheet = ({ return ''; }; + 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 ( @@ -295,6 +309,9 @@ const SimulationReportSheet = ({ {t('referenceEngine')} + + {t('simulationStopType')} + {operationalPointsList.map((step, index) => { const isFirstStep = index === 0; @@ -405,6 +422,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 51f2aa8feca..6e1d5c1e0c5 100644 --- a/front/src/applications/stdcm/components/StdcmResults/StdcmResults.tsx +++ b/front/src/applications/stdcm/components/StdcmResults/StdcmResults.tsx @@ -64,6 +64,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/hooks/useLinkedPathSearch.ts b/front/src/applications/stdcm/hooks/useLinkedPathSearch.ts index 0f35d41ccca..8e4b2ee6fe1 100644 --- a/front/src/applications/stdcm/hooks/useLinkedPathSearch.ts +++ b/front/src/applications/stdcm/hooks/useLinkedPathSearch.ts @@ -123,6 +123,7 @@ const useLinkedPathSearch = () => { setLinkedPathDate, setTrainNameInput, trainNameInput, + setLinkedPathResults, }; }; diff --git a/front/src/applications/stdcm/types.ts b/front/src/applications/stdcm/types.ts index 33320242e01..96a508246bf 100644 --- a/front/src/applications/stdcm/types.ts +++ b/front/src/applications/stdcm/types.ts @@ -76,6 +76,7 @@ export type StdcmResultsOperationalPoint = { departureTime: string; 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 e59d33124cb..49f508b5e13 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 { PathStep } from 'reducers/osrdconf/types'; import type { StdcmResultsOperationalPoint } from '../types'; @@ -112,6 +114,7 @@ export function getStopDurationBetweenTwoPositions( export function getOperationalPointsWithTimes( operationalPoints: SuggestedOP[], simulation: Extract, + pathSteps: PathStep[], departureTime: string ): StdcmResultsOperationalPoint[] { const { positions, times } = simulation.final_output; @@ -121,7 +124,10 @@ export function getOperationalPointsWithTimes( const [departureHour, departureMinute] = pathDepartureTime.split(':').map(Number); // Map operational points with their positions, times, and stop durations - const opResults = operationalPoints.map((op) => { + const opResults = operationalPoints.map((op, index) => { + const isFirst = index === 0; + const isLast = index === operationalPoints.length - 1; + const formattedTime = getTimeAtPosition( op.positionOnPath, positions, @@ -135,6 +141,10 @@ export function getOperationalPointsWithTimes( const durationToString = secondsToTimeString(durationInSeconds); const stopEndTime = computeStopDepartureTime(formattedTime, durationToString); + // Find the corresponding stopType from pathSteps + const correspondingStep = pathSteps.find((step) => step && matchPathStepAndOp(step, op)); + const stopType = isFirst || isLast ? 'serviceStop' : correspondingStep?.stopType; + return { opId: op.opId!, positionOnPath: op.positionOnPath, @@ -145,6 +155,7 @@ export function getOperationalPointsWithTimes( departureTime, stopEndTime, trackName: op.metadata?.trackName, + stopType, }; }); diff --git a/front/src/reducers/osrdconf/stdcmConf/index.ts b/front/src/reducers/osrdconf/stdcmConf/index.ts index b960299dc63..f2b4bfa5641 100644 --- a/front/src/reducers/osrdconf/stdcmConf/index.ts +++ b/front/src/reducers/osrdconf/stdcmConf/index.ts @@ -58,6 +58,7 @@ export const stdcmConfSlice = createSlice({ state.totalMass = stdcmConfInitialState.totalMass; state.maxSpeed = stdcmConfInitialState.maxSpeed; state.speedLimitByTag = stdcmConfInitialState.speedLimitByTag; + state.linkedPaths = stdcmConfInitialState.linkedPaths; }, updateTotalMass( state: Draft, @@ -171,6 +172,18 @@ export const stdcmConfSlice = createSlice({ (pathStep) => pathStep.id !== action.payload ); }, + resetLinkedPathResults( + state: Draft, + action: PayloadAction + ) { + const extremityPathStep = action.payload; + + if (extremityPathStep === 'destination') { + state.linkedPaths.anteriorPath = undefined; + } else { + state.linkedPaths.posteriorPath = undefined; + } + }, updateLinkedPathStep( state: Draft, action: PayloadAction<{