Compare commits
2 Commits
018f132501
...
523d6baea6
| Author | SHA1 | Date | |
|---|---|---|---|
| 523d6baea6 | |||
| 9e47f10440 |
@ -13,15 +13,9 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { useProjectContext } from "../../pages/project/ProjectPage";
|
import { useProjectContext } from "../../pages/project/ProjectPage";
|
||||||
import usePagination from "../../hooks/usePagination";
|
import usePagination from "../../hooks/usePagination";
|
||||||
|
import Pagination from "../common/Pagination";
|
||||||
|
|
||||||
const ProjectListView = ({
|
const ProjectListView = ({ data, currentPage, totalPages, paginate }) => {
|
||||||
currentItems,
|
|
||||||
selectedStatuses,
|
|
||||||
handleStatusChange,
|
|
||||||
setCurrentPage,
|
|
||||||
totalPages,
|
|
||||||
isLoading,
|
|
||||||
}) => {
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setMangeProject } = useProjectContext();
|
const { setMangeProject } = useProjectContext();
|
||||||
@ -132,152 +126,103 @@ const ProjectListView = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card page-min-h py-4 px-6 shadow-sm">
|
<div className="card page-min-h py-4 px-6 shadow-sm">
|
||||||
|
<div className="table-responsive text-nowrap page-min-h">
|
||||||
<div
|
<table className="table table-hover align-middle m-0">
|
||||||
className="table-responsive text-nowrap page-min-h"
|
<thead className="border-bottom ">
|
||||||
>
|
<tr>
|
||||||
<table className="table table-hover align-middle m-0">
|
|
||||||
<thead className="border-bottom ">
|
|
||||||
<tr>
|
|
||||||
{projectColumns.map((col) => (
|
|
||||||
<th key={col.key} colSpan={col.colSpan} className={`${col.className} table_header_border`}>
|
|
||||||
{col.label}
|
|
||||||
</th>
|
|
||||||
))}
|
|
||||||
<th className="text-center py-3">Action</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{currentItems?.map((project) => (
|
|
||||||
<tr key={project.id}>
|
|
||||||
{projectColumns.map((col) => (
|
{projectColumns.map((col) => (
|
||||||
<td
|
<th
|
||||||
key={col.key}
|
key={col.key}
|
||||||
colSpan={col.colSpan}
|
colSpan={col.colSpan}
|
||||||
className={`${col.className} py-5`}
|
className={`${col.className} table_header_border`}
|
||||||
style={{ paddingTop: "20px", paddingBottom: "20px" }}
|
|
||||||
>
|
>
|
||||||
{col.getValue
|
{col.label}
|
||||||
? col.getValue(project)
|
</th>
|
||||||
: project[col.key] || "N/A"}
|
|
||||||
</td>
|
|
||||||
))}
|
))}
|
||||||
<td
|
<th className="text-center py-3">Action</th>
|
||||||
className={`mx-2 ${
|
|
||||||
canManageProject ? "d-sm-table-cell" : "d-none"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="dropdown z-2">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn-icon btn-text-secondary rounded-pill dropdown-toggle hide-arrow p-0"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="bx bx-dots-vertical-rounded bx-sm text-muted"
|
|
||||||
data-bs-toggle="tooltip"
|
|
||||||
data-bs-offset="0,8"
|
|
||||||
data-bs-placement="top"
|
|
||||||
data-bs-custom-class="tooltip-dark"
|
|
||||||
title="More Action"
|
|
||||||
></i>
|
|
||||||
</button>
|
|
||||||
<ul className="dropdown-menu dropdown-menu-end">
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
aria-label="click to View details"
|
|
||||||
className="dropdown-item cursor-pointer"
|
|
||||||
>
|
|
||||||
<i className="bx bx-detail me-2"></i>
|
|
||||||
<span className="align-left">View details</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
className="dropdown-item cursor-pointer"
|
|
||||||
onClick={() =>
|
|
||||||
setMangeProject({
|
|
||||||
isOpen: true,
|
|
||||||
Project: project.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<i className="bx bx-pencil me-2"></i>
|
|
||||||
<span className="align-left">Modify</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li onClick={() => handleViewActivities(project.id)}>
|
|
||||||
<a className="dropdown-item cursor-pointer">
|
|
||||||
<i className="bx bx-task me-2"></i>
|
|
||||||
<span className="align-left">Activities</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</table>
|
{data?.map((project) => (
|
||||||
|
<tr key={project.id}>
|
||||||
|
{projectColumns.map((col) => (
|
||||||
|
<td
|
||||||
|
key={col.key}
|
||||||
|
colSpan={col.colSpan}
|
||||||
|
className={`${col.className} py-5`}
|
||||||
|
style={{ paddingTop: "20px", paddingBottom: "20px" }}
|
||||||
|
>
|
||||||
|
{col.getValue
|
||||||
|
? col.getValue(project)
|
||||||
|
: project[col.key] || "N/A"}
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
<td
|
||||||
|
className={`mx-2 ${
|
||||||
|
canManageProject ? "d-sm-table-cell" : "d-none"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="dropdown z-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-icon btn-text-secondary rounded-pill dropdown-toggle hide-arrow p-0"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="bx bx-dots-vertical-rounded bx-sm text-muted"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-offset="0,8"
|
||||||
|
data-bs-placement="top"
|
||||||
|
data-bs-custom-class="tooltip-dark"
|
||||||
|
title="More Action"
|
||||||
|
></i>
|
||||||
|
</button>
|
||||||
|
<ul className="dropdown-menu dropdown-menu-end">
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-label="click to View details"
|
||||||
|
className="dropdown-item cursor-pointer"
|
||||||
|
>
|
||||||
|
<i className="bx bx-detail me-2"></i>
|
||||||
|
<span className="align-left">View details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
className="dropdown-item cursor-pointer"
|
||||||
|
onClick={() =>
|
||||||
|
setMangeProject({
|
||||||
|
isOpen: true,
|
||||||
|
Project: project.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<i className="bx bx-pencil me-2"></i>
|
||||||
|
<span className="align-left">Modify</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li onClick={() => handleViewActivities(project.id)}>
|
||||||
|
<a className="dropdown-item cursor-pointer">
|
||||||
|
<i className="bx bx-task me-2"></i>
|
||||||
|
<span className="align-left">Activities</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isLoading && (
|
<Pagination
|
||||||
<div className="py-4">
|
currentPage={currentPage}
|
||||||
{" "}
|
totalPages={totalPages}
|
||||||
{isLoading && <p className="text-center">Loading...</p>}
|
paginate={paginate}
|
||||||
{!isLoading && filteredProjects.length === 0 && (
|
/>
|
||||||
<p className="text-center text-muted">No projects found.</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!isLoading && currentItems.length === 0 && (
|
|
||||||
<div className="py-6">
|
|
||||||
<p className="text-center text-muted">No projects found.</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{!isLoading && totalPages > 1 && (
|
|
||||||
<nav>
|
|
||||||
<ul className="pagination pagination-sm justify-content-end py-2">
|
|
||||||
<li className={`page-item ${currentPage === 1 && "disabled"}`}>
|
|
||||||
<button
|
|
||||||
className="page-link"
|
|
||||||
onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
|
|
||||||
>
|
|
||||||
«
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{[...Array(totalPages)].map((_, i) => (
|
|
||||||
<li
|
|
||||||
key={i}
|
|
||||||
className={`page-item ${currentPage === i + 1 && "active"}`}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="page-link"
|
|
||||||
onClick={() => setCurrentPage(i + 1)}
|
|
||||||
>
|
|
||||||
{i + 1}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
<li
|
|
||||||
className={`page-item ${
|
|
||||||
currentPage === totalPages && "disabled"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="page-link"
|
|
||||||
onClick={() =>
|
|
||||||
setCurrentPage((p) => Math.min(totalPages, p + 1))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
»
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 5px;
|
padding: 4px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@ -101,7 +101,7 @@ const SelectMultiple = ({
|
|||||||
value={searchText}
|
value={searchText}
|
||||||
onChange={(e) => setSearchText(e.target.value)}
|
onChange={(e) => setSearchText(e.target.value)}
|
||||||
className="multi-select-dropdown-search-input"
|
className="multi-select-dropdown-search-input"
|
||||||
style={{ width: "100%", padding: 4 }}
|
style={{ width: "100%", }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ const SelectMultiple = ({
|
|||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={val}
|
key={val}
|
||||||
className="badge bg-label-primary mx-1 py-2 mb-1"
|
className="badge bg-label-primary mx-1 py-2"
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -11,7 +11,12 @@ import { ITEMS_PER_PAGE, PROJECT_STATUS } from "../../utils/constants";
|
|||||||
import usePagination from "../../hooks/usePagination";
|
import usePagination from "../../hooks/usePagination";
|
||||||
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
||||||
|
|
||||||
const ProjectsDisplay = ({ listView, searchTerm, selectedStatuses, handleStatusChange }) => {
|
const ProjectsDisplay = ({
|
||||||
|
listView,
|
||||||
|
searchTerm,
|
||||||
|
selectedStatuses,
|
||||||
|
handleStatusChange,
|
||||||
|
}) => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const {
|
const {
|
||||||
manageProject,
|
manageProject,
|
||||||
@ -22,15 +27,12 @@ const ProjectsDisplay = ({ listView, searchTerm, selectedStatuses, handleStatusC
|
|||||||
|
|
||||||
const [projectList, setProjectList] = useState([]);
|
const [projectList, setProjectList] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
const { data, isLoading, isError, error } = useProjects(ITEMS_PER_PAGE, 1);
|
const { data, isLoading, isError, error } = useProjects(ITEMS_PER_PAGE, 1);
|
||||||
|
|
||||||
const filteredProjects =
|
const filteredProjects =
|
||||||
data?.data?.filter((project) => {
|
data?.data?.filter((project) => {
|
||||||
const statusId =
|
const statusId =
|
||||||
project.projectStatusId ??
|
project.projectStatusId ?? project?.status?.id ?? project?.statusId;
|
||||||
project?.status?.id ??
|
|
||||||
project?.statusId;
|
|
||||||
|
|
||||||
const matchesStatus = selectedStatuses.includes(statusId);
|
const matchesStatus = selectedStatuses.includes(statusId);
|
||||||
|
|
||||||
@ -41,15 +43,12 @@ const ProjectsDisplay = ({ listView, searchTerm, selectedStatuses, handleStatusC
|
|||||||
return matchesStatus && matchesSearch;
|
return matchesStatus && matchesSearch;
|
||||||
}) ?? [];
|
}) ?? [];
|
||||||
|
|
||||||
|
|
||||||
const paginate = (page) => {
|
const paginate = (page) => {
|
||||||
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const sortingProject = (projects) => {
|
const sortingProject = (projects) => {
|
||||||
if (!isLoading && Array.isArray(projects)) {
|
if (!isLoading && Array.isArray(projects)) {
|
||||||
const grouped = {};
|
const grouped = {};
|
||||||
@ -97,17 +96,15 @@ const ProjectsDisplay = ({ listView, searchTerm, selectedStatuses, handleStatusC
|
|||||||
<p>{error.message}</p>
|
<p>{error.message}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{listView ? (
|
{listView ? (
|
||||||
<ProjectListView
|
<ProjectListView
|
||||||
currentItems={currentItems}
|
data={projectList}
|
||||||
selectedStatuses={selectedStatuses}
|
currentPage={currentPage}
|
||||||
handleStatusChange={handleStatusChange}
|
totalPages={data?.totalPages}
|
||||||
setCurrentPage={setCurrentPage}
|
paginate={paginate}
|
||||||
totalPages={totalPages}
|
|
||||||
isLoading={isLoading}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ProjectCardView
|
<ProjectCardView
|
||||||
@ -118,7 +115,6 @@ const ProjectsDisplay = ({ listView, searchTerm, selectedStatuses, handleStatusC
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Project Manage Update or Create */}
|
|
||||||
{manageProject?.isOpen && (
|
{manageProject?.isOpen && (
|
||||||
<GlobalModel
|
<GlobalModel
|
||||||
size="md"
|
size="md"
|
||||||
@ -131,7 +127,6 @@ const ProjectsDisplay = ({ listView, searchTerm, selectedStatuses, handleStatusC
|
|||||||
/>
|
/>
|
||||||
</GlobalModel>
|
</GlobalModel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user