Merge branch 'feature/permission_table' into 'develop'

Feature/permission table

See merge request witel-front-end/rms!85
This commit is contained in:
AmirHossein Mahmoodi
2025-03-08 12:51:29 +00:00
21 changed files with 795 additions and 56 deletions

View File

@@ -0,0 +1,13 @@
import WithPermission from "@/core/middlewares/withPermission";
import PermissionTablePage from "@/components/dashboard/permissionTable";
export const metadata = {
title: "سطح دسترسی ها",
};
const Page = () => {
return (
<WithPermission permission_name={["show-permissions-page"]}>
<PermissionTablePage />
</WithPermission>
);
};
export default Page;

View File

@@ -70,8 +70,8 @@ const DamagesList = () => {
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_RECEIPT_DAMAGE_ITEMS_LIST}
page_name={"receiptDamanagePage"}
table_name={"damanageList"}
page_name={"receiptDamagePage"}
table_name={"receiptDamageList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}

View File

@@ -80,6 +80,7 @@ const CreateFormContent = ({ setOpen, SubmitDamage, defaultData }) => {
accident_type: defaultData.accident_type,
province_id: defaultData.province_id,
city_id: defaultData.city_id,
is_province: defaultData.is_province,
axis_name: defaultData.axis_name,
driver_name: defaultData.driver_name,
phone_number: defaultData.phone_number,

View File

@@ -3,66 +3,18 @@ import { Grid, Stack, TextField } from "@mui/material";
import MuiDatePicker from "@/core/components/MuiDatePicker";
import MuiTimePicker from "@/core/components/MuiTimePicker";
import SelectBox from "@/core/components/SelectBox";
import useProvinces from "@/lib/hooks/useProvince";
import PlateNumber from "@/core/components/PlateNumber";
import ImageUpload from "./ImageUpload";
import MapInfoOneMarker from "@/core/components/MapInfoOneMarker";
import CityController from "@/components/dashboard/damages/operator/Actions/create/Forms/CityController";
import PersianTextField from "@/core/components/PersianTextField";
import LogesticController from "./LogesticController";
const DamageInfo = ({ control, setValue, errors }) => {
const StartPoint = useWatch({ control, name: "start_point" });
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
return (
<Stack>
<Grid sx={{ mt: 2 }} container spacing={2}>
<Grid item xs={12} md={4}>
<Controller
name="province_id"
control={control}
render={({ field, fieldState: { error } }) => {
return (
<SelectBox
value={errorProvinces ? "error" : loadingProvinces ? "loading" : field.value || ""}
label="استان"
selectors={provinces}
schema={{ name: "name_fa", value: "id" }}
error={error}
onChange={field.onChange}
helperText={error?.message}
isLoading={loadingProvinces}
errorEcured={errorProvinces}
/>
);
}}
/>
</Grid>
<Grid item xs={12} md={4}>
<CityController control={control} />
</Grid>
<Grid item xs={12} md={4}>
<Controller
name="axis_name"
control={control}
render={({ field, fieldState: { error } }) => (
<PersianTextField
value={field.value}
variant="outlined"
name="axis_name"
fieldOnChange={field.onChange}
label="نام محور"
placeholder={"نام محور فارسی را وارد کنید"}
fullWidth
size="small"
error={error}
helperText={error?.message}
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
</Grid>
<LogesticController control={control} />
<Grid sx={{ mt: 2 }} container spacing={2}>
<Grid item xs={12} md={6}>
<Controller
@@ -73,7 +25,7 @@ const DamageInfo = ({ control, setValue, errors }) => {
value={field.value}
variant="outlined"
name="driver_name"
fieldOnChange={field.onChange}
onChange={field.onChange}
label="نام و نام خانوادگی راننده"
placeholder={"نام و نام خانوادگی فارسی را وارد کنید"}
fullWidth

View File

@@ -0,0 +1,64 @@
import { Controller, useWatch } from "react-hook-form";
import SelectBox from "@/core/components/SelectBox";
import useProvinces from "@/lib/hooks/useProvince";
import { Grid } from "@mui/material";
import CityController from "./CityController";
import PersianTextField from "@/core/components/PersianTextField";
const LogesticController = ({ control }) => {
const { provinces, errorProvinces, loadingProvinces } = useProvinces();
const isProvince = useWatch({ control, name: "is_province" });
return (
<Grid sx={{ mt: 1 }} container spacing={2}>
{!isProvince ? (
<Grid item xs={12} md={4}>
<Controller
name="province_id"
control={control}
render={({ field, fieldState: { error } }) => {
return (
<SelectBox
value={errorProvinces ? "error" : loadingProvinces ? "loading" : field.value || ""}
label="استان"
selectors={provinces}
schema={{ name: "name_fa", value: "id" }}
error={error}
disabled={isProvince}
onChange={field.onChange}
helperText={error?.message}
isLoading={loadingProvinces}
errorEcured={errorProvinces}
/>
);
}}
/>
</Grid>
) : null}
<Grid item xs={12} md={isProvince ? 6 : 4}>
<CityController control={control} />
</Grid>
<Grid item xs={12} md={isProvince ? 6 : 4}>
<Controller
name="axis_name"
control={control}
render={({ field, fieldState: { error } }) => (
<PersianTextField
value={field.value}
variant="outlined"
name="axis_name"
onChange={field.onChange}
label="نام محور"
placeholder={"نام محور فارسی را وارد کنید"}
fullWidth
size="small"
error={error}
helperText={error?.message}
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
</Grid>
);
};
export default LogesticController;

View File

@@ -5,9 +5,14 @@ import { format } from "date-fns";
import { CREATE_DAMAGE } from "@/core/utils/routes";
import useRequest from "@/lib/hooks/useRequest";
import CloseIcon from "@mui/icons-material/Close";
import { usePermissions } from "@/lib/hooks/usePermissions";
import { useAuth } from "@/lib/contexts/auth";
const OperatorCreateForm = ({ open, setOpen, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const { user } = useAuth();
const { data: userPermissions } = usePermissions();
const hasCreateProvincePermission = userPermissions.some((item) => ["add-receipt"].includes(item));
const SubmitCreateDamage = async (result) => {
const PlateNumber = `${result.plate_part1}-${result.plate_part2}-${result.plate_part3}-${result.plate_part4}`;
const formData = new FormData();
@@ -52,7 +57,8 @@ const OperatorCreateForm = ({ open, setOpen, mutate }) => {
accident_date: "",
accident_time: "",
accident_type: "",
province_id: null,
province_id: !hasCreateProvincePermission ? user.province_id : null,
is_province: !hasCreateProvincePermission,
city_id: null,
axis_name: "",
driver_name: "",

View File

@@ -5,11 +5,16 @@ import { GET_DAMAGE_ITEM_DETAILS, UPDATE_DAMAGE_ITEM } from "@/core/utils/routes
import DialogLoading from "@/core/components/DialogLoading";
import { format } from "date-fns";
import moment from "jalali-moment";
import { useAuth } from "@/lib/contexts/auth";
import { usePermissions } from "@/lib/hooks/usePermissions";
const EditController = ({ rowId, mutate, setOpenEditDialog }) => {
const requestServer = useRequest();
const [damageItemDetails, setDamageItemDetails] = useState(null);
const [damageItemDetailsLoading, setDamageItemDetailsLoading] = useState(false);
const { user } = useAuth();
const { data: userPermissions } = usePermissions();
const hasCreateProvincePermission = userPermissions.some((item) => ["add-receipt"].includes(item));
useEffect(() => {
setDamageItemDetailsLoading(true);
@@ -46,6 +51,7 @@ const EditController = ({ rowId, mutate, setOpenEditDialog }) => {
radio_button: damageItemDetails?.report_base === 1 ? "report_base" : "police_file_checkbox",
report_base: damageItemDetails?.report_base,
province_id: damageItemDetails?.province_id || null,
is_province: !hasCreateProvincePermission,
city_id: damageItemDetails?.city_id || null,
start_point: { lat: damageItemDetails?.lat || "", lng: damageItemDetails?.lng || "" },
};

View File

@@ -0,0 +1,219 @@
import StyledForm from "@/core/components/StyledForm";
import { yupResolver } from "@hookform/resolvers/yup";
import { Beenhere, ExitToApp } from "@mui/icons-material";
import {
Button,
DialogActions,
DialogContent,
Grid,
Stack,
TextField,
FormControlLabel,
Checkbox,
} from "@mui/material";
import { Controller, useForm } from "react-hook-form";
import { object, string } from "yup";
import PersianTextField from "@/core/components/PersianTextField";
const validationSchema = object({
name: string().required("وارد کردن نام انگلیسی الزامیست!"),
name_fa: string().required("وارد کردن نام فارسی الزامیست!"),
description: string().required("وارد کردن توضیحات الزامیست!"),
type: string().required("وارد کردن گروه (انگلیسی) الزامیست!"),
type_fa: string().required("وارد کردن گروه (فارسی) الزامیست!"),
});
const CreateFormContent = ({ setOpen, defaultValues, onSubmitBase }) => {
const {
control,
handleSubmit,
formState: { isSubmitting, errors },
} = useForm({
defaultValues,
resolver: yupResolver(validationSchema),
mode: "onBlur",
});
const handleOnSubmit = async (data) => {
await onSubmitBase(data);
};
return (
<>
<StyledForm onSubmit={handleSubmit(handleOnSubmit)}>
<DialogContent dividers>
<Stack spacing={3}>
<Stack>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<Controller
name="name"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="نام انگلیسی"
value={value}
onChange={onChange}
placeholder="نام انگلیسی را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Controller
name="name_fa"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<PersianTextField
fullWidth
size="small"
label="نام فارسی"
value={value}
onChange={onChange}
placeholder="نام فارسی را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
</Grid>
</Stack>
<Stack>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<Controller
name="type"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="گروه (انگلیسی)"
value={value}
onChange={onChange}
placeholder="گروه (انگلیسی) را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Controller
name="type_fa"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<PersianTextField
fullWidth
size="small"
label="گروه (فارسی)"
value={value}
onChange={onChange}
placeholder="گروه (فارسی) را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
</Grid>
</Stack>
<Stack>
<Grid container spacing={2}>
<Grid item xs={12} sm={12}>
<Controller
name="description"
control={control}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<TextField
fullWidth
size="small"
label="توضیحات"
multiline
rows={4}
value={value}
onChange={onChange}
placeholder="توضیحات را وارد کنید"
error={!!error}
helperText={error ? error.message : null}
variant="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
/>
</Grid>
</Grid>
</Stack>
<Stack>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<Controller
name="need_province"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Checkbox
{...field}
checked={field.value}
onChange={field.onChange}
/>
}
label="دسترسی استانی"
/>
)}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Controller
name="need_edare_shahri"
control={control}
render={({ field }) => (
<FormControlLabel
control={
<Checkbox
{...field}
checked={field.value}
onChange={field.onChange}
/>
}
label="دسترسی اداره شهری"
/>
)}
/>
</Grid>
</Grid>
</Stack>
</Stack>
</DialogContent>
<DialogActions>
<Button
onClick={() => setOpen(false)}
variant="outlined"
color="secondary"
startIcon={<ExitToApp />}
>
بستن
</Button>
<Button variant="contained" disabled={isSubmitting} type="submit" endIcon={<Beenhere />}>
{" "}
{isSubmitting ? "در حال ثبت سطح دسترسی" : "ثبت سطح دسترسی"}{" "}
</Button>
</DialogActions>
</StyledForm>
</>
);
};
export default CreateFormContent;

View File

@@ -0,0 +1,66 @@
import { Dialog, DialogTitle, IconButton } from "@mui/material";
import CreateFormContent from "./CreateFormContent";
import CloseIcon from "@mui/icons-material/Close";
import useRequest from "@/lib/hooks/useRequest";
import { CREATE_PERMISSION } from "@/core/utils/routes";
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
const CreateForm = ({ open, setOpen, mutate }) => {
const requestServer = useRequest({ notificationSuccess: true });
const defaultValues = {
name: "",
name_fa: "",
description: "",
type: "",
type_fa: "",
need_province: false,
need_edare_shahri: false,
};
const onSubmit = async (result) => {
const formData = new FormData();
formData.append("name", result.name);
formData.append("name_fa", result.name_fa);
formData.append("description", result.description);
formData.append("type", result.type);
formData.append("type_fa", result.type_fa);
formData.append("need_province", result.need_province ? 1 : 0);
formData.append("need_edare_shahri", result.need_edare_shahri ? 1 : 0);
await requestServer(CREATE_PERMISSION, "post", {
data: formData,
})
.then(() => {
mutate();
setOpen(false);
})
.catch(() => {});
};
return (
<Dialog open={open} fullWidth maxWidth="sm">
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
<DialogHeader>
<DialogTitle>ثبت سطح دسترسی جدید</DialogTitle>
</DialogHeader>
{open && (
<CreateFormContent
defaultValues={defaultValues}
onSubmitBase={onSubmit}
setOpen={setOpen}
mutate={mutate}
/>
)}
</Dialog>
);
};
export default CreateForm;

View File

@@ -0,0 +1,36 @@
import { AddCircle } from "@mui/icons-material";
import { Button, IconButton, useMediaQuery, useTheme } from "@mui/material";
import CreateForm from "./Form";
import { useState } from "react";
const CreatePermission = ({ mutate }) => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const [open, setOpen] = useState(false);
const handleOpen = () => {
setOpen(true);
};
return (
<>
{isMobile ? (
<IconButton aria-label="ثبت سطح دسترسی" color="primary" onClick={handleOpen}>
<AddCircle sx={{ fontSize: "25px" }} />
</IconButton>
) : (
<Button
size={"small"}
variant="contained"
color="primary"
startIcon={<AddCircle />}
onClick={handleOpen}
>
ثبت سطح دسترسی
</Button>
)}
<CreateForm open={open} setOpen={setOpen} mutate={mutate} />
</>
);
};
export default CreatePermission;

View File

@@ -0,0 +1,46 @@
import useRequest from "@/lib/hooks/useRequest";
import CreateFormContent from "../Create/Form/CreateFormContent";
import { UPDATE_PERMISSION } from "@/core/utils/routes";
import { DialogTitle } from "@mui/material";
import { DialogHeader } from "next/dist/client/components/react-dev-overlay/internal/components/Dialog";
const EditController = ({ rowId, mutate, setOpen, row }) => {
const requestServer = useRequest({ notificationSuccess: true });
const defaultData = {
name: row.original?.name || "",
name_fa: row.original?.name_fa || "",
description: row.original?.description || "",
type: row.original?.type || "",
type_fa: row.original?.type_fa || "",
need_province: row.original?.need_province || false,
need_edare_shahri: row.original?.need_edare_shahri || false,
};
const handleSubmit = async (result) => {
const formData = new FormData();
formData.append("name", result.name);
formData.append("name_fa", result.name_fa);
formData.append("description", result.description);
formData.append("type", result.type);
formData.append("type_fa", result.type_fa);
formData.append("need_province", result.need_province ? 1 : 0);
formData.append("need_edare_shahri", result.need_edare_shahri ? 1 : 0);
await requestServer(`${UPDATE_PERMISSION}/${rowId}`, "post", {
data: formData,
})
.then(() => {
mutate();
setOpen(false);
})
.catch(() => {});
};
return (
<>
<DialogHeader>
<DialogTitle>ویرایش سطح دسترسی جدید</DialogTitle>
</DialogHeader>
<CreateFormContent setOpen={setOpen} defaultValues={defaultData} onSubmitBase={handleSubmit} />
</>
);
};
export default EditController;

View File

@@ -0,0 +1,51 @@
import { useState } from "react";
import { Dialog, IconButton, Tooltip } from "@mui/material";
import BorderColorIcon from "@mui/icons-material/BorderColor";
import CloseIcon from "@mui/icons-material/Close";
import EditController from "./EditController";
const EditPermission = ({ mutate, row, rowId }) => {
const [open, setOpen] = useState(false);
return (
<>
<Tooltip title="ویرایش سطح دسترسی" arrow placement="right">
<IconButton
color="primary"
sx={{ textTransform: "unset", alignSelf: "center" }}
onClick={() => {
setOpen(true);
}}
>
<BorderColorIcon />
</IconButton>
</Tooltip>
<Dialog
fullWidth
open={open}
maxWidth={"sm"}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
>
<IconButton
aria-label="close"
onClick={() => setOpen(false)}
sx={(theme) => ({
position: "absolute",
right: 8,
top: 8,
zIndex: 50,
color: theme.palette.grey[500],
})}
>
<CloseIcon />
</IconButton>
{open && <EditController setOpen={setOpen} rowId={rowId} row={row} mutate={mutate} />}
</Dialog>
</>
);
};
export default EditPermission;

View File

@@ -0,0 +1,157 @@
"use client";
import DataTableWithAuth from "@/core/components/DataTableWithAuth";
import { GET_PERMISSION_TABLE_LIST } from "@/core/utils/routes";
import { Box, Stack, Typography } from "@mui/material";
import { useMemo } from "react";
import Toolbar from "./Toolbar";
import RowActions from "./RowActions";
import moment from "jalali-moment";
import DoneIcon from "@mui/icons-material/Done";
import ClearIcon from "@mui/icons-material/Clear";
const PermissionList = () => {
const columns = useMemo(
() => [
{
accessorKey: "id",
header: "کد یکتا",
id: "id",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
sortDescFirst: false,
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "type",
header: "گروه (انگلیسی)",
id: "type",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
sortDescFirst: false,
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "type_fa",
header: "گروه (فارسی)",
id: "type_fa",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
sortDescFirst: false,
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "name",
header: "نام انگلیسی",
id: "name",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "name_fa",
header: "نام فارسی",
id: "name_fa",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
},
{
accessorKey: "need_province",
header: "دسترسی استانی",
id: "need_province",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<>
{renderedCellValue === 1 ? (
<Stack alignItems={"center"} justifyContent={"center"}>
<DoneIcon color="primary" />
</Stack>
) : (
<Stack alignItems={"center"} justifyContent={"center"}>
<ClearIcon color="error" />
</Stack>
)}
</>
),
},
{
accessorKey: "need_edare_shahri",
header: "دسترسی اداره شهری",
id: "need_edare_shahri",
enableColumnFilter: true,
datatype: "text",
filterMode: "equals",
columnFilterModeOptions: ["equals", "contains"],
grow: false,
size: 100,
Cell: ({ renderedCellValue }) => (
<>
{renderedCellValue === 1 ? (
<Stack alignItems={"center"} justifyContent={"center"}>
<DoneIcon color="primary" />
</Stack>
) : (
<Stack alignItems={"center"} justifyContent={"center"}>
<ClearIcon color="error" />
</Stack>
)}
</>
),
},
{
accessorFn: (row) => {
const date = row.created_at ? new Date(row.created_at) : null;
return date ? moment(date).locale("fa").format("HH:mm | jYYYY/jMM/jDD") : "-";
},
header: "تاریخ ثبت",
id: "created_at",
enableColumnFilter: true,
datatype: "date",
filterMode: "between",
grow: false,
size: 100,
},
],
[]
);
return (
<>
<Box sx={{ p: 1, border: 1, borderColor: "divider", borderRadius: 1 }}>
<DataTableWithAuth
need_filter={true}
columns={columns}
sorting={[{ id: "id", desc: true }]}
table_url={GET_PERMISSION_TABLE_LIST}
page_name={"permissionTablePage"}
table_name={"permissionTableList"}
TableToolbar={Toolbar}
enableRowActions
positionActionsColumn={"last"}
RowActions={RowActions}
/>
</Box>
</>
);
};
export default PermissionList;

View File

@@ -0,0 +1,39 @@
import { Button, DialogActions, DialogContent, Stack, Typography } from "@mui/material";
import React, { useState } from "react";
import useRequest from "@/lib/hooks/useRequest";
import { DELETE_PERMISSION } from "@/core/utils/routes";
const DeleteContent = ({ rowId, mutate, setOpenDeleteDialog }) => {
const [submitting, setSubmitting] = useState(false);
const requestServer = useRequest({ notificationSuccess: true });
const handleClick = () => {
setSubmitting(true);
requestServer(`${DELETE_PERMISSION}/${rowId}`, "delete")
.then(() => {
mutate();
setSubmitting(false);
setOpenDeleteDialog(false);
})
.catch(() => {
setSubmitting(false);
});
};
return (
<>
<DialogContent>
<Stack alignItems="center" spacing={2}>
<Typography mt={2}>آیا از حذف سطح دسترسی اطمینان دارید؟</Typography>
</Stack>
</DialogContent>
<DialogActions sx={{ justifyContent: "center", paddingBottom: 2, width: "100%" }}>
<Button onClick={() => setOpenDeleteDialog(false)} variant="outlined" color="secondary">
خیر !
</Button>
<Button onClick={handleClick} variant="contained" color="error" disabled={submitting}>
{submitting ? "درحال حذف..." : "بله اطمینان دارم"}
</Button>
</DialogActions>
</>
);
};
export default DeleteContent;

View File

@@ -0,0 +1,34 @@
import DeleteIcon from "@mui/icons-material/Delete";
import { Dialog, DialogTitle, IconButton, Tooltip } from "@mui/material";
import { useState } from "react";
import DeleteContent from "./DeleteContent";
const DeleteDialog = ({ rowId, mutate }) => {
const [openDeleteDialog, setOpenDeleteDialog] = useState(false);
return (
<>
<Tooltip title="حذف">
<IconButton color="error" onClick={() => setOpenDeleteDialog(true)}>
<DeleteIcon />
</IconButton>
</Tooltip>
<Dialog
open={openDeleteDialog}
onClose={() => setOpenDeleteDialog(false)}
PaperProps={{
sx: {
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 16px 0px, rgba(60, 64, 67, 0.15) 0px 1px 10px 0px",
},
}}
dir="rtl"
maxWidth={"md"}
>
<DialogTitle>حذف سطح دسترسی</DialogTitle>
{openDeleteDialog && (
<DeleteContent rowId={rowId} mutate={mutate} setOpenDeleteDialog={setOpenDeleteDialog} />
)}
</Dialog>
</>
);
};
export default DeleteDialog;

View File

@@ -0,0 +1,12 @@
import { Box } from "@mui/material";
import EditPermission from "../Actions/Edit";
import DeleteDialog from "./DeleteDialog";
const RowActions = ({ row, mutate }) => {
return (
<Box sx={{ display: "flex", gap: 1, alignItems: "center" }}>
<EditPermission row={row} mutate={mutate} rowId={row.getValue("id")} />
<DeleteDialog mutate={mutate} rowId={row.getValue("id")} />
</Box>
);
};
export default RowActions;

View File

@@ -0,0 +1,9 @@
import CreatePermission from "./Actions/Create";
const Toolbar = ({ mutate }) => {
return (
<>
<CreatePermission mutate={mutate} />
</>
);
};
export default Toolbar;

View File

@@ -0,0 +1,13 @@
import PageTitle from "@/core/components/PageTitle";
import { Stack } from "@mui/material";
import PermissionList from "./PermissionList";
const PermissionTablePage = () => {
return (
<Stack spacing={1}>
<PageTitle title={"سطح دسترسی ها"} />
<PermissionList />
</Stack>
);
};
export default PermissionTablePage;

View File

@@ -3,11 +3,11 @@ import { TextField } from "@mui/material";
import { useRef } from "react";
const PersianTextField = (props) => {
const { fieldOnChange, ...rest } = props;
const { onChange, ...rest } = props;
const inputRef = useRef(null);
const handleChange = (value) => {
fieldOnChange(value);
onChange(value);
};
usePersianInput(inputRef, handleChange);

View File

@@ -17,6 +17,7 @@ import SpeedIcon from "@mui/icons-material/Speed";
import EngineeringIcon from "@mui/icons-material/Engineering";
import AssessmentIcon from "@mui/icons-material/Assessment";
import AssignmentLateIcon from "@mui/icons-material/AssignmentLate";
import LockPersonIcon from "@mui/icons-material/LockPerson";
import LineAxisIcon from "@mui/icons-material/LineAxis";
import ScienceIcon from "@mui/icons-material/Science";
import DriveEtaIcon from "@mui/icons-material/DriveEta";
@@ -490,6 +491,14 @@ export const pageMenu = [
icon: <BiotechIcon sx={{ width: "inherit", height: "inherit" }} />,
permissions: ["azmayesh-type-management"],
},
{
id: "permissionItem",
label: "سطح دسترسی ها",
type: "page",
route: "/dashboard/permission-table",
icon: <LockPersonIcon sx={{ width: "inherit", height: "inherit" }} />,
permissions: ["show-permissions-page"],
},
{
id: "CarDetails",
label: "اطلاعات خودرو",

View File

@@ -139,3 +139,9 @@ export const THIRD_STEP_STORE = api + "/api/v3/safety_and_privacy/third_step_sto
export const EXPORT_OPERATOR_ROAD_SAFETY = api + "/api/v3/safety_and_privacy/excel_report";
export const GET_ROAD_SAFETY_PROVINCE_ACTIVITY_REPORT = api + "/api/v3/safety_and_privacy_report/country_activity";
export const GET_ROAD_SAFETY_CITY_ACTIVITY_REPORT = api + "/api/v3/safety_and_privacy_report/province_activity";
//permission table
export const GET_PERMISSION_TABLE_LIST = api + "/api/v3/permissions";
export const DELETE_PERMISSION = api + "/api/v3/permissions";
export const UPDATE_PERMISSION = api + "/api/v3/permissions";
export const CREATE_PERMISSION = api + "/api/v3/permissions";