Skip to content

Commit 3bd5a07

Browse files
committed
front: refacto import modal and clean button colors
1 parent 1bd551d commit 3bd5a07

File tree

3 files changed

+109
-52
lines changed

3 files changed

+109
-52
lines changed

front/public/locales/en/operationalStudies/importTrainSchedule.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"startTime": "START",
2828
"status": {
2929
"calculatingTrainSchedule": "Calculating train schedules...",
30-
"calculatingTrainScheduleComplete": "Calculating train schedules is over (path {{pathId}}) {{trainIndex}}/{{trainsCount}}",
30+
"calculatingTrainScheduleComplete": "Calculating train schedules is over (path {{pathId}}) {{createdTrainsCount}}/{{trainsCount}}",
3131
"calculatingTrainScheduleCompleteAll_one": "All train schedules have been calculated : {{successfulTrainsCount}}/{{trainsCount}} train created.",
3232
"calculatingTrainScheduleCompleteAll_other": "All train schedules have been calculated : {{successfulTrainsCount}}/{{trainsCount}} trains created.",
3333
"calculatingTrainScheduleCompleteAllFailure": "All train schedule creations failed.",

front/public/locales/fr/operationalStudies/importTrainSchedule.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"startTime": "DÉBUT",
2828
"status": {
2929
"calculatingTrainSchedule": "Calculs de marches en cours…",
30-
"calculatingTrainScheduleComplete": "Calcul de marche terminé (path {{pathId}}) {{trainIndex}}/{{trainsCount}}",
30+
"calculatingTrainScheduleComplete": "Calcul de marche terminé (path {{pathId}}) {{createdTrainsCount}}/{{trainsCount}}",
3131
"calculatingTrainScheduleCompleteAll_one": "Tous les calculs de marches sont terminés: {{successfulTrainsCount}}/{{trainsCount}} train créé.",
3232
"calculatingTrainScheduleCompleteAll_other": "Tous les calculs de marches sont terminés: {{successfulTrainsCount}}/{{trainsCount}} trains créés.",
3333
"calculatingTrainScheduleCompleteAllFailure": "Tous les calculs de marche ont échoué.",

front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx

+107-50
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useMemo, useState } from 'react';
22
import cx from 'classnames';
33

44
import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF';
@@ -41,6 +41,25 @@ import { Point } from './types';
4141
*
4242
*/
4343

44+
enum IMPORT_STATUS {
45+
READY = 'ready',
46+
COMPLETING_POINTS = 'completing-points',
47+
ALL_POINTS_COMPLETED = 'all-points-completed',
48+
MISSING_ROLLING_STOCK = 'missing-rolling-stock',
49+
PATHFINDINGS_RUNNING = 'pathfindings-running',
50+
PATHFINDINGS_COMPLETED = 'pathfindings-completed',
51+
PATHFINDINGS_FAILED = 'pathfindings-failed',
52+
CREATING_TRAINS = 'creating-trains',
53+
CREATING_TRAINS_COMPLETED = 'creating-trains-completed',
54+
CREATING_TRAINS_FAILED = 'creating-trains-failed',
55+
}
56+
57+
const IMPORT_STATUS_ERROR = [
58+
IMPORT_STATUS.MISSING_ROLLING_STOCK,
59+
IMPORT_STATUS.PATHFINDINGS_FAILED,
60+
IMPORT_STATUS.CREATING_TRAINS_FAILED,
61+
];
62+
4463
interface ImportTrainScheduleModalProps {
4564
infraId: number;
4665
rollingStocks: LightRollingStock[];
@@ -77,20 +96,51 @@ const ImportTrainScheduleModal = ({
7796
{ trainNumber: string; pathString: string }[]
7897
>([]);
7998

80-
const [importStatus, setImportStatus] = useState(<span>{t('status.ready')}</span>);
81-
8299
const [viewport, setViewport] = useState(initialViewport);
83100
const [status, setStatus] = useState(initialStatus);
84101

102+
const [importStatus, setImportStatus] = useState<IMPORT_STATUS>(IMPORT_STATUS.READY);
103+
const [message, setMessage] = useState('');
104+
105+
const updateImportStatus = (newStatus: IMPORT_STATUS, newMessage = '') => {
106+
if (newStatus !== importStatus) setImportStatus(newStatus);
107+
if (newMessage !== '') {
108+
setMessage(newMessage);
109+
} else {
110+
switch (newStatus) {
111+
case IMPORT_STATUS.MISSING_ROLLING_STOCK:
112+
setMessage(
113+
[t('status.noImportationPossible'), t('status.missingRollingStock')].join('\n')
114+
);
115+
break;
116+
case IMPORT_STATUS.ALL_POINTS_COMPLETED:
117+
setMessage(t('status.uicComplete'));
118+
break;
119+
case IMPORT_STATUS.PATHFINDINGS_COMPLETED:
120+
setMessage(t('status.pathComplete'));
121+
break;
122+
case IMPORT_STATUS.PATHFINDINGS_FAILED:
123+
setMessage(t('status.pathsFailed'));
124+
break;
125+
case IMPORT_STATUS.CREATING_TRAINS_FAILED:
126+
setMessage(t('status.calculatingTrainScheduleCompleteAllFailure'));
127+
break;
128+
default:
129+
setMessage('');
130+
}
131+
}
132+
};
133+
134+
const importStatusIsError = useMemo(
135+
() => IMPORT_STATUS_ERROR.includes(importStatus),
136+
[importStatus]
137+
);
138+
85139
function testMissingInfos() {
86140
if (!rollingStockID) {
87-
setImportStatus(
88-
<span className="text-danger">
89-
{[t('status.noImportationPossible'), t('status.missingRollingStock')].join('\n')}
90-
</span>
91-
);
141+
updateImportStatus(IMPORT_STATUS.MISSING_ROLLING_STOCK);
92142
} else {
93-
setImportStatus(t('status.ready'));
143+
updateImportStatus(IMPORT_STATUS.READY);
94144
}
95145
}
96146

@@ -117,15 +167,16 @@ const ImportTrainScheduleModal = ({
117167
setUicNumberToComplete(uicNumberToCompleteLocal);
118168
const pointToComplete = pointsDictionnary[uic2complete[uicNumberToCompleteLocal]];
119169
getTrackSectionID(pointToComplete.latitude, pointToComplete.longitude);
120-
setImportStatus(
170+
updateImportStatus(
171+
IMPORT_STATUS.COMPLETING_POINTS,
121172
t('status.complete', {
122173
uicNumber: uicNumberToCompleteLocal,
123174
uicTotalCount: uic2complete.length,
124175
uicName: pointToComplete.name,
125176
})
126177
);
127178
} else {
128-
setImportStatus(t('status.uicComplete'));
179+
updateImportStatus(IMPORT_STATUS.ALL_POINTS_COMPLETED);
129180
setUicNumberToComplete(undefined);
130181
setStatus({ ...status, uicComplete: true });
131182
}
@@ -137,10 +188,10 @@ const ImportTrainScheduleModal = ({
137188

138189
function endGeneratePaths(newTrainsWithPath: TrainScheduleWithPath[]) {
139190
if (newTrainsWithPath.length > 0) {
140-
setImportStatus(t('status.pathComplete'));
141-
} else setImportStatus(<span className="text-danger">{t('status.pathsFailed')}</span>);
191+
updateImportStatus(IMPORT_STATUS.PATHFINDINGS_COMPLETED);
192+
} else updateImportStatus(IMPORT_STATUS.PATHFINDINGS_FAILED);
142193
setTrainsWithPath(newTrainsWithPath);
143-
setStatus({ ...status, uicComplete: true, pathFindingDone: true });
194+
setStatus({ ...status, pathFindingDone: true });
144195
}
145196

146197
/**
@@ -168,7 +219,8 @@ const ImportTrainScheduleModal = ({
168219
autocomplete,
169220
pointsDictionnary
170221
);
171-
setImportStatus(
222+
updateImportStatus(
223+
IMPORT_STATUS.PATHFINDINGS_RUNNING,
172224
t('status.searchingPath', {
173225
pathFindingsDoneCount,
174226
pathFindingsCount,
@@ -242,34 +294,33 @@ const ImportTrainScheduleModal = ({
242294

243295
async function generateTrainSchedules() {
244296
const payloads = generateTrainSchedulesPayload(trainsWithPath, timetableId);
245-
const trainsCount = payloads.length;
246-
setImportStatus(t('status.calculatingTrainSchedule'));
297+
const trainsCount = payloads.reduce((result, payload) => result + payload.schedules.length, 0);
298+
updateImportStatus(IMPORT_STATUS.CREATING_TRAINS, t('status.calculatingTrainSchedule'));
247299
const messages = [];
248300
let successfulTrainsCount = 0;
249-
let idx = 0;
250301
// eslint-disable-next-line no-restricted-syntax
251302
for await (const payload of payloads) {
252303
const success = await launchTrainSchedules(payload);
253-
const message = `${t(
254-
!success
304+
if (success) {
305+
successfulTrainsCount += payload.schedules.length;
306+
}
307+
const msg = `${t(
308+
success
255309
? 'status.calculatingTrainScheduleComplete'
256310
: 'errorMessages.unableToCreateTrainSchedule',
257311
{
258312
pathId: payload.path,
259-
trainIndex: idx,
260-
trainsCount: payloads.length,
313+
createdTrainsCount: successfulTrainsCount,
314+
trainsCount,
261315
}
262316
)}`;
263-
messages.push(message);
264-
if (success) {
265-
successfulTrainsCount += 1;
266-
}
267-
setImportStatus(<>{messages.join('\n')}</>);
268-
idx += 1;
317+
messages.push(msg);
318+
updateImportStatus(IMPORT_STATUS.CREATING_TRAINS, messages.join('\n'));
269319
}
270320
if (successfulTrainsCount > 0) {
271321
setStatus({ ...status, trainSchedulesDone: true, success: true });
272-
setImportStatus(
322+
updateImportStatus(
323+
IMPORT_STATUS.CREATING_TRAINS_COMPLETED,
273324
t('status.calculatingTrainScheduleCompleteAll', {
274325
count: successfulTrainsCount,
275326
successfulTrainsCount,
@@ -278,11 +329,7 @@ const ImportTrainScheduleModal = ({
278329
);
279330
} else {
280331
setStatus({ ...status, trainSchedulesDone: true });
281-
setImportStatus(
282-
<span className="text-danger">
283-
{t('status.calculatingTrainScheduleCompleteAllFailure')}
284-
</span>
285-
);
332+
updateImportStatus(IMPORT_STATUS.CREATING_TRAINS_FAILED);
286333
}
287334
}
288335

@@ -319,19 +366,27 @@ const ImportTrainScheduleModal = ({
319366
{!infraId || !timetableId || !rollingStockID ? null : (
320367
<>
321368
<button
322-
className={`btn btn-sm btn-block d-flex justify-content-between ${
323-
status.uicComplete ? 'btn-outline-success' : 'btn-primary'
324-
}`}
369+
className={cx('btn btn-sm btn-block d-flex justify-content-between', {
370+
'btn-primary': !status.uicComplete && !status.pathFindingDone,
371+
'btn-outline-success': status.uicComplete,
372+
'btn-outline-secondary': !status.uicComplete && status.pathFindingDone,
373+
})}
325374
type="button"
326375
onClick={() => completePaths(true)}
327376
>
328377
<span>1 — {t('completeTrackSectionID')}</span>
329378
<span>{Object.keys(pointsDictionnary).length}</span>
330379
</button>
331380
<button
332-
className={`btn btn-sm btn-block d-flex justify-content-between ${
333-
status.pathFindingDone ? 'btn-outline-success' : 'btn-primary'
334-
}`}
381+
className={cx('btn btn-sm btn-block d-flex justify-content-between', {
382+
'btn-primary': !status.pathFindingDone,
383+
'btn-outline-danger':
384+
status.uicComplete && importStatus === IMPORT_STATUS.PATHFINDINGS_FAILED,
385+
'btn-outline-success':
386+
status.uicComplete &&
387+
status.pathFindingDone &&
388+
importStatus !== IMPORT_STATUS.PATHFINDINGS_FAILED,
389+
})}
335390
disabled={!status.uicComplete}
336391
type="button"
337392
onClick={() => generatePaths()}
@@ -343,24 +398,26 @@ const ImportTrainScheduleModal = ({
343398
<button
344399
className={cx(
345400
'btn btn-sm btn-block d-flex justify-content-between text-wrap text-left',
346-
!status.pathFindingDone && 'btn-primary',
347-
status.pathFindingDone && trainsWithPath.length && 'btn-outline-success',
348-
status.pathFindingDone && !trainsWithPath.length && 'btn-outline-danger'
401+
{
402+
'btn-primary': !status.pathFindingDone,
403+
'btn-outline-success': status.pathFindingDone && !status.uicComplete,
404+
'btn-outline-danger': status.pathFindingDone && !trainsWithPath.length,
405+
}
349406
)}
350407
type="button"
408+
disabled={status.pathFindingDone && status.uicComplete}
351409
onClick={generateAutocompletePaths}
352410
>
353411
<span>1/2 — {t('generatePathsAuto')}</span>
354412
<span>{pathsDictionnary.length}</span>
355413
</button>
356414
<Spacer height={50} />
357415
<button
358-
className={cx(
359-
'btn btn-sm btn-block d-flex justify-content-between',
360-
!status.trainSchedulesDone && 'btn-primary',
361-
status.trainSchedulesDone && !status.success && 'btn-outline-danger',
362-
status.trainSchedulesDone && status.success && 'btn-outline-success'
363-
)}
416+
className={cx('btn btn-sm btn-block d-flex justify-content-between', {
417+
'btn-primary': !status.trainSchedulesDone,
418+
'btn-outline-danger': importStatus === IMPORT_STATUS.CREATING_TRAINS_FAILED,
419+
'btn-outline-success': importStatus === IMPORT_STATUS.CREATING_TRAINS_COMPLETED,
420+
})}
364421
disabled={!status.pathFindingDone || trainsWithPath.length === 0}
365422
type="button"
366423
onClick={generateTrainSchedules}
@@ -373,7 +430,7 @@ const ImportTrainScheduleModal = ({
373430
</>
374431
)}
375432

376-
<pre>{importStatus}</pre>
433+
<p className={cx(importStatusIsError && 'text-danger')}>{message}</p>
377434

378435
{uicNumberToComplete !== undefined && (
379436
<div className="automated-map">

0 commit comments

Comments
 (0)