Skip to content

Commit bedf9a2

Browse files
committed
front: allow changing a scenario's infrastructure
Signed-off-by: Theo Macron <theo.macron0315@gmail.com>
1 parent 129f37c commit bedf9a2

4 files changed

Lines changed: 33 additions & 23 deletions

File tree

front/public/locales/de/operational-studies.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@
202202
"scenarioDescriptionInvalid": "Die Beschreibung darf 1.024 Zeichen nicht überschreiten.",
203203
"scenarioDescriptionPlaceholder": "Kurzbeschreibung des Szenarios",
204204
"scenarioModificationTitle": "Szenario bearbeiten",
205-
"scenarioModifyButton": "Sichern",
206205
"scenarioName": "Szenarioname",
207206
"scenarioNameInvalid": "Der Szenarioname darf 128 Zeichen nicht überschreiten.",
208207
"scenarioTags": "Tags",

front/public/locales/en/operational-studies.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@
198198
"scenarioDescription": "Description",
199199
"scenarioDescriptionInvalid": "The description for the scenario must not exceed 1024 characters",
200200
"scenarioDescriptionPlaceholder": "Short description of the scenario",
201-
"scenarioModificationTitle": "Modify scenario",
202-
"scenarioModifyButton": "Save",
201+
"scenarioModificationTitle": "Edit scenario",
203202
"scenarioName": "Scenario's name",
204203
"scenarioNameInvalid": "You have to set a name for scenario which does not exceed 128 characters",
205204
"scenarioTags": "Tags",

front/public/locales/fr/operational-studies.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@
199199
"scenarioDescriptionInvalid": "La description pour le scénario ne doit pas dépasser 1024 caractères",
200200
"scenarioDescriptionPlaceholder": "Courte description du scénario",
201201
"scenarioModificationTitle": "Modifier le scénario",
202-
"scenarioModifyButton": "Enregistrer",
203202
"scenarioName": "Nom du scénario",
204203
"scenarioNameInvalid": "Vous devez renseigner un nom pour le scénario qui ne dépasse pas 128 caractères",
205204
"scenarioTags": "Étiquettes",

front/src/modules/scenario/components/AddOrEditScenarioModal.tsx

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'r
22

33
import { Pencil, Trash } from '@osrd-project/ui-icons';
44
import cx from 'classnames';
5-
import { sortBy } from 'lodash';
5+
import { isEqual, sortBy } from 'lodash';
66
import { useTranslation } from 'react-i18next';
77
import { FaPlus } from 'react-icons/fa';
88
import { GiElectric } from 'react-icons/gi';
@@ -24,7 +24,7 @@ import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF';
2424
import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider';
2525
import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF';
2626
import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF';
27-
import { useInfraID } from 'common/osrdContext';
27+
import { useInfraActions, useInfraID } from 'common/osrdContext';
2828
import { InfraSelectorModal } from 'modules/infra/components/InfraSelector';
2929
import DeleteItemsModal from 'modules/project/components/DeleteItemsModal';
3030
import { setFailure, setSuccess } from 'reducers/main';
@@ -69,6 +69,9 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
6969
const dispatch = useAppDispatch();
7070
const navigate = useNavigate();
7171
const infraID = useInfraID();
72+
const { updateInfraID } = useInfraActions();
73+
74+
const originalInfraIdRef = useRef(scenario?.infra_id);
7275

7376
const [currentScenario, setCurrentScenario] = useState<ScenarioForm>(scenario || emptyScenario);
7477

@@ -124,6 +127,15 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
124127

125128
const modalRef = useRef<HTMLDivElement | null>(null);
126129

130+
// Restore the scenario's infra in the global state when the edition modal is closed
131+
// without saving (cancel, close button or click outside).
132+
const handleClose = useCallback(() => {
133+
if (editionMode && originalInfraIdRef.current !== undefined) {
134+
dispatch(updateInfraID(originalInfraIdRef.current));
135+
}
136+
closeModal();
137+
}, [editionMode, dispatch, updateInfraID, closeModal]);
138+
127139
const { clickedOutside, setHasChanges, resetClickedOutside } = useModalOutsideClick(modalRef);
128140

129141
const handleScenarioInputChange = useInputChange(
@@ -266,10 +278,12 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
266278
}, [scenario]);
267279

268280
useEffect(() => {
269-
setCurrentScenario({ ...currentScenario, infra_id: infraID });
281+
const updated = { ...currentScenario, infra_id: infraID };
282+
setCurrentScenario(updated);
283+
setHasChanges(!isEqual(updated, initialValuesRef.current));
270284
}, [infraID]);
271285

272-
useModalFocusTrap(modalRef, closeModal);
286+
useModalFocusTrap(modalRef, handleClose);
273287

274288
return (
275289
<div data-testid="scenario-edition-modal" className="scenario-edition-modal" ref={modalRef}>
@@ -278,20 +292,21 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
278292
<div className="confirm-modal-content">
279293
<ConfirmModal
280294
title={t('common.leaveEditionMode', { ns: 'translation' })}
295+
onConfirm={handleClose}
281296
onCancel={resetClickedOutside}
282297
withCloseButton={false}
283298
/>
284299
</div>
285300
</div>
286301
)}
287-
<ModalHeaderSNCF withCloseButton withBorderBottom>
302+
<ModalHeaderSNCF withCloseButton withBorderBottom closePortalModal={handleClose}>
288303
<h1 className="scenario-edition-modal-title">
289304
{editionMode ? t('main.scenarioModificationTitle') : t('main.scenarioCreationTitle')}
290305
</h1>
291306
</ModalHeaderSNCF>
292307
<ModalBodySNCF>
293308
<div className="row">
294-
<div className={editionMode ? 'col-lg-12' : 'col-lg-6'}>
309+
<div className="col-lg-6">
295310
<div className="scenario-edition-modal-name">
296311
<InputSNCF
297312
id="scenarioInputName"
@@ -363,18 +378,16 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
363378
color="teal"
364379
/>
365380
</div>
366-
{!editionMode && (
367-
<div className="col-lg-6">
368-
<div
369-
className={cx('scenario-edition-modal-infraselector', {
370-
'scenario-edition-modal-infraselector-missing':
371-
displayErrors && !currentScenario.infra_id,
372-
})}
373-
>
374-
<InfraSelectorModal onlySelectionMode />
375-
</div>
381+
<div className="col-lg-6">
382+
<div
383+
className={cx('scenario-edition-modal-infraselector', {
384+
'scenario-edition-modal-infraselector-missing':
385+
displayErrors && !currentScenario.infra_id,
386+
})}
387+
>
388+
<InfraSelectorModal onlySelectionMode />
376389
</div>
377-
)}
390+
</div>
378391
</div>
379392
</ModalBodySNCF>
380393
<ModalFooterSNCF>
@@ -392,7 +405,7 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
392405
{t('main.scenarioDeleteButton')}
393406
</button>
394407
)}
395-
<button className="btn btn-sm btn-secondary mr-2" type="button" onClick={closeModal}>
408+
<button className="btn btn-sm btn-secondary mr-2" type="button" onClick={handleClose}>
396409
{t('main.scenarioCancel')}
397410
</button>
398411
{editionMode ? (
@@ -405,7 +418,7 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
405418
<span className="mr-2">
406419
<Pencil />
407420
</span>
408-
{t('main.scenarioModifyButton')}
421+
{t('main.scenarioModificationTitle')}
409422
</button>
410423
) : (
411424
<button

0 commit comments

Comments
 (0)