From d40103a83eb40cca89d8ef9c4de9f0988413478a Mon Sep 17 00:00:00 2001 From: Benoit Simard Date: Tue, 2 Jul 2024 13:54:11 +0200 Subject: [PATCH] front: manage error lifecycle on editor's form Fix #7446 When the initialEntity ref changes in the editor context, we remount the form to reset its state (mainly its isSubmitted state). It avoids top errors to be displayed when they should not. --- .../applications/editor/components/EditorForm.tsx | 2 +- .../components/PointEditionLeftPanel.tsx | 11 +++++++++++ .../editor/tools/pointEdition/tool-factory.tsx | 5 ++++- .../components/TrackEditionLeftPanel.tsx | 14 ++++++++++++-- .../editor/tools/trackEdition/tool.tsx | 5 ++++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/front/src/applications/editor/components/EditorForm.tsx b/front/src/applications/editor/components/EditorForm.tsx index 1d165f64bba..196fd9990e5 100644 --- a/front/src/applications/editor/components/EditorForm.tsx +++ b/front/src/applications/editor/components/EditorForm.tsx @@ -72,7 +72,6 @@ function EditorForm & { objType: string /** * When data or schema change - * => recompute formData by fixing LM */ useEffect(() => { setFormData(omitBy(data.properties, isNil)); @@ -98,6 +97,7 @@ function EditorForm & { objType: string
({ EditorContext ) as ExtendedEditorContextType>; const submitBtnRef = useRef(null); + const [formKey, setFormKey] = useState(state.initialEntity.properties.id); const isWayPoint = type === 'BufferStop' || type === 'Detector'; const isNew = state.entity.properties.id === NEW_ENTITY_ID; @@ -91,6 +93,14 @@ const PointEditionLeftPanel = ({ } }, [infraID, setState, state, state.entity.properties.track, trackState.id, trackState.type]); + /** + * When the ref of the initialEntity changed, + * we remount the form (to reset its state, mainly for errors) + */ + useEffect(() => { + setFormKey(uniqueId()); + }, [state.initialEntity]); + return ( <> {isWayPoint && !isNew && ( @@ -101,6 +111,7 @@ const PointEditionLeftPanel = ({ )} ({ return isEqual(entity, initialEntity); }, onClick({ setState, state: { initialEntity } }) { + const entity = cloneDeep(initialEntity); + // We set the initialEntity, so its ref changes and the form is remounted setState({ - entity: cloneDeep(initialEntity), + entity, + initialEntity: entity, }); }, }, diff --git a/front/src/applications/editor/tools/trackEdition/components/TrackEditionLeftPanel.tsx b/front/src/applications/editor/tools/trackEdition/components/TrackEditionLeftPanel.tsx index 94950cbf8b0..5e25235c061 100644 --- a/front/src/applications/editor/tools/trackEdition/components/TrackEditionLeftPanel.tsx +++ b/front/src/applications/editor/tools/trackEdition/components/TrackEditionLeftPanel.tsx @@ -1,7 +1,7 @@ -import React, { useContext, useEffect, useRef, useMemo } from 'react'; +import React, { useContext, useEffect, useRef, useMemo, useState } from 'react'; import type { JSONSchema7 } from 'json-schema'; -import { isNil, omit } from 'lodash'; +import { isNil, omit, uniqueId } from 'lodash'; import { useTranslation } from 'react-i18next'; import EditorForm from 'applications/editor/components/EditorForm'; @@ -33,6 +33,7 @@ const TrackEditionLeftPanel: React.FC = () => { EditorContext ) as ExtendedEditorContextType; const submitBtnRef = useRef(null); + const [formKey, setFormKey] = useState(state.initialTrack.properties.id); const { track, initialTrack } = state; const isNew = track.properties.id === NEW_ENTITY_ID; @@ -68,9 +69,18 @@ const TrackEditionLeftPanel: React.FC = () => { } as JSONSchema7; }, [editorState.editorSchema, track.objType, track.properties.extensions?.source]); + /** + * When the ref of the initialEntity changed, + * we remount the form (to reset its state, mainly for errors) + */ + useEffect(() => { + setFormKey(uniqueId()); + }, [state.initialTrack]); + return ( <> = { return isEqual(track, initialTrack); }, onClick({ setState, state: { initialTrack } }) { + // We set the initialEntity, so its ref changes and the form is remounted + const track = cloneDeep(initialTrack); setState({ - track: cloneDeep(initialTrack), + track, + initialTrack: track, }); }, },