forked from BLC/sgeUpdated
git-subtree-dir: sge-frontend git-subtree-mainline:876c278ac4git-subtree-split:5fa787e054
442 lines
13 KiB
JavaScript
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);
|