diff --git a/src/components/master/CreateRole.jsx b/src/components/master/CreateRole.jsx index 9f314612..707993db 100644 --- a/src/components/master/CreateRole.jsx +++ b/src/components/master/CreateRole.jsx @@ -141,77 +141,93 @@ const CreateRole = ({ modalType, onClose }) => { )} -
+
{masterFeatures.map((feature, featureIndex) => ( -
-
- {feature.name} +
+ {/* Feature Title */} +
+ {feature.name}
-
+ {/* Permissions Grid */} +
+
+ {Array.from({ + length: Math.ceil(feature.featurePermissions.length / 3), + }).map((_, rowIndex) => ( +
+ {feature.featurePermissions + .slice(rowIndex * 3, rowIndex * 3 + 3) + .map((perm, permIndex) => { + const refIndex = featureIndex * 10 + (rowIndex * 3 + permIndex); + return ( +
+ -
- {feature.featurePermissions.map((perm, permIndex) => { - const refIndex = featureIndex * 10 + permIndex; - return ( -
- -
-
(popoverRefs.current[refIndex] = el)} - tabIndex="0" - className="d-flex align-items-center avatar-group justify-content-center" - data-bs-toggle="popover" - refIndex - data-bs-trigger="focus" - data-bs-placement="right" - data-bs-html="true" - data-bs-content={` -
- ${perm.description} -
- `} - > -   - - - - -
-
+ {/* Info icon */} +
+
(popoverRefs.current[refIndex] = el)} + tabIndex="0" + className="d-flex align-items-center justify-content-center" + data-bs-toggle="popover" + data-bs-trigger="focus" + data-bs-placement="right" + data-bs-html="true" + data-bs-content={`
${perm.description}
`} + > +   + + + + +
+
+
+ ); + })}
- ); - })} + ))} +
-
+ +
))} + {errors.selectedPermissions && (

{errors.selectedPermissions.message}

)} diff --git a/src/components/master/EditRole.jsx b/src/components/master/EditRole.jsx index 91891b90..335ef092 100644 --- a/src/components/master/EditRole.jsx +++ b/src/components/master/EditRole.jsx @@ -7,7 +7,7 @@ import { useFeatures } from "../../hooks/useMasterRole"; import { MasterRespository } from "../../repositories/MastersRepository"; import { cacheData, getCachedData } from "../../slices/apiDataManager"; import showToast from "../../services/toastService"; -import {useUpdateApplicationRole} from "../../hooks/masterHook/useMaster"; +import { useUpdateApplicationRole } from "../../hooks/masterHook/useMaster"; @@ -28,144 +28,144 @@ const updateSchema = z.object({ const EditMaster = ({ master, onClose }) => { -const maxDescriptionLength = 255; -const popoverRefs = useRef([]); -const { masterFeatures } = useFeatures(); -const { mutate: updateApplicationRole, isPending: isLoading } = useUpdateApplicationRole(() => onClose?.()); + const maxDescriptionLength = 255; + const popoverRefs = useRef([]); + const { masterFeatures } = useFeatures(); + const { mutate: updateApplicationRole, isPending: isLoading } = useUpdateApplicationRole(() => onClose?.()); -const buildDefaultPermissions = () => { - const defaults = {}; - masterFeatures.forEach((feature) => { - feature.featurePermissions.forEach((perm) => { - const existing = master?.item?.featurePermission?.find(p => p.id === perm.id); - defaults[perm.id] = existing?.isEnabled || false; + const buildDefaultPermissions = () => { + const defaults = {}; + masterFeatures.forEach((feature) => { + feature.featurePermissions.forEach((perm) => { + const existing = master?.item?.featurePermission?.find(p => p.id === perm.id); + defaults[perm.id] = existing?.isEnabled || false; + }); }); - }); - return defaults; -}; - -const initialPermissions = buildDefaultPermissions(); - -const { - register, - handleSubmit, - formState: { errors, dirtyFields }, - setError, - reset, -} = useForm({ - resolver: zodResolver(updateSchema), - defaultValues: { - role: master?.item?.role || "", - description: master?.item?.description || "", - permissions: initialPermissions, - }, -}); - -const [descriptionLength, setDescriptionLength] = useState(master?.item?.description?.length || 0); - -const onSubmit = (data) => { - const existingIds = new Set(master?.item?.featurePermission?.map(p => p.id)); - - const updatedPermissions = Object.entries(data.permissions) - .filter(([id, value]) => { - return existingIds.has(id) || value === true || (dirtyFields.permissions?.[id]); - }) - .map(([id, value]) => ({ id, isEnabled: value })); - - if (updatedPermissions.length === 0) { - setError("permissions", { - type: "manual", - message: "At least one permission must be selected.", - }); - return; - } - - const payload = { - id: master?.item?.id, - role: data.role, - description: data.description, - featuresPermission: updatedPermissions, + return defaults; }; - updateApplicationRole({ id: payload.id, payload }); -}; -// const onSubmit = (data) => { -// setIsLoading(true) -// const existingIds = new Set( -// master?.item?.featurePermission?.map((p) => p.id) -// ); + const initialPermissions = buildDefaultPermissions(); - -// const updatedPermissions = Object.entries(data.permissions) -// .filter(([id, value]) => { -// if (existingIds.has(id)) return true; - -// return ( -// value === true || -// (dirtyFields.permissions && dirtyFields.permissions[id]) -// ); -// }) -// .map(([id, value]) => ({ id, isEnabled: value })); - - -// if (updatedPermissions.length === 0) { -// setError("permissions", { -// type: "manual", -// message: "At least one permission must be selected.", -// }); -// return; -// } - -// const updatedRole = { -// id: master?.item?.id, -// role: data.role, -// description: data.description, -// featuresPermission: updatedPermissions, -// }; -// MasterRespository.updateRoles(master?.item?.id, updatedRole).then((resp) => { -// setIsLoading(false) - - -// const cachedData = getCachedData("Application Role"); - -// if (cachedData) { - -// const updatedData = cachedData.map((role) => -// role.id === resp.data?.id ? { ...role, ...resp.data } : role -// ); - -// cacheData("Application Role", updatedData); -// } -// showToast("Application Role Updated successfully.", "success"); -// setIsLoading(false) -// onClose() -// }).catch((Err) => { -// showToast(Err.message, "error"); -// setIsLoading(false) -// }) - -// }; -useEffect(() => { - reset({ - role: master?.item?.role || "", - description: master?.item?.description || "", - permissions: buildDefaultPermissions(), + const { + register, + handleSubmit, + formState: { errors, dirtyFields }, + setError, + reset, + } = useForm({ + resolver: zodResolver(updateSchema), + defaultValues: { + role: master?.item?.role || "", + description: master?.item?.description || "", + permissions: initialPermissions, + }, }); - setDescriptionLength(master?.item?.description?.length || 0); -}, [master, reset]); -useEffect(() => { - popoverRefs.current.forEach((el) => { - if (el) { - new bootstrap.Popover(el, { - trigger: "focus", - placement: "right", - html: true, - content: el.getAttribute("data-bs-content"), + const [descriptionLength, setDescriptionLength] = useState(master?.item?.description?.length || 0); + + const onSubmit = (data) => { + const existingIds = new Set(master?.item?.featurePermission?.map(p => p.id)); + + const updatedPermissions = Object.entries(data.permissions) + .filter(([id, value]) => { + return existingIds.has(id) || value === true || (dirtyFields.permissions?.[id]); + }) + .map(([id, value]) => ({ id, isEnabled: value })); + + if (updatedPermissions.length === 0) { + setError("permissions", { + type: "manual", + message: "At least one permission must be selected.", }); + return; } - }); -}, [masterFeatures]); + + const payload = { + id: master?.item?.id, + role: data.role, + description: data.description, + featuresPermission: updatedPermissions, + }; + + updateApplicationRole({ id: payload.id, payload }); + }; + // const onSubmit = (data) => { + // setIsLoading(true) + // const existingIds = new Set( + // master?.item?.featurePermission?.map((p) => p.id) + // ); + + + // const updatedPermissions = Object.entries(data.permissions) + // .filter(([id, value]) => { + // if (existingIds.has(id)) return true; + + // return ( + // value === true || + // (dirtyFields.permissions && dirtyFields.permissions[id]) + // ); + // }) + // .map(([id, value]) => ({ id, isEnabled: value })); + + + // if (updatedPermissions.length === 0) { + // setError("permissions", { + // type: "manual", + // message: "At least one permission must be selected.", + // }); + // return; + // } + + // const updatedRole = { + // id: master?.item?.id, + // role: data.role, + // description: data.description, + // featuresPermission: updatedPermissions, + // }; + // MasterRespository.updateRoles(master?.item?.id, updatedRole).then((resp) => { + // setIsLoading(false) + + + // const cachedData = getCachedData("Application Role"); + + // if (cachedData) { + + // const updatedData = cachedData.map((role) => + // role.id === resp.data?.id ? { ...role, ...resp.data } : role + // ); + + // cacheData("Application Role", updatedData); + // } + // showToast("Application Role Updated successfully.", "success"); + // setIsLoading(false) + // onClose() + // }).catch((Err) => { + // showToast(Err.message, "error"); + // setIsLoading(false) + // }) + + // }; + useEffect(() => { + reset({ + role: master?.item?.role || "", + description: master?.item?.description || "", + permissions: buildDefaultPermissions(), + }); + setDescriptionLength(master?.item?.description?.length || 0); + }, [master, reset]); + + useEffect(() => { + popoverRefs.current.forEach((el) => { + if (el) { + new bootstrap.Popover(el, { + trigger: "focus", + placement: "right", + html: true, + content: el.getAttribute("data-bs-content"), + }); + } + }); + }, [masterFeatures]); return ( @@ -199,77 +199,91 @@ useEffect(() => { )}
-
+
+ {/* Scrollable Container */} +
+ {masterFeatures.map((feature, featureIndex) => ( +
+ {/* Feature Group Title */} +
{feature.name}
- {masterFeatures.map((feature, featureIndex) => ( -
- -
- {feature.name} -
-
- -
-
- {feature.featurePermissions.map((perm, permIndex) => { - const refIndex = (featureIndex * 10) + permIndex; - return ( - -
- - - - -
-
- (popoverRefs.current[refIndex] = el) - } - tabIndex="0" - className="d-flex align-items-center avatar-group justify-content-center" - data-bs-toggle="popover" refIndex - data-bs-trigger="focus" - data-bs-placement="right" - data-bs-html="true" - data-bs-content={` -
- ${perm.description} -
- `} + {/* Permissions Grid */} +
+ {feature.featurePermissions.map((perm, permIndex) => { + const refIndex = featureIndex * 10 + permIndex; + return ( +
+ + + {/* Info Icon */} +
+
(popoverRefs.current[refIndex] = el)} + tabIndex="0" + className="d-flex align-items-center justify-content-center" + data-bs-toggle="popover" + data-bs-trigger="focus" + data-bs-placement="right" + data-bs-html="true" + data-bs-content={`
${perm.description}
`} + > +   + + + + +
-
- ) - })} - + ); + })} +
+
-
-
- ))} + ))} +
+ + {/* Error Display */} {errors.permissions && (

{errors.permissions.message}

)}
+