From 245192ff65bf9cc004fe781aa437731c055b1332 Mon Sep 17 00:00:00 2001 From: Priscila Moneo Date: Mon, 18 May 2026 14:35:25 -0300 Subject: [PATCH] fix: improve global forms modal behavior Signed-off-by: Priscila Moneo --- src/actions/form-template-actions.js | 69 +++++++------------ .../form-templates/form-template-list-page.js | 14 +++- .../form-templates/form-template-popup.js | 43 ++++++++++-- 3 files changed, 76 insertions(+), 50 deletions(-) diff --git a/src/actions/form-template-actions.js b/src/actions/form-template-actions.js index 3a1bf67df..dfa330bdd 100644 --- a/src/actions/form-template-actions.js +++ b/src/actions/form-template-actions.js @@ -25,7 +25,6 @@ import { authErrorHandler, escapeFilterValue } from "openstack-uicore-foundation/lib/utils/actions"; -import history from "../history"; import { getAccessTokenSafely } from "../utils/methods"; import { DEFAULT_CURRENT_PAGE, @@ -185,6 +184,8 @@ export const saveFormTemplate = (entity) => async (dispatch) => { dispatch(startLoading()); const normalizedEntity = normalizeEntity(entity); + const materials = entity.materials ?? []; + const metaFields = entity.meta_fields ?? []; if (entity.id) { return putRequest( @@ -198,42 +199,29 @@ export const saveFormTemplate = (entity) => async (dispatch) => { .then(() => { const promises = []; - if (entity.materials.length > 0) { + if (materials.length > 0) { promises.push(saveFormTemplateMaterials(normalizedEntity)(dispatch)); } - if (entity.meta_fields.length > 0) { + if (metaFields.length > 0) { promises.push( saveFormTemplateMetaFieldTypes(normalizedEntity)(dispatch) ); } - Promise.all(promises) - .then(() => { - dispatch( - showSuccessMessage( - T.translate("edit_form_template.form_template_saved") - ) - ); - }) - .catch((err) => { - console.error(err); - }) - .finally(() => { - dispatch(stopLoading()); - }); + return Promise.all(promises).then(() => { + dispatch( + showSuccessMessage( + T.translate("edit_form_template.form_template_saved") + ) + ); + }); }) - .catch((err) => { - console.error(err); + .finally(() => { + dispatch(stopLoading()); }); } - const success_message = { - title: T.translate("general.done"), - html: T.translate("edit_form_template.form_template_created"), - type: "success" - }; - return postRequest( createAction(ADD_FORM_TEMPLATE), createAction(FORM_TEMPLATE_ADDED), @@ -246,31 +234,26 @@ export const saveFormTemplate = (entity) => async (dispatch) => { const formTemplate = { ...normalizedEntity, id: response.id }; const promises = []; - if (entity.materials.length > 0) { + if (materials.length > 0) { promises.push(saveFormTemplateMaterials(formTemplate)(dispatch)); } - if (entity.meta_fields.length > 0) { + if (metaFields.length > 0) { promises.push(saveFormTemplateMetaFieldTypes(formTemplate)(dispatch)); } - Promise.all(promises) - .then(() => { - dispatch( - showMessage(success_message, () => { - history.push("/app/form-templates"); - }) - ); - }) - .catch((err) => { - console.error(err); - }) - .finally(() => { - dispatch(stopLoading()); - }); + return Promise.all(promises).then(() => { + dispatch( + showMessage({ + title: T.translate("general.done"), + html: T.translate("edit_form_template.form_template_created"), + type: "success" + }) + ); + }); }) - .catch((err) => { - console.error(err); + .finally(() => { + dispatch(stopLoading()); }); }; diff --git a/src/pages/sponsors-global/form-templates/form-template-list-page.js b/src/pages/sponsors-global/form-templates/form-template-list-page.js index f5a379013..0d7fef187 100644 --- a/src/pages/sponsors-global/form-templates/form-template-list-page.js +++ b/src/pages/sponsors-global/form-templates/form-template-list-page.js @@ -212,6 +212,18 @@ const FormTemplateListPage = ({ sortDir: orderDir }; + const handleOnSave = async (values) => { + await saveFormTemplate(values); + getFormTemplates( + "", + DEFAULT_CURRENT_PAGE, + perPage, + order, + orderDir, + showArchived + ); + }; + return (

@@ -322,7 +334,7 @@ const FormTemplateListPage = ({ entity={currentFormTemplate} errors={currentFormTemplateErrors} open={formTemplatePopupOpen} - onSave={saveFormTemplate} + onSave={handleOnSave} toDuplicate={formTemplateDuplicate} onClose={() => setFormTemplatePopupOpen(false)} onMetaFieldTypeDeleted={deleteFormTemplateMetaFieldType} diff --git a/src/pages/sponsors-global/form-templates/form-template-popup.js b/src/pages/sponsors-global/form-templates/form-template-popup.js index 3a3a3f648..baef4dfdc 100644 --- a/src/pages/sponsors-global/form-templates/form-template-popup.js +++ b/src/pages/sponsors-global/form-templates/form-template-popup.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import T from "i18n-react/dist/i18n-react"; import PropTypes from "prop-types"; import { @@ -35,6 +35,13 @@ const FormTemplateDialog = ({ onMetaFieldTypeValueDeleted, entity: initialEntity }) => { + const [isSaving, setIsSaving] = useState(false); + + const closePopup = () => { + formik.resetForm(); + onClose(); + }; + const formik = useFormik({ initialValues: { ...initialEntity, @@ -64,15 +71,27 @@ const FormTemplateDialog = ({ })) })) }; - onSave(finalValues); + if (isSaving) return; + + setIsSaving(true); + Promise.resolve(onSave(finalValues)) + .then(() => { + closePopup(); + }) + .catch(() => { + // keep dialog open on save error to preserve user input + }) + .finally(() => { + setIsSaving(false); + }); } }); useScrollToError(formik); const handleClose = () => { - formik.resetForm(); - onClose(); + if (isSaving) return; + closePopup(); }; return ( @@ -84,10 +103,17 @@ const FormTemplateDialog = ({ disableEnforceFocus disableAutoFocus disableRestoreFocus + disableEscapeKeyDown={isSaving} + sx={{ zIndex: 1000 }} > Edit Item - handleClose()} sx={{ mr: 1 }}> + handleClose()} + sx={{ mr: 1 }} + disabled={isSaving} + > @@ -153,7 +179,12 @@ const FormTemplateDialog = ({ -