diff --git a/forms-flow-web/src/components/CustomComponents/MultiSelect.js b/forms-flow-web/src/components/CustomComponents/MultiSelect.js deleted file mode 100644 index 62d34bcca..000000000 --- a/forms-flow-web/src/components/CustomComponents/MultiSelect.js +++ /dev/null @@ -1,120 +0,0 @@ -import React, { useState, useRef, useEffect } from "react"; -import { useSelector } from "react-redux"; -import { ListGroup } from "react-bootstrap"; -import { CustomPill,DeleteIcon } from "@formsflow/components"; -import PropTypes from 'prop-types'; -import { HelperServices, StyleServices } from "@formsflow/service"; - -const RoleSelector = ({ - allRoles = [], - selectedRoles = [], - setSelectedRoles, - openByDefault = false, -}) => { - const primaryColor = StyleServices.getCSSVariable('--ff-primary'); - const [roleInput, setRoleInput] = useState(""); - const [filteredRoles, setFilteredRoles] = useState([]); - const [isDropdownOpen, setIsDropdownOpen] = useState(false); // To control dropdown visibility - const dropDownRef = useRef(null); - const inputRef = useRef(null); - const tenantKey = useSelector((state) => state.tenants?.tenantId); - useEffect(() => { - if (openByDefault && inputRef.current && !selectedRoles.length) { - inputRef.current.focus(); - } - }, [openByDefault]); - // Filter roles based on input - useEffect(() => { - const filtered = allRoles.filter( - (role) => - role.toLowerCase().includes(roleInput.toLowerCase()) && - !selectedRoles.includes(role) - ); - setFilteredRoles(filtered); - }, [roleInput, allRoles, selectedRoles]); - - // Handle input change - const handleRoleInputChange = (e) => { - setRoleInput(e.target.value); - }; - - // Handle role selection from dropdown - const handleRoleSelect = (role) => { - setSelectedRoles([...selectedRoles, role]); - setRoleInput(""); // Clear input - setIsDropdownOpen(false); // Close the dropdown after selecting a role - }; - - // Handle role removal - const removeRole = (roleToRemove) => { - setSelectedRoles(selectedRoles.filter((role) => role !== roleToRemove)); - }; - - // Close dropdown when clicking outside - useEffect(() => { - const handleClickOutside = (event) => { - if ( - dropDownRef.current && - !dropDownRef.current.contains(event.target) && - !inputRef.current.contains(event.target) - ) { - setIsDropdownOpen(false); // Close dropdown if clicked outside - } - }; - - document.addEventListener("mousedown", handleClickOutside); - return () => { - document.removeEventListener("mousedown", handleClickOutside); - }; - }, []); - - return ( -
-
- {selectedRoles.map((role, index) => ( - } - bg="primary" - onClick={() => removeRole(role)} - /> - ))} - setIsDropdownOpen(true)} // Open dropdown when input is focused - className="role-input" - ref={inputRef} // Reference to input for outside click handling - /> -
- - {isDropdownOpen && filteredRoles.length > 0 && ( -
- - {filteredRoles.map((role, index) => ( - handleRoleSelect(role)} - > - {HelperServices.removeTenantKeyFromData(role,tenantKey)} - - ))} - -
- )} -
- ); -}; - - -RoleSelector.propTypes = { - allRoles: PropTypes.array, - selectedRoles: PropTypes.array.isRequired, - setSelectedRoles: PropTypes.func.isRequired, - openByDefault: PropTypes.bool, -}; - -export default RoleSelector; diff --git a/forms-flow-web/src/components/Form/EditForm/FormEdit.js b/forms-flow-web/src/components/Form/EditForm/FormEdit.js index fbfe4e1a7..709d8ad03 100644 --- a/forms-flow-web/src/components/Form/EditForm/FormEdit.js +++ b/forms-flow-web/src/components/Form/EditForm/FormEdit.js @@ -61,7 +61,8 @@ import NewVersionModal from "../../Modals/NewVersionModal"; import { currentFormReducer } from "../../../modules/formReducer.js"; import { toast } from "react-toastify"; import userRoles from "../../../constants/permissions.js"; -import { generateUniqueId, isFormComponentsChanged, addTenantkey, textTruncate } from "../../../helper/helper.js"; +import { generateUniqueId, isFormComponentsChanged, addTenantkey, textTruncate, + convertMultiSelectOptionToValue } from "../../../helper/helper.js"; import { useMutation } from "react-query"; import NavigateBlocker from "../../CustomComponents/NavigateBlocker"; import { setProcessData, setFormPreviosData, setFormProcessesData } from "../../../actions/processActions.js"; @@ -538,12 +539,13 @@ const handleSaveLayout = () => { /* ----------- save settings function to be used in settings modal ---------- */ + const filterAuthorizationData = (authorizationData) => { if(authorizationData.selectedOption === "submitter"){ return {roles: [], userName:null, resourceDetails:{submitter:true}}; } if (authorizationData.selectedOption === "specifiedRoles") { - return { roles: authorizationData.selectedRoles, userName: "" }; + return { roles: convertMultiSelectOptionToValue(authorizationData.selectedRoles, "role"), userName: "" }; } return { roles: [], userName: preferred_username }; }; @@ -582,7 +584,7 @@ const handleSaveLayout = () => { resourceDetails: {}, roles: rolesState.FORM.selectedOption === "specifiedRoles" - ? rolesState.FORM.selectedRoles + ? convertMultiSelectOptionToValue(rolesState.FORM.selectedRoles, "role") : [], }, }; diff --git a/forms-flow-web/src/components/Form/EditForm/FormSettings.js b/forms-flow-web/src/components/Form/EditForm/FormSettings.js index b4cfdf43d..2d385367f 100644 --- a/forms-flow-web/src/components/Form/EditForm/FormSettings.js +++ b/forms-flow-web/src/components/Form/EditForm/FormSettings.js @@ -11,11 +11,11 @@ import { CustomRadioButton, FormInput, FormTextArea, + MultipleSelect } from "@formsflow/components"; -import MultiSelectComponent from "../../CustomComponents/MultiSelect"; import { MULTITENANCY_ENABLED } from "../../../constants/constants"; -import { addTenantkeyAsSuffix } from "../../../helper/helper"; +import { addTenantkeyAsSuffix, convertSelectedValueToMultiSelectOption } from "../../../helper/helper"; import { useDispatch, useSelector } from "react-redux"; import { getUserRoles } from "../../../apiManager/services/authorizationService"; import { useTranslation } from "react-i18next"; @@ -64,22 +64,26 @@ const FormSettings = forwardRef((props, ref) => { const publicUrlPath = `${window.location.origin}/public/form/`; const [urlPath,setUrlPath] = useState(publicUrlPath); - const setSelectedOption = (roles, option)=> roles.length ? "specifiedRoles" : option; + const setSelectedOption = (option, roles = [])=> roles.length ? "specifiedRoles" : option; + const multiSelectOptionKey = "role"; /* ------------------------- authorization variables ------------------------ */ const [rolesState, setRolesState] = useState({ DESIGN: { - selectedRoles: formAuthorization.DESIGNER?.roles, - selectedOption: setSelectedOption(formAuthorization.DESIGNER?.roles,"onlyYou"), + selectedRoles: convertSelectedValueToMultiSelectOption(formAuthorization.DESIGNER?.roles, + multiSelectOptionKey), + selectedOption: setSelectedOption("onlyYou", formAuthorization.DESIGNER?.roles), }, FORM: { roleInput: "", - selectedRoles: formAuthorization.FORM?.roles, - selectedOption: setSelectedOption(formAuthorization.FORM?.roles,"registeredUsers"), + selectedRoles: convertSelectedValueToMultiSelectOption(formAuthorization.FORM?.roles, + multiSelectOptionKey), + selectedOption: setSelectedOption("registeredUsers", formAuthorization.FORM?.roles), }, APPLICATION: { roleInput: "", - selectedRoles: formAuthorization.APPLICATION?.roles, - selectedOption: setSelectedOption(formAuthorization.APPLICATION?.roles, "submitter"), + selectedRoles: convertSelectedValueToMultiSelectOption(formAuthorization.APPLICATION?.roles, + multiSelectOptionKey), + selectedOption: setSelectedOption("submitter", formAuthorization.APPLICATION?.roles), /* The 'submitter' key is stored in 'resourceDetails'. If the roles array is not empty we assume that the submitter is true. */ } @@ -154,7 +158,7 @@ const FormSettings = forwardRef((props, ref) => { .then((res) => { if (res) { const { data = [] } = res; - setUserRoles(data.map((role) => role.name)); + setUserRoles(data.map((role,index) => ({[multiSelectOptionKey]:role.name, id: index}))); } }) .catch((error) => console.error("error", error)); @@ -162,7 +166,7 @@ const FormSettings = forwardRef((props, ref) => { - const handleRoleStateChange = (section, key, value) => { + const handleRoleStateChange = (section, key, value = []) => { setRolesState((prevState) => ({ ...prevState, [section]: { @@ -210,6 +214,10 @@ const FormSettings = forwardRef((props, ref) => { props.setIsSaveButtonDisabled(shouldDisableSaveButton); }, [rolesState, errors, formDetails]); + const handleRoleSelectForDesign = (roles) => handleRoleStateChange(DESIGN, "selectedRoles", roles); + const handleRoleSelectForForm = (roles) => handleRoleStateChange(FORM, "selectedRoles", roles); + const handleRoleSelectForApplication = (roles) => + handleRoleStateChange(APPLICATION, "selectedRoles", roles); return ( <> @@ -289,14 +297,15 @@ const FormSettings = forwardRef((props, ref) => { )} {rolesState.DESIGN.selectedOption === "specifiedRoles" && ( - - handleRoleStateChange(DESIGN, "selectedRoles", roles) - } + + )} @@ -338,14 +347,15 @@ const FormSettings = forwardRef((props, ref) => { )} {rolesState.FORM.selectedOption === "specifiedRoles" && ( - - handleRoleStateChange(FORM, "selectedRoles", roles) - } - /> + + )} @@ -378,14 +388,15 @@ const FormSettings = forwardRef((props, ref) => { )} {rolesState.APPLICATION.selectedOption === "specifiedRoles" && ( - - handleRoleStateChange(APPLICATION, "selectedRoles", roles) - } + + )} diff --git a/forms-flow-web/src/helper/helper.js b/forms-flow-web/src/helper/helper.js index ebf8cbd58..c76e806d7 100644 --- a/forms-flow-web/src/helper/helper.js +++ b/forms-flow-web/src/helper/helper.js @@ -114,5 +114,22 @@ const addTenantkeyAsSuffix = (value, tenantkey) => { } }; -export { generateUniqueId, replaceUrl, addTenantkey, removeTenantKey, textTruncate, renderPage, - filterSelectOptionByLabel, isFormComponentsChanged,addTenantkeyAsSuffix}; +/* ----------------- convert data from and into multiselect ----------------- */ +const convertMultiSelectOptionToValue = (selectedValues = [], key = null) => + selectedValues.map(i=> i[key]); + +const convertSelectedValueToMultiSelectOption = (values = [], key = null) => + values.map((value)=>({[key]:value, id:_.uniqueId(value)})); +/* ----------------------------------- --- ---------------------------------- */ +export { generateUniqueId, + replaceUrl, + addTenantkey, + removeTenantKey, + textTruncate, + renderPage, + filterSelectOptionByLabel, + isFormComponentsChanged, + addTenantkeyAsSuffix, + convertMultiSelectOptionToValue, + convertSelectedValueToMultiSelectOption +};