missing changes from PR : Add Search Bar in Assigned Employee Popup under Project > Teams #324
#324
This commit is contained in:
parent
dd0c7e95bf
commit
1e9db47144
@ -14,11 +14,13 @@ import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||
import { ASSIGN_TO_PROJECT } from "../../utils/constants";
|
||||
import ConfirmModal from "../common/ConfirmModal";
|
||||
import eventBus from "../../services/eventBus";
|
||||
import {useEmployeesByProjectAllocated, useManageProjectAllocation} from "../../hooks/useProjects";
|
||||
import {
|
||||
useEmployeesByProjectAllocated,
|
||||
useManageProjectAllocation,
|
||||
} from "../../hooks/useProjects";
|
||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
||||
|
||||
const Teams = () =>
|
||||
{
|
||||
const Teams = () => {
|
||||
// const {projectId} = useParams()
|
||||
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
||||
const projectId = useSelectedproject();
|
||||
@ -32,68 +34,72 @@ const Teams = () =>
|
||||
const [filteredEmployees, setFilteredEmployees] = useState([]);
|
||||
const [removingEmployeeId, setRemovingEmployeeId] = useState(null);
|
||||
const [assignedLoading, setAssignedLoading] = useState(false);
|
||||
const [ activeEmployee, setActiveEmployee ] = useState( true )
|
||||
const [deleteEmployee,setDeleteEmplyee] = useState(null)
|
||||
const [activeEmployee, setActiveEmployee] = useState(true);
|
||||
const [deleteEmployee, setDeleteEmplyee] = useState(null);
|
||||
const [searchTerm, setSearchTerm] = useState(""); // State for search term
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const HasAssignUserPermission = useHasUserPermission( ASSIGN_TO_PROJECT );
|
||||
const [ IsDeleteModal, setIsDeleteModal ] = useState( false )
|
||||
const {projectEmployees, loading:employeeLodaing, refetch} = useEmployeesByProjectAllocated( projectId )
|
||||
const {
|
||||
mutate: submitAllocations,
|
||||
isPending,
|
||||
isSuccess,
|
||||
isError,
|
||||
} = useManageProjectAllocation({
|
||||
onSuccessCallback: () => {
|
||||
setRemovingEmployeeId(null);
|
||||
setAssignedLoading(false);
|
||||
setDeleteEmplyee(null);
|
||||
closeDeleteModal();
|
||||
},
|
||||
onErrorCallback: () => {
|
||||
closeDeleteModal();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
const removeAllocation = (item) => {
|
||||
setRemovingEmployeeId(item.id);
|
||||
|
||||
submitAllocations({
|
||||
items: [
|
||||
{
|
||||
empID: item.employeeId,
|
||||
jobRoleId: item.jobRoleId,
|
||||
projectId: projectId,
|
||||
status: false,
|
||||
},
|
||||
],
|
||||
added: false,
|
||||
const HasAssignUserPermission = useHasUserPermission(ASSIGN_TO_PROJECT);
|
||||
const [IsDeleteModal, setIsDeleteModal] = useState(false);
|
||||
const {
|
||||
projectEmployees,
|
||||
loading: employeeLodaing,
|
||||
refetch,
|
||||
} = useEmployeesByProjectAllocated(projectId);
|
||||
const {
|
||||
mutate: submitAllocations,
|
||||
isPending,
|
||||
isSuccess,
|
||||
isError,
|
||||
} = useManageProjectAllocation({
|
||||
onSuccessCallback: () => {
|
||||
setRemovingEmployeeId(null);
|
||||
setAssignedLoading(false);
|
||||
setDeleteEmplyee(null);
|
||||
closeDeleteModal();
|
||||
},
|
||||
onErrorCallback: () => {
|
||||
closeDeleteModal();
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const removeAllocation = (item) => {
|
||||
setRemovingEmployeeId(item.id);
|
||||
|
||||
submitAllocations({
|
||||
items: [
|
||||
{
|
||||
empID: item.employeeId,
|
||||
jobRoleId: item.jobRoleId,
|
||||
projectId: projectId,
|
||||
status: false,
|
||||
},
|
||||
],
|
||||
added: false,
|
||||
});
|
||||
};
|
||||
|
||||
const handleEmpAlicationFormSubmit = (allocaionObj) => {
|
||||
let items = allocaionObj.map((item) => {
|
||||
return {
|
||||
empID: item.empID,
|
||||
jobRoleId: item.jobRoleId,
|
||||
projectId: projectId,
|
||||
status: true,
|
||||
};
|
||||
});
|
||||
let items = allocaionObj.map((item) => {
|
||||
return {
|
||||
empID: item.empID,
|
||||
jobRoleId: item.jobRoleId,
|
||||
projectId: projectId,
|
||||
status: true,
|
||||
};
|
||||
});
|
||||
|
||||
submitAllocations({ items, added: true });
|
||||
|
||||
setActiveEmployee(true);
|
||||
setFilteredEmployees(employees.filter((emp) => emp.isActive));
|
||||
|
||||
const dropdown = document.querySelector('select[name="DataTables_Table_0_length"]');
|
||||
if (dropdown) dropdown.value = "true";
|
||||
};
|
||||
setActiveEmployee(true);
|
||||
setFilteredEmployees(employees.filter((emp) => emp.isActive));
|
||||
|
||||
const dropdown = document.querySelector(
|
||||
'select[name="DataTables_Table_0_length"]'
|
||||
);
|
||||
if (dropdown) dropdown.value = "true";
|
||||
};
|
||||
|
||||
const getRole = (jobRoleId) => {
|
||||
if (loading) return "Loading...";
|
||||
@ -124,17 +130,17 @@ const {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(changeMaster("Job Role"));
|
||||
}, [dispatch]);
|
||||
|
||||
dispatch(changeMaster("Job Role"));
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if ( projectEmployees )
|
||||
{
|
||||
if (projectEmployees) {
|
||||
setEmployees(projectEmployees);
|
||||
setFilteredEmployees( projectEmployees?.filter( ( emp ) => emp.isActive ) );
|
||||
//setFilteredEmployees(projectEmployees?.filter((emp) => emp.isActive));
|
||||
const filtered = projectEmployees.filter((emp) => emp.isActive);
|
||||
setFilteredEmployees(filtered);
|
||||
}
|
||||
}, [projectEmployees,employeeLodaing]);
|
||||
}, [projectEmployees, employeeLodaing]);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
@ -142,24 +148,57 @@ const {
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
const filterAndSearchEmployees = useCallback(() => {
|
||||
const statusFiltered = employees.filter((emp) =>
|
||||
activeEmployee ? emp.isActive : !emp.isActive
|
||||
);
|
||||
|
||||
if (searchTerm === "") {
|
||||
setFilteredEmployees(statusFiltered);
|
||||
return;
|
||||
}
|
||||
|
||||
const lowercasedSearchTerm = searchTerm.toLowerCase();
|
||||
const searchedAndFiltered = statusFiltered.filter((item) => {
|
||||
const fullName =
|
||||
`${item.firstName} ${item.middleName} ${item.lastName}`.toLowerCase();
|
||||
const roleName = getRole(item.jobRoleId).toLowerCase();
|
||||
|
||||
return (
|
||||
fullName.includes(lowercasedSearchTerm) ||
|
||||
roleName.includes(lowercasedSearchTerm)
|
||||
);
|
||||
});
|
||||
|
||||
setFilteredEmployees(searchedAndFiltered);
|
||||
}, [employees, activeEmployee, searchTerm, getRole]);
|
||||
|
||||
useEffect(() => {
|
||||
filterAndSearchEmployees();
|
||||
}, [employees, activeEmployee, searchTerm, filterAndSearchEmployees]);
|
||||
|
||||
const handleFilterEmployee = (e) => {
|
||||
const filterValue = e.target.value;
|
||||
if ( filterValue === "true" )
|
||||
{
|
||||
setActiveEmployee(true)
|
||||
setFilteredEmployees(employees.filter((emp) => emp.isActive));
|
||||
} else {
|
||||
setFilteredEmployees( employees.filter( ( emp ) => !emp.isActive ) );
|
||||
setActiveEmployee(false)
|
||||
}
|
||||
// if (filterValue === "true") {
|
||||
// setActiveEmployee(true);
|
||||
// setFilteredEmployees(employees.filter((emp) => emp.isActive));
|
||||
// } else {
|
||||
// setFilteredEmployees(employees.filter((emp) => !emp.isActive));
|
||||
// setActiveEmployee(false);
|
||||
// }
|
||||
setActiveEmployee(filterValue === "true");
|
||||
setSearchTerm("");
|
||||
};
|
||||
|
||||
const deleteModalOpen = (item) =>
|
||||
{
|
||||
setDeleteEmplyee(item)
|
||||
setIsDeleteModal(true)
|
||||
}
|
||||
const closeDeleteModal = ()=> setIsDeleteModal(false)
|
||||
const handleSearch = (e) => {
|
||||
setSearchTerm(e.target.value);
|
||||
};
|
||||
|
||||
const deleteModalOpen = (item) => {
|
||||
setDeleteEmplyee(item);
|
||||
setIsDeleteModal(true);
|
||||
};
|
||||
const closeDeleteModal = () => setIsDeleteModal(false);
|
||||
|
||||
const handler = useCallback(
|
||||
(msg) => {
|
||||
@ -167,7 +206,7 @@ const {
|
||||
refetch();
|
||||
}
|
||||
},
|
||||
[projectId, refetch]
|
||||
[projectId, refetch]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -175,18 +214,19 @@ const {
|
||||
return () => eventBus.off("assign_project_all", handler);
|
||||
}, [handler]);
|
||||
|
||||
const employeeHandler = useCallback(
|
||||
const employeeHandler = useCallback(
|
||||
(msg) => {
|
||||
if(filteredEmployees.some((item) => item.employeeId == msg.employeeId)){
|
||||
if (filteredEmployees.some((item) => item.employeeId == msg.employeeId)) {
|
||||
refetch();
|
||||
}
|
||||
},[filteredEmployees, refetch]
|
||||
},
|
||||
[filteredEmployees, refetch]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
eventBus.on("employee",employeeHandler);
|
||||
return () => eventBus.off("employee",employeeHandler)
|
||||
},[employeeHandler])
|
||||
eventBus.on("employee", employeeHandler);
|
||||
return () => eventBus.off("employee", employeeHandler);
|
||||
}, [employeeHandler]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -208,8 +248,7 @@ const {
|
||||
></MapUsers>
|
||||
</div>
|
||||
|
||||
|
||||
{IsDeleteModal && (
|
||||
{IsDeleteModal && (
|
||||
<div
|
||||
className={`modal fade ${IsDeleteModal ? "show" : ""}`}
|
||||
tabIndex="-1"
|
||||
@ -220,7 +259,6 @@ const {
|
||||
}}
|
||||
aria-hidden="false"
|
||||
>
|
||||
|
||||
<ConfirmModal
|
||||
type={"delete"}
|
||||
header={"Removed Employee"}
|
||||
@ -235,8 +273,20 @@ const {
|
||||
|
||||
<div className="card card-action mb-6">
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-12 d-flex justify-content-between mb-1">
|
||||
<div className="row d-flex justify-content-between mb-4">
|
||||
<div className="col-md-6 col-12 d-flex align-items-center">
|
||||
<div className="dataTables_filter d-inline-flex align-items-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>
|
||||
</div>
|
||||
<div className="col-md-6 col-12 d-flex justify-content-end align-items-center">
|
||||
<div
|
||||
className="dataTables_length text-start py-2 px-2"
|
||||
id="DataTables_Table_0_length"
|
||||
@ -258,7 +308,7 @@ const {
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className={`link-button btn-sm m-1 ${
|
||||
className={`link-button btn-primary btn-sm ${
|
||||
HasAssignUserPermission ? "" : "d-none"
|
||||
}`}
|
||||
data-bs-toggle="modal"
|
||||
@ -271,91 +321,99 @@ const {
|
||||
</div>
|
||||
<div className="table-responsive text-nowrap">
|
||||
{employeeLodaing && <p>Loading..</p>}
|
||||
{!employeeLodaing && employees && employees.length > 0 && (
|
||||
<table className="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Assigned Date</th>
|
||||
{!activeEmployee && <th>Release Date</th>}
|
||||
<th>Project Role</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="table-border-bottom-0">
|
||||
{filteredEmployees &&
|
||||
filteredEmployees.map((item) => (
|
||||
<tr key={item.id}>
|
||||
<td>
|
||||
<div className="d-flex justify-content-start align-items-center">
|
||||
<Avatar
|
||||
firstName={item.firstName}
|
||||
lastName={item.lastName}
|
||||
></Avatar>
|
||||
<div className="d-flex flex-column">
|
||||
<a
|
||||
onClick={() =>
|
||||
navigate(`/employee/${item.employeeId}?for=attendance`)
|
||||
}
|
||||
className="text-heading text-truncate cursor-pointer"
|
||||
>
|
||||
<span className="fw-normal">
|
||||
{item.firstName} {item.middleName}{" "}
|
||||
{item.lastName}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{" "}
|
||||
{moment(item.allocationDate).format(
|
||||
"DD-MMM-YYYY"
|
||||
)}{" "}
|
||||
</td>
|
||||
{!activeEmployee && <td>
|
||||
{item.reAllocationDate
|
||||
? moment(item.reAllocationDate).format(
|
||||
"DD-MMM-YYYY"
|
||||
)
|
||||
: "Present"}
|
||||
</td>}
|
||||
<td>
|
||||
<span className="badge bg-label-primary me-1">
|
||||
{getRole(item.jobRoleId)}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{item.isActive && (
|
||||
<button
|
||||
aria-label="Delete"
|
||||
type="button"
|
||||
title="Remove from project"
|
||||
className="btn p-0 dropdown-toggle hide-arrow"
|
||||
onClick={() => deleteModalOpen(item)}
|
||||
>
|
||||
{" "}
|
||||
{removingEmployeeId === item.id ? (
|
||||
<div
|
||||
className="spinner-border spinner-border-sm text-primary"
|
||||
role="status"
|
||||
{!employeeLodaing &&
|
||||
filteredEmployees &&
|
||||
filteredEmployees.length > 0 && (
|
||||
<table className="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<div className="text-start ms-5">Name</div>
|
||||
</th>
|
||||
<th>Assigned Date</th>
|
||||
{!activeEmployee && <th>Release Date</th>}
|
||||
<th>Project Role</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="table-border-bottom-0">
|
||||
{filteredEmployees &&
|
||||
filteredEmployees.map((item) => (
|
||||
<tr key={item.id}>
|
||||
<td>
|
||||
<div className="d-flex justify-content-start align-items-center">
|
||||
<Avatar
|
||||
firstName={item.firstName}
|
||||
lastName={item.lastName}
|
||||
></Avatar>
|
||||
<div className="d-flex flex-column">
|
||||
<a
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`/employee/${item.employeeId}?for=attendance`
|
||||
)
|
||||
}
|
||||
className="text-heading text-truncate cursor-pointer"
|
||||
>
|
||||
<span className="visually-hidden">
|
||||
Loading...
|
||||
<span className="fw-normal">
|
||||
{item.firstName} {item.middleName}{" "}
|
||||
{item.lastName}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<i className="bx bx-trash me-1 text-danger"></i>
|
||||
)}
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{" "}
|
||||
{moment(item.allocationDate).format(
|
||||
"DD-MMM-YYYY"
|
||||
)}{" "}
|
||||
</td>
|
||||
{!activeEmployee && (
|
||||
<td>
|
||||
{item.reAllocationDate
|
||||
? moment(item.reAllocationDate).format(
|
||||
"DD-MMM-YYYY"
|
||||
)
|
||||
: "Present"}
|
||||
</td>
|
||||
)}
|
||||
{!item.isActive && <span>Not in project</span>}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
<td>
|
||||
<span className="badge bg-label-primary me-1">
|
||||
{getRole(item.jobRoleId)}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{item.isActive && (
|
||||
<button
|
||||
aria-label="Delete"
|
||||
type="button"
|
||||
title="Remove from project"
|
||||
className="btn p-0 dropdown-toggle hide-arrow"
|
||||
onClick={() => deleteModalOpen(item)}
|
||||
>
|
||||
{" "}
|
||||
{removingEmployeeId === item.id ? (
|
||||
<div
|
||||
className="spinner-border spinner-border-sm text-primary"
|
||||
role="status"
|
||||
>
|
||||
<span className="visually-hidden">
|
||||
Loading...
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<i className="bx bx-trash me-1 text-danger"></i>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
{!item.isActive && <span>Not in project</span>}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
{!employeeLodaing && filteredEmployees.length === 0 && (
|
||||
<div className="text-center text-muted py-3">
|
||||
{activeEmployee
|
||||
|
Loading…
x
Reference in New Issue
Block a user