Creating a list view for Services.
This commit is contained in:
parent
482b5a1680
commit
6dde240926
@ -26,13 +26,6 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
|
||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||
const { setMangeProject, setManageServiceProject } = useProjectContext();
|
||||
|
||||
const getProgress = (planned, completed) => {
|
||||
return (completed * 100) / planned + "%";
|
||||
};
|
||||
const getProgressInNumber = (planned, completed) => {
|
||||
return (completed * 100) / planned;
|
||||
};
|
||||
|
||||
const handleClose = () => setShowModal(false);
|
||||
|
||||
const handleViewProject = () => {
|
||||
@ -43,10 +36,6 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
|
||||
navigate(`/service-projects/${project.id}`);
|
||||
}
|
||||
};
|
||||
const handleViewActivities = () => {
|
||||
dispatch(setProjectId(project.id));
|
||||
navigate(`/activities/records?project=${project.id}`);
|
||||
};
|
||||
const handleManage = () => {
|
||||
if (isCore) {
|
||||
setMangeProject({
|
||||
@ -68,6 +57,8 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
|
||||
DeleteProject(projectId, false);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfirmModal
|
||||
@ -138,14 +129,6 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
|
||||
<span className="align-left">Modify</span>
|
||||
</a>
|
||||
</li>
|
||||
{isCore && (
|
||||
<li onClick={handleViewActivities}>
|
||||
<a className="dropdown-item">
|
||||
<i className="bx bx-task me-2"></i>
|
||||
<span className="align-left">Activities</span>
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
{!isCore && (
|
||||
<li
|
||||
onClick={() =>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import React, { useState } from "react";
|
||||
import { MANAGE_PROJECT,PROJECT_STATUS } from "../../../utils/constants";
|
||||
import { MANAGE_PROJECT, PROJECT_STATUS } from "../../../utils/constants";
|
||||
import { useProjects } from "../../../hooks/useProjects";
|
||||
import { formatNumber,formatUTCToLocalTime } from "../../../utils/dateUtils";
|
||||
import { formatNumber, formatUTCToLocalTime } from "../../../utils/dateUtils";
|
||||
import ProgressBar from "../../common/ProgressBar";
|
||||
import { getProjectStatusColor,getProjectStatusName } from "../../../utils/projectStatus";
|
||||
import { getProjectStatusColor, getProjectStatusName } from "../../../utils/projectStatus";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { setProjectId } from "../../../slices/localVariablesSlice";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@ -12,216 +12,169 @@ import { useProjectContext } from "../../../pages/project/ProjectPage";
|
||||
import usePagination from "../../../hooks/usePagination";
|
||||
import Pagination from "../../common/Pagination";
|
||||
|
||||
const ServiceProjectList = ({ data, currentPage, totalPages, paginate }) => {
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const { setMangeProject } = useProjectContext();
|
||||
// const { data, isLoading, isError, error } = useProjects();
|
||||
const ServiceProjectList = ({ data, currentPage, totalPages, paginate, isCore = true }) => {
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const { setMangeProject, setManageServiceProject } = useProjectContext();
|
||||
const handleClose = () => setShowModal(false);
|
||||
|
||||
// check Permissions
|
||||
const canManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||
// check Permissions
|
||||
const canManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||
|
||||
const projectColumns = [
|
||||
{
|
||||
key: "projectName",
|
||||
label: "Project Name",
|
||||
className: "text-start py-3",
|
||||
getValue: (p) => (
|
||||
<div
|
||||
className="text-primary cursor-pointer fw-bold py-3"
|
||||
onClick={() => {
|
||||
const projectColumns = [
|
||||
{
|
||||
key: "projectName",
|
||||
label: "Project Name",
|
||||
className: "text-start py-3",
|
||||
getValue: (p) => (
|
||||
<div
|
||||
className="text-primary cursor-pointer fw-bold py-3"
|
||||
onClick={() => {
|
||||
dispatch(setProjectId(p.id));
|
||||
navigate(`/service-projects/${p.id}`);
|
||||
}}
|
||||
>
|
||||
{p.shortName ? `${p.name} (${p.shortName})` : p.name}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "client.contactPerson",
|
||||
label: "Contact Person",
|
||||
className: "text-start small",
|
||||
getValue: (p) => p.client?.contactPerson || "N/A",
|
||||
},
|
||||
{
|
||||
key: "assignedDate",
|
||||
label: "Assign Date",
|
||||
className: "text-center small",
|
||||
getValue: (p) => formatUTCToLocalTime(p.assignedDate),
|
||||
},
|
||||
{
|
||||
key: "status",
|
||||
label: "Status",
|
||||
className: "text-center small",
|
||||
getValue: (p) => (
|
||||
<span className={`badge ${getProjectStatusColor(p.status?.id)}`}>
|
||||
{p.status?.status}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const handleViewProject = (p) => {
|
||||
if (isCore) {
|
||||
dispatch(setProjectId(p.id));
|
||||
navigate(`/projects/details`);
|
||||
}}
|
||||
>
|
||||
{p.shortName ? `${p.name} (${p.shortName})` : p.name}
|
||||
} else {
|
||||
navigate(`/service-projects/${p.id}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleManage = (p) => {
|
||||
if (isCore) {
|
||||
setMangeProject({
|
||||
isOpen: true,
|
||||
Project: p.id,
|
||||
});
|
||||
} else {
|
||||
setManageServiceProject({
|
||||
isOpen: true,
|
||||
project: p.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className="card page-min-h py-4 px-6 shadow-sm">
|
||||
<div className="table-responsive text-nowrap page-min-h">
|
||||
<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>
|
||||
{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"
|
||||
onClick={() => handleViewProject(project)}
|
||||
|
||||
>
|
||||
<i className="bx bx-detail me-2"></i>
|
||||
<span className="align-left">View details</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a className="dropdown-item" onClick={() => handleManage(project)}
|
||||
>
|
||||
<i className="bx bx-pencil me-2"></i>
|
||||
<span className="align-left">Modify</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
paginate={paginate}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "contactPerson",
|
||||
label: "Contact Person",
|
||||
className: "text-start small",
|
||||
getValue: (p) => `${p?.contactPerson ?? ""}`.trim() || "N/A",
|
||||
},
|
||||
{
|
||||
key: "startDate",
|
||||
label: "Start Date",
|
||||
className: "text-center small",
|
||||
getValue: (p) => formatUTCToLocalTime(p?.startDate) || "N/A",
|
||||
},
|
||||
{
|
||||
key: "deadline",
|
||||
label: "Deadline",
|
||||
className: "text-center small",
|
||||
getValue: (p) => formatUTCToLocalTime(p?.endDate) || "N/A",
|
||||
},
|
||||
{
|
||||
key: "task",
|
||||
label: "Task",
|
||||
colSpan: 2,
|
||||
className: "text-center small",
|
||||
getValue: (p) => formatNumber(p?.plannedWork) || "0",
|
||||
},
|
||||
{
|
||||
key: "progress",
|
||||
label: "Progress",
|
||||
className: "text-start small",
|
||||
|
||||
getValue: (p) => (
|
||||
<ProgressBar
|
||||
plannedWork={p.plannedWork}
|
||||
completedWork={p.completedWork}
|
||||
className="mb-0"
|
||||
height="6px"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "status",
|
||||
label: "Status",
|
||||
className: "text-center small",
|
||||
isFilter: true,
|
||||
customRender: (_, selectedStatuses, handleStatusChange) => (
|
||||
<div className="dropdown">
|
||||
<a
|
||||
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
Status <i className="bx bx-filter bx-sm"></i>
|
||||
</a>
|
||||
<ul className="dropdown-menu p-2 text-capitalize">
|
||||
{PROJECT_STATUS.map(({ id, label }) => (
|
||||
<li key={id}>
|
||||
<div className="form-check">
|
||||
<input
|
||||
className="form-check-input"
|
||||
type="checkbox"
|
||||
checked={selectedStatuses.includes(id)}
|
||||
onChange={() => handleStatusChange(id)}
|
||||
/>
|
||||
<label className="form-check-label">{label}</label>
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
),
|
||||
getValue: (p) => (
|
||||
<span className={`badge ${getProjectStatusColor(p.projectStatusId)}`}>
|
||||
{getProjectStatusName(p.projectStatusId)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const handleViewActivities = (project) => {
|
||||
dispatch(setProjectId(project));
|
||||
navigate(`/activities/records?project=${project}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="card page-min-h py-4 px-6 shadow-sm">
|
||||
<div className="table-responsive text-nowrap page-min-h">
|
||||
<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>
|
||||
{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>
|
||||
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
paginate={paginate}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default ServiceProjectList;
|
||||
|
||||
@ -13,7 +13,7 @@ import { SpinnerLoader } from "../../components/common/Loader";
|
||||
import ServiceProjectCard from "../../components/ServiceProject/ServiceProjectTeam/ServiceProjectCard";
|
||||
import ServiceProjectList from "../../components/ServiceProject/ServiceProjectTeam/ServiceProjectList";
|
||||
|
||||
const ServiceProjectDisplay = ({ listView ,selectedStatuses }) => {
|
||||
const ServiceProjectDisplay = ({ listView, selectedStatuses }) => {
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
const { manageServiceProject, setManageServiceProject } = useProjectContext();
|
||||
@ -50,15 +50,20 @@ const ServiceProjectDisplay = ({ listView ,selectedStatuses }) => {
|
||||
return (
|
||||
<div className="row">
|
||||
{listView ? (
|
||||
// <p>List</p>
|
||||
<ServiceProjectList projects={filteredProjects} />
|
||||
<ServiceProjectList
|
||||
data={filteredProjects}
|
||||
currentPage={currentPage}
|
||||
totalPages={data?.totalPages}
|
||||
paginate={paginate}
|
||||
isCore={false}
|
||||
/>
|
||||
) : (
|
||||
filteredProjects?.map((project) => (
|
||||
<ServiceProjectCard key={project.id} project={project} isCore={false} />
|
||||
))
|
||||
|
||||
)}
|
||||
|
||||
|
||||
<div className="col-12 d-flex justify-content-start mt-3">
|
||||
<Pagination
|
||||
currentPage={currentPage}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user