Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion front/public/locales/de/operational-studies.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@
"scenarioDescriptionInvalid": "Die Beschreibung darf 1.024 Zeichen nicht überschreiten.",
"scenarioDescriptionPlaceholder": "Kurzbeschreibung des Szenarios",
"scenarioModificationTitle": "Szenario bearbeiten",
"scenarioModifyButton": "Sichern",
"scenarioName": "Szenarioname",
"scenarioNameInvalid": "Der Szenarioname darf 128 Zeichen nicht überschreiten.",
"scenarioTags": "Tags",
Expand Down
3 changes: 1 addition & 2 deletions front/public/locales/en/operational-studies.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,7 @@
"scenarioDescription": "Description",
"scenarioDescriptionInvalid": "The description for the scenario must not exceed 1024 characters",
"scenarioDescriptionPlaceholder": "Short description of the scenario",
"scenarioModificationTitle": "Modify scenario",
"scenarioModifyButton": "Save",
"scenarioModificationTitle": "Edit scenario",
"scenarioName": "Scenario's name",
"scenarioNameInvalid": "You have to set a name for scenario which does not exceed 128 characters",
"scenarioTags": "Tags",
Expand Down
1 change: 0 additions & 1 deletion front/public/locales/fr/operational-studies.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@
"scenarioDescriptionInvalid": "La description pour le scénario ne doit pas dépasser 1024 caractères",
"scenarioDescriptionPlaceholder": "Courte description du scénario",
"scenarioModificationTitle": "Modifier le scénario",
"scenarioModifyButton": "Enregistrer",
"scenarioName": "Nom du scénario",
"scenarioNameInvalid": "Vous devez renseigner un nom pour le scénario qui ne dépasse pas 128 caractères",
"scenarioTags": "Étiquettes",
Expand Down
51 changes: 32 additions & 19 deletions front/src/modules/scenario/components/AddOrEditScenarioModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'r

import { Pencil, Trash } from '@osrd-project/ui-icons';
import cx from 'classnames';
import { sortBy } from 'lodash';
import { isEqual, sortBy } from 'lodash';
import { useTranslation } from 'react-i18next';
import { FaPlus } from 'react-icons/fa';
import { GiElectric } from 'react-icons/gi';
Expand All @@ -24,7 +24,7 @@ import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF';
import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider';
import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF';
import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF';
import { useInfraID } from 'common/osrdContext';
import { useInfraActions, useInfraID } from 'common/osrdContext';
import { InfraSelectorModal } from 'modules/infra/components/InfraSelector';
import DeleteItemsModal from 'modules/project/components/DeleteItemsModal';
import { setFailure, setSuccess } from 'reducers/main';
Expand Down Expand Up @@ -69,6 +69,9 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
const dispatch = useAppDispatch();
const navigate = useNavigate();
const infraID = useInfraID();
const { updateInfraID } = useInfraActions();

const originalInfraIdRef = useRef(scenario?.infra_id);

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

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

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

// Restore the scenario's infra in the global state when the edition modal is closed
// without saving (cancel, close button or click outside).
const handleClose = useCallback(() => {
if (editionMode && originalInfraIdRef.current !== undefined) {
dispatch(updateInfraID(originalInfraIdRef.current));
}
closeModal();
}, [editionMode, dispatch, updateInfraID, closeModal]);

const { clickedOutside, setHasChanges, resetClickedOutside } = useModalOutsideClick(modalRef);

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

useEffect(() => {
setCurrentScenario({ ...currentScenario, infra_id: infraID });
const updated = { ...currentScenario, infra_id: infraID };
setCurrentScenario(updated);
setHasChanges(!isEqual(updated, initialValuesRef.current));
}, [infraID]);

useModalFocusTrap(modalRef, closeModal);
useModalFocusTrap(modalRef, handleClose);

return (
<div data-testid="scenario-edition-modal" className="scenario-edition-modal" ref={modalRef}>
Expand All @@ -278,20 +292,21 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
<div className="confirm-modal-content">
<ConfirmModal
title={t('common.leaveEditionMode', { ns: 'translation' })}
onConfirm={handleClose}
onCancel={resetClickedOutside}
withCloseButton={false}
/>
</div>
</div>
)}
<ModalHeaderSNCF withCloseButton withBorderBottom>
<ModalHeaderSNCF withCloseButton withBorderBottom closePortalModal={handleClose}>
<h1 className="scenario-edition-modal-title">
{editionMode ? t('main.scenarioModificationTitle') : t('main.scenarioCreationTitle')}
</h1>
</ModalHeaderSNCF>
<ModalBodySNCF>
<div className="row">
<div className={editionMode ? 'col-lg-12' : 'col-lg-6'}>
<div className="col-lg-6">
<div className="scenario-edition-modal-name">
<InputSNCF
id="scenarioInputName"
Expand Down Expand Up @@ -363,18 +378,16 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
color="teal"
/>
</div>
{!editionMode && (
<div className="col-lg-6">
<div
className={cx('scenario-edition-modal-infraselector', {
'scenario-edition-modal-infraselector-missing':
displayErrors && !currentScenario.infra_id,
})}
>
<InfraSelectorModal onlySelectionMode />
</div>
<div className="col-lg-6">
<div
className={cx('scenario-edition-modal-infraselector', {
'scenario-edition-modal-infraselector-missing':
displayErrors && !currentScenario.infra_id,
})}
>
<InfraSelectorModal onlySelectionMode />
</div>
)}
</div>
</div>
</ModalBodySNCF>
<ModalFooterSNCF>
Expand All @@ -392,7 +405,7 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
{t('main.scenarioDeleteButton')}
</button>
)}
<button className="btn btn-sm btn-secondary mr-2" type="button" onClick={closeModal}>
<button className="btn btn-sm btn-secondary mr-2" type="button" onClick={handleClose}>
{t('main.scenarioCancel')}
</button>
{editionMode ? (
Expand All @@ -405,7 +418,7 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
<span className="mr-2">
<Pencil />
</span>
{t('main.scenarioModifyButton')}
{t('main.scenarioModificationTitle')}
</button>
) : (
<button
Expand Down