diff --git a/front/public/locales/en/operationalStudies/importTrainSchedule.json b/front/public/locales/en/operationalStudies/importTrainSchedule.json index b9a885184c1..833091d5a45 100644 --- a/front/public/locales/en/operationalStudies/importTrainSchedule.json +++ b/front/public/locales/en/operationalStudies/importTrainSchedule.json @@ -27,7 +27,7 @@ "startTime": "START", "status": { "calculatingTrainSchedule": "Calculating train schedules...", - "calculatingTrainScheduleComplete": "Calculating train schedules is over (path {{pathId}}) {{trainIndex}}/{{trainsCount}}", + "calculatingTrainScheduleComplete": "Calculating train schedules is over (path {{pathId}}) {{createdTrainsCount}}/{{trainsCount}}", "calculatingTrainScheduleCompleteAll_one": "All train schedules have been calculated : {{successfulTrainsCount}}/{{trainsCount}} train created.", "calculatingTrainScheduleCompleteAll_other": "All train schedules have been calculated : {{successfulTrainsCount}}/{{trainsCount}} trains created.", "calculatingTrainScheduleCompleteAllFailure": "All train schedule creations failed.", diff --git a/front/public/locales/fr/operationalStudies/importTrainSchedule.json b/front/public/locales/fr/operationalStudies/importTrainSchedule.json index 8fb03c4c3e4..eac668d909e 100644 --- a/front/public/locales/fr/operationalStudies/importTrainSchedule.json +++ b/front/public/locales/fr/operationalStudies/importTrainSchedule.json @@ -27,7 +27,7 @@ "startTime": "DÉBUT", "status": { "calculatingTrainSchedule": "Calculs de marches en cours…", - "calculatingTrainScheduleComplete": "Calcul de marche terminé (path {{pathId}}) {{trainIndex}}/{{trainsCount}}", + "calculatingTrainScheduleComplete": "Calcul de marche terminé (path {{pathId}}) {{createdTrainsCount}}/{{trainsCount}}", "calculatingTrainScheduleCompleteAll_one": "Tous les calculs de marches sont terminés: {{successfulTrainsCount}}/{{trainsCount}} train créé.", "calculatingTrainScheduleCompleteAll_other": "Tous les calculs de marches sont terminés: {{successfulTrainsCount}}/{{trainsCount}} trains créés.", "calculatingTrainScheduleCompleteAllFailure": "Tous les calculs de marche ont échoué.", diff --git a/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx b/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx index e049f913626..fd26f088bb9 100644 --- a/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx +++ b/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import cx from 'classnames'; import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; @@ -39,6 +39,25 @@ import { Point } from './types'; * */ +enum IMPORT_STATUS { + READY = 'ready', + COMPLETING_POINTS = 'completing-points', + ALL_POINTS_COMPLETED = 'all-points-completed', + MISSING_ROLLING_STOCK = 'missing-rolling-stock', + PATHFINDINGS_RUNNING = 'pathfindings-running', + PATHFINDINGS_COMPLETED = 'pathfindings-completed', + PATHFINDINGS_FAILED = 'pathfindings-failed', + CREATING_TRAINS = 'creating-trains', + CREATING_TRAINS_COMPLETED = 'creating-trains-completed', + CREATING_TRAINS_FAILED = 'creating-trains-failed', +} + +const IMPORT_STATUS_ERROR = [ + IMPORT_STATUS.MISSING_ROLLING_STOCK, + IMPORT_STATUS.PATHFINDINGS_FAILED, + IMPORT_STATUS.CREATING_TRAINS_FAILED, +]; + interface ImportTrainScheduleModalProps { infraId: number; rollingStocks: LightRollingStock[]; @@ -72,20 +91,51 @@ const ImportTrainScheduleModal = ({ { trainNumber: string; pathString: string }[] >([]); - const [importStatus, setImportStatus] = useState({t('status.ready')}); - const [viewport, setViewport] = useState(initialViewport); const [status, setStatus] = useState(initialStatus); + const [importStatus, setImportStatus] = useState(IMPORT_STATUS.READY); + const [message, setMessage] = useState(''); + + const updateImportStatus = (newStatus: IMPORT_STATUS, newMessage = '') => { + if (newStatus !== importStatus) setImportStatus(newStatus); + if (newMessage !== '') { + setMessage(newMessage); + } else { + switch (newStatus) { + case IMPORT_STATUS.MISSING_ROLLING_STOCK: + setMessage( + [t('status.noImportationPossible'), t('status.missingRollingStock')].join('\n') + ); + break; + case IMPORT_STATUS.ALL_POINTS_COMPLETED: + setMessage(t('status.uicComplete')); + break; + case IMPORT_STATUS.PATHFINDINGS_COMPLETED: + setMessage(t('status.pathComplete')); + break; + case IMPORT_STATUS.PATHFINDINGS_FAILED: + setMessage(t('status.pathsFailed')); + break; + case IMPORT_STATUS.CREATING_TRAINS_FAILED: + setMessage(t('status.calculatingTrainScheduleCompleteAllFailure')); + break; + default: + setMessage(''); + } + } + }; + + const importStatusIsError = useMemo( + () => IMPORT_STATUS_ERROR.includes(importStatus), + [importStatus] + ); + function testMissingInfos() { if (!rollingStockID) { - setImportStatus( - - {[t('status.noImportationPossible'), t('status.missingRollingStock')].join('\n')} - - ); + updateImportStatus(IMPORT_STATUS.MISSING_ROLLING_STOCK); } else { - setImportStatus(t('status.ready')); + updateImportStatus(IMPORT_STATUS.READY); } } @@ -112,7 +162,8 @@ const ImportTrainScheduleModal = ({ setUicNumberToComplete(uicNumberToCompleteLocal); const pointToComplete = pointsDictionnary[uic2complete[uicNumberToCompleteLocal]]; getTrackSectionID(pointToComplete.latitude, pointToComplete.longitude); - setImportStatus( + updateImportStatus( + IMPORT_STATUS.COMPLETING_POINTS, t('status.complete', { uicNumber: uicNumberToCompleteLocal, uicTotalCount: uic2complete.length, @@ -120,7 +171,7 @@ const ImportTrainScheduleModal = ({ }) ); } else { - setImportStatus(t('status.uicComplete')); + updateImportStatus(IMPORT_STATUS.ALL_POINTS_COMPLETED); setUicNumberToComplete(undefined); setStatus({ ...status, uicComplete: true }); } @@ -132,10 +183,10 @@ const ImportTrainScheduleModal = ({ function endGeneratePaths(newTrainsWithPath: TrainScheduleWithPath[]) { if (newTrainsWithPath.length > 0) { - setImportStatus(t('status.pathComplete')); - } else setImportStatus({t('status.pathsFailed')}); + updateImportStatus(IMPORT_STATUS.PATHFINDINGS_COMPLETED); + } else updateImportStatus(IMPORT_STATUS.PATHFINDINGS_FAILED); setTrainsWithPath(newTrainsWithPath); - setStatus({ ...status, uicComplete: true, pathFindingDone: true }); + setStatus({ ...status, pathFindingDone: true }); } /** @@ -163,7 +214,8 @@ const ImportTrainScheduleModal = ({ autocomplete, pointsDictionnary ); - setImportStatus( + updateImportStatus( + IMPORT_STATUS.PATHFINDINGS_RUNNING, t('status.searchingPath', { pathFindingsDoneCount, pathFindingsCount, @@ -227,34 +279,33 @@ const ImportTrainScheduleModal = ({ async function generateTrainSchedules() { const payloads = generateTrainSchedulesPayload(trainsWithPath, timetableId); - const trainsCount = payloads.length; - setImportStatus(t('status.calculatingTrainSchedule')); + const trainsCount = payloads.reduce((result, payload) => result + payload.schedules.length, 0); + updateImportStatus(IMPORT_STATUS.CREATING_TRAINS, t('status.calculatingTrainSchedule')); const messages = []; let successfulTrainsCount = 0; - let idx = 0; // eslint-disable-next-line no-restricted-syntax for await (const payload of payloads) { const success = await launchTrainSchedules(payload); - const message = `${t( - !success + if (success) { + successfulTrainsCount += payload.schedules.length; + } + const msg = `${t( + success ? 'status.calculatingTrainScheduleComplete' : 'errorMessages.unableToCreateTrainSchedule', { pathId: payload.path, - trainIndex: idx, - trainsCount: payloads.length, + createdTrainsCount: successfulTrainsCount, + trainsCount, } )}`; - messages.push(message); - if (success) { - successfulTrainsCount += 1; - } - setImportStatus(<>{messages.join('\n')}); - idx += 1; + messages.push(msg); + updateImportStatus(IMPORT_STATUS.CREATING_TRAINS, messages.join('\n')); } if (successfulTrainsCount > 0) { setStatus({ ...status, trainSchedulesDone: true, success: true }); - setImportStatus( + updateImportStatus( + IMPORT_STATUS.CREATING_TRAINS_COMPLETED, t('status.calculatingTrainScheduleCompleteAll', { count: successfulTrainsCount, successfulTrainsCount, @@ -263,11 +314,7 @@ const ImportTrainScheduleModal = ({ ); } else { setStatus({ ...status, trainSchedulesDone: true }); - setImportStatus( - - {t('status.calculatingTrainScheduleCompleteAllFailure')} - - ); + updateImportStatus(IMPORT_STATUS.CREATING_TRAINS_FAILED); } } @@ -304,9 +351,11 @@ const ImportTrainScheduleModal = ({ {!infraId || !timetableId || !rollingStockID ? null : ( <>