2025-04-21 15:41:37 +05:30

271 lines
9.0 KiB
JavaScript

import React, { useState, useEffect } from "react";
import MapUsers from "./MapUsers";
import showToast from "../../services/toastService";
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";
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 HasAssignUserPermission = useHasUserPermission(ASSIGN_TO_PROJECT);
const fetchEmployees = async () => {
try {
// if (!empRoles) {
ProjectRepository.getProjectAllocation(project.id)
.then((response) => {
setEmployees(response.data);
setFilteredEmployees(response.data.filter((emp) => emp.isActive));
})
.catch((error) => {
console.error(error);
setError("Failed to fetch data.");
});
} catch (err) {
setError("Failed to fetch activities.");
}
};
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) => {
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";
};
useEffect(() => {
fetchEmployees();
}, []);
useEffect(() => {
if (data) {
setEmpJobRoles(data);
}
}, [data]);
const handleFilterEmployee = (e) => {
const filterValue = e.target.value;
if (filterValue === "true") {
setFilteredEmployees(employees.filter((emp) => emp.isActive));
} else {
setFilteredEmployees(employees.filter((emp) => !emp.isActive));
}
};
return (
<>
<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">
<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}
// value={false}
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 btn-sm m-1 ${
HasAssignUserPermission ? "" : "d-none"
}`}
data-bs-toggle="modal"
data-bs-target="#user-model"
>
<i className="bx bx-plus-circle me-2"></i>
Assign Employee
</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={(e) => {
e.preventDefault(); // Prevent default link behavior
window.location.href =
"/employee/" + item.employee.id;
}}
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;