added serviceproject list
This commit is contained in:
parent
3d1d8264ad
commit
8eb34addcd
@ -9,14 +9,14 @@ import { useParams } from "react-router-dom";
|
||||
import ProjectPage from "../../pages/project/ProjectPage";
|
||||
import { useServiceProjectJobContext } from "./Jobs";
|
||||
|
||||
const JobList = ({ filterByProject }) => {
|
||||
const JobList = () => {
|
||||
const { setSelectedJob, setManageJob } = useServiceProjectJobContext();
|
||||
const { id } = useParams();
|
||||
const { projectId } = useParams();
|
||||
const { data, isLoading, isError, error } = useServiceProjectJobs(
|
||||
ITEMS_PER_PAGE,
|
||||
1,
|
||||
true,
|
||||
filterByProject ?? id
|
||||
projectId
|
||||
);
|
||||
|
||||
const jobGrid = [
|
||||
|
||||
@ -2,55 +2,53 @@ import React from "react";
|
||||
import Avatar from "../common/Avatar";
|
||||
|
||||
const JobStatusLog = ({ data }) => {
|
||||
console.log(data)
|
||||
console.log(data);
|
||||
return (
|
||||
<div className="card shadow-none p-0">
|
||||
<div className="card-body p-0">
|
||||
<div className="list-group">
|
||||
|
||||
{data?.map((item) => (
|
||||
|
||||
<div
|
||||
key={item.id}
|
||||
className="list-group-item border-0 border-bottom p-1"
|
||||
>
|
||||
<div className="d-flex justify-content-between">
|
||||
<div
|
||||
key={item.id}
|
||||
className="list-group-item border-0 border-bottom p-1"
|
||||
>
|
||||
<div className="d-flex justify-content-between">
|
||||
<div>
|
||||
<span className="fw-semibold">
|
||||
{item.nextStatus?.displayName ?? item.status?.displayName ?? "Status"}
|
||||
{item.nextStatus?.displayName ??
|
||||
item.status?.displayName ??
|
||||
"Status"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span className="badge bg-primary">
|
||||
{/* <span className="badge bg-primary">
|
||||
Level {item.nextStatus?.level ?? item.status?.level}
|
||||
</span>
|
||||
</span> */}
|
||||
</div>
|
||||
<div className="d-flex align-items-start mt-2 mx-0 px-0">
|
||||
<Avatar
|
||||
firstName={item.updatedBy?.firstName}
|
||||
lastName={item.updatedBy?.lastName}
|
||||
/>
|
||||
<div className="">
|
||||
<div className="d-flex flex-row gap-3">
|
||||
<span className="fw-semibold">
|
||||
{item.updatedBy?.firstName} {item.updatedBy?.lastName}
|
||||
</span>
|
||||
<span className="text-secondary">
|
||||
{/* <em>{formatUTCToLocalTime(item?.createdAt, true)}</em> */}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-muted text-secondary">
|
||||
{item?.updatedBy?.jobRoleName}
|
||||
</div>
|
||||
<div className="text-wrap">
|
||||
<p className="mb-1 mt-2 text-muted">{item.comment}</p>
|
||||
|
||||
</div>
|
||||
<div className="d-flex align-items-start mt-2 mx-0 px-0">
|
||||
<Avatar
|
||||
firstName={item.updatedBy?.firstName}
|
||||
lastName={item.updatedBy?.lastName}
|
||||
/>
|
||||
<div className="">
|
||||
<div className="d-flex flex-row gap-3">
|
||||
<span className="fw-semibold">
|
||||
{item.updatedBy?.firstName} {item.updatedBy?.lastName}
|
||||
</span>
|
||||
<span className="text-secondary">
|
||||
{/* <em>{formatUTCToLocalTime(item?.createdAt, true)}</em> */}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-muted text-secondary">
|
||||
{item?.updatedBy?.jobRoleName}
|
||||
</div>
|
||||
<div className="text-wrap">
|
||||
<p className="mb-1 mt-2 text-muted">{item.comment}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -16,7 +16,7 @@ const ManageJobTicket = ({ Job }) => {
|
||||
const tabsData = [
|
||||
{
|
||||
id: "comment",
|
||||
title: "Coments",
|
||||
title: "Comments",
|
||||
icon:"bx bx-comment me-2",
|
||||
active: true,
|
||||
content: <JobComments data={data} />,
|
||||
@ -58,7 +58,7 @@ const ManageJobTicket = ({ Job }) => {
|
||||
</span>{" "}
|
||||
<i className="bx bx-right-arrow-alt"></i>{" "}
|
||||
<span className="fw-medium">
|
||||
<i className="bx bx-calendar"></i> Due To : {formatUTCToLocalTime(data?.startDate)}
|
||||
<i className="bx bx-calendar"></i> Due on : {formatUTCToLocalTime(data?.startDate)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="d-block mt-2">
|
||||
@ -71,9 +71,9 @@ const ManageJobTicket = ({ Job }) => {
|
||||
firstName={data?.createdBy?.firstName}
|
||||
lastName={data?.createdBy?.lastName}
|
||||
/>{" "}
|
||||
<div className="d-flex flex-column">
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<p className="m-0">{`${data?.createdBy?.firstName} ${data?.createdBy?.lastName}`}</p>
|
||||
<small className="text-secondary">{data?.createdBy?.jobRoleName}</small>
|
||||
<small className="text-secondary ms-1">({data?.createdBy?.jobRoleName})</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex align-items-center">
|
||||
@ -84,9 +84,9 @@ const ManageJobTicket = ({ Job }) => {
|
||||
{data?.assignees?.map((emp)=>(
|
||||
<div className="d-flex flex-row ">
|
||||
<Avatar size="xs" firstName={emp.firstName} lastName={emp.lastName}/>
|
||||
<div className="d-flex flex-column">
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<p className="m-0">{`${emp.firstName} ${emp.lastName}`}</p>
|
||||
<small className="text-secondary">{emp.jobRoleName}</small>
|
||||
<small className="text-secondary ms-1">( {emp.jobRoleName} )</small>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import { useModal } from '../../../hooks/useAuth'
|
||||
import { useParams } from 'react-router-dom';
|
||||
import ServiceProjectTeamList from './ServiceProjectTeamList';
|
||||
|
||||
|
||||
const ProjectTeam = () => {
|
||||
@ -8,13 +9,13 @@ const {onOpen} = useModal("ServiceTeamAllocation");
|
||||
const {projectId}= useParams();
|
||||
|
||||
return (
|
||||
<div className='card page-min-h mt-2'>
|
||||
<div className='card page-min-h mt-2 px-4'>
|
||||
<div className='row text-end'>
|
||||
<div className='col-12'>
|
||||
<div className='p-2'><button onClick={()=>onOpen({projectId:projectId})} className='btn btn-sm btn-primary'><i className='bx bx-plus-circle me-2'></i>Assign Employee</button></div>
|
||||
<div className='p-2'><button onClick={()=>onOpen({projectId:projectId})} className='btn btn-sm btn-primary'>Manage Employee</button></div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <ServiceProjectTeamList/> */}
|
||||
<ServiceProjectTeamList/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ const ServiceProjectTeamAllocation = () => {
|
||||
isActive: true,
|
||||
};
|
||||
});
|
||||
AllocationTeam({ payload, isActive: true });
|
||||
AllocationTeam({ payload, isActive: true });
|
||||
};
|
||||
|
||||
const handleDeAllocation = (emp) => {
|
||||
@ -71,16 +71,13 @@ const ServiceProjectTeamAllocation = () => {
|
||||
},
|
||||
];
|
||||
|
||||
AllocationTeam({payload:payload,isActive:false});
|
||||
AllocationTeam({ payload: payload, isActive: false });
|
||||
};
|
||||
useEffect(() => {
|
||||
if(selectedEmployees?.length > 0 && !selectedTeam){
|
||||
handleRemove(selectedEmployees[0]?.id)
|
||||
showToast(
|
||||
`Please select a first role`,
|
||||
"warning"
|
||||
);
|
||||
}
|
||||
if (selectedEmployees?.length > 0 && !selectedTeam) {
|
||||
handleRemove(selectedEmployees[0]?.id);
|
||||
showToast(`Please select a first role`, "warning");
|
||||
}
|
||||
if (Team?.length > 0 && selectedEmployees?.length > 0) {
|
||||
setNonDuplicateEmployee((prev) => {
|
||||
let updated = [...prev];
|
||||
@ -113,7 +110,7 @@ const ServiceProjectTeamAllocation = () => {
|
||||
className="btn btn-sm btn-primary"
|
||||
onClick={() => setIsMenageEmployee(!isManageEmployee)}
|
||||
>
|
||||
Manage Employee
|
||||
<i className="bx bx-plus-circle me-2"></i>Add Employee
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -137,6 +134,7 @@ const ServiceProjectTeamAllocation = () => {
|
||||
|
||||
<div className="col-12 col-md-6 mb-3">
|
||||
<SelectEmployeeServerSide
|
||||
label="Select Employee"
|
||||
isMultiple={true}
|
||||
isFullObject={true}
|
||||
value={selectedEmployees}
|
||||
@ -151,7 +149,7 @@ const ServiceProjectTeamAllocation = () => {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{(selectedEmployees?.length > 0 && isManageEmployee ) && (
|
||||
{selectedEmployees?.length > 0 && isManageEmployee && (
|
||||
<div className="d-flex justify-content-end">
|
||||
{" "}
|
||||
<button
|
||||
|
||||
@ -1,12 +1,103 @@
|
||||
import React from 'react'
|
||||
import React from "react";
|
||||
import Avatar from "../../common/Avatar";
|
||||
import { formatUTCToLocalTime } from "../../../utils/dateUtils";
|
||||
import { useServiceProjectTeam } from "../../../hooks/useServiceProject";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { SpinnerLoader } from "../../common/Loader";
|
||||
|
||||
const ServiceProjectTeamList = () => {
|
||||
|
||||
const { projectId } = useParams();
|
||||
const { data, isLoading, isError, error } = useServiceProjectTeam(
|
||||
projectId,
|
||||
true
|
||||
);
|
||||
const servceProjectColmen = [
|
||||
{
|
||||
key: "employeName",
|
||||
label: "Name",
|
||||
getValue: (e) => {
|
||||
return (
|
||||
<div className="d-flex align-itmes-center">
|
||||
<Avatar />
|
||||
<span>{`${e.employee.firstName} ${e.employee.lastName}`}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "teamRole",
|
||||
label: "Role",
|
||||
getValue: (e) => {
|
||||
return (
|
||||
<div className="d-flex align-itmes-center">
|
||||
<span>{`${e.teamRole.firstName}`}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "assignedAt",
|
||||
label: "assigned Date",
|
||||
getValue: (e) => {
|
||||
return (
|
||||
<div className="d-flex align-itmes-center">
|
||||
{formatUTCToLocalTime(e.assignedAT)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
return (
|
||||
<div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div className="data-table table-responsive ">
|
||||
<table className="table w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
{servceProjectColmen.map((col) => (
|
||||
<th key={col.key}>{col.label}</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
export default ServiceProjectTeamList
|
||||
<tbody>
|
||||
{data?.length > 0 ? (
|
||||
data.map((emp) => (
|
||||
<tr key={emp?.id}>
|
||||
<td className="w-min">
|
||||
<div className="d-flex align-items-center gap-2 py-1">
|
||||
<Avatar
|
||||
size="xs"
|
||||
firstName={emp?.employee?.firstName}
|
||||
lastName={emp?.employee?.lastName}
|
||||
/>
|
||||
<span className="fw-medium">
|
||||
{`${emp?.employee?.firstName} ${emp?.employee?.lastName}`}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>{emp?.teamRole?.name}</td>
|
||||
|
||||
<td>{formatUTCToLocalTime(emp.assignedAt)}</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan={3} className="text-muted border-0 text-center py-4">
|
||||
{isLoading ? (
|
||||
<SpinnerLoader />
|
||||
) : (
|
||||
<div className="bg-light-secondary py-3 w-50 mx-auto my-2">
|
||||
<i className="bx bx-box bx-md text-primary"></i>
|
||||
<p className="fw-medium mt-3">Please Add an Employee</p>
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServiceProjectTeamList;
|
||||
|
||||
@ -150,11 +150,11 @@ const SelectEmployeeServerSide = ({
|
||||
</div>
|
||||
|
||||
{isLoading && (
|
||||
<li className="dropdown-item text-muted">Loading...</li>
|
||||
<li className="dropdown-item text-muted text-center">Loading...</li>
|
||||
)}
|
||||
|
||||
{!isLoading && options.length === 0 && (
|
||||
<li className="dropdown-item text-muted">No results found</li>
|
||||
<li className="dropdown-item text-muted text-center">No results found</li>
|
||||
)}
|
||||
|
||||
{!isLoading &&
|
||||
|
||||
@ -140,6 +140,24 @@ export function startSignalR(loggedUser) {
|
||||
) {
|
||||
emitters.image_gallery();
|
||||
}
|
||||
|
||||
// --- Service Project ----------------
|
||||
|
||||
if (keyword === "Service_Project") {
|
||||
queryClient.invalidateQueries(["serviceProjects"]);
|
||||
queryClient.invalidateQueries(["serviceProject"]);
|
||||
}
|
||||
|
||||
if (keyword === "Service_Project_Allocation") {
|
||||
queryClient.invalidateQueries(["serviceProjectTeam"]);
|
||||
}
|
||||
if (keyword === "Job_Ticket") {
|
||||
queryClient.invalidateQueries(["serviceProjectJobs"]);
|
||||
queryClient.invalidateQueries(["service-job"]);
|
||||
}
|
||||
if (keyword === "Job_Ticket_Comment") {
|
||||
queryClient.invalidateQueries(["jobComments"]);
|
||||
}
|
||||
});
|
||||
|
||||
connection.start();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user