From 6efc220a4459710d84a970269c75f8e410fad408 Mon Sep 17 00:00:00 2001 From: SharglutDev Date: Fri, 5 Jan 2024 17:11:17 +0100 Subject: [PATCH] front: improve simulation results performances --- .../Scenario/getSimulationResults.ts | 60 +++++++------- .../operationalStudies/views/Scenario.tsx | 23 +++++- .../views/SimulationResults.tsx | 7 +- .../stdcm/views/StdcmRequestModal.tsx | 79 ++++++++++--------- .../SpaceTimeChart/SpaceTimeChart.tsx | 4 +- .../SpaceTimeChart/withOSRDData.tsx | 8 +- .../components/SpeedSpaceChart/sampleData.ts | 1 - .../components/simulationResultsHelpers.ts | 1 - .../SubmitConfAddTrainSchedule.tsx | 5 +- .../SubmitConfUpdateTrainSchedules.tsx | 20 +++-- .../components/Timetable/Timetable.tsx | 26 +++++- .../TimetableManageTrainSchedule.tsx | 4 + .../Timetable/TimetableTrainCard.tsx | 23 +++++- front/src/reducers/osrdsimulation/index.ts | 8 -- .../src/reducers/osrdsimulation/selectors.ts | 1 - front/src/reducers/osrdsimulation/types.ts | 1 - 16 files changed, 172 insertions(+), 99 deletions(-) diff --git a/front/src/applications/operationalStudies/components/Scenario/getSimulationResults.ts b/front/src/applications/operationalStudies/components/Scenario/getSimulationResults.ts index d11eced8db1..879e3b80720 100644 --- a/front/src/applications/operationalStudies/components/Scenario/getSimulationResults.ts +++ b/front/src/applications/operationalStudies/components/Scenario/getSimulationResults.ts @@ -10,12 +10,14 @@ import { store } from 'store'; import i18n from 'i18next'; import { SimulationReport, - TimetableWithSchedulesDetails, TrainScheduleSummary, osrdEditoastApi, } from 'common/api/osrdEditoastApi'; import { extractMessageFromError } from 'utils/error'; import { AllowancesSettings, Projection } from 'reducers/osrdsimulation/types'; +import { ApiError } from 'common/api/baseGeneratedApis'; +import { SerializedError } from '@reduxjs/toolkit'; +import { differenceBy } from 'lodash'; export function selectProjection( trainSchedules: TrainScheduleSummary[], @@ -79,32 +81,36 @@ export function selectProjection( } /** - * Recover the time table for all the trains + * - If first load of the scenario, get all timetable trains results and update the simulation. + * - If adding/updating train(s), get these train results and update the simulation. + * - If deleting train(s) and there are still trains in the timetable, do nothing */ export default async function getSimulationResults( - timetable: TimetableWithSchedulesDetails, + trainSchedulesIDs: number[], selectedProjection: Projection, - allowancesSettings?: AllowancesSettings + allowancesSettings?: AllowancesSettings, + simulation?: SimulationReport[] ) { - store.dispatch(updateIsUpdating(true)); - const trainSchedulesIDs = timetable.train_schedule_summaries.map((train) => train.id); - if (trainSchedulesIDs.length > 0) { - // We use this syntax first because of the .initiate, to be able to unsubscribe from the results later - const results = store.dispatch( - osrdEditoastApi.endpoints.getTrainScheduleResults.initiate({ - timetableId: timetable.id, - pathId: selectedProjection.path, - }) - ); + store.dispatch(updateIsUpdating(true)); + try { + let simulationLocal = await store + .dispatch( + osrdEditoastApi.endpoints.postTrainScheduleResults.initiate({ + body: { + path_id: selectedProjection.path, + train_ids: trainSchedulesIDs, + }, + }) + ) + .unwrap(); - const { - data: simulationLocal, - isError: isGetTrainScheduleResultsError, - error: getTrainScheduleResultsError, - } = await results; + // Means that we are adding or updating a train and we need to add it in the present simulation + if (simulation) { + const unaffectedTrains = differenceBy(simulation, simulationLocal, 'id'); + simulationLocal = unaffectedTrains.concat(simulationLocal); + } - if (simulationLocal) { const sortedSimulationLocal = [...simulationLocal].sort( (a: SimulationReport, b: SimulationReport) => a.base.stops[0].time - b.base.stops[0].time ); @@ -123,23 +129,19 @@ export default async function getSimulationResults( } }); store.dispatch(updateAllowancesSettings(newAllowancesSettings)); - store.dispatch(updateIsUpdating(false)); - } else if (isGetTrainScheduleResultsError && getTrainScheduleResultsError) { + } catch (e) { store.dispatch( setFailure({ name: i18n.t('simulation:errorMessages.unableToRetrieveTrainSchedule'), - message: extractMessageFromError(getTrainScheduleResultsError), + message: extractMessageFromError(e as ApiError | SerializedError), }) ); + console.error('trainScheduleResults error : ', e); + } finally { store.dispatch(updateIsUpdating(false)); - console.error(getTrainScheduleResultsError); } - - // Manually dispatching an RTK request with .initiate will create a subscription entry, but we need to unsubscribe from that data also manually - otherwise the data stays in the cache permanently. - results.unsubscribe(); - } else { + } else if (!simulation) { store.dispatch(updateSimulation({ trains: [] })); - store.dispatch(updateIsUpdating(false)); store.dispatch(updateSelectedTrainId(undefined)); store.dispatch(updateSelectedProjection(undefined)); } diff --git a/front/src/applications/operationalStudies/views/Scenario.tsx b/front/src/applications/operationalStudies/views/Scenario.tsx index 8147fad0143..d056feba89b 100644 --- a/front/src/applications/operationalStudies/views/Scenario.tsx +++ b/front/src/applications/operationalStudies/views/Scenario.tsx @@ -20,7 +20,7 @@ import getSimulationResults, { import NavBarSNCF from 'common/BootstrapSNCF/NavBarSNCF'; import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { SimulationReport, osrdEditoastApi } from 'common/api/osrdEditoastApi'; import { useInfraID, useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; import Timetable from 'modules/trainschedule/components/Timetable/Timetable'; @@ -32,6 +32,7 @@ import type { RootState } from 'reducers'; import { updateSelectedProjection, updateSimulation } from 'reducers/osrdsimulation/actions'; import { getAllowancesSettings, + getPresentSimulation, getSelectedProjection, getSelectedTrainId, } from 'reducers/osrdsimulation/selectors'; @@ -52,6 +53,7 @@ export default function Scenario() { const [collapsedTimetable, setCollapsedTimetable] = useState(false); const [isInfraLoaded, setIsInfraLoaded] = useState(false); const [reloadCount, setReloadCount] = useState(1); + const [trainResultsToFetch, setTrainResultsToFetch] = useState(); const isUpdating = useSelector((state: RootState) => state.osrdsimulation.isUpdating); const { openModal } = useModal(); @@ -68,6 +70,7 @@ export default function Scenario() { const selectedTrainId = useSelector(getSelectedTrainId); const selectedProjection = useSelector(getSelectedProjection); const allowancesSettings = useSelector(getAllowancesSettings); + const simulation = useSelector(getPresentSimulation); const { projectId, studyId, scenarioId } = useMemo( () => ({ @@ -173,7 +176,19 @@ export default function Scenario() { useEffect(() => { if (timetable && infra?.state === 'CACHED' && selectedProjection) { - getSimulationResults(timetable, selectedProjection, allowancesSettings); + // If trainResultsToFetch is undefined that means it's the first load of the scenario + // and we want to get all timetable trains results + if (trainResultsToFetch) { + getSimulationResults( + trainResultsToFetch, + selectedProjection, + allowancesSettings, + simulation.trains as SimulationReport[] + ); + } else { + const trainScheduleIds = timetable.train_schedule_summaries.map((train) => train.id); + getSimulationResults(trainScheduleIds, selectedProjection, allowancesSettings); + } } }, [timetable, infra, selectedProjection]); @@ -281,6 +296,7 @@ export default function Scenario() { )} @@ -347,6 +365,7 @@ export default function Scenario() { displayTrainScheduleManagement !== MANAGE_TRAIN_SCHEDULE_TYPES.import } collapsedTimetable={collapsedTimetable} + setTrainResultsToFetch={setTrainResultsToFetch} /> )} diff --git a/front/src/applications/operationalStudies/views/SimulationResults.tsx b/front/src/applications/operationalStudies/views/SimulationResults.tsx index e8e4dd3e64e..842631efdcf 100644 --- a/front/src/applications/operationalStudies/views/SimulationResults.tsx +++ b/front/src/applications/operationalStudies/views/SimulationResults.tsx @@ -10,7 +10,6 @@ import { persistentUndoSimulation, } from 'reducers/osrdsimulation/simulation'; import { - getDisplaySimulation, getIsUpdating, getPresentSimulation, getSelectedTrain, @@ -37,17 +36,18 @@ const MAP_MIN_HEIGHT = 450; type SimulationResultsProps = { isDisplayed: boolean; collapsedTimetable: boolean; + setTrainResultsToFetch: (trainSchedulesIDs?: number[]) => void; }; export default function SimulationResults({ isDisplayed, collapsedTimetable, + setTrainResultsToFetch, }: SimulationResultsProps) { const { t } = useTranslation('simulation'); const dispatch = useDispatch(); // TIMELINE DISABLED // const { chart } = useSelector(getOsrdSimulation); - const displaySimulation = useSelector(getDisplaySimulation); const selectedTrain = useSelector(getSelectedTrain); const simulation = useSelector(getPresentSimulation); const isUpdating = useSelector(getIsUpdating); @@ -167,11 +167,12 @@ export default function SimulationResults({
- {displaySimulation && ( + {simulation.trains.length > 0 && ( )}
diff --git a/front/src/applications/stdcm/views/StdcmRequestModal.tsx b/front/src/applications/stdcm/views/StdcmRequestModal.tsx index f308f7a0447..24b0f76a182 100644 --- a/front/src/applications/stdcm/views/StdcmRequestModal.tsx +++ b/front/src/applications/stdcm/views/StdcmRequestModal.tsx @@ -46,8 +46,10 @@ export default function StdcmRequestModal(props: StdcmRequestModalProps) { const dispatch = useDispatch(); const [postStdcm] = osrdEditoastApi.endpoints.postStdcm.useMutation(); - const [getTrainScheduleResults] = - osrdEditoastApi.endpoints.getTrainScheduleResults.useLazyQuery(); + const [postTrainScheduleResults] = + osrdEditoastApi.endpoints.postTrainScheduleResults.useMutation(); + + const [getTimetable] = osrdEditoastApi.endpoints.getTimetableById.useLazyQuery(); const { updateItinerary } = useOsrdConfActions(); @@ -58,11 +60,11 @@ export default function StdcmRequestModal(props: StdcmRequestModalProps) { // https://developer.mozilla.org/en-US/docs/Web/API/AbortController const controller = new AbortController(); - const timetableId = osrdconf.timetableID; + const { timetableID } = osrdconf; useEffect(() => { const payload = formatStdcmConf(dispatch, t, osrdconf as OsrdStdcmConfState); - if (payload && currentStdcmRequestStatus === STDCM_REQUEST_STATUS.pending && timetableId) { + if (payload && currentStdcmRequestStatus === STDCM_REQUEST_STATUS.pending && timetableID) { postStdcm(payload) .unwrap() .then((result) => { @@ -75,39 +77,44 @@ export default function StdcmRequestModal(props: StdcmRequestModalProps) { id: 1500, isStdcm: true, }; - - getTrainScheduleResults({ - timetableId, - pathId: result.path.id, - }) - .unwrap() - .then((timetableTrains) => { - const trains: SimulationReport[] = [...timetableTrains, fakedNewTrain]; - const consolidatedSimulation = createTrain( - dispatch, - CHART_AXES.SPACE_TIME, - trains as Train[], // TODO: remove Train interface - t - ); - dispatch(updateConsolidatedSimulation(consolidatedSimulation)); - dispatch(updateSimulation({ trains })); - dispatch(updateSelectedTrainId(fakedNewTrain.id)); - - dispatch( - updateSelectedProjection({ - id: fakedNewTrain.id, - path: result.path.id, - }) - ); + getTimetable({ id: timetableID }).then(({ data: timetable }) => { + const trainIdsToFetch = + timetable?.train_schedule_summaries.map((train) => train.id) ?? []; + postTrainScheduleResults({ + body: { + path_id: result.path.id, + train_ids: trainIdsToFetch, + }, }) - .catch(() => { - dispatch( - setFailure({ - name: t('operationalStudies/manageTrainSchedule:errorMessages.stdcmError'), - message: t('translation:common.error'), - }) - ); - }); + .unwrap() + .then((timetableTrains) => { + const trains: SimulationReport[] = [...timetableTrains, fakedNewTrain]; + const consolidatedSimulation = createTrain( + dispatch, + CHART_AXES.SPACE_TIME, + trains as Train[], // TODO: remove Train interface + t + ); + dispatch(updateConsolidatedSimulation(consolidatedSimulation)); + dispatch(updateSimulation({ trains })); + dispatch(updateSelectedTrainId(fakedNewTrain.id)); + + dispatch( + updateSelectedProjection({ + id: fakedNewTrain.id, + path: result.path.id, + }) + ); + }) + .catch(() => { + dispatch( + setFailure({ + name: t('operationalStudies/manageTrainSchedule:errorMessages.stdcmError'), + message: t('translation:common.error'), + }) + ); + }); + }); } }) .catch((e) => { diff --git a/front/src/modules/simulationResult/components/SpaceTimeChart/SpaceTimeChart.tsx b/front/src/modules/simulationResult/components/SpaceTimeChart/SpaceTimeChart.tsx index e67f1d0014b..3f3582d764a 100644 --- a/front/src/modules/simulationResult/components/SpaceTimeChart/SpaceTimeChart.tsx +++ b/front/src/modules/simulationResult/components/SpaceTimeChart/SpaceTimeChart.tsx @@ -64,6 +64,7 @@ export type SpaceTimeChartProps = { onOffsetTimeByDragging?: (trains: Train[], offset: number, timePosition: Date) => void; onSetBaseHeight?: (newHeight: number) => void; isDisplayed?: boolean; + setTrainResultsToFetch?: (trainSchedulesIDs?: number[]) => void; }; export default function SpaceTimeChart(props: SpaceTimeChartProps) { @@ -85,6 +86,7 @@ export default function SpaceTimeChart(props: SpaceTimeChartProps) { isDisplayed = true, onOffsetTimeByDragging = noop, onSetBaseHeight = noop, + setTrainResultsToFetch = noop, } = props; const [baseHeight, setBaseHeight] = useState(initialHeight); @@ -122,7 +124,7 @@ export default function SpaceTimeChart(props: SpaceTimeChartProps) { train.id === selectedTrain.id ? timeShiftTrain(train as Train, offset) : train ); setTrainSimulations(trains as Train[]); - onOffsetTimeByDragging(trains, offset, timePosition); + onOffsetTimeByDragging(trains, offset, timePosition, setTrainResultsToFetch); } }, [trainSimulations, selectedTrain, onOffsetTimeByDragging] diff --git a/front/src/modules/simulationResult/components/SpaceTimeChart/withOSRDData.tsx b/front/src/modules/simulationResult/components/SpaceTimeChart/withOSRDData.tsx index b00b7122c02..914bec83e9f 100644 --- a/front/src/modules/simulationResult/components/SpaceTimeChart/withOSRDData.tsx +++ b/front/src/modules/simulationResult/components/SpaceTimeChart/withOSRDData.tsx @@ -52,9 +52,15 @@ function withOSRDData( const onOffsetTimeByDragging = ( trains: SimulationReport[], offset: number, - timePosition: Date + timePosition: Date, + setTrainResultsToFetch: (trainSchedulesIDs?: number[]) => void ) => { dispatch(persistentUpdateSimulation({ ...simulation, trains })); + + // Sets the train which needs its results to be updated + // We know it is always the selected train because when dragging one, it gets the selection + if (selectedTrain && setTrainResultsToFetch) setTrainResultsToFetch([selectedTrain.id]); + if (timePosition && offset) { const newTimePosition = sec2datetime(datetime2sec(timePosition) + offset); updateTimePosition(newTimePosition); diff --git a/front/src/modules/simulationResult/components/SpeedSpaceChart/sampleData.ts b/front/src/modules/simulationResult/components/SpeedSpaceChart/sampleData.ts index 652ec12744f..5481e86828d 100644 --- a/front/src/modules/simulationResult/components/SpeedSpaceChart/sampleData.ts +++ b/front/src/modules/simulationResult/components/SpeedSpaceChart/sampleData.ts @@ -6493,7 +6493,6 @@ const ORSD_GRAPH_SAMPLE_DATA: OsrdSimulationState = { speed_limit_tags: 'Aucune composition', }, ], - displaySimulation: true, simulation: { past: [ { diff --git a/front/src/modules/simulationResult/components/simulationResultsHelpers.ts b/front/src/modules/simulationResult/components/simulationResultsHelpers.ts index e721ce3dd78..194487dd7a5 100644 --- a/front/src/modules/simulationResult/components/simulationResultsHelpers.ts +++ b/front/src/modules/simulationResult/components/simulationResultsHelpers.ts @@ -41,7 +41,6 @@ export const changeTrain = error: getTrainDetailsError, isSuccess: isGetTrainDetailsSuccess, } = await dispatch(osrdEditoastApi.endpoints.getTrainScheduleById.initiate({ id })); - if (isGetTrainDetailsSuccess) { // TODO: add the other information of the trainSchedule (allowances...) const trainSchedule: TrainSchedulePatch = { diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfAddTrainSchedule.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfAddTrainSchedule.tsx index 1c025704f55..4726c09cfb2 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfAddTrainSchedule.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfAddTrainSchedule.tsx @@ -19,6 +19,7 @@ type SubmitConfAddTrainScheduleProps = { refetchTimetable: () => void; refetchConflicts: () => void; setIsWorking: (isWorking: boolean) => void; + setTrainResultsToFetch: (trainScheduleIds?: number[]) => void; }; type error400 = { @@ -37,6 +38,7 @@ export default function SubmitConfAddTrainSchedule({ refetchTimetable, refetchConflicts, setIsWorking, + setTrainResultsToFetch, }: SubmitConfAddTrainScheduleProps) { const [postTrainSchedule] = osrdEditoastApi.endpoints.postTrainScheduleStandaloneSimulation.useMutation(); @@ -87,7 +89,7 @@ export default function SubmitConfAddTrainSchedule({ } try { - await postTrainSchedule({ + const newTrainIds = await postTrainSchedule({ body: { path: pathfindingID, schedules, @@ -102,6 +104,7 @@ export default function SubmitConfAddTrainSchedule({ }) ); setIsWorking(false); + setTrainResultsToFetch(newTrainIds); refetchTimetable(); refetchConflicts(); } catch (e: unknown) { diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfUpdateTrainSchedules.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfUpdateTrainSchedules.tsx index 7f8c8d7dc28..7a87a1905bd 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfUpdateTrainSchedules.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/SubmitConfUpdateTrainSchedules.tsx @@ -18,6 +18,7 @@ import { updateSelectedProjection, updateSelectedTrainId } from 'reducers/osrdsi type SubmitConfUpdateTrainSchedulesProps = { setIsWorking: (isWorking: boolean) => void; setDisplayTrainScheduleManagement: (arg0: string) => void; + setTrainResultsToFetch: (trainScheduleIds?: number[]) => void; }; // Refacto in a component to prepare the migration of the patch in editoast (need to be a React component to use hooks inside like rtk's) @@ -25,21 +26,23 @@ type SubmitConfUpdateTrainSchedulesProps = { export default function SubmitConfUpdateTrainSchedules({ setIsWorking, setDisplayTrainScheduleManagement, + setTrainResultsToFetch, }: SubmitConfUpdateTrainSchedulesProps) { - const { getTrainScheduleIDsToModify } = useOsrdConfSelectors(); + const { getTrainScheduleIDsToModify, getConf, getPathfindingID, getName, getDepartureTime } = + useOsrdConfSelectors(); + const confName = useSelector(getName); + const simulationConf = useSelector(getConf); + const pathfindingID = useSelector(getPathfindingID); + const departureTime = useSelector(getDepartureTime); + const trainScheduleIDsToModify = useSelector(getTrainScheduleIDsToModify); + const { updateTrainScheduleIDsToModify } = useOsrdConfActions(); const dispatch = useDispatch(); const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); - const trainScheduleIDsToModify = useSelector(getTrainScheduleIDsToModify); + const [patchTrainSchedules] = osrdEditoastApi.endpoints.patchTrainSchedule.useMutation(); async function submitConfUpdateTrainSchedules() { - const { getConf, getPathfindingID, getName, getDepartureTime } = useOsrdConfSelectors(); - const simulationConf = useSelector(getConf); - const pathfindingID = useSelector(getPathfindingID); - const confName = useSelector(getName); - const departureTime = useSelector(getDepartureTime); - // First train tested, and next we put the other trains const formattedSimulationConf = formatConf(dispatch, t, simulationConf, true); if (!pathfindingID) { @@ -78,6 +81,7 @@ export default function SubmitConfUpdateTrainSchedules({ }) ); if (callSuccess) { + setTrainResultsToFetch(trainScheduleIDsToModify); dispatch( setSuccess({ title: t('trainUpdated'), diff --git a/front/src/modules/trainschedule/components/Timetable/Timetable.tsx b/front/src/modules/trainschedule/components/Timetable/Timetable.tsx index 32b26105900..d912941d054 100644 --- a/front/src/modules/trainschedule/components/Timetable/Timetable.tsx +++ b/front/src/modules/trainschedule/components/Timetable/Timetable.tsx @@ -23,11 +23,16 @@ import DeleteModal from 'common/BootstrapSNCF/ModalSNCF/DeleteModal'; import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; import TimetableTrainCard from 'modules/trainschedule/components/Timetable/TimetableTrainCard'; -import type { Conflict, Infra, TimetableWithSchedulesDetails } from 'common/api/osrdEditoastApi'; +import type { + Conflict, + Infra, + SimulationReport, + TimetableWithSchedulesDetails, +} from 'common/api/osrdEditoastApi'; import { setFailure, setSuccess } from 'reducers/main'; -import type { ScheduledTrain } from 'reducers/osrdsimulation/types'; -import { updateSelectedTrainId } from 'reducers/osrdsimulation/actions'; +import type { ScheduledTrain, SimulationSnapshot } from 'reducers/osrdsimulation/types'; +import { updateSelectedTrainId, updateSimulation } from 'reducers/osrdsimulation/actions'; import { getSelectedProjection } from 'reducers/osrdsimulation/selectors'; type TimetableProps = { @@ -38,6 +43,8 @@ type TimetableProps = { selectedTrainId?: number; refetchTimetable: () => void; conflicts?: Conflict[]; + setTrainResultsToFetch: (trainScheduleIds?: number[]) => void; + simulation: SimulationSnapshot; }; export default function Timetable({ @@ -48,6 +55,8 @@ export default function Timetable({ selectedTrainId, refetchTimetable, conflicts, + setTrainResultsToFetch, + simulation, }: TimetableProps) { const { t } = useTranslation(['operationalStudies/scenario', 'common/itemTypes']); @@ -155,6 +164,15 @@ export default function Timetable({ await deleteTrainSchedules({ body: { ids: selectedTrainIds } }) .unwrap() .then(() => { + const updatedSimulation = (simulation.trains as SimulationReport[]).filter( + (simulationTrain) => !selectedTrainIds.includes(simulationTrain.id) + ); + if (updatedSimulation.length > 0) { + setTrainResultsToFetch([]); + } else { + setTrainResultsToFetch(undefined); + } + dispatch(updateSimulation({ trains: updatedSimulation })); dispatch( setSuccess({ title: t('timetable.trainsSelectionDeletedCount', { count: trainsCount }), @@ -303,6 +321,8 @@ export default function Timetable({ } refetchTimetable={refetchTimetable} setDisplayTrainScheduleManagement={setDisplayTrainScheduleManagement} + setTrainResultsToFetch={setTrainResultsToFetch} + simulation={simulation} /> ))}
diff --git a/front/src/modules/trainschedule/components/Timetable/TimetableManageTrainSchedule.tsx b/front/src/modules/trainschedule/components/Timetable/TimetableManageTrainSchedule.tsx index d8774ac943f..a95aad187f3 100644 --- a/front/src/modules/trainschedule/components/Timetable/TimetableManageTrainSchedule.tsx +++ b/front/src/modules/trainschedule/components/Timetable/TimetableManageTrainSchedule.tsx @@ -17,6 +17,7 @@ import type { Infra } from 'common/api/osrdEditoastApi'; type TimetableManageTrainScheduleProps = { displayTrainScheduleManagement: string; setDisplayTrainScheduleManagement: (type: string) => void; + setTrainResultsToFetch: (trainScheduleIds?: number[]) => void; infraState?: Infra['state']; refetchTimetable: () => void; refetchConflicts: () => void; @@ -25,6 +26,7 @@ type TimetableManageTrainScheduleProps = { export default function TimetableManageTrainSchedule({ displayTrainScheduleManagement, setDisplayTrainScheduleManagement, + setTrainResultsToFetch, infraState, refetchTimetable, refetchConflicts, @@ -46,6 +48,7 @@ export default function TimetableManageTrainSchedule({ )} @@ -61,6 +64,7 @@ export default function TimetableManageTrainSchedule({ refetchTimetable={refetchTimetable} setIsWorking={setIsWorking} refetchConflicts={refetchConflicts} + setTrainResultsToFetch={setTrainResultsToFetch} /> )} diff --git a/front/src/modules/trainschedule/components/Timetable/TimetableTrainCard.tsx b/front/src/modules/trainschedule/components/Timetable/TimetableTrainCard.tsx index 8166822a929..25551ee6862 100644 --- a/front/src/modules/trainschedule/components/Timetable/TimetableTrainCard.tsx +++ b/front/src/modules/trainschedule/components/Timetable/TimetableTrainCard.tsx @@ -20,11 +20,15 @@ import trainNameWithNum from 'modules/trainschedule/components/ManageTrainSchedu import { useOsrdConfActions } from 'common/osrdContext'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import type { TrainScheduleValidation } from 'common/api/osrdEditoastApi'; +import type { SimulationReport, TrainScheduleValidation } from 'common/api/osrdEditoastApi'; import { setFailure, setSuccess } from 'reducers/main'; -import type { ScheduledTrain } from 'reducers/osrdsimulation/types'; -import { updateSelectedProjection, updateSelectedTrainId } from 'reducers/osrdsimulation/actions'; +import type { ScheduledTrain, SimulationSnapshot } from 'reducers/osrdsimulation/types'; +import { + updateSelectedProjection, + updateSelectedTrainId, + updateSimulation, +} from 'reducers/osrdsimulation/actions'; const invalidTrainValues: { [key in TrainScheduleValidation]: TrainScheduleValidation; @@ -45,6 +49,8 @@ type TimetableTrainCardProps = { refetchTimetable: () => void; toggleTrainSelection: (trainId: number) => void; setDisplayTrainScheduleManagement: (arg0: string) => void; + setTrainResultsToFetch: (trainScheduleId?: number[]) => void; + simulation: SimulationSnapshot; }; function TimetableTrainCard({ @@ -59,6 +65,8 @@ function TimetableTrainCard({ refetchTimetable, setDisplayTrainScheduleManagement, toggleTrainSelection, + setTrainResultsToFetch, + simulation, }: TimetableTrainCardProps) { const { data: rollingStock } = osrdEditoastApi.endpoints.getLightRollingStockByRollingStockId.useQuery({ @@ -91,6 +99,15 @@ function TimetableTrainCard({ deleteTrainScheduleById({ id: train.id }) .unwrap() .then(() => { + const updatedSimulation = (simulation.trains as SimulationReport[]).filter( + (simulationTrain) => simulationTrain.id !== train.id + ); + if (updatedSimulation.length > 0) { + setTrainResultsToFetch([]); + } else { + setTrainResultsToFetch(undefined); + } + dispatch(updateSimulation({ trains: updatedSimulation })); dispatch( setSuccess({ title: t('timetable.trainDeleted', { name: train.train_name }), diff --git a/front/src/reducers/osrdsimulation/index.ts b/front/src/reducers/osrdsimulation/index.ts index ed4347d9768..a9cf8cc4193 100644 --- a/front/src/reducers/osrdsimulation/index.ts +++ b/front/src/reducers/osrdsimulation/index.ts @@ -2,7 +2,6 @@ import produce from 'immer'; import { noop } from 'lodash'; import { AnyAction } from 'redux'; -import { SimulationReport } from 'common/api/osrdEditoastApi'; import { SIGNAL_BASE_DEFAULT, CHART_AXES } from 'modules/simulationResult/consts'; import { makeTrainListWithAllTrainsOffset } from 'modules/simulationResult/components/ChartHelpers/ChartHelpers'; import createTrain from 'modules/simulationResult/components/SpaceTimeChart/createTrain'; @@ -54,7 +53,6 @@ export const initialState: OsrdSimulationState = { signalBase: SIGNAL_BASE_DEFAULT, consolidatedSimulation: [], departureArrivalTimes: [], - displaySimulation: false, simulation: { past: [], present: { trains: [] }, @@ -111,12 +109,6 @@ export default function reducer(inputState: OsrdSimulationState | undefined, act draft.simulation.present.trains as Train[], // TODO: remove Train interface noop ); - draft.displaySimulation = - draft.simulation.present?.trains.length > 0 && - // TODO: delete this cast when we have chosen the appropriate type for the simulation - (draft.simulation.present.trains as SimulationReport[]).find( - (train) => train.id === state.selectedTrainId - ) !== undefined; break; case UPDATE_SPEEDSPACE_SETTINGS: diff --git a/front/src/reducers/osrdsimulation/selectors.ts b/front/src/reducers/osrdsimulation/selectors.ts index 187bac26ad1..4a037181577 100644 --- a/front/src/reducers/osrdsimulation/selectors.ts +++ b/front/src/reducers/osrdsimulation/selectors.ts @@ -15,7 +15,6 @@ export const getSelectedProjection = makeOsrdSimulationSelector('selectedProject export const getSelectedTrainId = makeOsrdSimulationSelector('selectedTrainId'); export const getSpeedSpaceSettings = makeOsrdSimulationSelector('speedSpaceSettings'); export const getConsolidatedSimulation = makeOsrdSimulationSelector('consolidatedSimulation'); -export const getDisplaySimulation = makeOsrdSimulationSelector('displaySimulation'); export const getPresentSimulation = (state: RootState) => state.osrdsimulation.simulation.present; diff --git a/front/src/reducers/osrdsimulation/types.ts b/front/src/reducers/osrdsimulation/types.ts index e8d604ae72a..98cfa6623eb 100644 --- a/front/src/reducers/osrdsimulation/types.ts +++ b/front/src/reducers/osrdsimulation/types.ts @@ -260,5 +260,4 @@ export interface OsrdSimulationState { present: SimulationSnapshot; future: SimulationHistory; }; - displaySimulation: boolean; }