employee assign perfectly with job role.

This commit is contained in:
Pramod Mahajan 2025-04-21 15:41:37 +05:30
parent a4285388f8
commit 6c2a6ca7f9
3 changed files with 117 additions and 370 deletions

View File

@ -1,8 +1,9 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import EmployeeRepository from "../../repositories/EmployeeRepository"; import EmployeeRepository from "../../repositories/EmployeeRepository";
import AssignEmployeeCard from "./AssignEmployeeCard"; import { useAllEmployees } from "../../hooks/useEmployees";
import {useAllEmployees} from "../../hooks/useEmployees";
import useSearch from "../../hooks/useSearch"; import useSearch from "../../hooks/useSearch";
import AssignEmployeeTable from "./AssignEmployeeTable";
import showToast from "../../services/toastService";
const MapUsers = ({ const MapUsers = ({
projectId, projectId,
@ -11,61 +12,59 @@ const MapUsers = ({
onSubmit, onSubmit,
allocation, allocation,
}) => { }) => {
const {employeesList, loading, error} = useAllEmployees(); const { employeesList, loading, error } = useAllEmployees();
const [selectedEmployees, setSelectedEmployees] = useState([]); const [selectedEmployees, setSelectedEmployees] = useState([]);
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const handleAllocationData = Array.isArray( allocation ) ? allocation : []; const handleAllocationData = Array.isArray(allocation) ? allocation : [];
const allocationEmployees = employeesList.map((employee) => { const allocationEmployees = employeesList.map((employee) => {
const allocationItem = handleAllocationData.find((alloc) => alloc.employeeId === employee.id); const allocationItem = handleAllocationData.find(
(alloc) => alloc.employeeId === employee.id
);
return { return {
...employee, ...employee,
isActive: allocationItem ? allocationItem.isActive : false, isActive: allocationItem ? allocationItem.isActive : false,
jobRoleId: allocationItem ? allocationItem.jobRoleId : employee.jobRoleId, jobRoleId: allocationItem ? allocationItem.jobRoleId : employee.jobRoleId,
}; };
} ); });
function parseDate(dateStr) {
return new Date(dateStr.split(".")[0]);
}
const latestAllocations = handleAllocationData.reduce((acc, alloc) => {
function parseDate(dateStr) {
return new Date(dateStr.split('.')[0]);
}
const latestAllocations = handleAllocationData.reduce((acc, alloc) => {
const existingAlloc = acc[alloc.employeeId]; const existingAlloc = acc[alloc.employeeId];
if (!existingAlloc) { if (!existingAlloc) {
acc[alloc.employeeId] = alloc; acc[alloc.employeeId] = alloc;
} else { } else {
const existingDate = parseDate(
existingAlloc.reAllocationDate || existingAlloc.allocationDate
);
const newDate = parseDate(alloc.reAllocationDate || alloc.allocationDate);
const existingDate = parseDate(existingAlloc.reAllocationDate || existingAlloc.allocationDate); if (newDate > existingDate) {
const newDate = parseDate(alloc.reAllocationDate || alloc.allocationDate); acc[alloc.employeeId] = alloc;
}
if (newDate > existingDate) {
acc[alloc.employeeId] = alloc;
}
} }
return acc; return acc;
}, {}); }, {});
const allocationEmployeesData = employeesList
const allocationEmployeesData = employeesList
.map((employee) => { .map((employee) => {
const allocationItem = latestAllocations[employee.id]; const allocationItem = latestAllocations[employee.id];
return { return {
...employee, ...employee,
isActive: allocationItem ? allocationItem.isActive : false, isActive: allocationItem ? allocationItem.isActive : false,
}; };
}) })
.filter( ( employee ) => employee.isActive === false ); .filter((employee) => employee.isActive === false);
const { filteredData, setSearchQuery } = useSearch(
allocationEmployeesData,
const { filteredData, setSearchQuery } = useSearch(allocationEmployeesData, searchText); searchText
);
const handleRoleChange = (employeeId, newRoleId) => { const handleRoleChange = (employeeId, newRoleId) => {
setSelectedEmployees((prevSelectedEmployees) => setSelectedEmployees((prevSelectedEmployees) =>
@ -78,7 +77,9 @@ const allocationEmployeesData = employeesList
const handleCheckboxChange = (employeeId) => { const handleCheckboxChange = (employeeId) => {
setSelectedEmployees((prevSelectedEmployees) => { setSelectedEmployees((prevSelectedEmployees) => {
const updatedEmployees = [...prevSelectedEmployees]; const updatedEmployees = [...prevSelectedEmployees];
const employeeIndex = updatedEmployees.findIndex((emp) => emp.id === employeeId); const employeeIndex = updatedEmployees.findIndex(
(emp) => emp.id === employeeId
);
if (employeeIndex !== -1) { if (employeeIndex !== -1) {
const isSelected = !updatedEmployees[employeeIndex].isSelected; const isSelected = !updatedEmployees[employeeIndex].isSelected;
@ -93,12 +94,17 @@ const allocationEmployeesData = employeesList
}); });
}; };
const handleSubmit = () => { const handleSubmit = () => {
const selected = selectedEmployees const selected = selectedEmployees
.filter((emp) => emp.isSelected) .filter((emp) => emp.isSelected)
.map((emp) => ({ empID: emp.id, jobRoleId: emp.jobRoleId })); .map((emp) => ({ empID: emp.id, jobRoleId: emp.jobRoleId }));
onSubmit(selected); if (selected.length > 0) {
console.log(selected);
onSubmit( selected );
setSelectedEmployees([])
} else {
showToast("Please select Employee", "error");
}
}; };
return ( return (
@ -118,20 +124,27 @@ const allocationEmployeesData = employeesList
</div> </div>
</div> </div>
<div className="modal-body p-sm-4 p-0"> <div className="modal-body p-sm-4 p-0">
<ul className="list-group border-none mb-2"> <table
{loading && !employeesList && <p>Loading...</p>} className="datatables-users table border-top dataTable no-footer dtr-column "
{filteredData.map((emp) => ( id="DataTables_Table_0"
<AssignEmployeeCard aria-describedby="DataTables_Table_0_info"
key={emp.id} style={{ width: "100%" }}
employee={emp} >
jobRoles={empJobRoles} <thead></thead>
isChecked={emp.isSelected} <tbody>
onRoleChange={handleRoleChange} {loading && !employeesList && <p>Loading...</p>}
onCheckboxChange={handleCheckboxChange} {filteredData.map((emp) => (
/> <AssignEmployeeTable
) )} key={emp.id}
{filteredData.length == 0 && <p>No Data Found</p>} employee={emp}
</ul> jobRoles={empJobRoles}
isChecked={emp.isSelected}
onRoleChange={handleRoleChange}
onCheckboxChange={handleCheckboxChange}
/>
))}
</tbody>
</table>
</div> </div>
<div className="modal-footer"> <div className="modal-footer">
<button className="btn btn-sm btn-success" onClick={handleSubmit}> <button className="btn btn-sm btn-success" onClick={handleSubmit}>

View File

@ -5,28 +5,24 @@ import Avatar from "../common/Avatar";
import moment from "moment"; import moment from "moment";
import ProjectRepository from "../../repositories/ProjectRepository"; import ProjectRepository from "../../repositories/ProjectRepository";
import {useDispatch} from "react-redux"; import { useDispatch } from "react-redux";
import {changeMaster} from "../../slices/localVariablesSlice"; import { changeMaster } from "../../slices/localVariablesSlice";
import useMaster from "../../hooks/masterHook/useMaster" import useMaster from "../../hooks/masterHook/useMaster";
import {useHasUserPermission} from "../../hooks/useHasUserPermission" import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import {ASSIGN_TO_PROJECT} from "../../utils/constants"; import { ASSIGN_TO_PROJECT } from "../../utils/constants";
const Teams = ({ project }) => {
const Teams = ( {project} ) => const dispatch = useDispatch();
{ dispatch(changeMaster("Job Role"));
const dispatch = useDispatch() const { data, loading } = useMaster();
dispatch( changeMaster( 'Job Role' ) )
const {data,loading} = useMaster()
const [isModalOpen, setIsModelOpen] = useState(false); const [isModalOpen, setIsModelOpen] = useState(false);
const [error, setError] = useState(""); const [error, setError] = useState("");
const [empJobRoles, setEmpJobRoles] = useState(null); const [empJobRoles, setEmpJobRoles] = useState(null);
const [clearFormTrigger, setClearFormTrigger] = useState(false); const [clearFormTrigger, setClearFormTrigger] = useState(false);
const [employees, setEmployees] = useState([]); const [employees, setEmployees] = useState([]);
const [ filteredEmployees, setFilteredEmployees ] = useState( [] ); const [filteredEmployees, setFilteredEmployees] = useState([]);
const HasAssignUserPermission = useHasUserPermission( ASSIGN_TO_PROJECT )
const HasAssignUserPermission = useHasUserPermission(ASSIGN_TO_PROJECT);
const fetchEmployees = async () => { const fetchEmployees = async () => {
try { try {
@ -69,7 +65,6 @@ const Teams = ( {project} ) =>
}; };
const handleEmpAlicationFormSubmit = (allocaionObj) => { const handleEmpAlicationFormSubmit = (allocaionObj) => {
let items = allocaionObj.map((item) => { let items = allocaionObj.map((item) => {
return { return {
empID: item.empID, empID: item.empID,
@ -79,12 +74,10 @@ const Teams = ( {project} ) =>
}; };
}); });
submitAllocations(items);
submitAllocations(items)
}; };
const getRole = ( jobRoleId ) => const getRole = (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";
@ -105,25 +98,22 @@ const Teams = ( {project} ) =>
document.body.classList.remove("modal-open"); document.body.classList.remove("modal-open");
document.querySelector(".modal-backdrop").remove(); document.querySelector(".modal-backdrop").remove();
} }
const modalBackdropElement = document.querySelector('.modal-backdrop'); const modalBackdropElement = document.querySelector(".modal-backdrop");
if (modalBackdropElement) { if (modalBackdropElement) {
modalBackdropElement.remove(); modalBackdropElement.remove();
} }
document.body.style.overflow = 'auto' document.body.style.overflow = "auto";
}; };
useEffect(() => { useEffect(() => {
fetchEmployees(); fetchEmployees();
}, [] ); }, []);
useEffect( () => useEffect(() => {
{ if (data) {
if ( data ) setEmpJobRoles(data);
{
setEmpJobRoles(data)
} }
},[data]) }, [data]);
const handleFilterEmployee = (e) => { const handleFilterEmployee = (e) => {
const filterValue = e.target.value; const filterValue = e.target.value;
@ -136,24 +126,24 @@ const Teams = ( {project} ) =>
return ( return (
<> <>
{isModalOpen && ( <div
<div className="modal fade"
className={`modal fade `} id="user-model"
id="user-model" tabIndex="-1"
tabIndex="-1" aria-labelledby="userModalLabel"
aria-hidden="true" aria-hidden="true"
> >
<MapUsers <MapUsers
projectId={project.id} projectId={project.id}
onClose={onModelClose} onClose={onModelClose}
empJobRoles={empJobRoles} empJobRoles={empJobRoles}
onSubmit={handleEmpAlicationFormSubmit} onSubmit={handleEmpAlicationFormSubmit}
allocation={employees} allocation={employees}
clearTrigger={clearFormTrigger} clearTrigger={clearFormTrigger}
onClearComplete={() => setClearFormTrigger(false)} onClearComplete={() => setClearFormTrigger(false)}
></MapUsers> ></MapUsers>
</div> </div>
)}
<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"> <div className="row">
@ -179,13 +169,14 @@ const Teams = ( {project} ) =>
</div> </div>
<button <button
type="button" type="button"
className={`link-button link-button-sm m-1 ${HasAssignUserPermission ? "":"d-none"}`} className={`link-button btn-sm m-1 ${
HasAssignUserPermission ? "" : "d-none"
}`}
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#user-model" data-bs-target="#user-model"
onClick={() => openModel()}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
Assign Users Assign Employee
</button> </button>
</div> </div>
</div> </div>
@ -198,7 +189,6 @@ const Teams = ( {project} ) =>
<th>Assigned Date</th> <th>Assigned Date</th>
<th>Release Date</th> <th>Release Date</th>
<th>Role</th> <th>Role</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
</thead> </thead>
@ -278,259 +268,3 @@ const Teams = ( {project} ) =>
export default Teams; export default Teams;
// const Teams = ({ project }) => {
// const dispatch = useDispatch()
// const {data, loading} = useMaster()
// const navigate = useNavigate()
// const [isModalOpen, setIsModelOpen] = useState(false);
// const [error, setError] = useState("");
// const [empJobRoles, setEmpJobRoles] = useState([]);
// const [clearFormTrigger, setClearFormTrigger] = useState(false);
// const [employees, setEmployees] = useState([]);
// const [ filteredEmployees, setFilteredEmployees ] = useState( [] );
// useEffect( () =>
// {
// dispatch( changeMaster( 'Job Role' ) )
// },[dispatch])
// const fetchEmployees = useCallback(async () => {
// try {
// const response = await ProjectRepository.getProjectAllocation(project.id);
// setEmployees(response.data);
// setFilteredEmployees(response.data.filter((emp) => emp.isActive));
// } catch (error) {
// console.error(error);
// setError("Failed to fetch data.");
// }
// }, [project.id]);
// useEffect(() => {
// fetchEmployees();
// }, [fetchEmployees]);
// useEffect(() => {
// if (data) setEmpJobRoles(data);
// }, [ data ] );
// const submitAllocations = (items) => {
// ProjectRepository.manageProjectAllocation(items)
// .then((response) => {
// showToast("Details updated successfully.", "success");
// setClearFormTrigger(true);
// fetchEmployees();
// })
// .catch((error) => {
// showToast(error.message, "error");
// });
// };
// const removeAllocation = (item) => {
// submitAllocations([
// {
// empID: item.employeeId,
// jobRoleId: item.jobRoleId,
// projectId: project.id,
// status: false,
// },
// ]);
// };
// const handleEmpAlicationFormSubmit = (allocaionObj) => {
// console.log("Form submitted:", allocaionObj);
// let items = allocaionObj.map((item) => {
// return {
// empID: item.empID,
// jobRoleId: item.jobRoleId,
// projectId: project.id,
// status: true,
// };
// });
// submitAllocations(items)
// };
// const getRole = ( jobRoleId ) =>
// {
// if (loading) return "Loading...";
// if (!Array.isArray(empJobRoles)) return "Unassigned";
// if (!jobRoleId) return "Unassigned";
// const role = empJobRoles.find((b) => b.id == jobRoleId);
// return role ? role.name : "Unassigned";
// };
// const openModel = () => {
// setIsModelOpen(true);
// };
// const onModelClose = () => {
// setIsModelOpen(false);
// const modalElement = document.getElementById("user-model");
// if (modalElement) {
// modalElement.classList.remove("show");
// modalElement.style.display = "none";
// document.body.classList.remove("modal-open");
// document.querySelector(".modal-backdrop").remove();
// }
// const modalBackdropElement = document.querySelector('.modal-backdrop');
// if (modalBackdropElement) {
// modalBackdropElement.remove();
// }
// document.body.style.overflow = 'auto'
// };
// const handleFilterEmployee = (e) => {
// const filterValue = e.target.value === "true";
// setFilteredEmployees(
// employees.filter((emp) => emp.isActive === filterValue)
// );
// };
// return (
// <>
// {isModalOpen && (
// <div
// className={`modal fade `}
// id="user-model"
// tabIndex="-1"
// aria-hidden="true"
// >
// <MapUsers
// projectId={project.id}
// onClose={onModelClose}
// empJobRoles={empJobRoles}
// onSubmit={handleEmpAlicationFormSubmit}
// allocation={employees}
// clearTrigger={clearFormTrigger}
// onClearComplete={() => setClearFormTrigger(false)}
// ></MapUsers>
// </div>
// )}
// <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="dataTables_length text-start py-2 px-2"
// id="DataTables_Table_0_length"
// >
// <label>
// <select
// name="DataTables_Table_0_length"
// aria-controls="DataTables_Table_0"
// className="form-select form-select-sm"
// onChange={handleFilterEmployee}
// aria-label=""
// defaultValue="true"
// >
// <option value="true">Active Employee</option>
// <option value="false">In-Active Employee</option>
// </select>
// </label>
// </div>
// <button
// type="button"
// className="link-button link-button-sm m-1"
// data-bs-toggle="modal"
// data-bs-target="#user-model"
// onClick={() => openModel()}
// >
// <i className="bx bx-plus-circle me-2"></i>
// Assign Users
// </button>
// </div>
// </div>
// <div className="table-responsive text-nowrap">
// {employees && employees.length > 0 ? (
// <table className="table ">
// <thead>
// <tr>
// <th>Name</th>
// <th>Assigned Date</th>
// <th>Release Date</th>
// <th>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
// href="#"
// onClick={()=> navigate(`/employee/${item.employeeId}`)}
// className="text-heading text-truncate"
// >
// <span className="fw-medium">
// {item.firstName} {item.lastName}
// </span>
// </a>
// </div>
// </div>
// </td>
// <td>
// {" "}
// {moment(item.allocationDate).format(
// "DD-MMM-YYYY"
// )}{" "}
// </td>
// <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={() => removeAllocation(item)}
// >
// {" "}
// <i className="bx bx-trash me-1 text-danger"></i>{" "}
// </button>
// )}
// {!item.isActive && <span>Not in project</span>}
// </td>
// </tr>
// ))}
// </tbody>
// </table>
// ) : (
// <span>No employees assigned to the project</span>
// )}
// </div>
// </div>
// </div>
// </>
// );
// };
// export default Teams;

View File

@ -18,7 +18,7 @@ const TaskPlannng = () => {
const {projects,loading:project_listLoader,error:projects_error} = useProjects(); const {projects,loading:project_listLoader,error:projects_error} = useProjects();
const dispatch = useDispatch(); const dispatch = useDispatch();
const selectedProject = useSelector((store)=>store.localVariables.projectId); const selectedProject = useSelector((store)=>store.localVariables.projectId);
console.log(selectedProject)
const [project, setProject] = useState(null); const [project, setProject] = useState(null);
const [projectDetails, setProjectDetails] = useState(null); const [projectDetails, setProjectDetails] = useState(null);