forked from Abdulbari/sgeUpdated
git-subtree-dir: sge-frontend git-subtree-mainline:876c278ac4git-subtree-split:5fa787e054
283 lines
8.5 KiB
JavaScript
283 lines
8.5 KiB
JavaScript
import React, { useEffect, useState } from "react";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { ChevronDown, Trash } from "react-feather";
|
|
import {
|
|
Card,
|
|
CardHeader,
|
|
CardTitle,
|
|
Input,
|
|
Label,
|
|
Row,
|
|
Col,
|
|
} from "reactstrap";
|
|
import DataTable from "react-data-table-component";
|
|
import ReactPaginate from "react-paginate";
|
|
import { useTranslation } from "react-i18next";
|
|
import {
|
|
getAllNotifications,
|
|
setNotificationRead,
|
|
notificationRemove,
|
|
} from "../redux/actions/notifications";
|
|
import { default as SweetAlert } from "sweetalert2";
|
|
import withReactContent from "sweetalert2-react-content";
|
|
|
|
const Swal = withReactContent(SweetAlert);
|
|
|
|
const Notifications = () => {
|
|
const { t } = useTranslation();
|
|
|
|
const conditionalRowStyles = [
|
|
{
|
|
when: (row) => row.read === false,
|
|
style: {
|
|
backgroundColor: "#028a4a1a",
|
|
},
|
|
},
|
|
];
|
|
|
|
const serverSideColumns = [
|
|
{
|
|
name: t("Notifications.title"),
|
|
selector: (row) => row.title,
|
|
sortable: true,
|
|
maxWidth: "500px",
|
|
},
|
|
{
|
|
name: t("Notifications.notificationType"),
|
|
selector: (row) => row.notificationType,
|
|
sortable: true,
|
|
maxWidth: "500px",
|
|
},
|
|
{
|
|
name: t("Notifications.content"),
|
|
selector: (row) => row.message,
|
|
sortable: true,
|
|
maxWidth: "500px",
|
|
},
|
|
{
|
|
name: t("Time"),
|
|
selector: (row) => row.createdDateTime,
|
|
sortable: true,
|
|
width: "250px",
|
|
cell: (row) => (
|
|
<span>{new Date(row.createdDateTime).toLocaleString("tr-TR")}</span>
|
|
),
|
|
},
|
|
{
|
|
name: t("Cruds.delete"),
|
|
allowOverflow: false,
|
|
maxWidth: "100px",
|
|
cell: (row) => {
|
|
return (
|
|
<div className="d-flex">
|
|
<a onClick={() => handleDeleteNotification(row)}>
|
|
<Trash size={15} />
|
|
</a>
|
|
</div>
|
|
);
|
|
},
|
|
},
|
|
];
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [rowsPerPage, setRowsPerPage] = useState(5);
|
|
const [searchValue, setSearchValue] = useState("");
|
|
|
|
const notificationsStore = useSelector((state) => state.notifications);
|
|
const [notifications, setNotifications] = useState([]);
|
|
|
|
useEffect(() => {
|
|
dispatch(getAllNotifications({ currentPage, rowsPerPage }));
|
|
}, [currentPage, rowsPerPage]);
|
|
|
|
useEffect(() => {
|
|
if (notificationsStore.notifications?.content) {
|
|
setNotifications(notificationsStore.notifications?.content);
|
|
}
|
|
}, [
|
|
notificationsStore.notifications?.content?.length,
|
|
notificationsStore.notifications,
|
|
]);
|
|
|
|
const handleFilter = (e) => {
|
|
setSearchValue(e.target.value);
|
|
|
|
if (e.target.value !== "") {
|
|
setCurrentPage(1);
|
|
setRowsPerPage(notificationsStore.notifications?.pageInfo?.totalElements);
|
|
setNotifications(
|
|
notificationsStore.notifications?.content.filter((notification) =>
|
|
notification.title
|
|
.toLowerCase()
|
|
.includes(e.target.value.toLowerCase())
|
|
)
|
|
);
|
|
} else {
|
|
setCurrentPage(1);
|
|
setRowsPerPage(5);
|
|
setNotifications(notificationsStore.notifications?.content);
|
|
}
|
|
};
|
|
|
|
const handlePagination = (page) => {
|
|
setCurrentPage(page.selected + 1);
|
|
setNotifications(notificationsStore.notifications?.content);
|
|
};
|
|
|
|
const handlePerPage = (e) => {
|
|
setCurrentPage(1);
|
|
setRowsPerPage(parseInt(e.target.value));
|
|
setNotifications(notificationsStore.notifications?.content);
|
|
};
|
|
|
|
const CustomPagination = () => {
|
|
const count = Number(
|
|
(
|
|
notificationsStore.notifications?.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 handleDeleteNotification = async (selectedNotification) => {
|
|
const result = await Swal.fire({
|
|
title: `${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) {
|
|
let selectedId = selectedNotification.id;
|
|
dispatch(notificationRemove({ selectedId, currentPage, rowsPerPage }));
|
|
}
|
|
//when notifications size is zero in current page and current page is not 1, change current page to previous page
|
|
if (notifications?.length == 1 && currentPage != 1) {
|
|
const newCurrentPage = currentPage - 1;
|
|
setCurrentPage(newCurrentPage);
|
|
dispatch(getAllNotifications({ currentPage, rowsPerPage }));
|
|
}
|
|
};
|
|
|
|
const ExpandableTable = ({ data }) => {
|
|
if (data.read === false) {
|
|
dispatch(setNotificationRead(data.id));
|
|
dispatch(getAllNotifications({ currentPage, rowsPerPage }));
|
|
}
|
|
return (
|
|
<div className="expandable-content p-2">
|
|
<p className="font-weight-bold">
|
|
{data?.title} / {data?.notificationType}
|
|
</p>
|
|
<p className="font-small-3 mt-2">{data.message}</p>
|
|
</div>
|
|
);
|
|
};
|
|
let listOfNumber = [5, 10, 25, 50, 75, 100];
|
|
return (
|
|
<div style={{ marginTop: "2%" }}>
|
|
<Card>
|
|
<CardHeader className="border-bottom">
|
|
<CardTitle tag="h4">{t("Notifications.notifications")}</CardTitle>
|
|
</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>
|
|
{!listOfNumber.includes(rowsPerPage) && (
|
|
<option value={rowsPerPage}>{rowsPerPage}</option>
|
|
)}
|
|
</Input>
|
|
</div>
|
|
</Col>
|
|
<Col
|
|
className="d-flex align-items-center justify-content-end mt-sm-0 mt-1 ml-md-auto"
|
|
sm="6"
|
|
md="3"
|
|
>
|
|
<Label className="mr-1" for="search-input">
|
|
{t("Filter")}
|
|
</Label>
|
|
<Input
|
|
className="dataTable-filter"
|
|
type="text"
|
|
bsSize="sm"
|
|
id="search-input"
|
|
value={searchValue}
|
|
onChange={handleFilter}
|
|
placeholder=""
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<DataTable
|
|
noHeader
|
|
pagination
|
|
paginationServer
|
|
className="react-dataTable"
|
|
columns={serverSideColumns}
|
|
conditionalRowStyles={conditionalRowStyles}
|
|
expandableRows
|
|
expandOnRowClicked
|
|
expandableRowsComponent={ExpandableTable}
|
|
sortIcon={<ChevronDown size={10} />}
|
|
paginationComponent={CustomPagination}
|
|
data={[...notifications]}
|
|
noDataComponent={
|
|
<p className="p-2">
|
|
{t("Notifications.notification")}
|
|
{t("Warnings.notFound")}
|
|
</p>
|
|
}
|
|
/>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Notifications;
|