-
-
-
-
-
-
-
+
+
+
+ {isLoading ? (
+
+ ) : data?.length === 0 ? (
+
No organizations found
+ ) : (
+ <>
+
+
+ >
+ )}
+
+
+
-
-
-
+
-
-
-
-
);
};
diff --git a/src/components/Project/Team/TeamEmployeeList.jsx b/src/components/Project/Team/TeamEmployeeList.jsx
index da62ac91..920d1f6f 100644
--- a/src/components/Project/Team/TeamEmployeeList.jsx
+++ b/src/components/Project/Team/TeamEmployeeList.jsx
@@ -1,12 +1,250 @@
-import React from 'react'
+import React, { useState, useEffect } from "react";
+import Avatar from "../../common/Avatar";
+import { useDebounce } from "../../../utils/appUtils";
+import { useSelectedProject } from "../../../slices/apiDataManager";
+import { useOrganizationEmployees } from "../../../hooks/useOrganization";
+import {
+ useEmployeesByProjectAllocated,
+ useManageProjectAllocation,
+} from "../../../hooks/useProjects";
+import useMaster, { useServices } from "../../../hooks/masterHook/useMaster";
+import showToast from "../../../services/toastService";
-const TeamEmployeeList = ({serviceId,organizationId}) => {
- const {} = use
- return (
-
-
-
- )
+const TeamEmployeeList = ({ organizationId, searchTerm, closeModal }) => {
+ const selectedProject = useSelectedProject();
+ const debounceSearchTerm = useDebounce(searchTerm, 500);
+
+ const {
+ data: employeesData = [],
+ isLoading,
+ isError,
+ error,
+ } = useOrganizationEmployees(
+ selectedProject,
+ organizationId,
+ debounceSearchTerm
+ );
+
+ const { projectEmployees, loading: employeeLodaing } =
+ useEmployeesByProjectAllocated(selectedProject, null);
+
+ const { data: jobRoles } = useMaster();
+ const { data: services } = useServices();
+
+ const [employees, setEmployees] = useState([]);
+
+ const { mutate: handleAssignEmployee, isPending } =
+ useManageProjectAllocation({
+ onSuccessCallback: () => {
+ closeModal();
+ },
+ onErrorCallback: () => {
+ closeModal();
+ },
+ });
+
+ useEffect(() => {
+ if (employeesData?.data?.length > 0) {
+ const available = employeesData.data.filter((emp) => {
+ const projEmp = projectEmployees.find((pe) => pe.employeeId === emp.id);
+ return !projEmp || projEmp.isActive === false;
+ });
+
+ setEmployees(
+ available.map((emp) => ({
+ ...emp,
+ isChecked: false,
+ jobRole: emp?.jobRoleId || null,
+ serviceId: "",
+ errors: {},
+ }))
+ );
+ }
+ }, [employeesData, projectEmployees, organizationId]);
+
+ const handleCheckboxChange = (index) => {
+ setEmployees((prev) => {
+ const newArr = [...prev];
+ newArr[index].isChecked = !newArr[index].isChecked;
+ newArr[index].errors = {};
+ return newArr;
+ });
+ };
+
+ const handleSelectChange = (index, field, value) => {
+ setEmployees((prev) => {
+ const newArr = [...prev];
+ newArr[index][field] = value;
+ newArr[index].errors[field] = "";
+ return newArr;
+ });
+ };
+
+ const onSubmit = () => {
+ const checkedEmployees = employees.filter((emp) => emp.isChecked);
+
+ setEmployees((prev) => prev.map((emp) => ({ ...emp, errors: {} })));
+
+ if (checkedEmployees.length === 0) {
+ showToast("Select at least one employee", "info");
+ return;
+ }
+
+ let hasError = false;
+ const newEmployees = employees.map((emp) => {
+ const empErrors = {};
+ if (emp.isChecked) {
+ if (!emp.jobRole) {
+ empErrors.jobRole = "Job role is required";
+ hasError = true;
+ }
+ if (!emp.serviceId) {
+ empErrors.serviceId = "Service is required";
+ hasError = true;
+ }
+ }
+ return { ...emp, errors: empErrors };
+ });
+
+ setEmployees(newEmployees);
+
+ if (hasError) return; // stop submit if validation fails
+
+ const payload = checkedEmployees.map((emp) => ({
+ employeeId: emp.id,
+ jobRoleId: emp.jobRole,
+ serviceId: emp.serviceId,
+ projectId: selectedProject,
+ status: true,
+ }));
+
+ handleAssignEmployee({ payload });
+
+ setEmployees((prev) =>
+ prev.map((emp) => ({
+ ...emp,
+ isChecked: false,
+ jobRole: "",
+ serviceId: "",
+ errors: {},
+ }))
+ );
+ };
+
+if (isLoading) {
+ return (
) ;
}
-export default TeamEmployeeList
+if (isError) {
+ return (
+
+ {error?.status === 400 ? (
+
Enter employee you want to find.
+ ) : (
+
Something went wrong. Please try again later.
+ )}
+
+
+ );
+}
+
+if (employees.length === 0) {
+ return(
No available employees to assign.
) ;
+}
+
+
+ return (
+
+
+
+
+ Employee |
+ Service |
+ Job Role |
+ Select |
+
+
+
+ {employees.map((emp, index) => (
+
+
+
+
+
+ {emp.firstName} {emp.lastName}
+
+
+ |
+
+
+ {emp.errors.serviceId && (
+ {emp.errors.serviceId}
+ )}
+ |
+
+
+ {emp.errors.jobRole && (
+ {emp.errors.jobRole}
+ )}
+ |
+
+ handleCheckboxChange(index)}
+ />
+ |
+
+ ))}
+
+
+
+
+
+
+
+ );
+};
+
+export default TeamEmployeeList;
diff --git a/src/components/Project/Team/Teams.jsx b/src/components/Project/Team/Teams.jsx
index f684347a..0d5d501d 100644
--- a/src/components/Project/Team/Teams.jsx
+++ b/src/components/Project/Team/Teams.jsx
@@ -24,24 +24,20 @@ import GlobalModel from "../../common/GlobalModel";
import TeamAssignToProject from "./TeamAssignToProject";
const Teams = () => {
- const projectId = useSelectedProject();
+ const selectedProject = useSelectedProject();
const dispatch = useDispatch();
- const [AssigTeam,setAssignTeam] = useState(false)
- const { data, loading } = useMaster();
- const [isModalOpen, setIsModelOpen] = useState(false);
- const [error, setError] = useState("");
- const [empJobRoles, setEmpJobRoles] = useState(null);
+ const [AssigTeam, setAssignTeam] = useState(false);
const [employees, setEmployees] = useState([]);
const [filteredEmployees, setFilteredEmployees] = useState([]);
- const [removingEmployeeId, setRemovingEmployeeId] = useState(null);
- const [assignedLoading, setAssignedLoading] = useState(false);
- const [activeEmployee, setActiveEmployee] = useState(true);
+ const [selectedEmployee, setSelectedEmployee] = useState(null);
const [deleteEmployee, setDeleteEmplyee] = useState(null);
const [searchTerm, setSearchTerm] = useState(""); // State for search term
const [selectedService, setSelectedService] = useState(null);
+ const [activeEmployee,setActiveEmployee] = useState(false)
const { data: assignedServices, isLoading: servicesLoading } =
- useProjectAssignedServices(projectId);
+ useProjectAssignedServices(selectedProject);
+ const {data:empJobRoles,loading} = useMaster()
const handleToggleActive = (e) => setActiveEmployee(e.target.checked);
const handleServiceChange = (e) => {
@@ -56,7 +52,7 @@ const Teams = () => {
projectEmployees,
loading: employeeLodaing,
refetch,
- } = useEmployeesByProjectAllocated(projectId, selectedService);
+ } = useEmployeesByProjectAllocated(selectedProject, selectedService,null,activeEmployee);
const {
mutate: submitAllocations,
isPending,
@@ -65,7 +61,6 @@ const Teams = () => {
} = useManageProjectAllocation({
onSuccessCallback: () => {
setRemovingEmployeeId(null);
- setAssignedLoading(false);
setDeleteEmplyee(null);
closeDeleteModal();
},
@@ -74,44 +69,20 @@ const Teams = () => {
},
});
- const removeAllocation = (item) => {
- setRemovingEmployeeId(item.id);
+ const handleDelete = (employee) => {
+ let payload = [
+ {
+ employeeId: employee.employeeId,
+ jobRoleId: employee.jobRoleId,
+ projectId: selectedProject,
+ serviceId: selectedService,
+ status: false,
+ },
+ ];
- submitAllocations({
- items: [
- {
- empID: item.employeeId,
- jobRoleId: item.jobRoleId,
- projectId: projectId,
- status: false,
- },
- ],
- added: false,
- });
+ submitAllocations({payload:payload});
};
-
- const handleEmpAlicationFormSubmit = (allocaionObj) => {
- 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";
- };
-
- const getRole = (jobRoleId) => {
+ const getJobRole = (jobRoleId) => {
if (loading) return "Loading...";
if (!Array.isArray(empJobRoles)) return "Unassigned";
if (!jobRoleId) return "Unassigned";
@@ -119,165 +90,47 @@ const Teams = () => {
const role = empJobRoles.find((b) => b.id == jobRoleId);
return role ? role.name : "Unassigned";
};
- const openModel = () => {
- setIsModelOpen(true);
- };
+ // const employeeHandler = useCallback(
+ // (msg) => {
+ // if (filteredEmployees.some((emp) => emp.employeeId == msg.employeeId)) {
+ // refetch();
+ // }
+ // },
+ // [filteredEmployees, refetch]
+ // );
- 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(() => {
- dispatch(changeMaster("Job Role"));
- }, [dispatch]);
-
- useEffect(() => {
- if (projectEmployees) {
- setEmployees(projectEmployees);
- const filtered = projectEmployees.filter((emp) => emp.isActive);
- setFilteredEmployees(filtered);
- }
- }, [projectEmployees, employeeLodaing]);
-
- useEffect(() => {
- if (data) {
- setEmpJobRoles(data);
- }
- }, [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();
- const orgName = (item.organizationName || "").toLowerCase();
- const serviceName = (item.serviceName || "").toLowerCase();
-
- return (
- fullName.includes(lowercasedSearchTerm) ||
- roleName.includes(lowercasedSearchTerm) ||
- orgName.includes(lowercasedSearchTerm) ||
- serviceName.includes(lowercasedSearchTerm)
- );
- });
-
- setFilteredEmployees(searchedAndFiltered);
- }, [employees, activeEmployee, searchTerm, getRole]);
-
- useEffect(() => {
- filterAndSearchEmployees();
- }, [employees, activeEmployee, searchTerm, filterAndSearchEmployees]);
-
- const handleFilterEmployee = (e) => {
- const filterValue = e.target.value;
- setActiveEmployee(filterValue === "true");
- setSearchTerm("");
- };
-
- const handleSearch = (e) => {
- setSearchTerm(e.target.value);
- };
-
- const deleteModalOpen = (item) => {
- setDeleteEmplyee(item);
- setIsDeleteModal(true);
- };
- const closeDeleteModal = () => setIsDeleteModal(false);
-
- const handler = useCallback(
- (msg) => {
- if (msg.projectIds.some((item) => item === projectId)) {
- refetch();
- }
- },
- [projectId, refetch]
- );
-
- useEffect(() => {
- eventBus.on("assign_project_all", handler);
- return () => eventBus.off("assign_project_all", handler);
- }, [handler]);
-
- const employeeHandler = useCallback(
- (msg) => {
- if (filteredEmployees.some((item) => item.employeeId == msg.employeeId)) {
- refetch();
- }
- },
- [filteredEmployees, refetch]
- );
-
- useEffect(() => {
- eventBus.on("employee", employeeHandler);
- return () => eventBus.off("employee", employeeHandler);
- }, [employeeHandler]);
+ // useEffect(() => {
+ // eventBus.on("employee", employeeHandler);
+ // return () => eventBus.off("employee", employeeHandler);
+ // }, [employeeHandler]);
return (
<>
-
-
-
-
-
{AssigTeam && (
-
setAssignTeam(false)}>
-
+ setAssignTeam(false)}
+ >
+ setAssignTeam(false)} />
)}
- {IsDeleteModal && (
- removeAllocation(deleteEmployee)}
- onClose={closeDeleteModal}
- loading={isPending}
- />
- )}
+ handleDelete(selectedEmployee)}
+ onClose={() => setSelectedEmployee(null)}
+ />
-
-
+
+ {/*
{!servicesLoading &&
assignedServices?.length > 0 &&
(assignedServices.length > 1 ? (
@@ -306,9 +159,9 @@ const Teams = () => {
) : (
{assignedServices[0].name}
))}
-
+
*/}
-
+
{
{activeEmployee ? "Active Employees" : "Inactive Employees"}
-
- x``
+
{HasAssignUserPermission && (
{employeeLodaing &&
Loading..
}
- {!employeeLodaing &&
- filteredEmployees &&
- filteredEmployees.length > 0 && (
-
-
-
-
- Name
- |
- Services |
- Organization |
- Assigned Date |
- {!activeEmployee && Release Date | }
- Project Role |
- Actions |
-
-
-
- {filteredEmployees &&
- filteredEmployees.map((item) => (
-
-
-
- |
-
- {item.serviceName || "N/A"} |
- {item.organizationName || "N/A"} |
-
-
- {moment(item.allocationDate).format("DD-MMM-YYYY")}
- |
- {!activeEmployee && (
-
- {item.reAllocationDate
- ? moment(item.reAllocationDate).format(
- "DD-MMM-YYYY"
+ {projectEmployees && projectEmployees.length > 0 && (
+
+
+
+
+ Name
+ |
+ Services |
+ Organization |
+ Assigned Date |
+ Release Date |
+ Project Role |
+ Actions |
+
+
+
+ {projectEmployees &&
+ projectEmployees.map((emp) => (
+
+
+ |
- )}
-
-
- {getRole(item.jobRoleId)}
-
- |
-
- {item.isActive ? (
-
- ) : (
- Not in project
- )}
- |
-
- ))}
-
-
- )}
- {!employeeLodaing && filteredEmployees.length === 0 && (
+
+ {emp.firstName}
+ {emp.lastName}
+
+
+
+
+ |
+
+ {emp.serviceName || "N/A"} |
+ {emp.organizationName || "N/A"} |
+
+
+ {moment(emp.allocationDate).format("DD-MMM-YYYY")}
+ |
+
+ {emp.reAllocationDate
+ ? moment(emp.reAllocationDate).format("DD-MMM-YYYY")
+ : "Present"}
+ |
+
+
+ {getJobRole(emp.jobRoleId)}
+
+ |
+
+ {emp.isActive ? (
+
+ ) : (
+ Not in project
+ )}
+ |
+
+ ))}
+
+
+ )}
+ {/* {!employeeLodaing && filteredEmployees.length === 0 && (
{activeEmployee
? "No active employees assigned to the project"
: "No inactive employees assigned to the project"}
- )}
+ )} */}
diff --git a/src/hooks/useOrganization.js b/src/hooks/useOrganization.js
index dea19874..d6c93693 100644
--- a/src/hooks/useOrganization.js
+++ b/src/hooks/useOrganization.js
@@ -35,6 +35,8 @@ export const useOrganizationModal = () => {
};
};
+// ================================Query=============================================================
+
export const useOrganizationBySPRID = (sprid) => {
return useQuery({
queryKey: ["organization by", sprid],
@@ -76,6 +78,25 @@ export const useOrganizationsList = (
});
};
+export const useOrganizationEmployees = (
+ projectId,
+ organizationId,
+ searchString
+) => {
+ return useQuery({
+ queryKey: ["OrgEmployees", projectId, organizationId, searchString],
+ queryFn: async () =>
+ await OrganizationRepository.getOrganizationEmployees(
+ projectId,
+ organizationId,
+ searchString
+ ),
+ enabled: !!projectId ,
+ });
+};
+
+// =================================Mutation========================================================
+
export const useCreateOrganization = (onSuccessCallback) => {
const useClient = useQueryClient();
return useMutation({
@@ -103,11 +124,11 @@ export const useAssignOrgToProject = (onSuccessCallback) => {
mutationFn: async (payload) =>
await OrganizationRepository.assignOrganizationToProject(payload),
onSuccess: (_, variables) => {
- const {projectId} = variables
+ const { projectId } = variables;
useClient.invalidateQueries({
queryKey: ["projectAssignedOrganiztions"],
});
- useClient.invalidateQueries({
+ useClient.invalidateQueries({
queryKey: ["projectAssignedOrganization", projectId],
});
showToast("Organization successfully", "success");
diff --git a/src/hooks/useProjects.js b/src/hooks/useProjects.js
index bdbd01c6..9225b0c4 100644
--- a/src/hooks/useProjects.js
+++ b/src/hooks/useProjects.js
@@ -54,7 +54,7 @@ export const useProjects = () => {
export const useEmployeesByProjectAllocated = (
projectId,
serviceId,
- organizationId,
+ organizationId,emloyeeeStatus
) => {
const {
data = [],
@@ -62,12 +62,12 @@ export const useEmployeesByProjectAllocated = (
refetch,
error,
} = useQuery({
- queryKey: ["empListByProjectAllocated", projectId, serviceId,organizationId],
+ queryKey: ["empListByProjectAllocated", projectId, serviceId,organizationId,emloyeeeStatus],
queryFn: async () => {
const res = await ProjectRepository.getProjectAllocation(
- projectId,
+ projectId, serviceId,
organizationId,
- serviceId
+ emloyeeeStatus
);
return res?.data || res;
},
@@ -413,8 +413,8 @@ export const useManageProjectAllocation = ({
const queryClient = useQueryClient();
const { mutate, isPending, isSuccess, isError } = useMutation({
- mutationFn: async ({ items }) => {
- const response = await ProjectRepository.manageProjectAllocation(items);
+ mutationFn: async ({payload}) => {
+ const response = await ProjectRepository.manageProjectAllocation(payload);
return response.data;
},
onSuccess: (data, variables, context) => {
diff --git a/src/repositories/OrganizationRespository.jsx b/src/repositories/OrganizationRespository.jsx
index 4b4ad1b0..28bbf3ce 100644
--- a/src/repositories/OrganizationRespository.jsx
+++ b/src/repositories/OrganizationRespository.jsx
@@ -10,11 +10,33 @@ const OrganizationRepository = {
);
},
- getOrganizationBySPRID :(sprid)=>api.get(`/api/Organization/list?sprid=${sprid}`),
+ getOrganizationBySPRID: (sprid) =>
+ api.get(`/api/Organization/list?sprid=${sprid}`),
- assignOrganizationToProject:(data)=>api.post(`/api/Organization/assign/project`,data),
+ assignOrganizationToProject: (data) =>
+ api.post(`/api/Organization/assign/project`, data),
- assignOrganizationToTenanat:(organizationId)=>api.post(`/api/Organization/assign/tenant/${organizationId}`)
+ assignOrganizationToTenanat: (organizationId) =>
+ api.post(`/api/Organization/assign/tenant/${organizationId}`),
+
+ getOrganizationEmployees: (projectId, organizationId, searchString) => {
+ let url = `/api/Employee/list/organizations/${projectId}`;
+ const queryParams = [];
+
+ if (organizationId) {
+ queryParams.push(`organizationId=${organizationId}`);
+ }
+
+ if (searchString) {
+ queryParams.push(`searchString=${encodeURIComponent(searchString)}`);
+ }
+
+ if (queryParams.length > 0) {
+ url += `?${queryParams.join("&")}`;
+ }
+
+ return api.get(url);
+ },
};
export default OrganizationRepository;
diff --git a/src/repositories/ProjectRepository.jsx b/src/repositories/ProjectRepository.jsx
index b1b0727f..43a1ee66 100644
--- a/src/repositories/ProjectRepository.jsx
+++ b/src/repositories/ProjectRepository.jsx
@@ -5,19 +5,21 @@ const ProjectRepository = {
getProjectByprojectId: (projetid) =>
api.get(`/api/project/details/${projetid}`),
- getProjectAllocation: (projectId, organizationId, serviceId) => {
- let url = `/api/project/allocation/${projectId}`;
+ getProjectAllocation: (projectId, serviceId, organizationId, employeeStatus) => {
+ let url = `/api/project/allocation/${projectId}`;
- const params = [];
- if (organizationId) params.push(`organizationId=${organizationId}`);
- if (serviceId) params.push(`serviceId=${serviceId}`);
+ const params = [];
+ if (organizationId) params.push(`organizationId=${organizationId}`);
+ if (serviceId) params.push(`serviceId=${serviceId}`);
+ if (employeeStatus !== undefined) params.push(`includeInactive=${employeeStatus}`);
- if (params.length > 0) {
- url += `?${params.join("&")}`;
- }
+ if (params.length > 0) {
+ url += `?${params.join("&")}`;
+ }
+
+ return api.get(url);
+},
- return api.get(url);
- },
getEmployeesByProject: (projectId) =>
api.get(`/api/Project/employees/get/${projectId}`),