marco.pms.web/src/pages/master/MasterTable.jsx

265 lines
8.9 KiB
JavaScript

import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { ITEMS_PER_PAGE, MANAGE_MASTER } from "../../utils/constants";
import showToast from "../../services/toastService";
const MasterTable = ({ data, columns, loading, handleModalData }) => {
const hasMasterPermission = useHasUserPermission(MANAGE_MASTER);
const selectedMaster = useSelector(
(store) => store.localVariables.selectedMaster
);
const hiddenColumns = [
"id",
"featurePermission",
"tenant",
"tenantId",
"checkLists",
"isSystem",
"isActive",
"noOfPersonsRequired",
"color",
"displayName",
"permissionIds",
"entityTypeId",
"regexExpression",
"isMandatory",
"maxFilesAllowed",
"maxSizeAllowedInMB",
"isValidationRequired",
"documentCategory",
];
const safeData = Array.isArray(data) ? data : [];
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage] = useState(ITEMS_PER_PAGE);
const sortKeys = {
"Application Role": "role",
Activity: "activityName",
"Job Role": "name",
};
const sortKey = sortKeys[selectedMaster];
const sortedData = [...safeData].sort((a, b) => {
if (!sortKey) return 0;
const aValue = a[sortKey] || "";
const bValue = b[sortKey] || "";
return aValue?.localeCompare(bValue);
});
// Pagination logic
const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentItems = sortedData.slice(indexOfFirstItem, indexOfLastItem);
useEffect(() => {
setCurrentPage(1);
}, [safeData]);
const paginate = (pageNumber) => setCurrentPage(pageNumber);
const totalPages = Math.ceil(safeData.length / itemsPerPage);
const updatedColumns = columns
.filter((col) => !hiddenColumns.includes(col.key))
.map((col) => ({
...col,
label:
col.key === "role" || col.key === "activityName" || col.key === "name"
? "Name"
: col.label,
}));
const handleSystemDefined = (message) => {
if (message) {
showToast(
`The system-defined item ${selectedMaster} cannot be ${message}.`
);
}
};
return (
<div className="table-responsive">
{loading ? (
<p>Loading...</p>
) : (
<table className="datatables-users table border-top dataTable no-footer dtr-column w-100">
<thead className="shadow-sm">
<tr>
<th></th>
<th className="text-start">
{" "}
{selectedMaster === "Activity" ? "Activity" : "Name"}
</th>
<th className="text-start d-none d-md-table-cell">
{" "}
{selectedMaster === "Activity"
? "Unit"
: selectedMaster === "Document Type"
? "Content Type"
: "Description"}
</th>
<th className={` ${!hasMasterPermission && "d-none"}`}>
Actions
</th>
</tr>
</thead>
<tbody>
{currentItems.length > 0 ? (
currentItems.map((item, index) => (
<tr key={index} >
<td style={{ width: "20px" }} className="py-3">
<i className="bx bx-right-arrow-alt"></i>
</td>
{updatedColumns.map((col) => (
<td className={`text-start mx-2 py-3 ${col.key === "description" && "d-none d-md-table-cell"}`} key={col.key} >
{col.key === "description" ? (
item[col.key] !== undefined &&
item[col.key] !== null ? (
item[col.key].length > 80 ? (
<>{item[col.key].slice(0, 80)}...</>
) : (
item[col.key]
)
) : (
" --- "
)
) : item[col.key] !== undefined &&
item[col.key] !== null ? (
item[col.key]
) : (
" --- "
)}
</td>
))}
<td className={!hasMasterPermission ? "d-none" : "py-3"}>
{(selectedMaster === "Application Role" ||
selectedMaster === "Work Category") &&
item?.isSystem ? (
<>
<button
aria-label="Modify"
type="button"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => handleSystemDefined("updated")}
>
<i className="bx bxs-edit me-2 text-primary"></i>
</button>
<button
aria-label="Delete"
type="button"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => handleSystemDefined("deleted")}
>
<i className="bx bx-trash me-1 text-danger"></i>
</button>
</>
) : (
<>
{selectedMaster === "Services" && (
<button
aria-label="View"
type="button"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() =>
handleModalData(`Manage-${selectedMaster}`, item, selectedMaster)
}
data-bs-toggle="modal"
data-bs-target="#servicesActivityTreeModal"
>
<i className="bx bx-show me-2 text-primary"></i>
</button>
)}
<button
aria-label="Modify"
type="button"
data-bs-toggle="modal"
data-bs-target="#master-modal"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() =>
handleModalData(
`Edit-${selectedMaster}`,
item,
selectedMaster
)
}
>
<i className="bx bxs-edit me-2 text-primary"></i>
</button>
<button
aria-label="Delete"
type="button"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() =>
handleModalData("delete", item, selectedMaster)
}
>
<i className="bx bx-trash me-1 text-danger"></i>
</button>
</>
)}
</td>
</tr>
))
) : (
<tr>
<td colSpan={updatedColumns.length + 4}>No results found.</td>
</tr>
)}
</tbody>
</table>
)}
{/* Pagination */}
{!loading && safeData.length > 20 && (
<nav aria-label="Page ">
<ul className="pagination pagination-sm justify-content-end mt-3">
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
<button
className="page-link btn-xs"
onClick={() => paginate(currentPage - 1)}
>
&laquo;
</button>
</li>
{[...Array(totalPages)].map((_, index) => (
<li
key={index}
className={`page-item ${
currentPage === index + 1 ? "active" : ""
}`}
>
<button
className="page-link"
onClick={() => paginate(index + 1)}
>
{index + 1}
</button>
</li>
))}
<li
className={`page-item ${
currentPage === totalPages ? "disabled" : ""
}`}
>
<button
className="page-link"
onClick={() => paginate(currentPage + 1)}
>
&raquo;
</button>
</li>
</ul>
</nav>
)}
</div>
);
};
export default MasterTable;