Files
sgeUpdated/sge-frontend/src/views/RoleManagement.js
Khaled Elagamy 85f1847070 Add 'sge-frontend/' from commit '5fa787e054b25ac53edc7ff0275ea7960a709401'
git-subtree-dir: sge-frontend
git-subtree-mainline: 876c278ac4
git-subtree-split: 5fa787e054
2025-08-04 00:27:23 +03:00

442 lines
13 KiB
JavaScript

import React, { useState, useEffect, memo } from "react";
import { useSelector, useDispatch } from "react-redux";
import ReactPaginate from "react-paginate";
import { ChevronDown, MoreVertical, Plus, Trash } from "react-feather";
import DataTable from "react-data-table-component";
import {
Card,
CardHeader,
CardTitle,
Input,
Label,
Row,
Col,
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
} from "reactstrap";
import { Edit } from "@mui/icons-material";
import { useSnackbar } from "notistack";
import { default as SweetAlert } from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import Select from "react-select";
import makeAnimated from "react-select/animated";
import {
getRolesWithPaginate,
deleteRoles,
addRoles,
updateRoles,
} from "../redux/actions/roles";
import { getUserPermissions, getAllPermissions } from "../redux/actions/permissions";
import { useTranslation } from "react-i18next";
import { permissionCheck } from "../components/permission-check";
import { customFilterForSelect } from "../utility/Utils";
const Swal = withReactContent(SweetAlert);
const animatedComponents = makeAnimated();
const RoleManagement = () => {
const { t } = useTranslation();
const initialColumns = [
{
name: t("Roles.roleName"),
selector: (row) => row.tag,
sortable: true,
maxWidth: "250px",
},
{
name: t("Roles.permissions"),
selector: (row) => row.permissions,
sortable: true,
minWidth: "250px",
cell: (row) => (
<span>{row.permissions?.map((perm) => perm?.description + " │ ")}</span>
),
},
{
name: t("Actions"),
allowOverflow: false,
maxWidth: "100px",
cell: (row) => {
return (
<div className="d-flex">
<UncontrolledDropdown>
<DropdownToggle className="pl-1" tag="span">
<MoreVertical size={15} />
</DropdownToggle>
<DropdownMenu container={"body"} left={"true"}>
{permissionCheck("role_update") && (
<DropdownItem
tag="a"
className="w-100"
onClick={() => handleEditRole(row)}
>
<Edit size={15} />
<span className="align-middle ml-50">
{t("Cruds.edit")}
</span>
</DropdownItem>
)}
{permissionCheck("role_delete") && (
<DropdownItem
tag="a"
className="w-100"
onClick={() => handleDeleteRole(row)}
>
<Trash size={15} />
<span className="align-middle ml-50">
{t("Cruds.delete")}
</span>
</DropdownItem>
)}
</DropdownMenu>
</UncontrolledDropdown>
</div>
);
},
},
];
useEffect(() => {
if (!(permissionCheck("role_delete") || permissionCheck("role_update"))) {
const updatedColumns = initialColumns.filter(
(column) => column.name !== ("Aksiyonlar" || "Actions")
);
setServerSideColumns(updatedColumns);
}
}, []);
const dispatch = useDispatch();
const { enqueueSnackbar } = useSnackbar();
const [currentPage, setCurrentPage] = useState(1);
const [rowsPerPage, setRowsPerPage] = useState(5);
const [loading, setLoading] = useState(false);
const [serverSideColumns, setServerSideColumns] = useState(initialColumns);
const permissionsStore = useSelector((state) => state.permissionsReducer);
const rolesStore = useSelector(
(state) => state.rolesReducer.rolesWithPaginate
);
const [permissionsOptions, setPermissionsOptions] = useState([]);
const [roles, setRoles] = useState([]);
const [showAddRoleModal, setShowAddRoleModal] = useState(false);
const [editingRoleData, setEditingRoleData] = useState(null);
useEffect(() => {
dispatch(
getRolesWithPaginate({
currentPage,
rowsPerPage,
})
);
}, [currentPage, rowsPerPage]);
useEffect(() => {
const roleTag = localStorage.getItem("roleTag");
if (roleTag === "SUPER_ADMIN") {
dispatch(getAllPermissions());
} else {
dispatch(getUserPermissions());
}
}, []);
useEffect(() => {
if (rolesStore?.content) {
setRoles(rolesStore?.content);
}
}, [rolesStore]);
useEffect(() => {
setPermissionsOptions(
permissionsStore?.permissions?.map((permission) => {
return {
value: permission?.id,
label: permission?.description,
};
})
);
}, [permissionsStore]);
const handlePagination = (page) => {
setCurrentPage(page.selected + 1);
setRoles(rolesStore?.content);
};
const handlePerPage = (e) => {
setCurrentPage(1);
setRowsPerPage(parseInt(e.target.value));
setRoles(rolesStore?.content);
};
const CustomPagination = () => {
const count = Number(
(rolesStore?.pageInfo?.totalElements / rowsPerPage).toFixed(1)
);
return (
<ReactPaginate
previousLabel={""}
nextLabel={""}
breakLabel="..."
pageCount={count || 1}
marginPagesDisplayed={2}
pageRangeDisplayed={2}
activeClassName="active"
forcePage={currentPage !== 0 ? currentPage - 1 : 0}
onPageChange={(page) => handlePagination(page)}
pageClassName={"page-item"}
nextLinkClassName={"page-link"}
nextClassName={"page-item next"}
previousClassName={"page-item prev"}
previousLinkClassName={"page-link"}
pageLinkClassName={"page-link"}
breakClassName="page-item"
breakLinkClassName="page-link"
containerClassName={
"pagination react-paginate separated-pagination pagination-sm justify-content-end pr-1 mt-1"
}
/>
);
};
const onAddRoleButtonPressed = () => {
setEditingRoleData({ id: null });
setShowAddRoleModal(true);
};
const onAddRoleModalButtonPressed = () => {
const arr = [];
const r = editingRoleData?.permissions?.forEach((s) => {
if (s?.value) {
arr.push('"' + s?.value + '"');
} else {
arr.push('"' + s + '"');
}
});
setLoading(true);
if (
rolesStore.roles?.some(
(c) => c.tag === editingRoleData.tag && c.id != editingRoleData.id
)
) {
enqueueSnackbar(t("Roles.existingRole"), {
variant: "error",
preventDuplicate: true,
});
setLoading(false);
return;
}
if (!editingRoleData.id) {
const newRoleData = {
tag: editingRoleData.tag?.toUpperCase(),
permissions: arr,
id: editingRoleData.id,
};
dispatch(addRoles(newRoleData))
.then(() => {
setLoading(false);
setShowAddRoleModal(false);
enqueueSnackbar(t("Warnings.addedSuccessfully"), {
variant: "success",
preventDuplicate: true,
});
})
.catch(() => {
setLoading(false);
setShowAddRoleModal(false);
enqueueSnackbar(t("Warnings.addedFail"), {
variant: "error",
preventDuplicate: true,
});
});
} else {
const newRoleData = {
id: editingRoleData.id,
tag: editingRoleData.tag?.toUpperCase(),
permissions: arr,
};
dispatch(updateRoles(newRoleData))
.then(() => {
enqueueSnackbar(t("Warnings.updatedSuccessfully"), {
variant: "success",
});
setLoading(false);
setEditingRoleData(null);
setShowAddRoleModal(false);
if (!editingRoleData.value) setEditingRoleData(null);
})
.catch(() => {
enqueueSnackbar(`${newRoleData.tag}, ${t("Warnings.updatedFail")}`, {
variant: "error",
});
setLoading(false);
});
}
};
const renderRoleModal = () => {
return (
<Modal
isOpen={showAddRoleModal}
toggle={() => setShowAddRoleModal(!showAddRoleModal)}
className="modal-dialog-centered"
>
<ModalHeader toggle={() => setShowAddRoleModal(!showAddRoleModal)}>
{editingRoleData?.id ? editingRoleData.tag : t("Roles.addRole")}
</ModalHeader>
<ModalBody>
<div className="mb-2">
<Label className="form-label" for="role-name">
{t("Roles.roleName")}:
</Label>
<Input
type="text"
id="role-name"
placeholder=""
value={editingRoleData?.tag || ""}
onChange={(e) =>
setEditingRoleData({
...editingRoleData,
tag: e.target.value,
})
}
/>
</div>
<div className="mb-2">
<Label className="form-label" for="permissions-select">
{t("Roles.permissions")}:
</Label>
<Select
id="permissions-select"
isClearable={false}
closeMenuOnSelect={false}
components={animatedComponents}
isMulti
options={permissionsOptions}
className="react-select"
placeholder=""
filterOption={customFilterForSelect}
defaultValue={editingRoleData?.permissions}
onChange={(value) => {
setEditingRoleData({
...editingRoleData,
permissions: value,
});
}}
/>
</div>
</ModalBody>
<ModalFooter>
<Button
disabled={!(editingRoleData?.permissions && editingRoleData?.tag)}
color="primary"
onClick={onAddRoleModalButtonPressed}
>
{loading
? t("Cruds.saving")
: !editingRoleData?.id
? t("Cruds.save")
: t("Cruds.update")}
</Button>
</ModalFooter>
</Modal>
);
};
const handleDeleteRole = async (selectedRole) => {
const result = await Swal.fire({
title: `${selectedRole.tag}, ${t("Warnings.sureForDelete")}`,
text: t("Warnings.notUndone"),
icon: "warning",
showCancelButton: true,
confirmButtonText: t("Cruds.delete"),
cancelButtonText: t("Cruds.cancel"),
customClass: {
confirmButton: "btn btn-primary",
cancelButton: "btn btn-danger ml-1",
},
buttonsStyling: false,
});
if (result.value !== null && result.value === true) {
dispatch(deleteRoles(selectedRole.id));
}
};
const handleEditRole = (selectedRole) => {
setShowAddRoleModal(true);
const selectedRolePermissions = selectedRole.permissions?.map((x) => ({
value: x.id,
label: x.description,
}));
setEditingRoleData({
...selectedRole,
permissions: selectedRolePermissions,
});
};
return (
<div style={{ marginTop: "2%" }}>
<Card>
<CardHeader className="border-bottom">
<CardTitle tag="h4">{t("Roles.roles")}</CardTitle>
{permissionCheck("role_create") && (
<Button
className="ml-2"
color="primary"
onClick={onAddRoleButtonPressed}
>
<Plus size={15} />
<span className="align-middle ml-50">{t("Roles.addRole")}</span>
</Button>
)}
</CardHeader>
<Row className="mx-0 mt-1 mb-50">
<Col sm="6" md="2">
<div className="d-flex align-items-center">
<Label for="sort-select">{t("Show")}</Label>
<Input
className="ml-1 dataTable-select"
type="select"
id="sort-select"
value={rowsPerPage}
onChange={(e) => handlePerPage(e)}
>
<option value={5}>5</option>
<option value={10}>10</option>
<option value={25}>25</option>
<option value={50}>50</option>
<option value={75}>75</option>
<option value={100}>100</option>
</Input>
</div>
</Col>
</Row>
<DataTable
noHeader
pagination
paginationServer
className="react-dataTable"
columns={serverSideColumns}
sortIcon={<ChevronDown size={10} />}
paginationComponent={CustomPagination}
data={[...roles]}
noDataComponent={<p className="p-2">{t("Warnings.notFound")}</p>}
/>
</Card>
{renderRoleModal()}
</div>
);
};
export default memo(RoleManagement);