feat: domains management
This commit is contained in:
133
src/partials/Admin/Access.tsx
Normal file
133
src/partials/Admin/Access.tsx
Normal file
@@ -0,0 +1,133 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getFaPermissions } from "../../utils/getFaPermissions";
|
||||
import { useApiRequest } from "../../utils/useApiRequest";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import Table from "../../components/Table/Table";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { AddAccess } from "./AddAccess";
|
||||
import { Popover } from "../../components/PopOver/PopOver";
|
||||
import { Tooltip } from "../../components/Tooltip/Tooltip";
|
||||
import { DeleteButtonForPopOver } from "../../components/PopOverButtons/PopOverButtons";
|
||||
import { CheckIcon, XMarkIcon } from "@heroicons/react/24/solid";
|
||||
import AutoComplete from "../../components/AutoComplete/AutoComplete";
|
||||
|
||||
export default function Access() {
|
||||
const { openModal } = useModalStore();
|
||||
const [pagesInfo, setPagesInfo] = useState({ page: 1, page_size: 10 });
|
||||
const [pagesTableData, setPagesTableData] = useState([]);
|
||||
const [selectedModifyKeys, setSelectedModifyKeys] = useState<
|
||||
(string | number)[]
|
||||
>([]);
|
||||
|
||||
const { data: pagesData, refetch } = useApiRequest({
|
||||
api: "/auth/api/v1/permission/",
|
||||
method: "get",
|
||||
params: {
|
||||
...pagesInfo,
|
||||
modify_state: selectedModifyKeys[0],
|
||||
},
|
||||
queryKey: ["permissions", pagesInfo, selectedModifyKeys],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (pagesData?.results) {
|
||||
const formattedData = pagesData.results.map((item: any, i: number) => {
|
||||
return [
|
||||
pagesInfo.page === 1
|
||||
? i + 1
|
||||
: i + pagesInfo.page_size * (pagesInfo.page - 1) + 1,
|
||||
item?.name,
|
||||
item?.description,
|
||||
`${getFaPermissions(item?.page)} (${item?.page})`,
|
||||
<Grid
|
||||
key={i}
|
||||
className="flex justify-center items-center bg-gray-300/10 rounded-full"
|
||||
>
|
||||
{item?.modify_state ? (
|
||||
<CheckIcon className="w-5 h-5 text-green-500" />
|
||||
) : (
|
||||
<XMarkIcon className="w-5 h-5 text-red-500" />
|
||||
)}
|
||||
</Grid>,
|
||||
<Popover key={i}>
|
||||
<Tooltip title="ویرایش" position="right">
|
||||
<Button
|
||||
variant="edit"
|
||||
page="permission_control"
|
||||
access="Post-access"
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "ویرایش دسترسی",
|
||||
content: <AddAccess item={item} getData={refetch} />,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<DeleteButtonForPopOver
|
||||
page="permission_control"
|
||||
access="Post-access"
|
||||
api={`auth/api/v1/permission/${item?.id}/`}
|
||||
getData={refetch}
|
||||
/>
|
||||
</Popover>,
|
||||
];
|
||||
});
|
||||
setPagesTableData(formattedData);
|
||||
}
|
||||
}, [pagesData, pagesInfo]);
|
||||
|
||||
return (
|
||||
<Grid container column>
|
||||
<Grid container className="items-center gap-2">
|
||||
<Button
|
||||
size="small"
|
||||
variant="submit"
|
||||
page="permission_control"
|
||||
access="Post-access"
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "ایجاد دسترسی",
|
||||
content: <AddAccess getData={refetch} />,
|
||||
});
|
||||
}}
|
||||
>
|
||||
ایجاد دسترسی
|
||||
</Button>
|
||||
<AutoComplete
|
||||
inPage
|
||||
size="small"
|
||||
data={[
|
||||
{ key: "", value: "کل موارد" },
|
||||
{ key: "true", value: "داخلی" },
|
||||
{ key: "false", value: "خارجی" },
|
||||
]}
|
||||
selectedKeys={selectedModifyKeys}
|
||||
onChange={(keys) => {
|
||||
setSelectedModifyKeys(keys);
|
||||
setPagesInfo((prev) => ({ ...prev, page: 1 }));
|
||||
}}
|
||||
title="فیلتر نوع دسترسی"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid className="w-full">
|
||||
<Table
|
||||
className="mt-2"
|
||||
onChange={setPagesInfo}
|
||||
count={pagesData?.count || 10}
|
||||
isPaginated
|
||||
title="مدیریت دسترسی ها"
|
||||
columns={[
|
||||
"ردیف",
|
||||
"دسترسی",
|
||||
"توضیحات",
|
||||
"صفحه",
|
||||
"دسترسی داخلی",
|
||||
"عملیات",
|
||||
]}
|
||||
rows={pagesTableData}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
196
src/partials/Admin/AddAccess.tsx
Normal file
196
src/partials/Admin/AddAccess.tsx
Normal file
@@ -0,0 +1,196 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Textfield from "../../components/Textfeild/Textfeild";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { zValidateString } from "../../data/getFormTypeErrors";
|
||||
import { z } from "zod";
|
||||
import { useApiMutation } from "../../utils/useApiRequest";
|
||||
import { useToast } from "../../hooks/useToast";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import AutoComplete from "../../components/AutoComplete/AutoComplete";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getFaPermissions } from "../../utils/getFaPermissions";
|
||||
import Checkbox from "../../components/CheckBox/CheckBox";
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
type AddAccessProps = {
|
||||
getData: () => void;
|
||||
item?: any;
|
||||
};
|
||||
|
||||
const schema = z.object({
|
||||
access: zValidateString("نام صفحه"),
|
||||
description: zValidateString("توضیحات"),
|
||||
selectedPageId: z
|
||||
.array(z.union([z.string(), z.number()]))
|
||||
.min(1, { message: "لطفاً یک صفحه انتخاب کنید." }),
|
||||
modify_state: z.boolean(),
|
||||
});
|
||||
|
||||
export const AddAccess = ({ getData, item }: AddAccessProps) => {
|
||||
const showToast = useToast();
|
||||
const { closeModal } = useModalStore();
|
||||
|
||||
const [selectedKeys, setSelectedKeys] = useState<(string | number)[]>([]);
|
||||
const [data, setData] = useState<any>([]);
|
||||
const [pagesData, setPagesData] = useState<any>(null);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
access: item?.name || "",
|
||||
description: item?.description || "",
|
||||
selectedPageId: [],
|
||||
modify_state: item?.modify_state || false,
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedKeys.length > 0) {
|
||||
setValue("selectedPageId", selectedKeys);
|
||||
}
|
||||
}, [selectedKeys, setValue]);
|
||||
|
||||
useEffect(() => {
|
||||
if (pagesData?.results && item?.page) {
|
||||
const matchingPage = pagesData.results.find(
|
||||
(page: any) => page.name === item.page,
|
||||
);
|
||||
if (matchingPage) {
|
||||
const keys = [matchingPage.id];
|
||||
setSelectedKeys(keys);
|
||||
setValue("selectedPageId", keys);
|
||||
}
|
||||
}
|
||||
}, [pagesData, item, setValue]);
|
||||
|
||||
const handleChangeComplete = (newSelectedKeys: (number | string)[]) => {
|
||||
setSelectedKeys(newSelectedKeys);
|
||||
};
|
||||
|
||||
const mutationPages = useApiMutation({
|
||||
api: "/auth/api/v1/page/",
|
||||
method: "get",
|
||||
});
|
||||
|
||||
const mutation = useApiMutation({
|
||||
api: `/auth/api/v1/permission/${item ? item?.id + "/" : ""}`,
|
||||
method: item ? "put" : "post",
|
||||
});
|
||||
|
||||
const getPages = async () => {
|
||||
const data = await mutationPages.mutateAsync({
|
||||
page: 1,
|
||||
page_size: 1000,
|
||||
});
|
||||
setPagesData(data);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getPages();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (pagesData?.results) {
|
||||
const d = pagesData.results.map((page: any) => ({
|
||||
key: page.id,
|
||||
value: `${getFaPermissions(page.name)} (${page.name})`,
|
||||
}));
|
||||
setData(d);
|
||||
}
|
||||
}, [pagesData]);
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
try {
|
||||
await mutation.mutateAsync({
|
||||
name: data.access,
|
||||
description: data.description,
|
||||
category: "api",
|
||||
meta: {},
|
||||
page: selectedKeys[0],
|
||||
modify_state: data?.modify_state,
|
||||
});
|
||||
showToast("عملیات با موفقیت انجام شد", "success");
|
||||
closeModal();
|
||||
getData();
|
||||
} catch (error: any) {
|
||||
if (error.status === 400) {
|
||||
showToast("این دسترسی تکراری است!", "error");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Grid container column className="gap-2">
|
||||
<Controller
|
||||
name="selectedPageId"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<AutoComplete
|
||||
data={data}
|
||||
selectedKeys={selectedKeys}
|
||||
onChange={(newSelectedKeys) => {
|
||||
handleChangeComplete(newSelectedKeys);
|
||||
field.onChange(newSelectedKeys);
|
||||
}}
|
||||
title="انتخاب صفحه"
|
||||
error={!!errors.selectedPageId}
|
||||
helperText={errors.selectedPageId?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="access"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Textfield
|
||||
fullWidth
|
||||
placeholder="نام دسترسی"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
error={!!errors.access}
|
||||
helperText={errors.access?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="description"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Textfield
|
||||
fullWidth
|
||||
placeholder="توضیحات"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
error={!!errors.description}
|
||||
helperText={errors.description?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Controller
|
||||
name="modify_state"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Checkbox
|
||||
checked={field.value}
|
||||
onChange={field.onChange}
|
||||
label="دسترسی داخلی"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button type="submit">ثبت</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
125
src/partials/Admin/AddDomain.tsx
Normal file
125
src/partials/Admin/AddDomain.tsx
Normal file
@@ -0,0 +1,125 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Textfield from "../../components/Textfeild/Textfeild";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import {
|
||||
zValidateString,
|
||||
zValidateEnglishString,
|
||||
} from "../../data/getFormTypeErrors";
|
||||
import { z } from "zod";
|
||||
import { useApiMutation } from "../../utils/useApiRequest";
|
||||
import { useToast } from "../../hooks/useToast";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import { getToastResponse } from "../../data/getToastResponse";
|
||||
|
||||
const schema = z.object({
|
||||
code: zValidateString("کد حوزه"),
|
||||
name: zValidateEnglishString("نام انگلیسی حوزه"),
|
||||
fa_name: zValidateString("نام حوزه"),
|
||||
});
|
||||
|
||||
type AddDomainProps = {
|
||||
getData: () => void;
|
||||
item?: any;
|
||||
};
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
export const AddDomain = ({ getData, item }: AddDomainProps) => {
|
||||
const showToast = useToast();
|
||||
const { closeModal } = useModalStore();
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
code: item?.code || "",
|
||||
name: item?.name || "",
|
||||
fa_name: item?.fa_name || "",
|
||||
},
|
||||
});
|
||||
|
||||
const mutation = useApiMutation({
|
||||
api: `/core/domain/${item ? item?.id + "/" : ""}`,
|
||||
method: item ? "put" : "post",
|
||||
});
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
try {
|
||||
await mutation.mutateAsync({
|
||||
code: data.code,
|
||||
name: data.name,
|
||||
fa_name: data.fa_name,
|
||||
});
|
||||
showToast(getToastResponse(item, "حوزه"), "success");
|
||||
closeModal();
|
||||
getData();
|
||||
} catch (error: any) {
|
||||
if (error?.status === 403) {
|
||||
showToast(
|
||||
error?.response?.data?.message || "این مورد تکراری است!",
|
||||
"error",
|
||||
);
|
||||
} else {
|
||||
showToast(
|
||||
error?.response?.data?.message || "خطا در ثبت اطلاعات!",
|
||||
"error",
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Grid container column className="gap-2">
|
||||
<Controller
|
||||
name="code"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Textfield
|
||||
fullWidth
|
||||
placeholder="کد حوزه"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
error={!!errors.code}
|
||||
helperText={errors.code?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="name"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Textfield
|
||||
fullWidth
|
||||
placeholder="نام انگلیسی حوزه"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
error={!!errors.name}
|
||||
helperText={errors.name?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Controller
|
||||
name="fa_name"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Textfield
|
||||
fullWidth
|
||||
placeholder="نام حوزه"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
error={!!errors.fa_name}
|
||||
helperText={errors.fa_name?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">ثبت</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
90
src/partials/Admin/AddPage.tsx
Normal file
90
src/partials/Admin/AddPage.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Textfield from "../../components/Textfeild/Textfeild";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { zValidateEnglishString } from "../../data/getFormTypeErrors";
|
||||
import { z } from "zod";
|
||||
import { useApiMutation } from "../../utils/useApiRequest";
|
||||
import { useToast } from "../../hooks/useToast";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
|
||||
const schema = z.object({
|
||||
page: zValidateEnglishString("نام صفحه"),
|
||||
});
|
||||
|
||||
type AddPageProps = {
|
||||
getData: () => void;
|
||||
item?: any;
|
||||
};
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
export const AddPage = ({ getData, item }: AddPageProps) => {
|
||||
const showToast = useToast();
|
||||
const { closeModal } = useModalStore();
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
page: item?.name || "",
|
||||
},
|
||||
});
|
||||
|
||||
const mutation = useApiMutation({
|
||||
api: `/auth/api/v1/page/${item ? item?.id + "/" : ""}`,
|
||||
method: item ? "put" : "post",
|
||||
});
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
try {
|
||||
const payload = {
|
||||
name: data.page,
|
||||
code: data.page + ".view",
|
||||
};
|
||||
|
||||
if (item) {
|
||||
await mutation.mutateAsync({
|
||||
...payload,
|
||||
id: item.id,
|
||||
});
|
||||
} else {
|
||||
await mutation.mutateAsync(payload);
|
||||
}
|
||||
|
||||
showToast("عملیات با موفقیت انجام شد", "success");
|
||||
closeModal();
|
||||
getData();
|
||||
} catch (error: any) {
|
||||
if (error.status === 400) {
|
||||
showToast("این صفحه تکراری است!", "error");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Grid container column className="gap-2">
|
||||
<Controller
|
||||
name="page"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<Textfield
|
||||
fullWidth
|
||||
placeholder="نام صفحه"
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
error={!!errors.page}
|
||||
helperText={errors.page?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">ثبت</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
161
src/partials/Admin/EditAccess.tsx
Normal file
161
src/partials/Admin/EditAccess.tsx
Normal file
@@ -0,0 +1,161 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import { useForm, Controller } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import { useApiMutation } from "../../utils/useApiRequest";
|
||||
import { useToast } from "../../hooks/useToast";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import AutoComplete from "../../components/AutoComplete/AutoComplete";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getFaPermissions } from "../../utils/getFaPermissions";
|
||||
import { useFetchProfile } from "../../hooks/useFetchProfile";
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
type AddAccessProps = {
|
||||
getData: () => void;
|
||||
item?: any;
|
||||
};
|
||||
|
||||
const schema = z.object({
|
||||
selectedAccessId: z
|
||||
.array(z.union([z.string(), z.number()]))
|
||||
.min(1, { message: "لطفاً یک دسترسی را انتخاب کنید." }),
|
||||
});
|
||||
|
||||
export const EditAccess = ({ getData, item }: AddAccessProps) => {
|
||||
const showToast = useToast();
|
||||
const { closeModal } = useModalStore();
|
||||
const { getProfile } = useFetchProfile();
|
||||
const [selectedKeys, setSelectedKeys] = useState<(string | number)[]>([]);
|
||||
const [data, setData] = useState<any>([]);
|
||||
const [accessData, setAccessData] = useState<any>(null);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
selectedAccessId: [],
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedKeys.length > 0) {
|
||||
setValue("selectedAccessId", selectedKeys);
|
||||
}
|
||||
}, [selectedKeys, setValue]);
|
||||
|
||||
useEffect(() => {
|
||||
if (accessData?.results && item?.permissions) {
|
||||
const permissionPageAccesses = item.permissions.flatMap(
|
||||
(option: any) => option.page_access || [],
|
||||
);
|
||||
|
||||
const matchingPages = accessData.results.filter((page: any) =>
|
||||
permissionPageAccesses.includes(page.name),
|
||||
);
|
||||
|
||||
const matchingIds = matchingPages.map((page: any) => page.id);
|
||||
|
||||
if (matchingIds.length > 0) {
|
||||
setSelectedKeys(matchingIds);
|
||||
setValue("selectedAccessId", matchingIds);
|
||||
} else {
|
||||
setSelectedKeys([]);
|
||||
setValue("selectedAccessId", []);
|
||||
}
|
||||
}
|
||||
}, [accessData, item, setValue]);
|
||||
|
||||
const handleChangeComplete = (newSelectedKeys: (number | string)[]) => {
|
||||
setSelectedKeys(newSelectedKeys);
|
||||
};
|
||||
|
||||
const mutationUserAccess = useApiMutation({
|
||||
api: "/auth/api/v1/permission/",
|
||||
method: "get",
|
||||
});
|
||||
|
||||
const mutation = useApiMutation({
|
||||
api: `/auth/api/v1/user-relations/${item ? item?.id + "/" : ""}`,
|
||||
method: "put",
|
||||
});
|
||||
|
||||
const getPages = async () => {
|
||||
const data = await mutationUserAccess.mutateAsync({
|
||||
page: 1,
|
||||
page_size: 10000,
|
||||
});
|
||||
setAccessData(data);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getPages();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (accessData?.results) {
|
||||
const sortedResults = [...accessData.results].sort((a, b) => {
|
||||
if (a.page < b.page) return -1;
|
||||
if (a.page > b.page) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
const d = sortedResults.map((access: any) => ({
|
||||
key: access.id,
|
||||
value: `${getFaPermissions(access.page)} - ${access?.description} (${
|
||||
access?.name
|
||||
}) `,
|
||||
}));
|
||||
setData(d);
|
||||
}
|
||||
}, [accessData]);
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
try {
|
||||
await mutation.mutateAsync({
|
||||
user: item?.user?.id,
|
||||
permissions: data.selectedAccessId,
|
||||
});
|
||||
showToast("عملیات با موفقیت انجام شد", "success");
|
||||
closeModal();
|
||||
getData();
|
||||
getProfile();
|
||||
} catch (error: any) {
|
||||
if (error.status === 400) {
|
||||
showToast("مشکلی پیش آمده است!", "error");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Grid container column className="gap-2 overflow-hidden">
|
||||
<Controller
|
||||
name="selectedAccessId"
|
||||
control={control}
|
||||
render={({ field }) => (
|
||||
<AutoComplete
|
||||
multiselect
|
||||
data={data}
|
||||
selectedKeys={selectedKeys}
|
||||
onChange={(newSelectedKeys) => {
|
||||
handleChangeComplete(newSelectedKeys);
|
||||
field.onChange(newSelectedKeys);
|
||||
}}
|
||||
title="انتخاب دسترسی"
|
||||
error={!!errors.selectedAccessId}
|
||||
helperText={errors.selectedAccessId?.message}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button type="submit">ثبت</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
118
src/partials/Admin/Pages.tsx
Normal file
118
src/partials/Admin/Pages.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getFaPermissions } from "../../utils/getFaPermissions";
|
||||
import { useApiRequest } from "../../utils/useApiRequest";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import Table from "../../components/Table/Table";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { AddPage } from "./AddPage";
|
||||
import { Popover } from "../../components/PopOver/PopOver";
|
||||
import { Tooltip } from "../../components/Tooltip/Tooltip";
|
||||
import { DeleteButtonForPopOver } from "../../components/PopOverButtons/PopOverButtons";
|
||||
import { ArrowPathIcon } from "@heroicons/react/24/outline";
|
||||
import { BooleanQuestion } from "../../components/BooleanQuestion/BooleanQuestion";
|
||||
|
||||
export default function Pages() {
|
||||
const { openModal } = useModalStore();
|
||||
const [pagesInfo, setPagesInfo] = useState({ page: 1, page_size: 10 });
|
||||
const [pagesTableData, setPagesTableData] = useState([]);
|
||||
|
||||
const { data: pagesData, refetch } = useApiRequest({
|
||||
api: "/auth/api/v1/page/",
|
||||
method: "get",
|
||||
params: pagesInfo,
|
||||
queryKey: ["pages", pagesInfo],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (pagesData?.results) {
|
||||
const formattedData = pagesData.results.map((item: any, i: number) => {
|
||||
return [
|
||||
pagesInfo.page === 1
|
||||
? i + 1
|
||||
: i + pagesInfo.page_size * (pagesInfo.page - 1) + 1,
|
||||
getFaPermissions(item?.name),
|
||||
item?.name,
|
||||
item?.permissions?.map((option: any) => option.name)?.join(" - "),
|
||||
<Popover key={i}>
|
||||
<Tooltip title="ویرایش" position="right">
|
||||
<Button
|
||||
page="permission_control"
|
||||
access="Post-Page"
|
||||
variant="edit"
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "ویرایش صفحه",
|
||||
content: <AddPage item={item} getData={refetch} />,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<DeleteButtonForPopOver
|
||||
page="permission_control"
|
||||
access="Post-Page"
|
||||
api={`auth/api/v1/page/${item?.id}/`}
|
||||
getData={refetch}
|
||||
/>
|
||||
</Popover>,
|
||||
];
|
||||
});
|
||||
setPagesTableData(formattedData);
|
||||
}
|
||||
}, [pagesData, pagesInfo]);
|
||||
|
||||
return (
|
||||
<Grid container column>
|
||||
<Grid container className="items-center gap-2">
|
||||
<Button
|
||||
size="small"
|
||||
page="permission_control"
|
||||
access="Post-Page"
|
||||
variant="submit"
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "ایجاد صفحه",
|
||||
content: <AddPage getData={refetch} />,
|
||||
});
|
||||
}}
|
||||
>
|
||||
ایجاد صفحه
|
||||
</Button>
|
||||
{(window.location.origin.includes("localhost") ||
|
||||
window.location.origin.includes("tdam.rasadyar")) && (
|
||||
<Tooltip title="ارسال لیست به سامانه" position="top">
|
||||
<Button
|
||||
size="small"
|
||||
page="permission_control"
|
||||
access="Post-Page"
|
||||
icon={<ArrowPathIcon className="w-5 h-5" />}
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "آیا از ارسال لیست به سامانه مطمئنید؟",
|
||||
content: (
|
||||
<BooleanQuestion
|
||||
getData={refetch}
|
||||
api={`auth/api/v1/update_access/`}
|
||||
method="post"
|
||||
/>
|
||||
),
|
||||
});
|
||||
}}
|
||||
>
|
||||
{" "}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Grid>
|
||||
<Table
|
||||
className="mt-2"
|
||||
onChange={setPagesInfo}
|
||||
count={pagesData?.count || 10}
|
||||
isPaginated
|
||||
title="صفحات سامانه"
|
||||
columns={["ردیف", "صفحه", "کلید", "دسترسی ها", "عملیات"]}
|
||||
rows={pagesTableData}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
71
src/partials/Admin/UnusedAccess.tsx
Normal file
71
src/partials/Admin/UnusedAccess.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { getFaPermissions } from "../../utils/getFaPermissions";
|
||||
import { useApiRequest } from "../../utils/useApiRequest";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import Table from "../../components/Table/Table";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Button from "../../components/Button/Button";
|
||||
import { AddAccess } from "./AddAccess";
|
||||
import { Popover } from "../../components/PopOver/PopOver";
|
||||
import { Tooltip } from "../../components/Tooltip/Tooltip";
|
||||
import { DeleteButtonForPopOver } from "../../components/PopOverButtons/PopOverButtons";
|
||||
|
||||
export default function UnusedAccess() {
|
||||
const { openModal } = useModalStore();
|
||||
const [pagesInfo, setPagesInfo] = useState({ page: 1, page_size: 10 });
|
||||
const [pagesTableData, setPagesTableData] = useState([]);
|
||||
|
||||
const { data: pagesData, refetch } = useApiRequest({
|
||||
api: "/auth/api/v1/permission/connectionless_permissions/",
|
||||
method: "get",
|
||||
params: pagesInfo,
|
||||
queryKey: ["connectionless_permissions", pagesInfo],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (pagesData?.results) {
|
||||
const formattedData = pagesData.results.map((item: any, i: number) => {
|
||||
return [
|
||||
pagesInfo.page === 1
|
||||
? i + 1
|
||||
: i + pagesInfo.page_size * (pagesInfo.page - 1) + 1,
|
||||
item?.name,
|
||||
item?.description,
|
||||
`${getFaPermissions(item?.page)} (${item?.page})`,
|
||||
<Popover key={i}>
|
||||
<Tooltip title="ویرایش" position="right">
|
||||
<Button
|
||||
variant="edit"
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "ویرایش دسترسی",
|
||||
content: <AddAccess item={item} getData={refetch} />,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<DeleteButtonForPopOver
|
||||
api={`auth/api/v1/permission/${item?.id}/`}
|
||||
getData={refetch}
|
||||
/>
|
||||
</Popover>,
|
||||
];
|
||||
});
|
||||
setPagesTableData(formattedData);
|
||||
}
|
||||
}, [pagesData, pagesInfo]);
|
||||
|
||||
return (
|
||||
<Grid container column>
|
||||
<Table
|
||||
className="mt-2"
|
||||
onChange={setPagesInfo}
|
||||
count={pagesData?.count || 10}
|
||||
isPaginated
|
||||
title="دسترسی های غیر فعال"
|
||||
columns={["ردیف", "دسترسی", "توضیحات", "صفحه", "عملیات"]}
|
||||
rows={pagesTableData}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user