From dd8df1d18acef83e5ab03a10e84aa2c528641024 Mon Sep 17 00:00:00 2001 From: Bonymol-aot Date: Fri, 20 Jun 2025 08:08:13 -0700 Subject: [PATCH] FWF-4820: [BugFix] Button count down & validations updated --- .../AttributeFIlterModalBody.tsx | 74 ++++++++++++------- .../TaskFilterModal/SaveFilterTab.tsx | 4 +- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/forms-flow-review/src/components/AttributeFilterModal/AttributeFIlterModalBody.tsx b/forms-flow-review/src/components/AttributeFilterModal/AttributeFIlterModalBody.tsx index f620e41f8..122248a8a 100644 --- a/forms-flow-review/src/components/AttributeFilterModal/AttributeFIlterModalBody.tsx +++ b/forms-flow-review/src/components/AttributeFilterModal/AttributeFIlterModalBody.tsx @@ -6,6 +6,7 @@ import { InputDropdown, SaveIcon, UpdateIcon, + useSuccessCountdown, } from "@formsflow/components"; import { useEffect, useMemo, useState } from "react"; import { Modal } from "react-bootstrap"; @@ -45,6 +46,12 @@ const AttributeFilterModalBody = ({ onClose, toggleUpdateModal, updateSuccess, t if (deleteSuccess.showSuccess) { deleteButtonVariant = "success"; } + + const { + successState: saveSuccess, + startSuccessCountdown: setSaveSuccess, +} = useSuccessCountdown(); + const limit = useSelector((state: any) => state.task.limit); const selectedFilter = useSelector((state: any) => state.task.selectedFilter); @@ -60,7 +67,6 @@ const AttributeFilterModalBody = ({ onClose, toggleUpdateModal, updateSuccess, t (state: any) => state.task.attributeFilterToEdit ); const [filterName, setFilterName] = useState(attributeFilter?.name || ""); - const saveIconColor = getIconColor(isUnsavedFilter || !filterName || filterNameError || deleteSuccess?.showSuccess); const deleteIconColor = getIconColor(updateSuccess?.showSuccess); const { data: userList } = useSelector( (state: any) => state.task.userList @@ -107,8 +113,10 @@ const AttributeFilterModalBody = ({ onClose, toggleUpdateModal, updateSuccess, t SAME_AS_TASKS: 'SAME_AS_TASK_FILTER', }; - const [shareAttrFilter, setShareAttrFilter] = useState(FILTER_SHARE_OPTIONS.PRIVATE); // need to handle in edit stage - + const [shareAttrFilter, setShareAttrFilter] = useState(FILTER_SHARE_OPTIONS.PRIVATE); + const saveIconColor = getIconColor(isUnsavedFilter || !filterName || filterNameError|| !shareAttrFilter || deleteSuccess?.showSuccess); + + /* ---------------------------- access management --------------------------- */ const isCreator = @@ -366,21 +374,26 @@ const createFilterShareOption = (labelKey, value) => ({ } const noFieldChanged = isUnsavedFilter ? false : isEqual(selectedAttributeFilter, createAttributeFilterPayload()); const saveFilterAttributes = async () => { - try { - - const filterToSave = createAttributeFilterPayload(); - const response = await createFilter(filterToSave ); - // need to update selected attribute filter in redux - dispatch(setSelectedBpmAttributeFilter(response.data)); - const newAttributeFilterList = [...attributeFilterList,response.data] - dispatch(setAttributeFilterList(newAttributeFilterList)); - dispatch(fetchServiceTaskList(filterToSave, null, 1, limit)); - // setShowUpdateModal(false); - } catch (error) { - console.error("Failed to save filter attributes:", error); - } - onClose(); - }; + try { + const filterToSave = createAttributeFilterPayload(); + const response = await createFilter(filterToSave); + + setSaveSuccess(() => { + onClose(); + }, 2); + + // need to update selected attribute filter in redux + dispatch(setSelectedBpmAttributeFilter(response.data)); + const newAttributeFilterList = [...attributeFilterList, response.data]; + dispatch(setAttributeFilterList(newAttributeFilterList)); + dispatch(fetchServiceTaskList(filterToSave, null, 1, limit)); + } catch (error) { + console.error("Failed to save filter attributes:", error); + } +}; + +const saveButtonVariant = saveSuccess.showSuccess ? "success" : "secondary"; + const handleUpdateModalClick =()=>{ dispatch(setAttributeFilterToEdit(createAttributeFilterPayload())) @@ -409,7 +422,7 @@ const createFilterShareOption = (labelKey, value) => ({ null: } dataTestId="save-attribute-filter" ariaLabel={t("Update This Filter")} - disabled={deleteSuccess.showSuccess ||noFieldChanged} + disabled={deleteSuccess.showSuccess || noFieldChanged || !shareAttrFilter} /> ({ return (
} - dataTestId="save-attribute-filter" - ariaLabel={t("Save Attribute Filter")} - disabled={isUnsavedFilter || filterNameError || noFieldChanged || !filterName} - /> + variant={saveButtonVariant} + size="md" + label={ + saveSuccess.showSuccess + ? `${t("Saved!")} (${saveSuccess.countdown})` + : t("Save This Filter") + } + onClick={saveFilterAttributes} + icon={saveSuccess.showSuccess ? null : } + dataTestId="save-attribute-filter" + ariaLabel={t("Save Attribute Filter")} + disabled={isUnsavedFilter || filterNameError || noFieldChanged || !filterName} +/> +
); } diff --git a/forms-flow-review/src/components/TaskFilterModal/SaveFilterTab.tsx b/forms-flow-review/src/components/TaskFilterModal/SaveFilterTab.tsx index 667c708f9..bedda73c1 100644 --- a/forms-flow-review/src/components/TaskFilterModal/SaveFilterTab.tsx +++ b/forms-flow-review/src/components/TaskFilterModal/SaveFilterTab.tsx @@ -45,7 +45,7 @@ const SaveFilterTab = ({ const [filterNameError, setFilterNameError] = useState(""); const getIconColor = (disabled) => (disabled ? whiteColor : baseColor); const saveIconColor = getIconColor( - createAndUpdateFilterButtonDisabled || filterNameError || deleteSuccess?.showSuccess + createAndUpdateFilterButtonDisabled || filterNameError || deleteSuccess?.showSuccess || !shareFilter|| (shareFilter === SPECIFIC_USER_OR_GROUP && !shareFilterForSpecificRole) ); const { createFilters,manageAllFilters } = userRoles(); const deleteIconColor = getIconColor(successState?.showSuccess); @@ -189,7 +189,7 @@ const SaveFilterTab = ({ } dataTestId="save-task-filter" ariaLabel={t("Update This Filter")} - disabled={deleteSuccess?.showSuccess || createAndUpdateFilterButtonDisabled || filterNameError} + disabled={deleteSuccess?.showSuccess || createAndUpdateFilterButtonDisabled || filterNameError ||!shareFilter || (shareFilter === SPECIFIC_USER_OR_GROUP && !shareFilterForSpecificRole) } />