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

View File

@ -5,29 +5,25 @@ import Avatar from "../common/Avatar";
import moment from "moment";
import ProjectRepository from "../../repositories/ProjectRepository";
import {useDispatch} from "react-redux";
import {changeMaster} from "../../slices/localVariablesSlice";
import useMaster from "../../hooks/masterHook/useMaster"
import {useHasUserPermission} from "../../hooks/useHasUserPermission"
import {ASSIGN_TO_PROJECT} from "../../utils/constants";
import { useDispatch } from "react-redux";
import { changeMaster } from "../../slices/localVariablesSlice";
import useMaster from "../../hooks/masterHook/useMaster";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { ASSIGN_TO_PROJECT } from "../../utils/constants";
const Teams = ( {project} ) =>
{
const dispatch = useDispatch()
dispatch( changeMaster( 'Job Role' ) )
const {data,loading} = useMaster()
const Teams = ({ project }) => {
const dispatch = useDispatch();
dispatch(changeMaster("Job Role"));
const { data, loading } = useMaster();
const [isModalOpen, setIsModelOpen] = useState(false);
const [error, setError] = useState("");
const [empJobRoles, setEmpJobRoles] = useState(null);
const [clearFormTrigger, setClearFormTrigger] = useState(false);
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 () => {
try {
// if (!empRoles) {
@ -49,7 +45,7 @@ const Teams = ( {project} ) =>
ProjectRepository.manageProjectAllocation(items)
.then((response) => {
showToast("Details updated successfully.", "success");
setClearFormTrigger(true);
setClearFormTrigger(true);
fetchEmployees();
})
.catch((error) => {
@ -69,7 +65,6 @@ const Teams = ( {project} ) =>
};
const handleEmpAlicationFormSubmit = (allocaionObj) => {
let items = allocaionObj.map((item) => {
return {
empID: item.empID,
@ -79,23 +74,21 @@ const Teams = ( {project} ) =>
};
});
submitAllocations(items)
submitAllocations(items);
};
const getRole = ( jobRoleId ) =>
{
const getRole = (jobRoleId) => {
if (loading) return "Loading...";
if (!Array.isArray(empJobRoles)) return "Unassigned";
if (!Array.isArray(empJobRoles)) return "Unassigned";
if (!jobRoleId) return "Unassigned";
const role = empJobRoles.find((b) => b.id == jobRoleId);
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");
@ -105,25 +98,22 @@ const Teams = ( {project} ) =>
document.body.classList.remove("modal-open");
document.querySelector(".modal-backdrop").remove();
}
const modalBackdropElement = document.querySelector('.modal-backdrop');
const modalBackdropElement = document.querySelector(".modal-backdrop");
if (modalBackdropElement) {
modalBackdropElement.remove();
modalBackdropElement.remove();
}
document.body.style.overflow = 'auto'
document.body.style.overflow = "auto";
};
useEffect(() => {
fetchEmployees();
}, [] );
useEffect( () =>
{
if ( data )
{
setEmpJobRoles(data)
}, []);
useEffect(() => {
if (data) {
setEmpJobRoles(data);
}
},[data])
}, [data]);
const handleFilterEmployee = (e) => {
const filterValue = e.target.value;
@ -133,27 +123,27 @@ const Teams = ( {project} ) =>
setFilteredEmployees(employees.filter((emp) => !emp.isActive));
}
};
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="modal fade"
id="user-model"
tabIndex="-1"
aria-labelledby="userModalLabel"
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">
@ -179,13 +169,14 @@ const Teams = ( {project} ) =>
</div>
<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-target="#user-model"
onClick={() => openModel()}
>
<i className="bx bx-plus-circle me-2"></i>
Assign Users
Assign Employee
</button>
</div>
</div>
@ -198,7 +189,6 @@ const Teams = ( {project} ) =>
<th>Assigned Date</th>
<th>Release Date</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
@ -278,259 +268,3 @@ const Teams = ( {project} ) =>
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 dispatch = useDispatch();
const selectedProject = useSelector((store)=>store.localVariables.projectId);
console.log(selectedProject)
const [project, setProject] = useState(null);
const [projectDetails, setProjectDetails] = useState(null);