diff --git a/pmp-reactjs-ui/public/i18n/ara.json b/pmp-reactjs-ui/public/i18n/ara.json index 7f6176da..51d55800 100644 --- a/pmp-reactjs-ui/public/i18n/ara.json +++ b/pmp-reactjs-ui/public/i18n/ara.json @@ -597,6 +597,15 @@ "headerMsg": "هل تريد إلغاء تنشيط الشريك بمعرف الشريك: {{partnerId}} التابع للمؤسسة: {{organizationName}}", "description": "عند النقر على تأكيد، سيتم إلغاء تنشيط الشريك المحدد ولن يتمكن بعد ذلك من إجراء أي عمليات في بوابة PMS" }, + "createPolicyGroup": { + "policies":"السياسات", + "createPolicyGroup": "إنشاء مجموعة السياسات", + "policyGroupName": "اسم مجموعة السياسات", + "enterNameforPolicyGroup": "أدخل اسمًا لمجموعة السياسات", + "policyGroupDescription":"وصف مجموعة السياسات", + "enterPolicyGroupDescription": "أدخل وصفًا حول مجموعة السياسات هنا", + "errorInCreatePolicyGroup": "أثناء إنشاء السياسة، واجهنا خطأ" + }, "policyGroupList": { "policies": "السياسات", "policyGroup":"مجموعة السياسات", diff --git a/pmp-reactjs-ui/public/i18n/eng.json b/pmp-reactjs-ui/public/i18n/eng.json index 7ff53e53..0caf5d10 100644 --- a/pmp-reactjs-ui/public/i18n/eng.json +++ b/pmp-reactjs-ui/public/i18n/eng.json @@ -593,6 +593,15 @@ "headerMsg": "Do you want to deactivate partner with Partner ID: {{partnerId}} belonging to Organization : {{organizationName}}", "description": "Upon clicking ‘Confirm’, the selected partner will be deactivated and will no longer have access to perform any operations in the PMS portal." }, + "createPolicyGroup": { + "policies":"Policies", + "createPolicyGroup": "Create Policy Group", + "policyGroupName": "Policy Group Name", + "enterNameforPolicyGroup": "Enter name for Policy Group", + "policyGroupDescription":"Policy Group Description", + "enterPolicyGroupDescription": "Enter description about Policy Group here", + "errorInCreatePolicyGroup": "While Creating Policy, we have encountered with an error." + }, "policyGroupList": { "policies": "Policies", "policyGroup":"Policy Group", diff --git a/pmp-reactjs-ui/public/i18n/fra.json b/pmp-reactjs-ui/public/i18n/fra.json index 3748f780..dc8127f4 100644 --- a/pmp-reactjs-ui/public/i18n/fra.json +++ b/pmp-reactjs-ui/public/i18n/fra.json @@ -582,20 +582,29 @@ "searchOrganisation": "Rechercher une organisation", "searchEmailAddress": "Rechercher une adresse e-mail", "searchPolicyGroup": "Groupe de stratégies de recherche" - }, - "viewPartnerDetails": { - "viewPartnerDetails": "Afficher les détails du partenaire", - "listOfPartners": "Liste des partenaires", - "organizationName": "Nom de l'Organisation", - "createdOn":"Créé le", - "expiryDate": "Date et heure d'expiration", - "emailId": "Identifiant de courrier électronique", - "errorInPartnerList": "Lors de la récupération des détails du partenaire, nous avons rencontré une erreur.", - "originalCertificateSuccessMsg": "Certificat original téléchargé avec succès." - }, - "deactivatePartner": { - "headerMsg": "En cliquant sur Confirmer, le partenaire sélectionné sera désactivé et n'aura plus accès pour effectuer aucune opération dans le portail PMS", - "description": "En cliquant sur « Confirmer », le partenaire sélectionné sera désactivé et n’aura plus accès pour effectuer aucune opération dans le portail PMS." + }, + "viewPartnerDetails": { + "viewPartnerDetails": "Afficher les détails du partenaire", + "listOfPartners": "Liste des partenaires", + "organizationName": "Nom de l'Organisation", + "createdOn":"Créé le", + "expiryDate": "Date et heure d'expiration", + "emailId": "Identifiant de courrier électronique", + "errorInPartnerList": "Lors de la récupération des détails du partenaire, nous avons rencontré une erreur.", + "originalCertificateSuccessMsg": "Certificat original téléchargé avec succès." + }, + "deactivatePartner": { + "headerMsg": "En cliquant sur Confirmer, le partenaire sélectionné sera désactivé et n'aura plus accès pour effectuer aucune opération dans le portail PMS", + "description": "En cliquant sur « Confirmer », le partenaire sélectionné sera désactivé et n’aura plus accès pour effectuer aucune opération dans le portail PMS." + }, + "createPolicyGroup": { + "policies":"Politiques", + "createPolicyGroup": "Créer un groupe de stratégies", + "policyGroupName": "Nom du groupe de stratégies", + "enterNameforPolicyGroup": "Entrez le nom du groupe de stratégies", + "policyGroupDescription":"Description du groupe de stratégies", + "enterPolicyGroupDescription": "Entrez la description du groupe de stratégies ici", + "errorInCreatePolicyGroup": "Lors de la création de la stratégie, nous avons rencontré une erreur" }, "policyGroupList": { "policies": "Politiques", diff --git a/pmp-reactjs-ui/src/AppRoutes.js b/pmp-reactjs-ui/src/AppRoutes.js index 732cdd26..6115cac3 100644 --- a/pmp-reactjs-ui/src/AppRoutes.js +++ b/pmp-reactjs-ui/src/AppRoutes.js @@ -27,9 +27,10 @@ import RootTrustCertificateList from './pages/admin/certificates/RootTrustCertif import UploadRootTrustCertificate from './pages/admin/certificates/UploadRootTrustCertificate.js'; import PartnersList from './pages/admin/partners/PartnersList.js'; import ViewPartnerDetails from './pages/admin/partners/ViewPartnerDetails.js'; -import PolicyGroupList from './pages/admin/policies/PolicyGroupList.js'; -import AuthPoliciesList from './pages/admin/policies/AuthPoliciesList.js'; -import DataSharePoliciesList from './pages/admin/policies/DataSharePoliciesList.js'; +import CreatePolicyGroup from './pages/admin/policyManager/CreatePolicyGroup.js'; +import PolicyGroupList from './pages/admin/policyManager/PolicyGroupList.js'; +import AuthPoliciesList from './pages/admin/policyManager/AuthPoliciesList.js'; +import DataSharePoliciesList from './pages/admin/policyManager/DataSharePoliciesList.js'; function AppRoutes() { @@ -148,15 +149,19 @@ function AppRoutes() { element: }, { - path: 'admin/policies/policyGroupList', + path: 'admin/policyManager/createPolicyGroup', + element: + }, + { + path: 'admin/policyManager/policyGroupList', element: }, { - path: 'admin/policies/authPoliciesList', + path: 'admin/policyManager/authPoliciesList', element: }, { - path: 'admin/policies/dataSharePoliciesList', + path: 'admin/policyManager/dataSharePoliciesList', element: }, { diff --git a/pmp-reactjs-ui/src/nav/SideNav.js b/pmp-reactjs-ui/src/nav/SideNav.js index 19d1aa34..467ca07c 100644 --- a/pmp-reactjs-ui/src/nav/SideNav.js +++ b/pmp-reactjs-ui/src/nav/SideNav.js @@ -22,7 +22,7 @@ function SideNav({ open, policyRequiredPartnerTypes, partnerType }) { // console.log(selectedPath); if (selectedPath.includes('dashboard')) { setActiveIcon("home"); - } else if (selectedPath.includes('admin/policies')) { + } else if (selectedPath.includes('admin/policyManager')) { setActiveIcon("admin_policies"); } else if (selectedPath.includes('partnerCertificate')) { setActiveIcon("partnerCertificate"); @@ -98,7 +98,7 @@ function SideNav({ open, policyRequiredPartnerTypes, partnerType }) { navigate('/partnermanagement/admin/partnersList'); }; const showAdminPolicies = () => { - navigate('/partnermanagement/admin/policies/policyGroupList'); + navigate('/partnermanagement/admin/policyManager/policyGroupList'); }; const showPartnerPolicyMapping = () => { setActiveIcon("partnerPolicyMapping"); diff --git a/pmp-reactjs-ui/src/pages/admin/partners/PartnersList.js b/pmp-reactjs-ui/src/pages/admin/partners/PartnersList.js index 8ac9bffc..289bda49 100644 --- a/pmp-reactjs-ui/src/pages/admin/partners/PartnersList.js +++ b/pmp-reactjs-ui/src/pages/admin/partners/PartnersList.js @@ -234,10 +234,7 @@ function PartnersList() { ); return ( -
+
{!dataLoaded && } {dataLoaded && ( <> diff --git a/pmp-reactjs-ui/src/pages/admin/policies/AuthPoliciesList.js b/pmp-reactjs-ui/src/pages/admin/policyManager/AuthPoliciesList.js similarity index 100% rename from pmp-reactjs-ui/src/pages/admin/policies/AuthPoliciesList.js rename to pmp-reactjs-ui/src/pages/admin/policyManager/AuthPoliciesList.js diff --git a/pmp-reactjs-ui/src/pages/admin/policyManager/CreatePolicyGroup.js b/pmp-reactjs-ui/src/pages/admin/policyManager/CreatePolicyGroup.js new file mode 100644 index 00000000..e8923ec3 --- /dev/null +++ b/pmp-reactjs-ui/src/pages/admin/policyManager/CreatePolicyGroup.js @@ -0,0 +1,194 @@ +import React, { useEffect, useState } from 'react'; +import { useNavigate, useBlocker } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { createRequest, getPolicyManagerUrl, handleServiceErrors, isLangRTL, onPressEnterKey, trimAndReplace } from '../../../utils/AppUtils'; +import { getUserProfile } from '../../../services/UserProfileService'; +import BlockerPrompt from "../../common/BlockerPrompt"; +import Title from '../../common/Title'; +import LoadingIcon from '../../common/LoadingIcon'; +import ErrorMessage from '../../common/ErrorMessage'; +import { HttpService } from '../../../services/HttpService'; + +function CreatePolicyGroup() { + + const { t } = useTranslation(); + const navigate = useNavigate(); + const isLoginLanguageRTL = isLangRTL(getUserProfile().langCode); + const [dataLoaded, setDataLoaded] = useState(false); + const [errorCode, setErrorCode] = useState(""); + const [errorMsg, setErrorMsg] = useState(""); + const [policyGroupName, setPolicyGroupName] = useState(''); + const [policyGroupDesc, setPolicyGroupDesc] = useState(''); + const [isSubmitClicked, setIsSubmitClicked] = useState(false); + const [validationError, setValidationError] = useState(""); + const [createPolicySuccess, setCreatePolicySuccess] = useState(false); + let isCancelledClicked = false; + + const blocker = useBlocker( + ({ currentLocation, nextLocation }) => { + if (isSubmitClicked || isCancelledClicked || createPolicySuccess) { + setIsSubmitClicked(false); + isCancelledClicked = false; + return false; + } + return ( + (policyGroupName !== "" || policyGroupDesc !== "") && currentLocation.pathname !== nextLocation.pathname + ); + } + ); + + useEffect(() => { + const shouldWarnBeforeUnload = () => { + return policyGroupName !== "" || + policyGroupDesc !== "" + }; + + const handleBeforeUnload = (event) => { + if (shouldWarnBeforeUnload() && !isSubmitClicked) { + event.preventDefault(); + event.returnValue = ''; + } + }; + + window.addEventListener('beforeunload', handleBeforeUnload); + + return () => { + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, [policyGroupName, policyGroupDesc, isSubmitClicked]); + + const clearForm = () => { + setPolicyGroupName(""); + setPolicyGroupDesc(""); + setValidationError(""); + }; + + const isFormValid = () => { + return policyGroupName && policyGroupDesc && !validationError; + }; + + const onChangePolicyGroupName = (value) => { + setPolicyGroupName(value); + }; + + const onChangePolicyGroupDesc = (value) => { + setPolicyGroupDesc(value); + }; + + const clickOnCancel = () => { + navigate('/partnermanagement/admin/policyManager/policyGroupList'); + }; + + const clickOnSubmit = async () => { + setIsSubmitClicked(true); + setErrorCode(""); + setErrorMsg(""); + // let request = createRequest({ + // name: trimAndReplace(policyGroupName), + // desc: trimAndReplace(policyGroupDesc) + // }); + // try { + // const response = await HttpService.post(getPolicyManagerUrl(`/policies/group/new`, process.env.NODE_ENV), request, { + // headers: { + // 'Content-Type': 'application/json' + // } + // }); + // if (response) { + // const responseData = response.data; + // if (responseData && responseData.response) { + // const resData = responseData.response; + // console.log(`Response data: ${resData}`); + + // } else { + // handleServiceErrors(responseData, setErrorCode, setErrorMsg); + // } + // } else { + // setErrorMsg(t('createPolicyGroup.errorInCreatePolicyGroup')); + // } + // setDataLoaded(false); + // } catch (err) { + // setErrorMsg(err); + // console.log("Error fetching data: ", err); + // } + setIsSubmitClicked(false); + } + + const cancelErrorMsg = () => { + setErrorMsg(""); + }; + + + const handleFormSubmit = (event) => { + event.preventDefault(); + }; + + const style = { + backArrowIcon: "!mt-[9%]", + }; + + return ( +
+ {dataLoaded && ( + + )} + {!dataLoaded && ( + <> + {errorMsg && ( + + )} +
+
+ + </div> + <div className="w-[100%] bg-snow-white mt-[1.5%] rounded-lg shadow-md"> + <div className="px-[2.5%] py-[2%]"> + <p className="text-base text-[#3D4468]">{t('requestPolicy.mandatoryFieldsMsg1')} <span className="text-crimson-red">*</span> {t('requestPolicy.mandatoryFieldsMsg2')}</p> + <form onSubmit={handleFormSubmit}> + <div className="flex flex-col"> + <div className="space-y-6"> + <div className="my-4"> + <div className="flex flex-col w-[48%] max-[450px]:w-full"> + <label className={`block text-dark-blue text-sm font-semibold mb-1 ${isLoginLanguageRTL ? "mr-1" : "ml-1"}`}>{t('createPolicyGroup.policyGroupName')}<span className="text-crimson-red mx-1">*</span></label> + <input value={policyGroupName} onChange={(e) => onChangePolicyGroupName(e.target.value)} maxLength={128} + className="h-12 px-2 py-3 border border-[#707070] rounded-md text-md text-dark-blue bg-white leading-tight focus:outline-none focus:shadow-outline overflow-x-auto whitespace-nowrap no-scrollbar" + placeholder={t('createPolicyGroup.enterNameforPolicyGroup')} id="policy_group_name" + /> + </div> + </div> + </div> + <div className="space-y-6"> + <div className="my-4"> + <div className="flex flex-col w-full max-[450px]:w-full"> + <label className={`block text-dark-blue text-sm font-semibold mb-1 ${isLoginLanguageRTL ? "mr-1" : "ml-1"}`}>{t('createPolicyGroup.policyGroupDescription')}<span className="text-crimson-red mx-1">*</span></label> + <textarea value={policyGroupDesc} onChange={(e) => onChangePolicyGroupDesc(e.target.value)} maxLength={256} + className="h-14 px-2 py-3 border border-[#707070] rounded-md text-md text-dark-blue bg-white leading-tight focus:outline-none focus:shadow-outline overflow-x-auto whitespace-nowrap no-scrollbar" + placeholder={t('createPolicyGroup.enterPolicyGroupDescription')} id="policy_group_description" + /> + </div> + </div> + </div> + </div> + </form> + </div> + <div className="border bg-medium-gray" /> + <div className="flex flex-row max-[450px]:flex-col px-[3%] py-9 justify-between max-[450px]:space-y-2"> + <button id="createPolicy_clear_form" onClick={() => clearForm()} className={`w-40 h-10 mr-3 border-[#1447B2] ${isLoginLanguageRTL ? "mr-2" : "ml-2"} border rounded-md bg-white text-tory-blue text-sm font-semibold`} tabIndex="0" onKeyPress={(e) => onPressEnterKey(e, clearForm())}> + {t('requestPolicy.clearForm')} + </button> + <div className={`flex flex-row max-[450px]:flex-col space-x-3 max-[450px]:space-x-0 max-[450px]:space-y-2 w-full md:w-auto justify-end`}> + <button id="createPolicy_cancel_btn" onClick={() => clickOnCancel()} className={`${isLoginLanguageRTL ? "ml-2" : "mr-2"} w-11/12 md:w-40 h-10 border-[#1447B2] border rounded-md bg-white text-tory-blue text-sm font-semibold`}>{t('requestPolicy.cancel')}</button> + <button id="createPolicy_submit_btn" disabled={!isFormValid()} onClick={() => clickOnSubmit()} className={`${isLoginLanguageRTL ? "ml-2" : "mr-2"} w-11/12 md:w-40 h-10 border-[#1447B2] border rounded-md text-sm font-semibold ${isFormValid() ? 'bg-tory-blue text-white' : 'border-[#A5A5A5] bg-[#A5A5A5] text-white cursor-not-allowed'}`} tabIndex="0" onKeyPress={(e) => onPressEnterKey(e, clearForm())}> + {t('requestPolicy.submit')} + </button> + </div> + </div> + </div> + </div> + </> + )} + <BlockerPrompt blocker={blocker} /> + </div> + ) +} + +export default CreatePolicyGroup; \ No newline at end of file diff --git a/pmp-reactjs-ui/src/pages/admin/policies/DataSharePoliciesList.js b/pmp-reactjs-ui/src/pages/admin/policyManager/DataSharePoliciesList.js similarity index 100% rename from pmp-reactjs-ui/src/pages/admin/policies/DataSharePoliciesList.js rename to pmp-reactjs-ui/src/pages/admin/policyManager/DataSharePoliciesList.js diff --git a/pmp-reactjs-ui/src/pages/admin/policies/PoliciesTab.js b/pmp-reactjs-ui/src/pages/admin/policyManager/PoliciesTab.js similarity index 93% rename from pmp-reactjs-ui/src/pages/admin/policies/PoliciesTab.js rename to pmp-reactjs-ui/src/pages/admin/policyManager/PoliciesTab.js index 3c169202..b62da546 100644 --- a/pmp-reactjs-ui/src/pages/admin/policies/PoliciesTab.js +++ b/pmp-reactjs-ui/src/pages/admin/policyManager/PoliciesTab.js @@ -10,21 +10,21 @@ function PoliciesTab ({activePolicyGroup, setActivePolicyGroup, activeAuthPolicy const navigate = useNavigate(); const changeToPolicyGroup = () => { - navigate('/partnermanagement/admin/policies/policyGroupList') + navigate('/partnermanagement/admin/policyManager/policyGroupList') setActivePolicyGroup(true); setActiveAuthPolicy(false); setActiveDataSharePolicy(false); }; const changeToAuthPolicy = () => { - navigate('/partnermanagement/admin/policies/authPoliciesList') + navigate('/partnermanagement/admin/policyManager/authPoliciesList') setActivePolicyGroup(false); setActiveAuthPolicy(true); setActiveDataSharePolicy(false); }; const changeToDataSharePolicy = () => { - navigate('/partnermanagement/admin/policies/dataSharePoliciesList') + navigate('/partnermanagement/admin/policyManager/dataSharePoliciesList') setActivePolicyGroup(false); setActiveAuthPolicy(false); setActiveDataSharePolicy(true); diff --git a/pmp-reactjs-ui/src/pages/admin/policies/PolicyGroupList.js b/pmp-reactjs-ui/src/pages/admin/policyManager/PolicyGroupList.js similarity index 96% rename from pmp-reactjs-ui/src/pages/admin/policies/PolicyGroupList.js rename to pmp-reactjs-ui/src/pages/admin/policyManager/PolicyGroupList.js index ec355641..2aa0185d 100644 --- a/pmp-reactjs-ui/src/pages/admin/policies/PolicyGroupList.js +++ b/pmp-reactjs-ui/src/pages/admin/policyManager/PolicyGroupList.js @@ -23,6 +23,10 @@ function PolicyGroupList() { const [activeDataSharePolicy, setActiveDataSharePolicy] = useState(false); const [policyGroupList, setPolicyGroupList] = useState([]); + const createPolicyGroup = () => { + navigate('/partnermanagement/admin/policyManager/createPolicyGroup'); + }; + const cancelErrorMsg = () => { setErrorMsg(""); }; @@ -74,7 +78,7 @@ function PolicyGroupList() { <div className="flex flex-col justify-center"> <img src={rectangleGrid} alt="" /> {activePolicyGroup && - (<button id='create_policy_group_btn' type="button" + (<button id='create_policy_group_btn' type="button" onClick={createPolicyGroup} className={`text-white font-semibold mt-8 bg-tory-blue rounded-md text-sm mx-8 py-3`}> {t('policyGroupList.createPolicyGroup')} </button>) diff --git a/pmp-reactjs-ui/src/pages/dashboard/Dashboard.js b/pmp-reactjs-ui/src/pages/dashboard/Dashboard.js index 1319e340..1b7f7175 100644 --- a/pmp-reactjs-ui/src/pages/dashboard/Dashboard.js +++ b/pmp-reactjs-ui/src/pages/dashboard/Dashboard.js @@ -174,7 +174,7 @@ function Dashboard() { } const policiesInAdmin = () => { - navigate('/partnermanagement/admin/policies/policyGroupList') + navigate('/partnermanagement/admin/policyManager/policyGroupList') } const cancelErrorMsg = () => {