Skip to content

Commit

Permalink
MOSIP-33206: Ui integration of Create OIDC Client (#437)
Browse files Browse the repository at this point in the history
Signed-off-by: SwethaKrish4 <[email protected]>
  • Loading branch information
SwethaKrish4 authored Jun 10, 2024
1 parent f4a5410 commit cc148c4
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 44 deletions.
10 changes: 5 additions & 5 deletions pmp-reactjs-ui/public/i18n/ara.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,16 @@
"publicKey": "المفتاح العمومي",
"publicKeyToolTip": "يُسمح بتنسيق JWK فقط",
"publicKeyPlaceHolder": "أدخل المفتاح العام بتنسيق JWK فقط",
"loginUrl": "عنوان URL لتسجيل الدخول",
"loginUrlPlaceHolder": "أدخل عنوان URL للشعار",
"redirectUrl": "إعادة توجيه URL",
"logoUrl": "عنوان URI للشعار",
"logoUrlPlaceHolder": "أدخل عنوان URI للشعار",
"redirectUrl": "إعادة توجيه URI",
"redirectUrlPlaceHolder": "أدخل إعادة توجيه URI",
"enterLogoUrl": "أدخل عنوان URL للشعار",
"grantTypes": "أنواع المنح",
"enterGrantTypes": "أدخل أنواع المنح",
"delete": "يمسح",
"addNew": "اضف جديد",
"commentBoxDesc": "اذكر الغرض من طلب عميل OIDC"
"commentBoxDesc": "اذكر الغرض من طلب عميل OIDC",
"errorInCreateOIDC": "أثناء طلب عميل OIDC، واجهنا خطأ"
},
"serverError": {
"PMS_COR_001": "معلمة الإدخال مفقود",
Expand Down
10 changes: 5 additions & 5 deletions pmp-reactjs-ui/public/i18n/eng.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,16 @@
"publicKey": "Public Key",
"publicKeyToolTip": "Only JWK format is allowed",
"publicKeyPlaceHolder": "Enter public key in JWK format only",
"loginUrl": "Login URL",
"loginUrlPlaceHolder": "Enter Logo URL",
"redirectUrl": "Redirect URL",
"logoUrl": "Logo URI",
"logoUrlPlaceHolder": "Enter Logo URI",
"redirectUrl": "Redirect URI",
"redirectUrlPlaceHolder": "Enter Redirect URI",
"enterLogoUrl": "Enter Logo Url",
"grantTypes": "Grant Types",
"enterGrantTypes": "Enter Grant Types",
"delete": "Delete",
"addNew": "Add New",
"commentBoxDesc": "Mention the purpose of requesting the OIDC Client"
"commentBoxDesc": "Mention the purpose of requesting the OIDC Client",
"errorInCreateOIDC": "While requesting OIDC Client, we have encountered with an error"
},
"serverError": {
"PMS_COR_001": "Missing Input Parameter",
Expand Down
10 changes: 5 additions & 5 deletions pmp-reactjs-ui/public/i18n/fra.json
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,16 @@
"publicKey": "Clé publique",
"publicKeyToolTip": "Seul le format JWK est autorisé",
"publicKeyPlaceHolder": "Saisissez la clé publique au format JWK uniquement",
"loginUrl": "URL de connexion",
"loginUrlPlaceHolder": "Entrez l'URL du logo",
"redirectUrl": "URL de redirection",
"logoUrl": "URI de Logo",
"logoUrlPlaceHolder": "Entrez l'URI du logo",
"redirectUrl": "URI de redirection",
"redirectUrlPlaceHolder": "Entrez l'URI de redirection",
"enterLogoUrl": "Entrez l'URL du logo",
"grantTypes": "Types de subventions",
"enterGrantTypes": "Entrez les types de subventions",
"delete": "Supprimer",
"addNew": "Ajouter un nouveau",
"commentBoxDesc": "Mentionner le but de la demande du client OIDC"
"commentBoxDesc": "Mentionner le but de la demande du client OIDC",
"errorInCreateOIDC": "Lors de la demande du client OIDC, nous avons rencontré une erreur"
},
"serverError": {
"PMS_COR_001": "Paramètre d'entrée manquant",
Expand Down
89 changes: 66 additions & 23 deletions pmp-reactjs-ui/src/pages/authenticationServices/CreateOidcClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ function CreateOidcClient() {
const [oidcClientName, setOidcClientName] = useState("");
const [publicKey, setPublicKey] = useState("");
const [showPublicKeyToolTip, setShowPublicKeyToolTip] = useState(false);
const [loginUrl, setLoginUrl] = useState("");
const [redirectUrls, setRedirectUrls] = useState([]);
const [redirectUrl, setRedirectUrl] = useState("");
const [redirectUrlList, setRedirectUrlList] = useState([]);
const [logoUrl, setLogoUrl] = useState("");
const [typeOfGrants, setTypeOfGrants] = useState([]);
const [grantTypes, setGrantTypes] = useState("");
Expand Down Expand Up @@ -45,9 +45,8 @@ function CreateOidcClient() {
if (responseData.response) {
const resData = responseData.response;
setPartnerData(resData);

console.log(resData);
setPartnerIdDropdownData(createPartnerIdDropdownData('partnerId', resData));
setPoliciesDropdownData(createPoliciesDropdownData('policyName', resData));
} else {
handleServiceErrors(responseData, setErrorCode, setErrorMsg);
}
Expand Down Expand Up @@ -96,7 +95,8 @@ function CreateOidcClient() {
if (!alreadyAdded) {
dataArr.push({
fieldCode: policy[fieldName],
fieldValue: policy[fieldName]
fieldValue: policy[fieldName],
fieldDescription: policy.policyDescription
});
}
});
Expand All @@ -111,6 +111,7 @@ function CreateOidcClient() {
if (selectedPartner) {
setPartnerType(getPartnerTypeDescription(selectedPartner.partnerType, t));
setPolicyGroupName(selectedPartner.policyGroupName);
setPoliciesDropdownData(createPoliciesDropdownData('policyName', partnerData));
}
};

Expand Down Expand Up @@ -139,19 +140,19 @@ function CreateOidcClient() {
// Below code related to adding & deleting of Redirect URLs

const addRedirectUrl = () => {
const updatedRedirectUrls = [...redirectUrls, []];
setRedirectUrls(updatedRedirectUrls);
const updatedRedirectUrls = [...redirectUrlList, []];
setRedirectUrlList(updatedRedirectUrls);
console.log(updatedRedirectUrls);
};
const handleRedirectUrlChange = (event, i) => {
const inputRedirectUrls = [...redirectUrls];
const inputRedirectUrls = [...redirectUrlList];
inputRedirectUrls[i] = event.target.value;
setRedirectUrls(inputRedirectUrls);
setRedirectUrlList(inputRedirectUrls);
};
const deleteLogoUrl = (i) => {
const filteredRedirectUrls = [...redirectUrls];
const filteredRedirectUrls = [...redirectUrlList];
filteredRedirectUrls.splice(i, 1);
setRedirectUrls(filteredRedirectUrls);
setRedirectUrlList(filteredRedirectUrls);
};

// Below code related to addind & deleting of Grant Types
Expand All @@ -172,18 +173,59 @@ function CreateOidcClient() {
setTypeOfGrants(filteredTypeOfGrants);
};

const clickOnSubmit = async () => {
setErrorCode("");
setErrorMsg("");
setDataLoaded(false);
let request = {
request: {
name: oidcClientName,
policyId: policyId,
publicKey: publicKey,
authPartnerId: partnerId,
logoUri: logoUrl,
redirectUris: redirectUrlList,
grantTypes: typeOfGrants,
clientAuthMethods: ["private_key_jwt"],
clientNameLangMap: {
"eng": oidcClientName
}
},
}
console.log(request);
try {
const response = await HttpService.post(getPartnerManagerUrl(`/oauth/client`, process.env.NODE_ENV), request);
if (response) {
const responseData = response.data;
if (responseData && responseData.response) {
const resData = responseData.response;
console.log(resData);
console.log(`Response data: ${resData.length}`);
} else {
handleServiceErrors(responseData, setErrorCode, setErrorMsg);
}
} else {
setErrorMsg(t('createOidcClient.errorInCreateOIDC'));
}
setDataLoaded(true);
} catch (err) {
setErrorMsg(err);
console.log("Error fetching data: ", err);
}
}


const clearForm = () => {
setPartnerComments("");
setOidcClientName("");
setPublicKey("");
setLoginUrl("");
setRedirectUrl("");
};

const styles = {
outerDiv: "!ml-0 !mb-0",
dropdownLabel: "!text-base !mb-1",
dropdownButton: "!w-full !h-12 !rounded-md !text-lg !text-left !text-grayish-blue",
dropdownButton: "!w-full !h-12 !rounded-md !text-lg !text-left",
selectionBox: "!top-12"
}

Expand Down Expand Up @@ -231,7 +273,7 @@ function CreateOidcClient() {
</div>
<div className="flex flex-col w-[48%]">
<label className="block text-dark-blue text-base font-semibold mb-1">{t('requestPolicy.partnerType')}<span className="text-crimson-red">*</span></label>
<button disabled className="flex items-center justify-between w-full h-12 px-2 py-2 border border-[#C1C1C1] rounded-md text-lg text-grayish-blue bg-platinum-gray leading-tight focus:outline-none focus:shadow-outline" type="button">
<button disabled className="flex items-center justify-between w-full h-12 px-2 py-2 border border-[#C1C1C1] rounded-md text-lg text-vulcan bg-platinum-gray leading-tight focus:outline-none focus:shadow-outline" type="button">
<span>{partnerType || t('requestPolicy.partnerType')}</span>
<svg className={`w-3 h-2 ml-3 transform 'rotate-0' text-gray-500 text-base`} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="m1 1 4 4 4-4" />
Expand All @@ -242,21 +284,22 @@ function CreateOidcClient() {
<div className="flex flex-row justify-between space-x-4 my-[1%]">
<div className="flex flex-col w-[48%]">
<label className="block text-dark-blue text-base font-semibold mb-1">{t('requestPolicy.policyGroup')}<span className="text-crimson-red">*</span></label>
<button disabled className="flex items-center justify-between w-full h-12 px-2 py-2 border border-[#C1C1C1] rounded-md text-lg text-grayish-blue bg-platinum-gray leading-tight focus:outline-none focus:shadow-outline" type="button">
<button disabled className="flex items-center justify-between w-full h-12 px-2 py-2 border border-[#C1C1C1] rounded-md text-lg text-vulcan bg-platinum-gray leading-tight focus:outline-none focus:shadow-outline" type="button">
<span>{policyGroupName || t('requestPolicy.policyGroup')}</span>
<svg className={`w-3 h-2 ml-3 transform 'rotate-0' text-gray-500 text-base`} xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
<path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="m1 1 4 4 4-4" />
</svg>
</button>
</div>
<div className="flex flex-col w-[48%]">
<DropdownComponent
<DropdownWithSearchComponent
fieldName='policyName'
dropdownDataList={policiesDropdownData}
onDropDownChangeEvent={onChangePolicyName}
fieldNameKey='requestPolicy.policyName*'
placeHolderKey='createOidcClient.policyNamePlaceHolder'
selectedDropdownValue={policyName}
searchKey='commons.search'
styleSet={styles}
addInfoIcon={true}
disabled={!partnerId}
Expand Down Expand Up @@ -290,10 +333,10 @@ function CreateOidcClient() {
</div>
<div className="flex my-[1%]">
<div className="flex flex-col w-[562px]">
<label className="block text-dark-blue text-base font-semibold mb-1">{t('createOidcClient.loginUrl')}<span className="text-crimson-red">*</span></label>
<input value={loginUrl} onChange={(e) => setLoginUrl(e.target.value)}
<label className="block text-dark-blue text-base font-semibold mb-1">{t('createOidcClient.logoUrl')}<span className="text-crimson-red">*</span></label>
<input value={logoUrl} onChange={(e) => setLogoUrl(e.target.value)}
className="h-12 px-2 py-3 border border-[#707070] rounded-md text-md text-dark-blue dark:placeholder-gray-400 bg-white leading-tight focus:outline-none focus:shadow-outline overflow-x-auto whitespace-nowrap no-scrollbar"
placeholder={t('createOidcClient.loginUrlPlaceHolder')} />
placeholder={t('createOidcClient.logoUrlPlaceHolder')} />
</div>
</div>

Expand All @@ -302,13 +345,13 @@ function CreateOidcClient() {
<label className="block text-dark-blue text-base font-semibold mb-1">{t('createOidcClient.redirectUrl')}<span className="text-crimson-red">*</span></label>
<ul>
<div className="flex w-f justify-between h-11 px-2 py-2 border border-[#707070] rounded-md text-md text-dark-blue dark:placeholder-gray-400 bg-white leading-tight focus:outline-none focus:shadow-outline overflow-x-auto whitespace-nowrap no-scrollbar focus:shadow-outline">
<input value={logoUrl} onChange={(e) => setLogoUrl(e.target.value)} placeholder={t('createOidcClient.redirectUrlPlaceHolder')} className="w-[85%] focus:outline-none" />
<input value={redirectUrl} onChange={(e) => setRedirectUrl(e.target.value)} placeholder={t('createOidcClient.redirectUrlPlaceHolder')} className="w-[85%] focus:outline-none" />
</div>
{redirectUrls.map((data, index) => {
{redirectUrlList.map((data, index) => {
return (
<li key={index}>
<div className="flex w-full justify-between h-11 px-2 py-2 mt-1 border border-[#707070] rounded-md text-md text-dark-blue dark:placeholder-gray-400 bg-white leading-tight focus:outline-none focus:shadow-outline overflow-x-auto whitespace-nowrap no-scrollbar">
<input value={data} onChange={(e) => handleRedirectUrlChange(e, index)} placeholder={t("createOidcClient.enterLogoUrl")} className="w-[85%] focus:outline-none" />
<input value={data} onChange={(e) => handleRedirectUrlChange(e, index)} placeholder={t("createOidcClient.redirectUrlPlaceHolder")} className="w-[85%] focus:outline-none" />
<p onClick={() => deleteLogoUrl(index)} className="text-sm text-[#1447b2] font-semibold cursor-pointer">
{t('createOidcClient.delete')}
</p>
Expand Down Expand Up @@ -363,7 +406,7 @@ function CreateOidcClient() {
<button onClick={() => clearForm()} className="mr-2 w-40 h-12 border-[#1447B2] border rounded-md bg-white text-tory-blue text-base font-semibold">{t('requestPolicy.clearForm')}</button>
<div className="flex flex-row space-x-3 w-full md:w-auto justify-end">
<button onClick={() => moveToAuthenticationServices(navigate)} className={`${isLoginLanguageRTL ?"ml-2" :"mr-2"} w-40 h-12 border-[#1447B2] border rounded-md bg-white text-tory-blue text-base font-semibold`}>{t('requestPolicy.cancel')}</button>
<button className={`${isLoginLanguageRTL ?"ml-2" :"mr-2"} w-40 h-12 border-[#1447B2] border rounded-md text-base font-semibold bg-tory-blue text-white`}>{t('requestPolicy.submit')}</button>
<button onClick={() => clickOnSubmit()} className={`${isLoginLanguageRTL ?"ml-2" :"mr-2"} w-40 h-12 border-[#1447B2] border rounded-md text-base font-semibold bg-tory-blue text-white`}>{t('requestPolicy.submit')}</button>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@

import { useState, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { handleMouseClickForDropdown } from '../../../utils/AppUtils';
import { handleMouseClickForDropdown, isLangRTL } from '../../../utils/AppUtils';
import { getUserProfile } from '../../../services/UserProfileService';
import infoIcon from '../../../svg/info_icon.svg';

function DropdownWithSearchComponent({ fieldName, dropdownDataList, onDropDownChangeEvent, fieldNameKey,
placeHolderKey, searchKey, selectedDropdownValue, styleSet}) {
placeHolderKey, searchKey, selectedDropdownValue, styleSet, addInfoIcon, infoKey, disabled}) {

const { t } = useTranslation();
const isLoginLanguageRTL = isLangRTL(getUserProfile().langCode);

const [selectedDropdownEntry, setSelectedDropdownEntry] = useState("");
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [showTooltip, setShowTooltip] = useState(false);
const [searchItem, setSearchItem] = useState("");
const dropdownRef = useRef(null);
const tooltipRef = useRef(null);

const containsAsterisk = fieldNameKey.includes('*');
fieldNameKey = containsAsterisk ? fieldNameKey.replace('*', '') : fieldNameKey;
Expand All @@ -25,6 +30,11 @@ function DropdownWithSearchComponent({ fieldName, dropdownDataList, onDropDownCh
return clickOutSideDropdown;
}, [dropdownRef]);

useEffect(() => {
const clickOutSideDropdown = handleMouseClickForDropdown(tooltipRef, () => setShowTooltip(false));
return clickOutSideDropdown;
}, [tooltipRef]);

useEffect(() => {
setSelectedDropdownEntry(selectedDropdownValue || "");
}, [selectedDropdownValue]);
Expand All @@ -35,17 +45,31 @@ function DropdownWithSearchComponent({ fieldName, dropdownDataList, onDropDownCh
onDropDownChangeEvent(fieldName, selectedid);
};
const openDropdown = () => {
setSearchItem("");
setIsDropdownOpen(!isDropdownOpen);
if (!disabled) {
setSearchItem("");
setIsDropdownOpen(!isDropdownOpen);
};
};

const handleIconClick = () => {
setShowTooltip(!showTooltip);
};

return (
<div key={fieldName} className={`ml-4 mb-2 ${(styleSet && styleSet.outerDiv) ? styleSet.outerDiv : ''}`}>
<label className={`block text-dark-blue font-semibold text-sm mb-2 ${(styleSet && styleSet.dropdownLabel) ? styleSet.dropdownLabel : ''}`}>
<label className={`flex text-dark-blue font-semibold text-sm mb-2 ${(styleSet && styleSet.dropdownLabel) ? styleSet.dropdownLabel : ''}`}>
{t(fieldNameKey)}{containsAsterisk ? <span className="text-crimson-red">*</span> : ":"}
{addInfoIcon && (
<img src={infoIcon} alt="" className= {`cursor-pointer`} onClick={handleIconClick}></img>
)}
</label>
{showTooltip && (
<div ref={tooltipRef} className={`z-20 p-4 -mt-[4.5%] w-[20%] max-h-[32%] overflow-y-auto absolute ${isLoginLanguageRTL?"mr-[9.5%]":"ml-[8.5%]"} shadow-lg bg-white border border-gray-300 rounded`}>
<p className="text-black text-sm">{t(infoKey)}</p>
</div>
)}
<div className="relative w-full" ref={dropdownRef}>
<button onClick={openDropdown} className={`flex items-center justify-between w-[282px] h-10 px-2 py-2 border border-[#707070] bg-white rounded-[4px] text-[15px] ${selectedDropdownEntry ? 'text-[#343434]' : 'text-grayish-blue'} leading-tight focus:outline-none
<button onClick={openDropdown} disabled={disabled} className={`flex items-center justify-between w-[282px] h-10 px-2 py-2 border border-[#707070] bg-white rounded-[4px] text-[15px] ${selectedDropdownEntry ? 'text-[#343434]' : 'text-grayish-blue'} leading-tight focus:outline-none
focus:shadow-none overflow-x-auto whitespace-nowrap no-scrollbar ${(styleSet && styleSet.dropdownButton) ? styleSet.dropdownButton : ''}`} type="button">
<span>{
selectedDropdownEntry ?
Expand Down

0 comments on commit cc148c4

Please sign in to comment.