implement partial react-query in task assignment flow
This commit is contained in:
parent
7fbbe98373
commit
f848f97d87
@ -21,17 +21,13 @@ const InfraPlanning = () =>
|
||||
{
|
||||
const {profile: LoggedUser, refetch : fetchData} = useProfile()
|
||||
const dispatch = useDispatch()
|
||||
const {projects,loading:project_listLoader,error:projects_error} = useProjects()
|
||||
// const {projects,loading:project_listLoader,error:projects_error} = useProjects()
|
||||
|
||||
const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
||||
const ManageInfra = useHasUserPermission( MANAGE_PROJECT_INFRA )
|
||||
const {projects_Details, loading: project_deatilsLoader, error: project_error,refetch} = useProjectDetails( selectedProject )
|
||||
const reloadedData = useSelector( ( store ) => store.localVariables.reload )
|
||||
|
||||
// useEffect( () =>
|
||||
// {
|
||||
// dispatch(setProjectId(projects[0]?.id))
|
||||
// }, [ projects ] )
|
||||
|
||||
useEffect( () =>
|
||||
{
|
||||
@ -48,24 +44,6 @@ const InfraPlanning = () =>
|
||||
<div className="card">
|
||||
<div className="card-body" style={{ padding: "0.5rem" }}>
|
||||
<div className="align-items-center">
|
||||
{/* <div className="row ">
|
||||
<div className="col-sm-3 col-8 text-start mb-1">
|
||||
<select name="DataTables_Table_0_length"
|
||||
aria-controls="DataTables_Table_0"
|
||||
className="form-select form-select-sm"
|
||||
value={selectedProject}
|
||||
onChange={(e)=>dispatch(setProjectId(e.target.value))}
|
||||
aria-label=""
|
||||
>
|
||||
{(project_listLoader || projects.length < 0) && <option value="Loading..." disabled>Loading...</option> }
|
||||
|
||||
{!project_listLoader && projects?.map((project)=>(
|
||||
<option key={project.id} value={project.id}>{project.name}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div> */}
|
||||
<div className="row ">
|
||||
{project_deatilsLoader && ( <p>Loading...</p> )}
|
||||
{( !project_deatilsLoader && projects_Details?.buildings.length === 0 ) && ( <p>No Result Found</p> )}
|
||||
|
@ -5,9 +5,21 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
import showToast from "../../services/toastService";
|
||||
import { TasksRepository } from "../../repositories/TaskRepository";
|
||||
import {useReportTask} from "../../hooks/useTasks";
|
||||
|
||||
export const ReportTask = ({ report, closeModal, refetch }) => {
|
||||
export const ReportTask = ({ report, closeModal }) => {
|
||||
const [ loading, setloading ] = useState( false );
|
||||
const { mutate: reportTask, isPending } = useReportTask({
|
||||
onSuccessCallback: () => {
|
||||
// refetch();
|
||||
reset();
|
||||
setloading(false);
|
||||
closeModal();
|
||||
},
|
||||
onErrorCallback: () => {
|
||||
setloading(false);
|
||||
},
|
||||
} );
|
||||
|
||||
const maxPending =
|
||||
report?.workItem?.plannedWork - report?.workItem?.completedWork;
|
||||
@ -43,13 +55,35 @@ export const ReportTask = ({ report, closeModal, refetch }) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (report) {
|
||||
reset({ completedTask: 0, comment: "" }); // optional: customize default if needed
|
||||
reset({ completedTask: 0, comment: "" });
|
||||
}
|
||||
}, [report, reset]);
|
||||
|
||||
|
||||
const onSubmit = async (data) => {
|
||||
try {
|
||||
// const onSubmit = async (data) => {
|
||||
// try {
|
||||
// setloading(true);
|
||||
// const reportData = {
|
||||
// ...data,
|
||||
// id: report?.id,
|
||||
// reportedDate: new Date().toISOString(),
|
||||
// checkList: [],
|
||||
// };
|
||||
|
||||
// let response = await TasksRepository.reportTask(reportData);
|
||||
// showToast("Task Reported Successfully.", "success");
|
||||
// refetch();
|
||||
// reset()
|
||||
// setloading(false);
|
||||
// closeModal();
|
||||
// } catch ( error )
|
||||
// {
|
||||
// const msg = error.response.data.message || error.message || "Error Occur During Api Call"
|
||||
// showToast(msg, "error");
|
||||
// }
|
||||
// }
|
||||
|
||||
const onSubmit = (data) => {
|
||||
setloading(true);
|
||||
const reportData = {
|
||||
...data,
|
||||
@ -58,17 +92,7 @@ useEffect(() => {
|
||||
checkList: [],
|
||||
};
|
||||
|
||||
let response = await TasksRepository.reportTask(reportData);
|
||||
showToast("Task Reported Successfully.", "success");
|
||||
refetch();
|
||||
reset()
|
||||
setloading(false);
|
||||
closeModal();
|
||||
} catch ( error )
|
||||
{
|
||||
const msg = error.response.data.message || error.message || "Error Occur During Api Call"
|
||||
showToast(msg, "error");
|
||||
}
|
||||
reportTask(reportData);
|
||||
};
|
||||
const handleClose = () => {
|
||||
closeModal();
|
||||
|
@ -9,7 +9,7 @@ import Avatar from "../common/Avatar";
|
||||
import { getBgClassFromHash } from "../../utils/projectStatus";
|
||||
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
||||
import ImagePreview from "../common/ImagePreview";
|
||||
import { useAuditStatus } from "../../hooks/useTasks";
|
||||
import { useAuditStatus, useSubmitTaskComment } from "../../hooks/useTasks";
|
||||
|
||||
const ReportTaskComments = ({
|
||||
commentsData,
|
||||
@ -49,6 +49,17 @@ const ReportTaskComments = ({
|
||||
const [comments, setComment] = useState([]);
|
||||
const { status, loading: auditStatusLoading } = useAuditStatus();
|
||||
const [ IsNeededSubTask, setIsNeededSubTask ] = useState( false );
|
||||
const { submitComment, isPending } = useSubmitTaskComment({
|
||||
actionAllow,
|
||||
onSuccessCallback: (data) => {
|
||||
setComment((prev) => [...prev, data]);
|
||||
reset();
|
||||
if ( actionAllow )
|
||||
{
|
||||
handleCloseAction(IsNeededSubTask);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
watch,
|
||||
@ -88,63 +99,66 @@ const ReportTaskComments = ({
|
||||
}
|
||||
}, [comments]);
|
||||
|
||||
const onSubmit = async (data) => {
|
||||
let payload = {
|
||||
...data,
|
||||
[actionAllow ? "id" : "taskAllocationId"]: commentsData?.id,
|
||||
...(actionAllow ? {} : { commentDate: new Date().toISOString() }),
|
||||
// const onSubmit = async (data) => {
|
||||
// let payload = {
|
||||
// ...data,
|
||||
// [actionAllow ? "id" : "taskAllocationId"]: commentsData?.id,
|
||||
// ...(actionAllow ? {} : { commentDate: new Date().toISOString() }),
|
||||
// };
|
||||
|
||||
// try {
|
||||
// setloading(true);
|
||||
// const resp = actionAllow
|
||||
// ? await TasksRepository.auditTask(payload)
|
||||
// : await TasksRepository.taskComments(payload);
|
||||
|
||||
// setComment((prevItems) => [...prevItems, resp.data]);
|
||||
|
||||
// const taskList = getCachedData("taskList");
|
||||
|
||||
// if (actionAllow) {
|
||||
// handleCloseAction(IsNeededSubTask);
|
||||
// showToast(
|
||||
// "Review submitted successfully. Record has been updated.",
|
||||
// "success"
|
||||
// );
|
||||
// } else {
|
||||
// if (taskList && taskList.data) {
|
||||
// const updatedTaskList = taskList.data.map((task) => {
|
||||
// if (task.id === resp.data.taskAllocationId) {
|
||||
// const existingComments = Array.isArray(task.comments)
|
||||
// ? task.comments
|
||||
// : [];
|
||||
// return {
|
||||
// ...task,
|
||||
// comments: [...existingComments, resp.data],
|
||||
// };
|
||||
// }
|
||||
// return task;
|
||||
// });
|
||||
|
||||
// cacheData("taskList", {
|
||||
// data: updatedTaskList,
|
||||
// projectId: taskList.projectId,
|
||||
// });
|
||||
// }
|
||||
// showToast("Successfully Sent", "success");
|
||||
// }
|
||||
|
||||
// reset();
|
||||
// setloading(false);
|
||||
// } catch (error) {
|
||||
// setloading(false);
|
||||
// showToast(
|
||||
// error.response.data?.message || "Something went wrong",
|
||||
// "error"
|
||||
// );
|
||||
// }
|
||||
// };
|
||||
|
||||
const onSubmit = (formData) => {
|
||||
submitComment({ data: formData, commentsData });
|
||||
};
|
||||
|
||||
try {
|
||||
setloading(true);
|
||||
const resp = actionAllow
|
||||
? await TasksRepository.auditTask(payload)
|
||||
: await TasksRepository.taskComments(payload);
|
||||
|
||||
setComment((prevItems) => [...prevItems, resp.data]);
|
||||
|
||||
const taskList = getCachedData("taskList");
|
||||
|
||||
if (actionAllow) {
|
||||
handleCloseAction(IsNeededSubTask);
|
||||
showToast(
|
||||
"Review submitted successfully. Record has been updated.",
|
||||
"success"
|
||||
);
|
||||
} else {
|
||||
if (taskList && taskList.data) {
|
||||
const updatedTaskList = taskList.data.map((task) => {
|
||||
if (task.id === resp.data.taskAllocationId) {
|
||||
const existingComments = Array.isArray(task.comments)
|
||||
? task.comments
|
||||
: [];
|
||||
return {
|
||||
...task,
|
||||
comments: [...existingComments, resp.data],
|
||||
};
|
||||
}
|
||||
return task;
|
||||
});
|
||||
|
||||
cacheData("taskList", {
|
||||
data: updatedTaskList,
|
||||
projectId: taskList.projectId,
|
||||
});
|
||||
}
|
||||
showToast("Successfully Sent", "success");
|
||||
}
|
||||
|
||||
reset();
|
||||
setloading(false);
|
||||
} catch (error) {
|
||||
setloading(false);
|
||||
showToast(
|
||||
error.response.data?.message || "Something went wrong",
|
||||
"error"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const selectedAuditStatus = watch("workStatus");
|
||||
|
||||
useEffect(() => {
|
||||
@ -234,7 +248,6 @@ const ReportTaskComments = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="d-flex align-items-center flex-wrap">
|
||||
<p className="fw-bold text-start m-0 me-1">
|
||||
<i className="fa-solid me-2 fs-6 fa-users-gear"></i>Team :
|
||||
@ -260,12 +273,10 @@ const ReportTaskComments = ({
|
||||
<div className="fw-normal ms-2">{commentsData?.description}</div>
|
||||
</div>
|
||||
|
||||
|
||||
{commentsData?.approvedBy && (
|
||||
<>
|
||||
<hr className="my-1" />
|
||||
<div className="row">
|
||||
|
||||
<div className="col-12 col-sm-6">
|
||||
{commentsData.approvedBy && (
|
||||
<div className="fw-bold text-start d-flex align-items-center">
|
||||
@ -300,9 +311,11 @@ const ReportTaskComments = ({
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 d-flex">
|
||||
<span className="fw-bold">Total Approved : </span><span className="ms-2">{commentsData?.completedTask }</span>
|
||||
<span className="fw-bold">Total Approved : </span>
|
||||
<span className="ms-2">{commentsData?.completedTask}</span>
|
||||
</div>
|
||||
</> )}
|
||||
</>
|
||||
)}
|
||||
|
||||
{commentsData?.reportedPreSignedUrls?.length > 0 && (
|
||||
<>
|
||||
@ -319,7 +332,7 @@ const ReportTaskComments = ({
|
||||
)}
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="text-start">
|
||||
{( actionAllow && !commentsData.approvedBy ) && (
|
||||
{actionAllow && !commentsData.approvedBy && (
|
||||
<>
|
||||
<div className="row align-items-end my-1">
|
||||
<div className="col-6 col-sm-4 text-start">
|
||||
@ -366,7 +379,6 @@ const ReportTaskComments = ({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</>
|
||||
)}
|
||||
<i className="bx bx-comment-detail me-2"></i>
|
||||
@ -382,10 +394,16 @@ const ReportTaskComments = ({
|
||||
)}
|
||||
<div
|
||||
className={` ${
|
||||
(actionAllow && !commentsData.approvedBy)? " d-flex justify-content-between" : "text-end"
|
||||
actionAllow && !commentsData.approvedBy
|
||||
? " d-flex justify-content-between"
|
||||
: "text-end"
|
||||
} mt-2`}
|
||||
>
|
||||
<div className={`form-check ${!(actionAllow && !commentsData.approvedBy) && "d-none"} `}>
|
||||
<div
|
||||
className={`form-check ${
|
||||
!(actionAllow && !commentsData.approvedBy) && "d-none"
|
||||
} `}
|
||||
>
|
||||
<input
|
||||
className="form-check-input"
|
||||
type="checkbox"
|
||||
|
@ -120,10 +120,10 @@ const Header = () => {
|
||||
[fetchData,projectNames,selectedProject]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
eventBus.on("assign_project_one", handler);
|
||||
return () => eventBus.off("assign_project_one", handler);
|
||||
}, [handler]);
|
||||
// useEffect(() => {
|
||||
// eventBus.on("assign_project_one", handler);
|
||||
// return () => eventBus.off("assign_project_one", handler);
|
||||
// }, [handler]);
|
||||
|
||||
const newProjectHandler = useCallback(
|
||||
async (msg) => {
|
||||
@ -139,10 +139,23 @@ const Header = () => {
|
||||
[HasManageProjectPermission,projectNames]
|
||||
);
|
||||
|
||||
// useEffect(() => {
|
||||
// eventBus.on("project", newProjectHandler);
|
||||
// return () => eventBus.off("project", newProjectHandler);
|
||||
// }, [handler]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
eventBus.on("assign_project_one", handler);
|
||||
eventBus.on("project", newProjectHandler);
|
||||
return () => eventBus.off("project", newProjectHandler);
|
||||
}, [handler]);
|
||||
|
||||
return () => {
|
||||
eventBus.off("assign_project_one", handler);
|
||||
eventBus.off("project", newProjectHandler);
|
||||
};
|
||||
}, [handler, newProjectHandler]);
|
||||
|
||||
|
||||
return (
|
||||
<nav
|
||||
className="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
|
||||
|
@ -11,6 +11,7 @@ import { TasksRepository } from "../../repositories/ProjectRepository";
|
||||
import showToast from "../../services/toastService";
|
||||
import { useProjectDetails } from "../../hooks/useProjects";
|
||||
import eventBus from "../../services/eventBus";
|
||||
import { useCreateTask } from "../../hooks/useTasks";
|
||||
|
||||
const AssignTask = ({ assignData, onClose, setAssigned }) => {
|
||||
const maxPlanned =
|
||||
@ -41,9 +42,12 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
|
||||
const [isHelpVisibleTarget, setIsHelpVisibleTarget] = useState(false);
|
||||
const helpPopupRefTarget = useRef(null);
|
||||
const [isHelpVisible, setIsHelpVisible] = useState(false);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const { mutate: assignTask, isPending: isSubmitting } = useCreateTask({
|
||||
onSuccessCallback: () => {
|
||||
closedModel();
|
||||
},
|
||||
});
|
||||
|
||||
// Refs for Bootstrap Popovers
|
||||
const infoRef = useRef(null);
|
||||
const infoRef1 = useRef(null);
|
||||
|
||||
@ -149,34 +153,49 @@ const AssignTask = ({ assignData, onClose, setAssigned }) => {
|
||||
);
|
||||
|
||||
// Form submission handler
|
||||
const onSubmit = async (data) => {
|
||||
const selectedEmployeeIds = data.selectedEmployees;
|
||||
setIsSubmitting(true);
|
||||
// Prepare taskTeam data (only IDs are needed for the backend based on previous context)
|
||||
const taskTeamWithDetails = selectedEmployeeIds
|
||||
.map((empId) => {
|
||||
return empId; // Return just the ID as per previous discussions
|
||||
})
|
||||
.filter(Boolean); // Ensure no nulls if employee not found (though unlikely with current logic)
|
||||
// const onSubmit = async (data) => {
|
||||
// const selectedEmployeeIds = data.selectedEmployees;
|
||||
// setIsSubmitting(true);
|
||||
// // Prepare taskTeam data (only IDs are needed for the backend based on previous context)
|
||||
// const taskTeamWithDetails = selectedEmployeeIds
|
||||
// .map((empId) => {
|
||||
// return empId; // Return just the ID as per previous discussions
|
||||
// })
|
||||
// .filter(Boolean); // Ensure no nulls if employee not found (though unlikely with current logic)
|
||||
|
||||
// Format data for API call
|
||||
// // Format data for API call
|
||||
// const formattedData = {
|
||||
// taskTeam: taskTeamWithDetails,
|
||||
// plannedTask: data.plannedTask,
|
||||
// description: data.description,
|
||||
// assignmentDate: new Date().toISOString(), // Current date/time
|
||||
// workItemId: assignData?.workItem?.workItem.id,
|
||||
// };
|
||||
|
||||
// try {
|
||||
// await TasksRepository.assignTask(formattedData);
|
||||
// setIsSubmitting( false );
|
||||
// showToast("Task Assined Successfully.", "success");
|
||||
// closedModel();
|
||||
// } catch (error) {
|
||||
// setIsSubmitting(false);
|
||||
// showToast("Something went wrong. Please try again.", "error");
|
||||
// }
|
||||
// };
|
||||
|
||||
const onSubmit = (data) => {
|
||||
const selectedEmployeeIds = data.selectedEmployees;
|
||||
|
||||
const taskTeamWithDetails = selectedEmployeeIds?.map((empId) => empId)?.filter(Boolean);
|
||||
const formattedData = {
|
||||
taskTeam: taskTeamWithDetails,
|
||||
plannedTask: data.plannedTask,
|
||||
description: data.description,
|
||||
assignmentDate: new Date().toISOString(), // Current date/time
|
||||
assignmentDate: new Date().toISOString(),
|
||||
workItemId: assignData?.workItem?.workItem.id,
|
||||
};
|
||||
|
||||
try {
|
||||
await TasksRepository.assignTask(formattedData);
|
||||
setIsSubmitting( false );
|
||||
showToast("Task Assined Successfully.", "success");
|
||||
closedModel();
|
||||
} catch (error) {
|
||||
setIsSubmitting(false);
|
||||
showToast("Something went wrong. Please try again.", "error");
|
||||
}
|
||||
assignTask(formattedData);
|
||||
};
|
||||
|
||||
// Handler to close the modal and reset form
|
||||
|
@ -2,103 +2,282 @@ import { useEffect, useState } from "react";
|
||||
import { TasksRepository } from "../repositories/TaskRepository";
|
||||
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
||||
import {MasterRespository} from "../repositories/MastersRepository";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import showToast from "../services/toastService";
|
||||
import {useSelector} from "react-redux";
|
||||
// import {formatDate} from "../utils/dateUtils";
|
||||
|
||||
export const useTaskList = (projectId, dateFrom, toDate) => {
|
||||
const [TaskList, setTaskList] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
// export const useTaskList = (projectId, dateFrom, toDate) => {
|
||||
// const [TaskList, setTaskList] = useState([]);
|
||||
// const [loading, setLoading] = useState(false);
|
||||
// const [error, setError] = useState(null);
|
||||
|
||||
const fetchList = async (projectId, dateFrom, toDate) => {
|
||||
const taskList_cached = getCachedData("taskList");
|
||||
// if (!taskList_cached || taskList_cached?.projectId !== projectId) {
|
||||
try {
|
||||
setLoading(true);
|
||||
const resp = await TasksRepository.getTaskList(
|
||||
// const fetchList = async (projectId, dateFrom, toDate) => {
|
||||
// const taskList_cached = getCachedData("taskList");
|
||||
// // if (!taskList_cached || taskList_cached?.projectId !== projectId) {
|
||||
// try {
|
||||
// setLoading(true);
|
||||
// const resp = await TasksRepository.getTaskList(
|
||||
// projectId,
|
||||
// dateFrom,
|
||||
// toDate
|
||||
// );
|
||||
// setTaskList(resp.data);
|
||||
// cacheData("taskList", { projectId: projectId, data: resp.data });
|
||||
// setLoading(false);
|
||||
// } catch (err) {
|
||||
// setLoading(false);
|
||||
// setError(err);
|
||||
// }
|
||||
// // } else {
|
||||
// // setTaskList(taskList_cached.data);
|
||||
// // }
|
||||
// };
|
||||
// useEffect( () =>
|
||||
// {
|
||||
|
||||
// if (projectId && dateFrom && toDate) {
|
||||
// fetchList(projectId, dateFrom, toDate);
|
||||
// }
|
||||
|
||||
// }, [projectId, dateFrom, toDate]);
|
||||
|
||||
// return { TaskList, loading, error, refetch:fetchList};
|
||||
// };
|
||||
|
||||
|
||||
// export const useTaskById = (TaskId) =>
|
||||
// {
|
||||
// const [Task, setTask] = useState([]);
|
||||
// const [loading, setLoading] = useState(false);
|
||||
// const [ error, setError ] = useState( null );
|
||||
|
||||
|
||||
|
||||
// const fetchTask = async(TaskId) =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// let res = await TasksRepository.getTaskById( TaskId );
|
||||
// setTask( res.data );
|
||||
|
||||
// } catch ( error )
|
||||
// {
|
||||
// setError(err)
|
||||
// }
|
||||
// }
|
||||
// useEffect( () =>
|
||||
// {
|
||||
// if ( TaskId )
|
||||
// {
|
||||
// fetchTask(TaskId)
|
||||
// }
|
||||
// }, [ TaskId ] )
|
||||
// return { Task,loading}
|
||||
// }
|
||||
|
||||
// export const useAuditStatus = () =>
|
||||
// {
|
||||
// const [ status, setStatus ] = useState( [] );
|
||||
// const [ error, setError ] = useState( '' );
|
||||
// const [ loading, setLoading ] = useState( false )
|
||||
|
||||
// const fetchStatus = async() =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// const res = await MasterRespository.getAuditStatus()
|
||||
// setStatus( res.data )
|
||||
// cacheData("AuditStatus",res.data)
|
||||
// } catch ( err )
|
||||
// {
|
||||
// setError(err)
|
||||
// }
|
||||
// }
|
||||
// useEffect(() => {
|
||||
// const cache_status = getCachedData('AuditStatus');
|
||||
// if (cache_status) {
|
||||
// setStatus(cache_status);
|
||||
// } else {
|
||||
// fetchStatus();
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
// return {status,error,loading}
|
||||
// }
|
||||
|
||||
// ---------Query---------------------------------
|
||||
|
||||
export const useTaskList = (projectId, dateFrom, toDate) => {
|
||||
const enabled = !!projectId && !!dateFrom && !!toDate;
|
||||
|
||||
const {
|
||||
data: TaskList = [],
|
||||
isLoading: loading,
|
||||
error,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ["taskList", projectId, dateFrom, toDate],
|
||||
queryFn: async () => {
|
||||
const response = await TasksRepository.getTaskList(
|
||||
projectId,
|
||||
dateFrom,
|
||||
toDate
|
||||
);
|
||||
setTaskList(resp.data);
|
||||
cacheData("taskList", { projectId: projectId, data: resp.data });
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setLoading(false);
|
||||
setError(err);
|
||||
}
|
||||
// } else {
|
||||
// setTaskList(taskList_cached.data);
|
||||
// }
|
||||
return response.data;
|
||||
},
|
||||
enabled,
|
||||
|
||||
});
|
||||
|
||||
return { TaskList, loading, error, refetch };
|
||||
};
|
||||
useEffect( () =>
|
||||
{
|
||||
|
||||
if (projectId && dateFrom && toDate) {
|
||||
fetchList(projectId, dateFrom, toDate);
|
||||
}
|
||||
export const useTaskById = (TaskId) => {
|
||||
const {
|
||||
data: Task = null,
|
||||
isLoading: loading,
|
||||
error,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ["taskDetails", TaskId],
|
||||
queryFn: async () => {
|
||||
const res = await TasksRepository.getTaskById(TaskId);
|
||||
return res.data;
|
||||
},
|
||||
enabled: !!TaskId,
|
||||
});
|
||||
|
||||
}, [projectId, dateFrom, toDate]);
|
||||
return { Task, loading, error, refetch };
|
||||
};
|
||||
|
||||
return { TaskList, loading, error, refetch:fetchList};
|
||||
// export const useActivities = () => {
|
||||
// return useQuery({
|
||||
// queryKey: ["activitiesMaster"],
|
||||
// queryFn: async () => {
|
||||
// const response = await ActivityRepository.getActivities();
|
||||
// return response.data;
|
||||
// },
|
||||
|
||||
// });
|
||||
// };
|
||||
|
||||
export const useAuditStatus = () => {
|
||||
const {
|
||||
data: status = [],
|
||||
isLoading: loading,
|
||||
error,
|
||||
refetch,
|
||||
} = useQuery({
|
||||
queryKey: ["AuditStatus"],
|
||||
queryFn: async () => {
|
||||
const res = await MasterRespository.getAuditStatus();
|
||||
return res.data;
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
return { status, loading, error, refetch };
|
||||
};
|
||||
|
||||
|
||||
export const useTaskById = (TaskId) =>
|
||||
{
|
||||
const [Task, setTask] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [ error, setError ] = useState( null );
|
||||
// -----------------------Mutation------------------------
|
||||
const toDate = new Date().toISOString().split('T')[0];
|
||||
const dateFrom = new Date(Date.now() - 6 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
||||
|
||||
|
||||
|
||||
const fetchTask = async(TaskId) =>
|
||||
export const useReportTask = ( {onSuccessCallback, onErrorCallback} = {} ) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
let res = await TasksRepository.getTaskById( TaskId );
|
||||
setTask( res.data );
|
||||
const queryClient = useQueryClient();
|
||||
const {
|
||||
mutate,
|
||||
isPending,
|
||||
isSuccess,
|
||||
isError,
|
||||
error,
|
||||
} = useMutation({
|
||||
mutationFn: async (reportData) => {
|
||||
return await TasksRepository.reportTask(reportData);
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
showToast( "Task Reported Successfully.", "success" );
|
||||
queryClient.invalidateQueries({ queryKey: ["taskList"] });
|
||||
if (onSuccessCallback) onSuccessCallback(data);
|
||||
},
|
||||
onError: (error) => {
|
||||
const msg =
|
||||
error?.response?.data?.message || error.message || "Error occurred during API call";
|
||||
showToast( msg, "error" );
|
||||
if (onErrorCallback) onErrorCallback(error);
|
||||
},
|
||||
});
|
||||
|
||||
} catch ( error )
|
||||
return {
|
||||
mutate,
|
||||
isPending,
|
||||
isSuccess,
|
||||
isError,
|
||||
error,
|
||||
};
|
||||
};
|
||||
|
||||
export const useSubmitTaskComment = ({ actionAllow, onSuccessCallback }) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { mutate, isPending } = useMutation({
|
||||
mutationFn: async ({ data, commentsData }) => {
|
||||
const payload = {
|
||||
...data,
|
||||
[actionAllow ? "id" : "taskAllocationId"]: commentsData?.id,
|
||||
...(actionAllow ? {} : { commentDate: new Date().toISOString() }),
|
||||
};
|
||||
|
||||
const response = actionAllow
|
||||
? await TasksRepository.auditTask(payload)
|
||||
: await TasksRepository.taskComments(payload);
|
||||
|
||||
return response.data;
|
||||
},
|
||||
|
||||
onSuccess: ( data ) =>
|
||||
{
|
||||
setError(err)
|
||||
}
|
||||
}
|
||||
useEffect( () =>
|
||||
queryClient.invalidateQueries({ queryKey: ["taskList"] });
|
||||
if (actionAllow) {
|
||||
showToast("Review submitted successfully.", "success");
|
||||
} else
|
||||
{
|
||||
if ( TaskId )
|
||||
{
|
||||
fetchTask(TaskId)
|
||||
}
|
||||
}, [ TaskId ] )
|
||||
return { Task,loading}
|
||||
showToast("Comment sent successfully.", "success");
|
||||
}
|
||||
|
||||
export const useAuditStatus = () =>
|
||||
{
|
||||
const [ status, setStatus ] = useState( [] );
|
||||
const [ error, setError ] = useState( '' );
|
||||
const [ loading, setLoading ] = useState( false )
|
||||
onSuccessCallback?.(data);
|
||||
},
|
||||
|
||||
const fetchStatus = async() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
const res = await MasterRespository.getAuditStatus()
|
||||
setStatus( res.data )
|
||||
cacheData("AuditStatus",res.data)
|
||||
} catch ( err )
|
||||
{
|
||||
setError(err)
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
const cache_status = getCachedData('AuditStatus');
|
||||
if (cache_status) {
|
||||
setStatus(cache_status);
|
||||
} else {
|
||||
fetchStatus();
|
||||
}
|
||||
}, []);
|
||||
onError: (error) => {
|
||||
const msg = error?.response?.data?.message || error.message || "Error during API call";
|
||||
showToast(msg, "error");
|
||||
},
|
||||
});
|
||||
|
||||
return {status,error,loading}
|
||||
}
|
||||
return { submitComment: mutate, isPending };
|
||||
};
|
||||
|
||||
export const useCreateTask = ( {onSuccessCallback, onErrorCallback} = {} ) =>
|
||||
{
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (payload) => {
|
||||
return await TasksRepository.assignTask(payload);
|
||||
},
|
||||
onSuccess: ( _, variables ) =>
|
||||
{
|
||||
queryClient.invalidateQueries({ queryKey: ["taskList"] });
|
||||
showToast("Task Assigned Successfully.", "success");
|
||||
if (onSuccessCallback) onSuccessCallback(variables);
|
||||
},
|
||||
onError: ( error ) =>
|
||||
{
|
||||
showToast("Something went wrong. Please try again.", "error");
|
||||
if (onErrorCallback) onErrorCallback(error);
|
||||
},
|
||||
});
|
||||
};
|
@ -9,7 +9,7 @@ import ReportTaskComments from "../../components/Activities/ReportTaskComments";
|
||||
import DateRangePicker from "../../components/common/DateRangePicker";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import moment from "moment";
|
||||
import FilterIcon from "../../components/common/FilterIcon"; // Import the FilterIcon component
|
||||
import FilterIcon from "../../components/common/FilterIcon";
|
||||
import GlobalModel from "../../components/common/GlobalModel";
|
||||
import AssignTask from "../../components/Project/AssignTask";
|
||||
import SubTask from "../../components/Activities/SubTask";
|
||||
@ -20,14 +20,14 @@ const DailyTask = () => {
|
||||
const selectedProject = useSelector(
|
||||
(store) => store.localVariables.projectId
|
||||
);
|
||||
const {
|
||||
projects,
|
||||
loading: project_loading,
|
||||
error: projects_Error,
|
||||
} = useProjects();
|
||||
// const {
|
||||
// projects,
|
||||
// loading: project_loading,
|
||||
// error: projects_Error,
|
||||
// } = useProjects();
|
||||
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
// const [initialized, setInitialized] = useState(false);
|
||||
// const dispatch = useDispatch();
|
||||
|
||||
const [filters, setFilters] = useState({
|
||||
selectedBuilding: "",
|
||||
@ -35,23 +35,23 @@ const DailyTask = () => {
|
||||
selectedActivities: [],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!project_loading && projects.length > 0 && !initialized) {
|
||||
if (projectIdFromUrl) {
|
||||
dispatch(setProjectId(projectIdFromUrl));
|
||||
} else if (selectedProject === 1 || selectedProject === undefined) {
|
||||
dispatch(setProjectId(projects[0].id));
|
||||
}
|
||||
setInitialized(true);
|
||||
}
|
||||
}, [
|
||||
project_loading,
|
||||
projects,
|
||||
projectIdFromUrl,
|
||||
selectedProject,
|
||||
initialized,
|
||||
dispatch,
|
||||
]);
|
||||
// useEffect(() => {
|
||||
// if (!project_loading && projects.length > 0 && !initialized) {
|
||||
// if (projectIdFromUrl) {
|
||||
// dispatch(setProjectId(projectIdFromUrl));
|
||||
// } else if (selectedProject === 1 || selectedProject === undefined) {
|
||||
// dispatch(setProjectId(projects[0].id));
|
||||
// }
|
||||
// setInitialized(true);
|
||||
// }
|
||||
// }, [
|
||||
// project_loading,
|
||||
// projects,
|
||||
// projectIdFromUrl,
|
||||
// selectedProject,
|
||||
// initialized,
|
||||
// dispatch,
|
||||
// ]);
|
||||
|
||||
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
||||
|
||||
@ -61,11 +61,12 @@ const DailyTask = () => {
|
||||
error: task_error,
|
||||
refetch,
|
||||
} = useTaskList(
|
||||
initialized ? selectedProject : null,
|
||||
initialized ? dateRange.startDate : null,
|
||||
initialized ? dateRange.endDate : null
|
||||
selectedProject || null,
|
||||
dateRange?.startDate || null,
|
||||
dateRange?.endDate || null
|
||||
);
|
||||
|
||||
|
||||
const [TaskLists, setTaskLists] = useState([]);
|
||||
const [dates, setDates] = useState([]);
|
||||
const popoverRefs = useRef([]);
|
||||
@ -83,8 +84,8 @@ const DailyTask = () => {
|
||||
}
|
||||
|
||||
if (filters.selectedFloors.length > 0) {
|
||||
filteredTasks = filteredTasks.filter((task) =>
|
||||
filters.selectedFloors.includes(
|
||||
filteredTasks = filteredTasks?.filter((task) =>
|
||||
filters.selectedFloors?.includes(
|
||||
task?.workItem?.workArea?.floor?.floorName
|
||||
)
|
||||
);
|
||||
@ -103,9 +104,9 @@ const DailyTask = () => {
|
||||
}
|
||||
}, [
|
||||
TaskList,
|
||||
filters.selectedBuilding,
|
||||
filters.selectedFloors,
|
||||
filters.selectedActivities,
|
||||
filters?.selectedBuilding,
|
||||
filters?.selectedFloors,
|
||||
filters?.selectedActivities,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
@ -150,43 +151,41 @@ const DailyTask = () => {
|
||||
const handlecloseModal = () =>
|
||||
{
|
||||
setIsModalOpen( false )
|
||||
refetch(selectedProject, dateRange.startDate, dateRange.endDate);
|
||||
// refetch();
|
||||
}
|
||||
const handleProjectChange = (e) => {
|
||||
const newProjectId = e.target.value;
|
||||
dispatch(setProjectId(newProjectId));
|
||||
setTaskLists([]);
|
||||
setFilters({
|
||||
selectedBuilding: "",
|
||||
selectedFloors: [],
|
||||
selectedActivities: [],
|
||||
});
|
||||
};
|
||||
// const handleProjectChange = (e) => {
|
||||
// const newProjectId = e.target.value;
|
||||
// dispatch(setProjectId(newProjectId));
|
||||
// setTaskLists([]);
|
||||
// setFilters({
|
||||
// selectedBuilding: "",
|
||||
// selectedFloors: [],
|
||||
// selectedActivities: [],
|
||||
// });
|
||||
// };
|
||||
|
||||
const handleCloseAction = (IsSubTask) => {
|
||||
if (IsSubTask) {
|
||||
setIsSubTaskNeeded(true);
|
||||
setIsModalOpenComment(false);
|
||||
} else {
|
||||
refetch(selectedProject, dateRange.startDate, dateRange.endDate);
|
||||
// refetch();
|
||||
setIsModalOpenComment(false);
|
||||
}
|
||||
};
|
||||
const hanleCloseSubTask = () => {
|
||||
setIsSubTaskNeeded(false);
|
||||
setComment( null );
|
||||
refetch(selectedProject, dateRange.startDate, dateRange.endDate);
|
||||
// refetch();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
|
||||
{isModalOpen && <GlobalModel isOpen={isModalOpen} size="md" closeModal={handlecloseModal} >
|
||||
<ReportTask
|
||||
report={selectedTask}
|
||||
closeModal={handlecloseModal}
|
||||
refetch={refetch}
|
||||
// refetch={refetch}
|
||||
/>
|
||||
</GlobalModel>}
|
||||
|
||||
@ -255,7 +254,7 @@ const DailyTask = () => {
|
||||
</thead>
|
||||
<tbody className="table-border-bottom-0">
|
||||
{/* --- Spinner when tasks are loading --- */}
|
||||
{(task_loading || project_loading) && (
|
||||
{task_loading && (
|
||||
<tr>
|
||||
<td colSpan={6} className="text-center">
|
||||
{" "}
|
||||
@ -272,7 +271,6 @@ const DailyTask = () => {
|
||||
</tr>
|
||||
)}
|
||||
{!task_loading &&
|
||||
!project_loading &&
|
||||
TaskLists.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={6} className="text-center">
|
||||
|
@ -1,110 +1,9 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import "../../components/Project/ProjectInfra.css";
|
||||
|
||||
import ProjectRepository from "../../repositories/ProjectRepository";
|
||||
import React from "react";
|
||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||
import InfraPlanning from "../../components/Activities/InfraPlanning";
|
||||
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
||||
import { useProfile } from "../../hooks/useProfile";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useProjectDetails, useProjects } from "../../hooks/useProjects";
|
||||
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||
import showToast from "../../services/toastService";
|
||||
|
||||
|
||||
const TaskPlannng = () => {
|
||||
const { profile } = useProfile();
|
||||
const {
|
||||
projects,
|
||||
loading: project_listLoader,
|
||||
error: projects_error,
|
||||
} = useProjects();
|
||||
const dispatch = useDispatch();
|
||||
const selectedProject = useSelector(
|
||||
(store) => store.localVariables.projectId
|
||||
);
|
||||
|
||||
|
||||
const [project, setProject] = useState(null);
|
||||
const [projectDetails, setProjectDetails] = useState(null);
|
||||
const [activities, setActivities] = useState(null);
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
const fetchActivities = async () => {
|
||||
try {
|
||||
const activities_cache = getCachedData("activitiesMaster");
|
||||
|
||||
if (!activities_cache) {
|
||||
ActivityeRepository.getActivities()
|
||||
.then((response) => {
|
||||
setActivities(response.data);
|
||||
cacheData("activitiesMaster", response.data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError("Failed to fetch data.");
|
||||
});
|
||||
} else {
|
||||
setActivities(activities_cache);
|
||||
}
|
||||
} catch (err) {
|
||||
setError("Failed to fetch activities.");
|
||||
} finally {
|
||||
// setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const project_cache = getCachedData("projectInfo");
|
||||
if (!project_cache || !project_cache.projectId == selectedProject) {
|
||||
ProjectRepository.getProjectByprojectId(selectedProject)
|
||||
.then((response) => {
|
||||
setProjectDetails(response);
|
||||
setProject(response);
|
||||
cacheData("projectInfo", {
|
||||
data: response.data,
|
||||
projectId: selectedProject,
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
const message =
|
||||
error.response?.data?.message ||
|
||||
error.message ||
|
||||
"An unexpected error occurred";
|
||||
showToast( message, "error" );
|
||||
});
|
||||
} else {
|
||||
setProjectDetails(project_cache);
|
||||
}
|
||||
} catch (err) {
|
||||
setError( "Failed to fetch data." );
|
||||
const message =
|
||||
error.response?.data?.message ||
|
||||
error.message ||
|
||||
"An unexpected error occurred";
|
||||
showToast( message, "error" );
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const [activePill, setActivePill] = useState("profile");
|
||||
|
||||
const handlePillClick = (pillKey) => {
|
||||
setActivePill(pillKey);
|
||||
};
|
||||
|
||||
const handleDataChange = (data) => {
|
||||
fetchData();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (projects.length != 0 && selectedProject) {
|
||||
fetchData();
|
||||
fetchActivities();
|
||||
}
|
||||
}, [selectedProject]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -115,17 +14,7 @@ const TaskPlannng = () => {
|
||||
{ label: "Daily Task Planning", link: "/activities/task" },
|
||||
]}
|
||||
></Breadcrumb>
|
||||
{project_listLoader && <p>Loading..</p>}
|
||||
{!project_listLoader && projects.length === 0 && (
|
||||
<p>No Project Found.</p>
|
||||
)}
|
||||
{!project_listLoader && projects.length > 0 && (
|
||||
<InfraPlanning
|
||||
data={projectDetails}
|
||||
activityMaster={activities}
|
||||
onDataChange={handleDataChange}
|
||||
/>
|
||||
)}
|
||||
<InfraPlanning/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -9,6 +9,7 @@ import eventBus from "./eventBus";
|
||||
import { useSelector } from "react-redux";
|
||||
import { clearApiCacheKey } from "../slices/apiCacheSlice";
|
||||
import {BASE_URL} from "../utils/constants";
|
||||
import { queryClient } from "../layouts/AuthLayout";
|
||||
const base_Url = BASE_URL;
|
||||
let connection = null;
|
||||
|
||||
@ -57,7 +58,8 @@ export function startSignalR(loggedUser) {
|
||||
data.keyword == "Create_Project" ||
|
||||
data.keyword == "Update_Project"
|
||||
) {
|
||||
clearCacheKey("projectslist");
|
||||
// clearCacheKey("projectslist");
|
||||
queryClient.invalidateQueries(['projectslist']);
|
||||
eventBus.emit("project", data);
|
||||
}
|
||||
|
||||
@ -83,13 +85,22 @@ export function startSignalR(loggedUser) {
|
||||
|
||||
// if created or updated Employee
|
||||
if (data.keyword == "Employee") {
|
||||
clearCacheKey("employeeListByProject");
|
||||
clearCacheKey("allEmployeeList");
|
||||
clearCacheKey("allInactiveEmployeeList");
|
||||
clearCacheKey("employeeProfile");
|
||||
// clearCacheKey("employeeListByProject");
|
||||
// clearCacheKey("allEmployeeList");
|
||||
// clearCacheKey("allInactiveEmployeeList");
|
||||
// clearCacheKey("employeeProfile");
|
||||
clearCacheKey("Attendance");
|
||||
clearCacheKey("regularizedList")
|
||||
clearCacheKey("AttendanceLogs")
|
||||
|
||||
// ---we can do also----
|
||||
// queryClient.removeQueries(['allEmployee', true]);
|
||||
// but best practies is refetch
|
||||
queryClient.invalidateQueries(['allEmployee', true]);
|
||||
queryClient.invalidateQueries(['allEmployee', false]);
|
||||
queryClient.invalidateQueries(['employeeProfile', data.response?.employeeId]);
|
||||
queryClient.invalidateQueries(['employeeListByProject']); // optional if scope
|
||||
queryClient
|
||||
eventBus.emit("employee", data);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user