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