added filter and sorted employee list - Team

This commit is contained in:
pramod.mahajan 2025-09-27 10:12:34 +05:30
parent 2ef1fcfd1d
commit 265c74f079

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect, useCallback, useMemo } from "react";
import MapUsers from "../MapUsers"; import MapUsers from "../MapUsers";
import { Link, NavLink, useNavigate, useParams } from "react-router-dom"; import { Link, NavLink, useNavigate, useParams } from "react-router-dom";
@ -28,16 +28,15 @@ const Teams = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [AssigTeam, setAssignTeam] = useState(false); const [AssigTeam, setAssignTeam] = useState(false);
const [employees, setEmployees] = useState([]); const [employees, setEmployees] = useState([]);
const [filteredEmployees, setFilteredEmployees] = useState([]);
const [selectedEmployee, setSelectedEmployee] = useState(null); const [selectedEmployee, setSelectedEmployee] = useState(null);
const [deleteEmployee, setDeleteEmplyee] = useState(null); const [deleteEmployee, setDeleteEmplyee] = useState(null);
const [searchTerm, setSearchTerm] = useState(""); // State for search term const [searchTerm, setSearchTerm] = useState(""); // State for search term
const [selectedService, setSelectedService] = useState(null); const [selectedService, setSelectedService] = useState(null);
const [activeEmployee,setActiveEmployee] = useState(false) const [activeEmployee, setActiveEmployee] = useState(false);
const { data: assignedServices, isLoading: servicesLoading } = const { data: assignedServices, isLoading: servicesLoading } =
useProjectAssignedServices(selectedProject); useProjectAssignedServices(selectedProject);
const {data:empJobRoles,loading} = useMaster() const { data: empJobRoles, loading } = useMaster();
const handleToggleActive = (e) => setActiveEmployee(e.target.checked); const handleToggleActive = (e) => setActiveEmployee(e.target.checked);
const handleServiceChange = (e) => { const handleServiceChange = (e) => {
@ -52,7 +51,12 @@ const Teams = () => {
projectEmployees, projectEmployees,
loading: employeeLodaing, loading: employeeLodaing,
refetch, refetch,
} = useEmployeesByProjectAllocated(selectedProject, selectedService,null,activeEmployee); } = useEmployeesByProjectAllocated(
selectedProject,
selectedService,
null,
activeEmployee
);
const { const {
mutate: submitAllocations, mutate: submitAllocations,
isPending, isPending,
@ -80,9 +84,9 @@ const Teams = () => {
}, },
]; ];
submitAllocations({payload:payload}); submitAllocations({ payload: payload });
}; };
const getJobRole = (jobRoleId) => { const getJobRole = (jobRoleId) => {
if (loading) return "Loading..."; if (loading) return "Loading...";
if (!Array.isArray(empJobRoles)) return "Unassigned"; if (!Array.isArray(empJobRoles)) return "Unassigned";
if (!jobRoleId) return "Unassigned"; if (!jobRoleId) return "Unassigned";
@ -90,19 +94,36 @@ const Teams = () => {
const role = empJobRoles.find((b) => b.id == jobRoleId); const role = empJobRoles.find((b) => b.id == jobRoleId);
return role ? role.name : "Unassigned"; return role ? role.name : "Unassigned";
}; };
// const employeeHandler = useCallback(
// (msg) => {
// if (filteredEmployees.some((emp) => emp.employeeId == msg.employeeId)) {
// refetch();
// }
// },
// [filteredEmployees, refetch]
// );
// useEffect(() => { const filteredEmployees = useMemo(() => {
// eventBus.on("employee", employeeHandler); if (!projectEmployees || !searchTerm?.trim()) return projectEmployees;
// return () => eventBus.off("employee", employeeHandler);
// }, [employeeHandler]); const lower = searchTerm.toLowerCase();
return projectEmployees?.filter((emp) => {
const fullName = `${emp.firstName ?? ""} ${
emp.lastName ?? ""
}`.toLowerCase();
const joberole = getJobRole(emp?.jobRoleId)?.toLowerCase();
return fullName?.includes(lower) || joberole?.includes(lower);
});
}, [projectEmployees, searchTerm]);
const handleSearch = (e) => setSearchTerm(e.target.value);
const employeeHandler = useCallback(
(msg) => {
if (filteredEmployees.some((emp) => emp.employeeId == msg.employeeId)) {
refetch();
}
},
[filteredEmployees, refetch]
);
useEffect(() => {
eventBus.on("employee", employeeHandler);
return () => eventBus.off("employee", employeeHandler);
}, [employeeHandler]);
return ( return (
<> <>
@ -112,7 +133,7 @@ const Teams = () => {
isOpen={AssigTeam} isOpen={AssigTeam}
closeModal={() => setAssignTeam(false)} closeModal={() => setAssignTeam(false)}
> >
<TeamAssignToProject closeModal={() => setAssignTeam(false)} /> <TeamAssignToProject closeModal={() => setAssignTeam(false)} />
</GlobalModel> </GlobalModel>
)} )}
@ -128,79 +149,85 @@ const Teams = () => {
<div className="card card-action mb-6"> <div className="card card-action mb-6">
<div className="card-body"> <div className="card-body">
<div className="row d-flex justify-content-between mb-4"> <div className="row align-items-center justify-content-between mb-4 g-3">
<div className="col-md-6 col-12 d-flex align-emps-center"> <div className="col-md-6 col-12 algin-items-center">
{/* <div className="dataTables_length text-start py-1 px-0 col-md-4 col-12"> <div className="d-flex flex-wrap align-items-center gap-3">
{!servicesLoading && <div>
assignedServices?.length > 0 && {!servicesLoading && (
(assignedServices.length > 1 ? ( <>
<label> {(!assignedServices || assignedServices.length === 0) && (
<select <span className="badge bg-label-secondary">
name="DataTables_Table_0_length" Not Service Assigned
aria-controls="DataTables_Table_0" </span>
className="form-select form-select-sm" )}
aria-label="Select Service"
value={selectedService} {assignedServices?.length === 1 && (
onChange={handleServiceChange} <span className="badge bg-label-secondary">
style={{ {assignedServices[0].name}
fontSize: "0.875rem", </span>
height: "35px", )}
width: "190px",
}} {assignedServices?.length > 1 && (
> <select
<option value="">All Services</option> className="form-select form-select-sm"
{assignedServices.map((service) => ( aria-label="Select Service"
<option key={service.id} value={service.id}> value={selectedService}
{service.name} onChange={handleServiceChange}
</option> >
))} <option value="">All Services</option>
</select> {assignedServices.map((service) => (
</label> <option key={service.id} value={service.id}>
) : ( {service.name}
<h5>{assignedServices[0].name}</h5> </option>
))} ))}
</div> */} </select>
)}
</>
)}
</div>
<div className="form-check form-switch d-flex align-items-center text-nowrap">
<input
type="checkbox"
className="form-check-input"
id="activeEmployeeSwitch"
checked={activeEmployee}
onChange={handleToggleActive}
/>
<label
className="form-check-label ms-2"
htmlFor="activeEmployeeSwitch"
>
{activeEmployee ? "Active Employees" : "Inactive Employees"}
</label>
</div>
</div>
</div> </div>
<div className="col-md-6 col-12 d-flex justify-content-end align-emps-center">
<div className="form-check form-switch me-2 mt-2"> <div className="col-md-6 col-12 d-flex justify-content-md-end align-items-center justify-content-start gap-3">
<input <input
type="checkbox" type="search"
className="form-check-input" className="form-control form-control-sm"
checked={activeEmployee} placeholder="Search by Name or Role"
onChange={handleToggleActive} aria-controls="DataTables_Table_0"
id="activeEmployeeSwitch" style={{ maxWidth: "200px" }}
/> value={searchTerm}
<label onChange={handleSearch}
className="form-check-label ms-0 " />
htmlFor="activeEmployeeSwitch"
>
{activeEmployee ? "Active Employees" : "Inactive Employees"}
</label>
</div>
<div className="dataTables_filter d-inline-flex align-emps-center ms-2">
<input
type="search"
className="form-control form-control-sm me-4"
placeholder="Search by Name or Role"
aria-controls="DataTables_Table_0"
// value={searchTerm}
// onChange={handleSearch}
/>
</div>
{HasAssignUserPermission && ( {HasAssignUserPermission && (
<button <button
type="button" type="button"
className={`link-button btn-primary btn-sm `} className="btn btn-primary btn-sm text-nowrap"
// data-bs-toggle="modal"
// data-bs-target="#user-model"
onClick={() => setAssignTeam(true)} onClick={() => setAssignTeam(true)}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-1"></i>
Assign Employee Assign Employee
</button> </button>
)} )}
</div> </div>
</div> </div>
<div className="table-responsive text-nowrap"> <div className="table-responsive text-nowrap">
{employeeLodaing && <p>Loading..</p>} {employeeLodaing && <p>Loading..</p>}
{projectEmployees && projectEmployees.length > 0 && ( {projectEmployees && projectEmployees.length > 0 && (
@ -213,72 +240,80 @@ const Teams = () => {
<th>Services</th> <th>Services</th>
<th>Organization</th> <th>Organization</th>
<th>Assigned Date</th> <th>Assigned Date</th>
<th>Release Date</th> {activeEmployee && <th>Release Date</th>}
<th>Project Role</th> <th>Project Role</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody className="table-border-bottom-0"> <tbody className="table-border-bottom-0">
{projectEmployees && {filteredEmployees &&
projectEmployees.map((emp) => ( filteredEmployees
<tr key={emp.id}> .sort((a, b) =>
<td> (a.firstName || "").localeCompare(b.firstName || "")
<div className="d-flex justify-content-start align-items-center"> )
<Avatar .map((emp) => (
firstName={emp.firstName} <tr key={emp.id}>
lastName={emp.lastName} <td>
/> <div className="d-flex justify-content-start align-items-center">
<div className="d-flex flex-column"> <Avatar
<a firstName={emp.firstName}
onClick={() => lastName={emp.lastName}
navigate( />
`/employee/${emp.employeeId}?for=attendance` <div className="d-flex flex-column">
) <a
} onClick={() =>
className="text-heading text-truncate cursor-pointer" navigate(
> `/employee/${emp.employeeId}?for=attendance`
<span className="fw-normal"> )
{emp.firstName} }
{emp.lastName} className="text-heading text-truncate cursor-pointer"
</span> >
</a> <span className="fw-normal">
{emp.firstName}
{emp.lastName}
</span>
</a>
</div>
</div> </div>
</div> </td>
</td>
<td>{emp.serviceName || "N/A"}</td> <td>{emp.serviceName || "N/A"}</td>
<td>{emp.organizationName || "N/A"}</td> <td>{emp.organizationName || "N/A"}</td>
<td> <td>
{moment(emp.allocationDate).format("DD-MMM-YYYY")} {moment(emp.allocationDate).format("DD-MMM-YYYY")}
</td> </td>
<td> {activeEmployee && (
{emp.reAllocationDate <td>
? moment(emp.reAllocationDate).format("DD-MMM-YYYY") {emp.reAllocationDate
: "Present"} ? moment(emp.reAllocationDate).format(
</td> "DD-MMM-YYYY"
<td> )
<span className="badge bg-label-primary me-1"> : "Present"}
{getJobRole(emp.jobRoleId)} </td>
</span>
</td>
<td>
{emp.isActive ? (
<button
aria-label="Delete"
type="button"
title="Remove from project"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => setSelectedEmployee(emp)}
>
<i className="bx bx-trash me-1 text-danger"></i>
</button>
) : (
<span>Not in project</span>
)} )}
</td> <td>
</tr> <span className="badge bg-label-primary me-1">
))} {getJobRole(emp.jobRoleId)}
</span>
</td>
<td>
{emp.isActive ? (
<button
aria-label="Delete"
type="button"
title="Remove from project"
className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => setSelectedEmployee(emp)}
>
<i className="bx bx-trash me-1 text-danger"></i>
</button>
) : (
<span>Not in project</span>
)}
</td>
</tr>
))}
</tbody> </tbody>
</table> </table>
)} )}