678 lines
19 KiB
JavaScript
678 lines
19 KiB
JavaScript
import { useCallback, useEffect, useState } from "react";
|
|
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
|
import ProjectRepository from "../repositories/ProjectRepository";
|
|
import { useProfile } from "./useProfile";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { setProjectId } from "../slices/localVariablesSlice";
|
|
import EmployeeList from "../components/Directory/EmployeeList";
|
|
import eventBus from "../services/eventBus";
|
|
import {
|
|
Mutation,
|
|
useMutation,
|
|
useQuery,
|
|
useQueryClient,
|
|
} from "@tanstack/react-query";
|
|
import showToast from "../services/toastService";
|
|
|
|
export const useCurrentService = () => {
|
|
return useSelector((store) => store.globalVariables.selectedServiceId);
|
|
};
|
|
|
|
// ------------------------------Query-------------------
|
|
|
|
export const useProjects = () => {
|
|
const loggedUser = useSelector((store) => store.globalVariables.loginUser);
|
|
return useQuery({
|
|
queryKey: ["ProjectsList"],
|
|
queryFn: async () => {
|
|
const response = await ProjectRepository.getProjectList();
|
|
return response.data;
|
|
},
|
|
enabled: !!loggedUser,
|
|
});
|
|
};
|
|
|
|
export const useEmployeesByProjectAllocated = (
|
|
projectId,
|
|
serviceId,
|
|
organizationId,
|
|
emloyeeeStatus
|
|
) => {
|
|
const {
|
|
data = [],
|
|
isLoading,
|
|
refetch,
|
|
error,
|
|
} = useQuery({
|
|
queryKey: [
|
|
"empListByProjectAllocated",
|
|
projectId,
|
|
serviceId,
|
|
organizationId,
|
|
emloyeeeStatus,
|
|
],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.getProjectAllocation(
|
|
projectId,
|
|
serviceId,
|
|
organizationId,
|
|
emloyeeeStatus
|
|
);
|
|
return res?.data || res;
|
|
},
|
|
enabled: !!projectId,
|
|
onError: (error) => {
|
|
showToast(
|
|
error.message || "Error while fetching project allocated employees",
|
|
"error"
|
|
);
|
|
},
|
|
});
|
|
|
|
return {
|
|
projectEmployees: data,
|
|
loading: isLoading,
|
|
error,
|
|
refetch,
|
|
};
|
|
};
|
|
|
|
export const useProjectDetails = (projectId, isAuto = true) => {
|
|
const {
|
|
data: projects_Details,
|
|
isLoading,
|
|
error,
|
|
refetch,
|
|
} = useQuery({
|
|
queryKey: ["projectInfo", projectId],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.getProjectByprojectId(projectId);
|
|
return res.data || res;
|
|
},
|
|
enabled: !!projectId && isAuto,
|
|
onError: (error) => {
|
|
showToast(
|
|
error.message || "Error while Fetching project Details",
|
|
"error"
|
|
);
|
|
},
|
|
});
|
|
return { projects_Details, loading: isLoading, error, refetch };
|
|
};
|
|
|
|
export const useProjectsByEmployee = (employeeId) => {
|
|
const {
|
|
data: projectList = [],
|
|
isLoading,
|
|
error,
|
|
refetch,
|
|
} = useQuery({
|
|
queryKey: ["ProjectsByEmployee", employeeId],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.getProjectsByEmployee(employeeId);
|
|
return res.data || res;
|
|
},
|
|
enabled: !!employeeId,
|
|
onError: (error) => {
|
|
showToast(
|
|
error.message || "Error while Fetching project Employee",
|
|
"error"
|
|
);
|
|
},
|
|
});
|
|
return { projectList, loading: isLoading, error, refetch };
|
|
};
|
|
|
|
export const useProjectsAllocationByEmployee = (employeeId) => {
|
|
const {
|
|
data: projectList = [],
|
|
isLoading,
|
|
error,
|
|
refetch,
|
|
} = useQuery({
|
|
queryKey: ["ProjectsAllocationByEmployee", employeeId],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.getProjectsAllocationByEmployee(
|
|
employeeId
|
|
);
|
|
const sortedProjects = [...res.data].sort((a, b) =>
|
|
a.projectName.localeCompare(b.projectName)
|
|
);
|
|
return sortedProjects || res;
|
|
|
|
//return res.data || res;
|
|
},
|
|
enabled: !!employeeId,
|
|
onError: (error) => {
|
|
showToast(
|
|
error.message || "Error while Fetching project Employee",
|
|
"error"
|
|
);
|
|
},
|
|
});
|
|
return { projectList, loading: isLoading, error, refetch };
|
|
};
|
|
|
|
export const useProjectName = () => {
|
|
const {
|
|
data = [],
|
|
isLoading,
|
|
error,
|
|
refetch,
|
|
isError,
|
|
} = useQuery({
|
|
queryKey: ["basicProjectNameList"],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.projectNameList();
|
|
return res.data || res;
|
|
},
|
|
onError: (error) => {
|
|
showToast(error.message || "Error while Fetching project Name", "error");
|
|
},
|
|
});
|
|
return {
|
|
projectNames: data,
|
|
loading: isLoading,
|
|
Error: error,
|
|
refetch,
|
|
isError,
|
|
};
|
|
};
|
|
|
|
export const useProjectInfra = (projectId, serviceId) => {
|
|
const {
|
|
data: projectInfra,
|
|
isLoading,
|
|
error,
|
|
isFetched,
|
|
} = useQuery({
|
|
queryKey: ["ProjectInfra", projectId, serviceId],
|
|
queryFn: async () => {
|
|
if (!projectId) return null;
|
|
const res = await ProjectRepository.getProjectInfraByproject(
|
|
projectId,
|
|
serviceId
|
|
);
|
|
return res.data;
|
|
},
|
|
enabled: !!projectId,
|
|
onError: (error) => {
|
|
showToast(error.message || "Error while fetching project infra", "error");
|
|
},
|
|
});
|
|
|
|
return { projectInfra, isLoading, error, isFetched };
|
|
};
|
|
|
|
export const useProjectTasks = (
|
|
workAreaId,
|
|
serviceId = null,
|
|
isExpandedArea = false
|
|
) => {
|
|
const { data, isLoading, error } = useQuery({
|
|
queryKey: ["WorkItems", workAreaId, serviceId],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.getProjectTasksByWorkArea(
|
|
workAreaId,
|
|
serviceId
|
|
);
|
|
return res.data; // return actual task list
|
|
},
|
|
enabled: !!workAreaId && isExpandedArea, // only fetch if workAreaId exists and area is expanded
|
|
onError: (err) => {
|
|
showToast(err.message || "Error while fetching project tasks", "error");
|
|
},
|
|
});
|
|
|
|
return { ProjectTaskList: data, isLoading, error };
|
|
};
|
|
|
|
export const useProjectTasksByEmployee = (employeeId, fromDate, toDate) => {
|
|
return useQuery({
|
|
queryKey: ["TasksByEmployee", employeeId],
|
|
queryFn: async () => {
|
|
const res = await ProjectRepository.getProjectTasksByEmployee(
|
|
employeeId,
|
|
fromDate,
|
|
toDate
|
|
);
|
|
return res.data;
|
|
},
|
|
enabled: !!employeeId && !!fromDate && !!toDate,
|
|
onError: (error) => {
|
|
showToast(error.message || "Error while Fetching project Tasks", "error");
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useProjectLevelEmployeeList = (ProjectId) => {
|
|
return useQuery({
|
|
queryKey: ["ProjectLevelEmployeeList", ProjectId],
|
|
queryFn: async () => {
|
|
const resp = await ProjectRepository.getProjectLevelEmployeeList(
|
|
ProjectId
|
|
);
|
|
return resp.data;
|
|
},
|
|
enabled: !!ProjectId,
|
|
});
|
|
};
|
|
|
|
export const useProjectLevelModules = () => {
|
|
return useQuery({
|
|
queryKey: ["ProjectLevelModules"],
|
|
queryFn: async () => {
|
|
const resp = await ProjectRepository.getProjectLevelModules();
|
|
return resp.data;
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useProjectLevelEmployeePermission = (employeeId, projectId) => {
|
|
return useQuery({
|
|
queryKey: ["ProjectLevelEmployeePermission", employeeId, projectId],
|
|
queryFn: async () => {
|
|
const resp = await ProjectRepository.getProjectLevelEmployeePermissions(
|
|
employeeId,
|
|
projectId
|
|
);
|
|
return resp.data;
|
|
},
|
|
enabled: !!employeeId && !!projectId,
|
|
});
|
|
};
|
|
|
|
export const useProjectAssignedOrganizations = (projectId) => {
|
|
return useQuery({
|
|
queryKey: ["projectAssignedOrganiztions", projectId],
|
|
queryFn: async () => {
|
|
const resp = await ProjectRepository.getProjectAssignedOrganizations(
|
|
projectId
|
|
);
|
|
return resp.data;
|
|
},
|
|
enabled: !!projectId,
|
|
});
|
|
};
|
|
export const useProjectAssignedServices = (projectId) => {
|
|
return useQuery({
|
|
queryKey: ["projectAssignedServices", projectId],
|
|
queryFn: async () => {
|
|
const resp = await ProjectRepository.getProjectAssignedServices(
|
|
projectId
|
|
);
|
|
return resp.data;
|
|
},
|
|
enabled: !!projectId,
|
|
});
|
|
};
|
|
|
|
export const useEmployeeForTaskAssign = (
|
|
projectId,
|
|
serviceId,
|
|
organizationId
|
|
) => {
|
|
return useQuery({
|
|
queryKey: ["EmployeeForTaskAssign", projectId, serviceId, organizationId],
|
|
queryFn: async () =>
|
|
await ProjectRepository.getEmployeeForTaskAssign(
|
|
projectId,
|
|
serviceId,
|
|
organizationId
|
|
),
|
|
});
|
|
};
|
|
|
|
// -- -------------Mutation-------------------------------
|
|
|
|
export const useCreateProject = ( onSuccessCallback ) => {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: async (payload) => {
|
|
const res = await ProjectRepository.manageProject(payload);
|
|
return res.data;
|
|
},
|
|
onSuccess: (data) => {
|
|
// Invalidate the cache
|
|
queryClient.invalidateQueries({ queryKey: ["ProjectsList"] });
|
|
queryClient.invalidateQueries({ queryKey: ["basicProjectNameList"] });
|
|
|
|
// Emit event for consumers (like useProjects or others)
|
|
eventBus.emit("project", {
|
|
keyword: "Create_Project",
|
|
response: data,
|
|
});
|
|
|
|
showToast("Project Created successfully.", "success");
|
|
|
|
if (onSuccessCallback) {
|
|
onSuccessCallback(data);
|
|
}
|
|
},
|
|
onError: (error) => {
|
|
showToast(error.message || "Error while creating project", "error");
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useUpdateProject = ( onSuccessCallback ) => {
|
|
const queryClient = useQueryClient();
|
|
const { mutate, isPending, isSuccess, isError } = useMutation({
|
|
mutationFn: async ({ projectId, payload }) => {
|
|
return await ProjectRepository.updateProject(projectId, payload);
|
|
},
|
|
|
|
onSuccess: (data, variables) => {
|
|
const { projectId } = variables;
|
|
|
|
queryClient.invalidateQueries({ queryKey: ["ProjectsList"] });
|
|
queryClient.invalidateQueries({ queryKey: ["projectInfo", projectId] });
|
|
queryClient.invalidateQueries({ queryKey: ["basicProjectNameList"] });
|
|
|
|
eventBus.emit("project", {
|
|
keyword: "Update_Project",
|
|
response: data,
|
|
});
|
|
|
|
showToast("Project updated successfully.", "success");
|
|
|
|
if (onSuccessCallback) {
|
|
onSuccessCallback(data);
|
|
}
|
|
},
|
|
|
|
onError: (error) => {
|
|
console.log(error);
|
|
showToast(error?.message || "Error while updating project", "error");
|
|
},
|
|
});
|
|
|
|
return {
|
|
mutate,
|
|
isPending,
|
|
isSuccess,
|
|
isError,
|
|
};
|
|
};
|
|
|
|
export const useManageProjectInfra = ({ onSuccessCallback }) => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: async ({ infraObject, projectId }) => {
|
|
return await ProjectRepository.manageProjectInfra(infraObject);
|
|
},
|
|
onSuccess: (data, variables) => {
|
|
const { projectId } = variables;
|
|
queryClient.invalidateQueries({ queryKey: ["ProjectInfra", projectId] });
|
|
if (onSuccessCallback) onSuccessCallback(data, variables);
|
|
},
|
|
onError: (error) => {
|
|
showToast(error.message || "Failed to update Project Infra", "error");
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useManageProjectAllocation = ({
|
|
onSuccessCallback,
|
|
onErrorCallback,
|
|
}) => {
|
|
const queryClient = useQueryClient();
|
|
|
|
const { mutate, isPending, isSuccess, isError } = useMutation({
|
|
mutationFn: async ({ payload }) => {
|
|
const response = await ProjectRepository.manageProjectAllocation(payload);
|
|
return response.data;
|
|
},
|
|
onSuccess: (data, variables, context) => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["empListByProjectAllocated"],
|
|
});
|
|
queryClient.removeQueries({ queryKey: ["projectEmployees"] });
|
|
queryClient.removeQueries({ queryKey: ["EmployeeForTaskAssign"] });
|
|
if (variables.actionType === "assign") {
|
|
showToast("Employee Assigned Successfully", "success");
|
|
} else {
|
|
showToast("Removed Employee Successfully", "success");
|
|
}
|
|
|
|
if (onSuccessCallback) onSuccessCallback(data, context);
|
|
},
|
|
onError: (error) => {
|
|
const message =
|
|
error?.response?.data?.message ||
|
|
error.message ||
|
|
"Error occurred during API call";
|
|
showToast(message, "error");
|
|
if (onErrorCallback) onErrorCallback(error);
|
|
},
|
|
});
|
|
|
|
return {
|
|
mutate,
|
|
isPending,
|
|
isSuccess,
|
|
isError,
|
|
};
|
|
};
|
|
|
|
export const useManageTask = ({ onSuccessCallback }) => {
|
|
const queryClient = useQueryClient();
|
|
const selectedProject = useSelector(
|
|
(store) => store.localVariables.projectId
|
|
);
|
|
return useMutation({
|
|
mutationFn: async ({
|
|
payload,
|
|
PreviousPlannedWork,
|
|
previousCompletedWork,
|
|
buildingId,
|
|
floorId,
|
|
workAreaId,
|
|
}) => await ProjectRepository.manageProjectTasks(payload),
|
|
onSuccess: (data, variables) => {
|
|
const {
|
|
workAreaId,
|
|
buildingId,
|
|
floorId,
|
|
PreviousPlannedWork,
|
|
previousCompletedWork,
|
|
} = variables;
|
|
queryClient.invalidateQueries({ queryKey: ["WorkItems"] });
|
|
const getPlannedDelta = (previous, current) => current - previous;
|
|
queryClient.setQueryData(["ProjectInfra", selectedProject], (oldData) => {
|
|
if (!oldData) return oldData;
|
|
const { workAreaId, floorId, buildingId } = variables;
|
|
const updatedData = JSON.parse(JSON.stringify(oldData));
|
|
return updatedData.map((building) => {
|
|
if (building.id !== buildingId) return building;
|
|
return {
|
|
...building,
|
|
floors: building.floors.map((floor) => {
|
|
if (floor.id !== floorId) return floor;
|
|
|
|
return {
|
|
...floor,
|
|
workAreas: floor.workAreas.map((area) => {
|
|
if (area.id !== workAreaId) return area;
|
|
|
|
const previousPlanned = PreviousPlannedWork ?? 0;
|
|
const currentPlanned =
|
|
data?.data[0]?.workItem.plannedWork ?? 0;
|
|
|
|
const plannedWorkDelta = getPlannedDelta(
|
|
previousPlanned,
|
|
currentPlanned
|
|
);
|
|
const updatedPlannedWork =
|
|
(area.plannedWork ?? 0) + plannedWorkDelta;
|
|
const previousCompleted = previousCompletedWork;
|
|
|
|
const currentCompleted =
|
|
data?.data[0]?.workItem.completedWork ?? 0;
|
|
const completedWorkDelta = getPlannedDelta(
|
|
previousCompleted,
|
|
currentCompleted
|
|
);
|
|
const updatedCompletedWork =
|
|
(area.completedWork ?? 0) + completedWorkDelta;
|
|
return {
|
|
...area,
|
|
plannedWork: updatedPlannedWork,
|
|
completedWork: updatedCompletedWork,
|
|
};
|
|
}),
|
|
};
|
|
}),
|
|
};
|
|
});
|
|
});
|
|
|
|
queryClient.setQueryData(["ProjectsList"], (projects) => {
|
|
if (!projects) return projects;
|
|
|
|
return projects.map((project) => {
|
|
if (project.id !== selectedProject) return project;
|
|
|
|
const previousPlanned = PreviousPlannedWork ?? 0;
|
|
const currentPlanned = data?.data[0]?.workItem.plannedWork ?? 0;
|
|
|
|
const plannedWorkDelta = getPlannedDelta(
|
|
previousPlanned,
|
|
currentPlanned
|
|
);
|
|
const updatedPlannedWork =
|
|
(project.plannedWork ?? 0) + plannedWorkDelta;
|
|
const previousCompleted = previousCompletedWork;
|
|
const currentCompleted = data?.data[0]?.workItem.completedWork ?? 0;
|
|
const completedWorkDelta = getPlannedDelta(
|
|
previousCompleted,
|
|
currentCompleted
|
|
);
|
|
const updatedCompletedWork =
|
|
(project.completedWork ?? 0) + completedWorkDelta;
|
|
return {
|
|
...project,
|
|
plannedWork: updatedPlannedWork,
|
|
completedWork: updatedCompletedWork,
|
|
};
|
|
});
|
|
});
|
|
if (onSuccessCallback) onSuccessCallback(data);
|
|
},
|
|
onError: (error) => {
|
|
const message =
|
|
error?.response?.data?.message ||
|
|
error.message ||
|
|
"Error occurred during API call";
|
|
showToast(message, "error");
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useDeleteProjectTask = (onSuccessCallback) => {
|
|
const queryClient = useQueryClient();
|
|
const selectedProject = useSelector(
|
|
(store) => store.localVariables.projectId
|
|
);
|
|
return useMutation({
|
|
mutationFn: async ({
|
|
workItemId,
|
|
workAreaId,
|
|
completedTask,
|
|
plannedTask,
|
|
}) => {
|
|
return await ProjectRepository.deleteProjectTask(workItemId);
|
|
},
|
|
onSuccess: (_, variables) => {
|
|
const { completedTask, plannedTask, workAreaId, buildingId, floorId } =
|
|
variables;
|
|
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["WorkItems", variables.workAreaId],
|
|
});
|
|
|
|
queryClient.setQueryData(["ProjectInfra", selectedProject], (oldData) => {
|
|
if (!oldData) return oldData;
|
|
|
|
const { workAreaId, floorId, buildingId, plannedTask, completedTask } =
|
|
variables;
|
|
|
|
const updatedData = JSON.parse(JSON.stringify(oldData));
|
|
|
|
return updatedData.map((building) => {
|
|
if (building.id !== buildingId) return building;
|
|
|
|
return {
|
|
...building,
|
|
floors: building.floors.map((floor) => {
|
|
if (floor.id !== floorId) return floor;
|
|
|
|
return {
|
|
...floor,
|
|
workAreas: floor.workAreas.map((area) => {
|
|
if (area.id !== workAreaId) return area;
|
|
|
|
return {
|
|
...area,
|
|
plannedWork: (area.plannedWork ?? 0) - plannedTask,
|
|
completedWork: (area.completedWork ?? 0) - completedTask,
|
|
};
|
|
}),
|
|
};
|
|
}),
|
|
};
|
|
});
|
|
});
|
|
|
|
queryClient.setQueryData(["ProjectsList"], (projects) => {
|
|
if (!projects) return projects;
|
|
|
|
return projects.map((project) => {
|
|
if (project.id !== selectedProject) return project;
|
|
|
|
return {
|
|
...project,
|
|
plannedWork: (project.plannedWork ?? 0) - plannedTask,
|
|
completedWork: (project.completedWork ?? 0) - completedTask,
|
|
};
|
|
});
|
|
});
|
|
showToast("Task deleted successfully", "success");
|
|
if (onSuccessCallback) onSuccessCallback();
|
|
},
|
|
onError: (error) => {
|
|
showToast(
|
|
error?.response?.data?.message ||
|
|
error.message ||
|
|
"Failed to delete task",
|
|
"error"
|
|
);
|
|
if (onSuccessCallback) onSuccessCallback();
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useUpdateProjectLevelEmployeePermission = () => {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: async (payload) =>
|
|
await ProjectRepository.updateProjectLevelEmployeePermission(payload),
|
|
onSuccess: (data, variables, context) => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["ProjectLevelEmployeePermission"],
|
|
});
|
|
showToast("Permission Updated successfully", "success");
|
|
},
|
|
onError: (error) => {
|
|
showToast(
|
|
error?.response?.data?.message ||
|
|
error.message ||
|
|
"Failed to delete task",
|
|
"error"
|
|
);
|
|
if (onSuccessCallback) onSuccessCallback();
|
|
},
|
|
});
|
|
};
|