diff --git a/forms-flow-web/src/components/CustomComponents/settingsModal.js b/forms-flow-web/src/components/CustomComponents/settingsModal.js index 5eeb314c88..d5c555b86a 100644 --- a/forms-flow-web/src/components/CustomComponents/settingsModal.js +++ b/forms-flow-web/src/components/CustomComponents/settingsModal.js @@ -11,45 +11,21 @@ import _set from "lodash/set"; import _cloneDeep from "lodash/cloneDeep"; import _camelCase from "lodash/camelCase"; -const SettingsModal = ({ show, handleClose, handleConfirm }) => { +const SettingsModal = + ({ show, handleClose, handleConfirm, rolesState, + setRolesState, formDetails, updateFormName, updateFormDescription, formDisplay, + setFormDisplay, newPath, handleFormPathChange }) => { const { t } = useTranslation(); const dispatch = useDispatch(); - - const [rolesState, setRolesState] = useState({ - edit: { - roleInput: '', - filteredRoles: [], - selectedRoles: [], - selectedOption: 'onlyYou', - }, - create: { - roleInput: '', - filteredRoles: [], - selectedRoles: [], - selectedOption: 'registeredUsers', - isChecked: false, - }, - view: { - roleInput: '', - filteredRoles: [], - selectedRoles: [], - selectedOption: 'submitter', - }, - }); - const [userRoles, setUserRoles] = useState([]); const [url, setUrl] = useState(''); - const formName = useSelector((state) => state.form.form.name); - const formDescription = useSelector((state) => state.process.formProcessList.description); - const formPath = useSelector((state) => state.form.form.path); - - const [copied, setCopied] = useState(false); - const [newPath, setNewPath] = useState(formPath); - const [newFormName, setNewFormName] = useState(formName); - const [newFormDescription, setNewFormDescription] = useState(formDescription); - const formData = useSelector((state) => state.form?.form); - const reducer = (form, { type, value }) => { - const formCopy = _cloneDeep(form); + const [copied, setCopied] = useState(false); + const formData = useSelector((state) => state.form?.form.path); + const [editIndexValue, setEditIndexValue] = useState(0); + const [createIndexValue, setCreateIndexValue] = useState(0); + const [viewIndexValue, setViewIndexValue] = useState(0); + const reducer = (path, { type, value }) => { + const formCopy = _cloneDeep(path); switch (type) { case "formChange": for (let prop in value) { @@ -84,7 +60,7 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { target.type === "checkbox" ? target.checked ? "wizard" : "form" : target.value; - + setFormDisplay(value); dispatchFormAction({ type: path, value }); }; @@ -171,10 +147,6 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { }); }; - const handleFormPathChange = (e) => { - setNewPath(e.target.value); - }; - const handleClickOutside = (event) => { if (dropEditRef.current && !dropEditRef.current.contains(event.target)) { setRolesState((prevState) => ({ @@ -203,6 +175,7 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { }; }, []); + return ( <Modal className="d-flex flex-column align-items-start w-100 settings-modal" show={show} onHide={handleClose} dialogClassName="modal-50w" backdrop="static"> <Modal.Header> @@ -212,11 +185,16 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { {/* Section 1: Basic */} <div className='section'> <h5 className='fw-bold'>{t("Basic")}</h5> - <FormInput value={newFormName} label={t("Name")} onChange={(e) => setNewFormName(e.target.value)} dataTestid="form-name" ariaLabel={t("Form Name")} /> + <FormInput + value={formDetails.name} + label={t("Name")} + onChange={(e) => updateFormName(e.target.value)} + dataTestid="form-name" + ariaLabel={t("Form Name")} /> <FormTextArea label={t("Description")} - value={newFormDescription} - onChange={(e) => setNewFormDescription(e.target.value)} + value={formDetails.description} + onChange={(e) => updateFormDescription(e.target.value)} aria-label={t("Description of the edited form")} data-testid="form-description" maxRows={3} @@ -236,7 +214,7 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { type="checkbox" id="createCheckbox" label={t("Allow adding multiple pages in this form")} - checked={form.display === "wizard"} + checked={formDisplay === "wizard"} onChange={(event) => handleChange("display", event)} @@ -252,9 +230,32 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { <Form.Label className='field-label'>{t("Who Can Edit This Form")}</Form.Label> <CustomRadioButton items={[ - { label: t("Only You"), onClick: () => setRolesState((prev) => ({ ...prev, edit: { ...prev.edit, selectedOption: 'onlyYou' } })) }, - { label: t("You and specified roles"), onClick: () => setRolesState((prev) => ({ ...prev, edit: { ...prev.edit, selectedOption: 'specifiedRoles' } })) }, - ]} dataTestid="edit-submission-role" ariaLabel={t("Edit Submission Role")} /> + { + label: t("Only You"), + onClick: () => { + setRolesState((prev) => ({ + ...prev, + edit: { ...prev.edit, selectedOption: 'onlyYou' } + })); + setEditIndexValue(0); + } + }, + { + label: t("You and specified roles"), + onClick: () => { + setRolesState((prev) => ({ + ...prev, + edit: { ...prev.edit, selectedOption: 'specifiedRoles' } + })); + setEditIndexValue(1); + } + }, + ]} + dataTestid="edit-submission-role" + ariaLabel={t("Edit Submission Role")} + indexValue={editIndexValue} + /> + {rolesState.edit.selectedOption === 'onlyYou' && ( <FormInput disabled={true} /> @@ -289,15 +290,40 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { type="checkbox" id="createCheckbox" label={t("Anonymous users")} - checked={rolesState.create.isChecked} + checked={rolesState.create.isPublic} onChange={() => setRolesState((prev) => - ({ ...prev, create: { ...prev.create, isChecked: !prev.create.isChecked } }))} + ({ ...prev, create: { ...prev.create, isPublic: !prev.create.isPublic } }))} className='field-label' /> - <CustomRadioButton items={[ - { label: t("Registered users"), onClick: () => setRolesState((prev) => ({ ...prev, create: { ...prev.create, selectedOption: 'registeredUsers' } })) }, - { label: t("Specific roles"), onClick: () => setRolesState((prev) => ({ ...prev, create: { ...prev.create, selectedOption: 'specifiedRoles' } })) }, - ]} dataTestid="create-submission-role" ariaLabel={t("Create Submission Role")} /> + <CustomRadioButton + items={[ + { + label: t("Registered users"), + onClick: () => { + setRolesState((prev) => ({ + ...prev, + create: { ...prev.create, selectedOption: 'registeredUsers' } + })); + setCreateIndexValue(0); + // Set index value for Registered users + } + }, + { + label: t("Specific roles"), + onClick: () => { + setRolesState((prev) => ({ + ...prev, + create: { ...prev.create, selectedOption: 'specifiedRoles' } + })); + setCreateIndexValue(1); // Set index value for Specific roles + } + }, + ]} + dataTestid="create-submission-role" + ariaLabel={t("Create Submission Role")} + indexValue={createIndexValue} +/> + {rolesState.create.selectedOption === 'registeredUsers' && ( <FormInput disabled={true} /> @@ -329,13 +355,33 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { <Form.Label className="field-label mt-3">{t("Who Can View Submissions")}</Form.Label> <CustomRadioButton - items={[ - { label: t("Submitter"), onClick: () => setRolesState((prev) => ({ ...prev, view: { ...prev.view, selectedOption: 'submitter' } })) }, - { label: t("Submitter and specified roles"), onClick: () => setRolesState((prev) => ({ ...prev, view: { ...prev.view, selectedOption: 'specifiedRoles' } })) }, - ]} - dataTestid="view-submission-role" - ariaLabel={t("View Submission Role")} - /> + items={[ + { + label: t("Submitter"), + onClick: () => { + setRolesState((prev) => ({ + ...prev, + view: { ...prev.view, selectedOption: 'submitter' } + })); + setViewIndexValue(0); // Set index value for Submitter + } + }, + { + label: t("Submitter and specified roles"), + onClick: () => { + setRolesState((prev) => ({ + ...prev, + view: { ...prev.view, selectedOption: 'specifiedRoles' } + })); + setViewIndexValue(0); + } + }, + ]} + dataTestid="view-submission-role" + ariaLabel={t("View Submission Role")} + indexValue={viewIndexValue} +/> + {rolesState.view.selectedOption === 'submitter' && ( <FormInput disabled={true} /> @@ -381,8 +427,8 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { </div> <div className='modal-hr' /> - - <div className="section"> + {rolesState.create.isPublic && ( + <div className="section"> <h5 className='fw-bold'>{t("Link for this form")}</h5> <div className="info-panel"> <div className='d-flex align-items-center'> @@ -411,12 +457,9 @@ const SettingsModal = ({ show, handleClose, handleConfirm }) => { </InputGroup.Text> </InputGroup> </Form.Group> - - - - - </div> + )} + </Modal.Body> <Modal.Footer className="d-flex justify-content-start"> <CustomButton diff --git a/forms-flow-web/src/components/Form/Item/Edit.js b/forms-flow-web/src/components/Form/Item/Edit.js index 99770fd95d..ea641882da 100644 --- a/forms-flow-web/src/components/Form/Item/Edit.js +++ b/forms-flow-web/src/components/Form/Item/Edit.js @@ -76,6 +76,7 @@ const Edit = React.memo(() => { const { t } = useTranslation(); const errors = useSelector((state) => state.form?.error); const processListData = useSelector((state) => state.process?.formProcessList); + const formAuthorization = useSelector((state) => state.process.authorizationDetails); const formData = useSelector((state) => state.form?.form); const [form, dispatchFormAction] = useReducer(reducer, _cloneDeep(formData)); const publisText = processListData.status == "active" ? "Unpublish" : "Publish"; @@ -95,10 +96,16 @@ const Edit = React.memo(() => { const applicationCount = useSelector((state) => state.process?.applicationCount); const [showSaveModal, setShowSaveModal] = useState(false); const [hasRendered, setHasRendered] = useState(false); + const [isLoadingDiagram, setIsLoadingDiagram] = useState(true); - //it returns the digram (old method); - // const diagramXML = useSelector((state) => state.process.processDiagramXML); - const roleIds = useSelector((state) => state.user?.roleIds || {}); + const formPath = useSelector((state) => state.form.form.path); + const [newPath, setNewPath] = useState(formPath); + + + const preferred_userName = useSelector( + (state) => state.user?.userDetail?.preferred_username || "" + ); + const [showSettingsModal, setShowSettingsModal] = useState(false); const handleOpenModal = () => setShowSettingsModal(true); const handleCloseModal = () => setShowSettingsModal(false); @@ -113,12 +120,45 @@ const Edit = React.memo(() => { WORKFLOW: "WORKFLOW" }; + const [formDetails, setFormDetails] = useState({ + name: processListData.formName, + description: processListData.description, + }); + + const [formDisplay, setFormDisplay] = useState(processListData.formType); + + const [rolesState, setRolesState] = useState({ + edit: { + roleInput: '', + filteredRoles: [], + selectedRoles: formAuthorization.DESIGNER?.roles, + selectedOption: 'onlyYou', + }, + create: { + roleInput: '', + filteredRoles: [], + selectedRoles: formAuthorization.FORM?.roles, + selectedOption: 'registeredUsers', + isPublic: processListData.anonymous, + + }, + view: { + roleInput: '', + filteredRoles: [], + selectedRoles: formAuthorization.APPLICATION?.roles, + selectedOption: 'submitter', + }, + }); + useEffect(() => { if (showFlow) { setHasRendered(true); } }, [showFlow]); + const handleFormPathChange = (e) => { + setNewPath(e.target.value); + }; const handleShowLayout = () => { setShowFlow(false); @@ -150,6 +190,22 @@ useEffect(() => { + const updateFormName = (formName) => { + setFormDetails((prevState) => ({ + ...prevState, + name: formName, + })); + dispatchFormAction({ type: "title", formName }); + }; + const updateFormDescription = (formDescription) => { + setFormDetails((prevState) => ({ + ...prevState, + description: formDescription, + })); + dispatchFormAction({type: "description", formDescription}); + }; + + //for save farm const isMapperSaveNeeded = (newData) => { return ( @@ -232,17 +288,18 @@ useEffect(() => { }; const handleConfirmSettings = () => { const parentFormId = processListData.parentFormId; - const mapper = { + const mapper = { formId: form._id, - formName: form.title, - description: formDescription, + formName: formDetails?.name, + description: formDetails?.description, status: processListData.status || "inactive", taskVariables: processListData.taskVariables ? processListData.taskVariables : [], - anonymous: formAccess[0]?.roles.includes(roleIds.ANONYMOUS), - parentFormId: parentFormId, + anonymous: rolesState.create.isPublic, + parentFormId: parentFormId, formType: form.type, + display: formDisplay, processKey: workflow?.value, processName: workflow?.name, id: processListData.id, @@ -250,27 +307,30 @@ useEffect(() => { statusChanged: false, resourceId: form._id, }; - + const authorizations = { application: { resourceId:parentFormId , resourceDetails: {}, - roles: [] - }, + roles: rolesState.view.selectedOption === "specifiedRoles" ? rolesState.view.selectedRoles : [], + ...(rolesState.view.selectedOption === "submitter" && { userName: preferred_userName }) // TBD + }, designer: { resourceId: parentFormId, resourceDetails: {}, - roles: [] + roles: rolesState.edit.selectedOption === "specifiedRoles" ? rolesState.edit.selectedRoles : [], + ...(rolesState.edit.selectedOption === "onlyYou" && { userName: preferred_userName }) }, - form: { - resourceId: parentFormId, - resourceDetails: {}, - roles: [] - } -}; - dispatch(saveFormProcessMapperPut({mapper, authorizations})); + form: { + resourceId: parentFormId, + resourceDetails: {}, + roles: rolesState.create.selectedOption === "specifiedRoles" ? rolesState.create.selectedRoles : [], + } }; - + dispatch(saveFormProcessMapperPut({ mapper, authorizations })); + handleCloseModal(); + }; + const closeSaveModal = () => { setShowSaveModal(false); @@ -362,9 +422,7 @@ useEffect(() => { console.log("discardChanges"); }; - // const editorSettings = () => { - // console.log("ecitorActions"); - // }; + const editorActions = () => { setNewActionModal(true); }; @@ -386,8 +444,14 @@ useEffect(() => { text={t("Loading...")} > -<SettingsModal show={showSettingsModal} handleClose={handleCloseModal} -handleConfirm={handleConfirmSettings} /> + <SettingsModal show={showSettingsModal} handleClose={handleCloseModal} + handleConfirm={handleConfirmSettings} + rolesState={rolesState} setRolesState={setRolesState} + setFormDetails={setFormDetails} formDetails={formDetails} + updateFormName={updateFormName} formDisplay={formDisplay} + setFormDisplay={setFormDisplay} + updateFormDescription={updateFormDescription} newPath={newPath} + handleFormPathChange={handleFormPathChange}/> <Errors errors={errors} />