From 3bf0308631dacd96e633485001ddd871c6d1fe06 Mon Sep 17 00:00:00 2001 From: karimaldeen Date: Tue, 24 Sep 2024 14:54:27 +0300 Subject: [PATCH] end role and permission # 166 --- .../Roles/Permissions/FN/formatAbilityData.ts | 21 +++ .../Permissions/FN/formatArrayToPermission.ts | 14 ++ .../FN/mergePermissionsWithAbilities.ts | 54 ++++++ .../Permissions/FN/transformPermissions.ts | 31 ++++ .../Admin/Roles/Permissions/FormTable.tsx | 9 +- src/Pages/Admin/Roles/Permissions/Page.tsx | 4 +- src/Pages/Admin/Roles/Permissions/Table.tsx | 162 +++++++----------- .../Roles/Permissions/useTableColumns.tsx | 64 ++++--- src/Styles/Layout/PageHeader.scss | 4 + src/translate/ar.json | 9 +- 10 files changed, 248 insertions(+), 124 deletions(-) create mode 100644 src/Pages/Admin/Roles/Permissions/FN/formatAbilityData.ts create mode 100644 src/Pages/Admin/Roles/Permissions/FN/formatArrayToPermission.ts create mode 100644 src/Pages/Admin/Roles/Permissions/FN/mergePermissionsWithAbilities.ts create mode 100644 src/Pages/Admin/Roles/Permissions/FN/transformPermissions.ts diff --git a/src/Pages/Admin/Roles/Permissions/FN/formatAbilityData.ts b/src/Pages/Admin/Roles/Permissions/FN/formatAbilityData.ts new file mode 100644 index 0000000..ff3f102 --- /dev/null +++ b/src/Pages/Admin/Roles/Permissions/FN/formatAbilityData.ts @@ -0,0 +1,21 @@ +export const formatAbilityData = (Data: any[]) => { + const newArray: Array<{ name: any; [key: string]: boolean }> = []; + console.log(Data, "Data"); + for (let i = 0; i < Data.length; i++) { + const currentObject = Data?.[i]; + console.log(currentObject); + const newObjectShape = { + name: currentObject?.name, + delete: typeof currentObject?.delete === "boolean" ? false : "disabled", + index: typeof currentObject?.index === "boolean" ? false : "disabled", + show: typeof currentObject?.show === "boolean" ? false : "disabled", + store: typeof currentObject?.store === "boolean" ? false : "disabled", + update: typeof currentObject?.update === "boolean" ? false : "disabled", + } as any; + console.log(newObjectShape); + + newArray.push(newObjectShape); + } + + return newArray; + }; \ No newline at end of file diff --git a/src/Pages/Admin/Roles/Permissions/FN/formatArrayToPermission.ts b/src/Pages/Admin/Roles/Permissions/FN/formatArrayToPermission.ts new file mode 100644 index 0000000..497ad2e --- /dev/null +++ b/src/Pages/Admin/Roles/Permissions/FN/formatArrayToPermission.ts @@ -0,0 +1,14 @@ +export const formatArrayToPermissions = ( newArray: Array<{ name: any; [key: string]: boolean }>): string[] => { + const Data: string[] = []; + + newArray.forEach((obj) => { + const permission = obj.name; + Object.keys(obj).forEach((key) => { + if (key !== "name" && key !== "ALL" && obj[key] && obj[key] === true) { + Data.push(`${permission}::${key}`); + } + }); + }); + + return Data; + }; \ No newline at end of file diff --git a/src/Pages/Admin/Roles/Permissions/FN/mergePermissionsWithAbilities.ts b/src/Pages/Admin/Roles/Permissions/FN/mergePermissionsWithAbilities.ts new file mode 100644 index 0000000..eec8751 --- /dev/null +++ b/src/Pages/Admin/Roles/Permissions/FN/mergePermissionsWithAbilities.ts @@ -0,0 +1,54 @@ +export const mergePermissionsWithAbilities = ( + newShapeArray: Record[], + Ability: Record[] + ) => { + const newShapeMap = new Map(newShapeArray.map((item) => [item.name, item])); + console.log(newShapeMap, "newShapeMap"); + + return Ability.map((abilityItem) => { + const correspondingNewShape = newShapeMap.get(abilityItem.name); + console.log(correspondingNewShape); + + let ALL = false; + if (correspondingNewShape) { + if ( + correspondingNewShape["index"] && + correspondingNewShape["show"] && + correspondingNewShape["store"] && + correspondingNewShape["update"] && + correspondingNewShape["delete"] + ) { + ALL = true; + } + console.log(correspondingNewShape); + + return { + ...abilityItem, + delete: + typeof correspondingNewShape.delete === "boolean" + ? correspondingNewShape.delete + : "disabled", + index: + typeof correspondingNewShape.index === "boolean" + ? correspondingNewShape.index + : "disabled", + show: + typeof correspondingNewShape.show === "boolean" + ? correspondingNewShape.show + : "disabled", + store: + typeof correspondingNewShape.store === "boolean" + ? correspondingNewShape.store + : "disabled", + update: + typeof correspondingNewShape.update === "boolean" + ? correspondingNewShape.update + : "disabled", + ALL: ALL, + }; + } + + // Return original ability item if no match found + return abilityItem; + }); + }; \ No newline at end of file diff --git a/src/Pages/Admin/Roles/Permissions/FN/transformPermissions.ts b/src/Pages/Admin/Roles/Permissions/FN/transformPermissions.ts new file mode 100644 index 0000000..d5052a6 --- /dev/null +++ b/src/Pages/Admin/Roles/Permissions/FN/transformPermissions.ts @@ -0,0 +1,31 @@ +export const transformPermissions = (Data: string[]) => { + const newArray: Array<{ name: any; [key: string]: boolean }> = []; + const hashMap = new Map(); + + for (let i = 0; i < Data.length; i++) { + const [permission, value] = Data[i].split("::"); + const existingIndex = hashMap.get(permission); + + if (existingIndex !== undefined) { + if (value) { + newArray[existingIndex][value] = true; + } + if ( + newArray[existingIndex]["index"] && + newArray[existingIndex]["show"] && + newArray[existingIndex]["store"] && + newArray[existingIndex]["update"] && + newArray[existingIndex]["delete"] + ) { + newArray[existingIndex]["ALL"] = true; + } + } else { + const newObject = value + ? ({ name: permission, [value]: true } as any) + : { name: permission }; + newArray.push(newObject); + hashMap.set(permission, newArray.length - 1); + } + } + return newArray; + }; \ No newline at end of file diff --git a/src/Pages/Admin/Roles/Permissions/FormTable.tsx b/src/Pages/Admin/Roles/Permissions/FormTable.tsx index 0d9512f..bc68f7d 100644 --- a/src/Pages/Admin/Roles/Permissions/FormTable.tsx +++ b/src/Pages/Admin/Roles/Permissions/FormTable.tsx @@ -2,8 +2,13 @@ import React from 'react' import DataTable from '../../../../Layout/Dashboard/Table/DataTable' import { useColumns } from './useTableColumns' import { useFormikContext } from 'formik' +import { TableProps } from 'antd' -const FormTable = ({response}:{response:any}) => { + + interface IFormTable extends TableProps { + response:any + } +const FormTable = ({response,...props}:IFormTable) => { const {values} = useFormikContext() return ( @@ -16,7 +21,7 @@ const FormTable = ({response}:{response:any}) => { pagination={false} loading={false} rowKey={"name"} - + {...props} /> diff --git a/src/Pages/Admin/Roles/Permissions/Page.tsx b/src/Pages/Admin/Roles/Permissions/Page.tsx index bcd3423..f7d11f9 100644 --- a/src/Pages/Admin/Roles/Permissions/Page.tsx +++ b/src/Pages/Admin/Roles/Permissions/Page.tsx @@ -22,11 +22,11 @@ const TableHeader = () => { pageTitle="role" addModal={false} /> - + /> */} diff --git a/src/Pages/Admin/Roles/Permissions/Table.tsx b/src/Pages/Admin/Roles/Permissions/Table.tsx index e03b52a..c711fc9 100644 --- a/src/Pages/Admin/Roles/Permissions/Table.tsx +++ b/src/Pages/Admin/Roles/Permissions/Table.tsx @@ -1,7 +1,6 @@ -import React from "react"; +import React, { Suspense } from "react"; import { useFilterState } from "../../../../Components/Utils/Filter/FilterState"; import { useFilterStateState } from "../../../../zustand/Filter"; -import { useAddPermissions, useGetAllPermissions } from "../../../../api/Permissions"; import { useParams } from "react-router-dom"; import { ParamsEnum } from "../../../../enums/params"; import { Form, Formik } from "formik"; @@ -9,6 +8,12 @@ import FormTable from "./FormTable"; import { useTranslation } from "react-i18next"; import { useGetAllRole, useUpdateRole } from "../../../../api/role"; import { useGetAllAbility } from "../../../../api/Ability"; +import LoadingLottie from "../../../../Components/Lottie/Loading/LoadingLottie"; +import { Button } from "antd"; +import { transformPermissions } from "./FN/transformPermissions"; +import { formatAbilityData } from "./FN/formatAbilityData"; +import { mergePermissionsWithAbilities } from "./FN/mergePermissionsWithAbilities"; +import { formatArrayToPermissions } from "./FN/formatArrayToPermission"; const App: React.FC = () => { const { role_id } = useParams(); @@ -19,113 +24,72 @@ const App: React.FC = () => { const response = useGetAllRole({ pagination: true, - show:role_id, + show: role_id, name, sort_by, ...filterState, }); - const {data} = useGetAllAbility() - const AllAbilityData = data?.data ?? [] ; - const currentData = response?.data?.data?.abilities ?? [] ; - console.log(currentData,"currentData"); - - const GetAllAbility = (Data:string[])=>{ - const newArray: Array<{ name: any; [key: string]: boolean }> = []; - const hashMap = new Map(); - - for (let i = 0; i < Data.length; i++) { - const [permission, value] = Data[i].split("::"); - const existingIndex = hashMap.get(permission); - - if (existingIndex !== undefined) { - - } else { - const newObject = permission as any; - newArray.push(newObject); - hashMap.set(permission, newArray.length - 1); - - } - } - return newArray - } - const Ability = GetAllAbility(AllAbilityData ?? []) ?? [] - /// time complexity O(n) -_- - console.log(Ability); - - const changePermissionShape = (Data:string[])=>{ - const newArray: Array<{ name: any; [key: string]: boolean }> = []; - const hashMap = new Map(); - - for (let i = 0; i < Data.length; i++) { - const [permission, value] = Data[i].split("::"); - const existingIndex = hashMap.get(permission); - - if (existingIndex !== undefined) { - if(value){ - console.log(1); - - newArray[existingIndex][value] = true; - } - if(newArray[existingIndex]["index"] && newArray[existingIndex]["show"] && newArray[existingIndex]["store"] && newArray[existingIndex]["update"] && newArray[existingIndex]["delete"]){ - - newArray[existingIndex]["ALL"] = true; - } - } else { - const newObject = value ? { name: permission, [value]: true } as any : {name: permission} ; - newArray.push(newObject); - hashMap.set(permission, newArray.length - 1); - - } - } - return newArray - } - const newShapeArray = changePermissionShape([...currentData,...Ability]) + const { data, isLoading } = useGetAllAbility(); + const AllAbilityData = data?.data ?? []; + const currentData = response?.data?.data?.abilities ?? []; - const [t] = useTranslation() - const reverseChangePermissionShape = ( - newArray: Array<{ name: any; [key: string]: boolean }> - ): string[] => { - const Data: string[] = []; - - newArray.forEach((obj) => { - const permission = obj.name; - Object.keys(obj).forEach((key) => { - if (key !== "name" && key !== "ALL" && obj[key]) { - Data.push(`${permission}::${key}`); - } - }); - }); - - return Data; - }; - const {mutate} = useUpdateRole() - const handelSubmit = (values:any)=>{ + + const AllAbility = transformPermissions(AllAbilityData ?? []); + + + const Ability = formatAbilityData(AllAbility) ?? []; + const newShapeArray = transformPermissions([...currentData]); + + + const finalShape = mergePermissionsWithAbilities(newShapeArray, Ability); + + const [t] = useTranslation(); + + const { mutate, isLoading: UpdateLoading } = useUpdateRole(); + const handelSubmit = (values: any) => { console.log(values); - - const dataToSend = reverseChangePermissionShape(values); + + const dataToSend = formatArrayToPermissions(values); console.log(dataToSend); - mutate({ - id:role_id, - abilities:dataToSend - }) - } - + id: role_id, + abilities: dataToSend?.length > 0 ? dataToSend : "", + }); + }; + const disabled = + isLoading || response.isLoading || response.isRefetching || UpdateLoading; return ( - - {({handleSubmit})=>{ - return ( -
+ + {({ dirty }) => { + return ( + +
+ +
- -
- -
- - ) - }} - -
+ }> + + + ), + size: "large", + }} + /> + + + ); + }} +
); }; diff --git a/src/Pages/Admin/Roles/Permissions/useTableColumns.tsx b/src/Pages/Admin/Roles/Permissions/useTableColumns.tsx index 9e387ce..81ea659 100644 --- a/src/Pages/Admin/Roles/Permissions/useTableColumns.tsx +++ b/src/Pages/Admin/Roles/Permissions/useTableColumns.tsx @@ -13,6 +13,10 @@ export const useColumns = () => { cloneValue[index] = {}; } cloneValue[index][type] = !cloneValue[index][type]; + + if(!cloneValue[index][type]){ + cloneValue[index]["ALL"] = false + } setValues(cloneValue) }; @@ -24,22 +28,22 @@ export const useColumns = () => { if(cloneValue[index]["ALL"]){ cloneValue[index] = { name:cloneValue[index]?.name , - delete: false, - index: false, - show: false, - store: false, - update: false, + delete: typeof cloneValue[index]?.delete === "boolean" ? false : "disabled" , + index: typeof cloneValue[index]?.index === "boolean" ? false : "disabled" , + show: typeof cloneValue[index]?.show === "boolean" ? false : "disabled" , + store: typeof cloneValue[index]?.store === "boolean" ? false : "disabled" , + update: typeof cloneValue[index]?.update === "boolean" ? false : "disabled" , ALL: false } }else{ cloneValue[index] = { name:cloneValue[index]?.name , - delete: true, - index: true, - show: true, - store: true, - update: true, + delete: typeof cloneValue[index]?.delete === "boolean" ? true : "disabled" , + index: typeof cloneValue[index]?.index === "boolean" ? true : "disabled" , + show: typeof cloneValue[index]?.show === "boolean" ? true : "disabled" , + store: typeof cloneValue[index]?.store === "boolean" ? true : "disabled" , + update: typeof cloneValue[index]?.update === "boolean" ? true : "disabled" , ALL: true } @@ -57,11 +61,10 @@ setValues(cloneValue) const CheckBoxField = ({record,type,index}:{record:any,type:string,index:number})=>{ - - - const isChecked = record?.[type] ; - return onChange(type,index)} checked={isChecked} />; + const isChecked = record?.[type] === true ; + const isDisabled = record?.[type] === "disabled" ; + return onChange(type,index)} checked={isChecked} disabled={isDisabled} />; } @@ -71,11 +74,31 @@ setValues(cloneValue) return !!item?.index && !!item?.show && !!item?.store && !!item?.update && !!item?.delete }) const onChangeAllPermissions = ()=>{ - const newShape =cloneValue?.map((item:any)=>{ + const newShape =cloneValue?.map((item:any,index:number)=>{ if(IsAllValuesTrue){ - return {...item,delete: false,index: false,show: false,store: false,update: false,ALL: false} - }else{ - return {...item,delete: true,index: true,show: true,store: true,update: true,ALL: true} + console.log(item); + + return { + ...item, + delete: typeof item?.delete === "boolean" ? false : "disabled", + index: typeof item?.index === "boolean" ? false : "disabled", + show: typeof item?.show === "boolean" ? false : "disabled", + store: typeof item?.store === "boolean" ? false : "disabled", + update: typeof item?.update === "boolean" ? false : "disabled", + ALL: false + } + }else{ + console.log(item); + + return { + ...item, + delete: typeof item?.delete === "boolean" ? true : "disabled", + index: typeof item?.index === "boolean" ? true : "disabled", + show: typeof item?.show === "boolean" ? true : "disabled", + store: typeof item?.store === "boolean" ? true : "disabled", + update: typeof item?.update === "boolean" ? true : "disabled", + ALL: true + } } }) setValues(newShape) @@ -83,8 +106,6 @@ setValues(cloneValue) return onChangeAllPermissions()} checked={IsAllValuesTrue} />; } - - const columns: TableColumnsType = [ { @@ -92,6 +113,9 @@ setValues(cloneValue) dataIndex: "name", key: "name", align: "center", + render: (_text,record,index) => { + return ( <> {t(`models.${record?.name}`)} ); + }, }, { title: t("columns.add"), diff --git a/src/Styles/Layout/PageHeader.scss b/src/Styles/Layout/PageHeader.scss index a5be4fe..820498d 100644 --- a/src/Styles/Layout/PageHeader.scss +++ b/src/Styles/Layout/PageHeader.scss @@ -41,4 +41,8 @@ .PageTitleLastItem { color: #202C4B !important; +} + +.permissions_submit_button{ + transform: translateY(-40px); } \ No newline at end of file diff --git a/src/translate/ar.json b/src/translate/ar.json index f06aacc..3297f29 100644 --- a/src/translate/ar.json +++ b/src/translate/ar.json @@ -389,7 +389,14 @@ "sale":"عملية بيع", "collections": "التحصيلات", "phone_number":"رقم الهاتف", - "email_address":"عنوان البريد الإلكتروني" + "email_address":"عنوان البريد الإلكتروني", + "ability": "القدرات", + "answer": "إجابة", + "area": "منطقة", + "city": "مدينة", + "coupon": "قسيمة", + "package": "حزمة", + "packageItem": "عنصر الحزمة" }, "education_class_actions": { "Student_Records": "سجلات الطلاب",