end role and permission # 166

This commit is contained in:
karimaldeen 2024-09-24 14:54:27 +03:00
parent 9a6e5bc53d
commit 3bf0308631
10 changed files with 248 additions and 124 deletions

View File

@ -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;
};

View File

@ -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;
};

View File

@ -0,0 +1,54 @@
export const mergePermissionsWithAbilities = (
newShapeArray: Record<any, any>[],
Ability: Record<any, boolean | "disabled" | "string">[]
) => {
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;
});
};

View File

@ -0,0 +1,31 @@
export const transformPermissions = (Data: string[]) => {
const newArray: Array<{ name: any; [key: string]: boolean }> = [];
const hashMap = new Map<string, number>();
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;
};

View File

@ -2,8 +2,13 @@ import React from 'react'
import DataTable from '../../../../Layout/Dashboard/Table/DataTable' import DataTable from '../../../../Layout/Dashboard/Table/DataTable'
import { useColumns } from './useTableColumns' import { useColumns } from './useTableColumns'
import { useFormikContext } from 'formik' 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<any>() const {values} = useFormikContext<any>()
return ( return (
@ -16,7 +21,7 @@ const FormTable = ({response}:{response:any}) => {
pagination={false} pagination={false}
loading={false} loading={false}
rowKey={"name"} rowKey={"name"}
{...props}
/> />
</div> </div>

View File

@ -22,11 +22,11 @@ const TableHeader = () => {
pageTitle="role" pageTitle="role"
addModal={false} addModal={false}
/> />
<FilterLayout {/* <FilterLayout
sub_children={""} sub_children={""}
filterTitle="page_header.permissions" filterTitle="page_header.permissions"
haveFilter={false} haveFilter={false}
/> /> */}
<Table /> <Table />
</Suspense> </Suspense>

View File

@ -1,7 +1,6 @@
import React from "react"; import React, { Suspense } from "react";
import { useFilterState } from "../../../../Components/Utils/Filter/FilterState"; import { useFilterState } from "../../../../Components/Utils/Filter/FilterState";
import { useFilterStateState } from "../../../../zustand/Filter"; import { useFilterStateState } from "../../../../zustand/Filter";
import { useAddPermissions, useGetAllPermissions } from "../../../../api/Permissions";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { ParamsEnum } from "../../../../enums/params"; import { ParamsEnum } from "../../../../enums/params";
import { Form, Formik } from "formik"; import { Form, Formik } from "formik";
@ -9,6 +8,12 @@ import FormTable from "./FormTable";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useGetAllRole, useUpdateRole } from "../../../../api/role"; import { useGetAllRole, useUpdateRole } from "../../../../api/role";
import { useGetAllAbility } from "../../../../api/Ability"; 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 App: React.FC = () => {
const { role_id } = useParams<ParamsEnum>(); const { role_id } = useParams<ParamsEnum>();
@ -24,107 +29,66 @@ const App: React.FC = () => {
sort_by, sort_by,
...filterState, ...filterState,
}); });
const {data} = useGetAllAbility() const { data, isLoading } = useGetAllAbility();
const AllAbilityData = data?.data ?? []; const AllAbilityData = data?.data ?? [];
const currentData = response?.data?.data?.abilities ?? []; 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<string, number>();
for (let i = 0; i < Data.length; i++) { const AllAbility = transformPermissions(AllAbilityData ?? []);
const [permission, value] = Data[i].split("::");
const existingIndex = hashMap.get(permission);
if (existingIndex !== undefined) {
} else { const Ability = formatAbilityData(AllAbility) ?? [];
const newObject = permission as any; const newShapeArray = transformPermissions([...currentData]);
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 finalShape = mergePermissionsWithAbilities(newShapeArray, Ability);
const newArray: Array<{ name: any; [key: string]: boolean }> = [];
const hashMap = new Map<string, number>();
for (let i = 0; i < Data.length; i++) { const [t] = useTranslation();
const [permission, value] = Data[i].split("::");
const existingIndex = hashMap.get(permission);
if (existingIndex !== undefined) { const { mutate, isLoading: UpdateLoading } = useUpdateRole();
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 [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 handelSubmit = (values: any) => {
console.log(values); console.log(values);
const dataToSend = reverseChangePermissionShape(values); const dataToSend = formatArrayToPermissions(values);
console.log(dataToSend); console.log(dataToSend);
mutate({ mutate({
id: role_id, id: role_id,
abilities:dataToSend abilities: dataToSend?.length > 0 ? dataToSend : "",
}) });
} };
const disabled =
isLoading || response.isLoading || response.isRefetching || UpdateLoading;
return ( return (
<Formik initialValues={newShapeArray} onSubmit={handelSubmit} enableReinitialize> <Formik initialValues={finalShape} onSubmit={handelSubmit} enableReinitialize>
{({handleSubmit})=>{ {({ dirty }) => {
return ( return (
<Form> <Form>
<div className="permissions_submit_button mt-4">
<FormTable response={response} /> <Button
<div className="permissions_submit_button"> className="button"
<button className="button" type="submit" >{t("practical.submit")}</button> disabled={disabled || !dirty}
htmlType="submit"
>
{t("practical.submit")}
</Button>
</div> </div>
</Form>
)
}}
<FormTable
response={response}
loading={{
spinning: disabled,
indicator: (
<Suspense fallback={<></>}>
<LoadingLottie />
</Suspense>
),
size: "large",
}}
/>
</Form>
);
}}
</Formik> </Formik>
); );
}; };

View File

@ -13,6 +13,10 @@ export const useColumns = () => {
cloneValue[index] = {}; cloneValue[index] = {};
} }
cloneValue[index][type] = !cloneValue[index][type]; cloneValue[index][type] = !cloneValue[index][type];
if(!cloneValue[index][type]){
cloneValue[index]["ALL"] = false
}
setValues(cloneValue) setValues(cloneValue)
}; };
@ -24,22 +28,22 @@ export const useColumns = () => {
if(cloneValue[index]["ALL"]){ if(cloneValue[index]["ALL"]){
cloneValue[index] = { cloneValue[index] = {
name:cloneValue[index]?.name , name:cloneValue[index]?.name ,
delete: false, delete: typeof cloneValue[index]?.delete === "boolean" ? false : "disabled" ,
index: false, index: typeof cloneValue[index]?.index === "boolean" ? false : "disabled" ,
show: false, show: typeof cloneValue[index]?.show === "boolean" ? false : "disabled" ,
store: false, store: typeof cloneValue[index]?.store === "boolean" ? false : "disabled" ,
update: false, update: typeof cloneValue[index]?.update === "boolean" ? false : "disabled" ,
ALL: false ALL: false
} }
}else{ }else{
cloneValue[index] = { cloneValue[index] = {
name:cloneValue[index]?.name , name:cloneValue[index]?.name ,
delete: true, delete: typeof cloneValue[index]?.delete === "boolean" ? true : "disabled" ,
index: true, index: typeof cloneValue[index]?.index === "boolean" ? true : "disabled" ,
show: true, show: typeof cloneValue[index]?.show === "boolean" ? true : "disabled" ,
store: true, store: typeof cloneValue[index]?.store === "boolean" ? true : "disabled" ,
update: true, update: typeof cloneValue[index]?.update === "boolean" ? true : "disabled" ,
ALL: true ALL: true
} }
@ -58,10 +62,9 @@ setValues(cloneValue)
const CheckBoxField = ({record,type,index}:{record:any,type:string,index:number})=>{ const CheckBoxField = ({record,type,index}:{record:any,type:string,index:number})=>{
const isChecked = record?.[type] === true ;
const isChecked = record?.[type] ; const isDisabled = record?.[type] === "disabled" ;
return <Checkbox onChange={()=>onChange(type,index)} checked={isChecked} disabled={isDisabled} />;
return <Checkbox onChange={()=>onChange(type,index)} checked={isChecked} />;
} }
@ -71,11 +74,31 @@ setValues(cloneValue)
return !!item?.index && !!item?.show && !!item?.store && !!item?.update && !!item?.delete return !!item?.index && !!item?.show && !!item?.store && !!item?.update && !!item?.delete
}) })
const onChangeAllPermissions = ()=>{ const onChangeAllPermissions = ()=>{
const newShape =cloneValue?.map((item:any)=>{ const newShape =cloneValue?.map((item:any,index:number)=>{
if(IsAllValuesTrue){ if(IsAllValuesTrue){
return {...item,delete: false,index: false,show: false,store: false,update: false,ALL: false} 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{ }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" ? 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) setValues(newShape)
@ -83,8 +106,6 @@ setValues(cloneValue)
return <Checkbox onChange={()=>onChangeAllPermissions()} checked={IsAllValuesTrue} />; return <Checkbox onChange={()=>onChangeAllPermissions()} checked={IsAllValuesTrue} />;
} }
const columns: TableColumnsType<any> = [ const columns: TableColumnsType<any> = [
{ {
@ -92,6 +113,9 @@ setValues(cloneValue)
dataIndex: "name", dataIndex: "name",
key: "name", key: "name",
align: "center", align: "center",
render: (_text,record,index) => {
return ( <> {t(`models.${record?.name}`)} </> );
},
}, },
{ {
title: t("columns.add"), title: t("columns.add"),

View File

@ -42,3 +42,7 @@
.PageTitleLastItem { .PageTitleLastItem {
color: #202C4B !important; color: #202C4B !important;
} }
.permissions_submit_button{
transform: translateY(-40px);
}

View File

@ -389,7 +389,14 @@
"sale":"عملية بيع", "sale":"عملية بيع",
"collections": "التحصيلات", "collections": "التحصيلات",
"phone_number":"رقم الهاتف", "phone_number":"رقم الهاتف",
"email_address":"عنوان البريد الإلكتروني" "email_address":"عنوان البريد الإلكتروني",
"ability": "القدرات",
"answer": "إجابة",
"area": "منطقة",
"city": "مدينة",
"coupon": "قسيمة",
"package": "حزمة",
"packageItem": "عنصر الحزمة"
}, },
"education_class_actions": { "education_class_actions": {
"Student_Records": "سجلات الطلاب", "Student_Records": "سجلات الطلاب",