343 lines
11 KiB
JavaScript
343 lines
11 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import { useForm } from "react-hook-form";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { z } from "zod";
|
|
|
|
import { useActivitiesMaster } from "../../../hooks/masterHook/useMaster";
|
|
import { useProjectDetails } from "../../../hooks/useProjects";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import ProjectRepository from "../../../repositories/ProjectRepository";
|
|
import {
|
|
cacheData,
|
|
clearCacheKey,
|
|
getCachedData,
|
|
} from "../../../slices/apiDataManager";
|
|
import { refreshData } from "../../../slices/localVariablesSlice";
|
|
import showToast from "../../../services/toastService";
|
|
|
|
const taskSchema = z
|
|
.object({
|
|
activityID: z.string().min(1, "Activity is required"),
|
|
plannedWork: z.number().min(1, "Planned Work must be greater than 0"),
|
|
completedWork: z.number().min(0, "Completed Work must be greater than 0"),
|
|
})
|
|
.refine(
|
|
(data) =>
|
|
data.completedWork === undefined ||
|
|
data.completedWork <= data.plannedWork,
|
|
{
|
|
message: "Completed Work cannot be greater than Planned Work",
|
|
path: ["completedWork"], // error will show next to this field
|
|
}
|
|
);
|
|
|
|
const EditActivityModal = ({
|
|
workItem,
|
|
workArea,
|
|
building,
|
|
floor,
|
|
onClose,
|
|
}) => {
|
|
const selectedProject = useSelector(
|
|
(store) => store.localVariables.projectId
|
|
);
|
|
const defaultModel = {
|
|
activityID: 0,
|
|
plannedWork: 0,
|
|
completedWork: 0,
|
|
};
|
|
|
|
const { projects_Details, refetch } = useProjectDetails(selectedProject);
|
|
const { activities, loading, error } = useActivitiesMaster();
|
|
const [formData, setFormData] = useState(defaultModel);
|
|
const [selectedActivity, setSelectedActivity] = useState(null);
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [activityData, setActivityData] = useState([]);
|
|
const dispatch = useDispatch();
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
reset,
|
|
setValue,
|
|
getValues,
|
|
watch,
|
|
} = useForm({
|
|
resolver: zodResolver(taskSchema),
|
|
defaultValues: defaultModel,
|
|
});
|
|
|
|
const handleActivityChange = (e) => {
|
|
const selectedId = Number(e.target.value);
|
|
const selected = activityData.find((a) => a.id === selectedId);
|
|
setSelectedActivity(selected || null);
|
|
setValue("activityID", selectedId);
|
|
};
|
|
|
|
const onSubmitForm = async (data) => {
|
|
const updatedProject = { ...projects_Details };
|
|
const finalData = {
|
|
...data,
|
|
id: workItem?.workItem?.id ?? workItem?.id,
|
|
buildingID: building?.id,
|
|
floorId: floor?.id,
|
|
workAreaId: workArea?.id,
|
|
};
|
|
|
|
ProjectRepository.manageProjectTasks([finalData])
|
|
.then((response) => {
|
|
if (response?.data[0]) {
|
|
const { workItemId, workItem } = response.data[0];
|
|
|
|
let finalUpdatedWorkItem = null;
|
|
const newProject = {
|
|
...updatedProject,
|
|
buildings: updatedProject.buildings.map((building) =>
|
|
building.id === finalData.buildingID
|
|
? {
|
|
...building,
|
|
floors: building.floors.map((floor) =>
|
|
floor.id === finalData.floorId
|
|
? {
|
|
...floor,
|
|
workAreas: floor.workAreas.map((workArea) =>
|
|
workArea.id === workItem?.workAreaId
|
|
? {
|
|
...workArea,
|
|
workItems: (() => {
|
|
const exists = workArea.workItems.some(
|
|
(item) =>
|
|
String(
|
|
item?.workItem?.id ?? item?.id
|
|
) === String(finalData.id)
|
|
);
|
|
|
|
finalUpdatedWorkItem = workItem;
|
|
|
|
return exists
|
|
? workArea.workItems.map((item) =>
|
|
String(
|
|
item?.workItem?.id ?? item?.id
|
|
) === String(finalData.id)
|
|
? workItem
|
|
: item
|
|
)
|
|
: [...workArea.workItems, workItem];
|
|
})(),
|
|
}
|
|
: workArea
|
|
),
|
|
}
|
|
: floor
|
|
),
|
|
}
|
|
: building
|
|
),
|
|
};
|
|
cacheData("projectInfo", {
|
|
projectId: newProject.id,
|
|
data: newProject,
|
|
});
|
|
resetForm();
|
|
dispatch( refreshData( true ) );
|
|
showToast("Activity Updated Successfully","success")
|
|
|
|
onClose();
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
showToast(error.message, "error");
|
|
});
|
|
};
|
|
|
|
const resetForm = () => {
|
|
setFormData(defaultModel);
|
|
setSelectedActivity(null);
|
|
reset(defaultModel);
|
|
};
|
|
|
|
useEffect(() => {
|
|
reset({
|
|
activityID: workItem?.workItem?.activityId || workItem?.activityId || 0,
|
|
plannedWork:
|
|
workItem?.workItem?.plannedWork || workItem?.plannedWork || 0,
|
|
completedWork:
|
|
workItem?.workItem?.completedWork || workItem?.completedWork || 0,
|
|
});
|
|
return () => reset();
|
|
}, [activities, workItem]);
|
|
|
|
const ISselectedActivity = watch("activityID");
|
|
useEffect(() => {
|
|
const selected = activities.find((a) => a.id === ISselectedActivity);
|
|
setSelectedActivity(selected || null);
|
|
}, [ISselectedActivity]);
|
|
return (
|
|
<div className="modal-dialog modal-lg modal-simple modal-edit-user">
|
|
<div className="modal-content">
|
|
<div className="modal-body">
|
|
<div className="row">
|
|
<button
|
|
type="button"
|
|
className="btn-close"
|
|
aria-label="Close"
|
|
onClick={onClose}
|
|
/>
|
|
<div className="text-center mb-1">
|
|
<h5 className="mb-1">Manage Task</h5>
|
|
</div>
|
|
<form className="row g-2" onSubmit={handleSubmit(onSubmitForm)}>
|
|
{/* Select Building */}
|
|
<div className="col-6 col-md-6">
|
|
<label className="form-label" htmlFor="buildingID">
|
|
Select Building
|
|
</label>
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-sm"
|
|
value={building?.name}
|
|
disabled
|
|
/>
|
|
</div>
|
|
|
|
{/* Select Floor */}
|
|
<div className="col-6 col-md-6">
|
|
<label className="form-label" htmlFor="floorId">
|
|
Select Floor
|
|
</label>
|
|
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-sm"
|
|
value={floor?.floorName}
|
|
disabled
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 col-md-12">
|
|
<label className="form-label" htmlFor="workAreaId">
|
|
Select Work Area
|
|
</label>
|
|
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-sm"
|
|
value={workArea?.areaName}
|
|
disabled
|
|
/>
|
|
</div>
|
|
|
|
{/* Select Activity */}
|
|
<div className="col-12 col-md-12">
|
|
<label className="form-label" htmlFor="activityID">
|
|
Select Activity
|
|
</label>
|
|
<select
|
|
id="activityID"
|
|
className="form-select form-select-sm"
|
|
{...register("activityID")}
|
|
>
|
|
{loading ? (
|
|
<option value="">Loading...</option>
|
|
) : (
|
|
<option disabled>Select Activity</option>
|
|
)}
|
|
{activities &&
|
|
activities.length > 0 &&
|
|
activities
|
|
.slice()
|
|
.sort((a, b) =>
|
|
(a.activityName || "").localeCompare(
|
|
b.activityName || ""
|
|
)
|
|
)
|
|
.map((activity) => (
|
|
<option key={activity.id} value={activity.id}>
|
|
{activity.activityName}
|
|
</option>
|
|
))}
|
|
{!loading && activityData.length === 0 && (
|
|
<option disabled>No activities available</option>
|
|
)}
|
|
</select>
|
|
|
|
{errors.activityID && (
|
|
<p className="danger-text">{errors.activityID.message}</p>
|
|
)}
|
|
</div>
|
|
|
|
{/* Planned Work */}
|
|
{/* {ISselectedActivity && ( */}
|
|
<div className="col-5 col-md-5">
|
|
<label className="form-label" htmlFor="plannedWork">
|
|
Planned Work
|
|
</label>
|
|
<input
|
|
{...register("plannedWork", { valueAsNumber: true })}
|
|
type="number"
|
|
className="form-control form-control-sm me-2"
|
|
placeholder="Planned Work"
|
|
/>
|
|
|
|
{errors.plannedWork && (
|
|
<p className="danger-text">{errors.plannedWork.message}</p>
|
|
)}
|
|
</div>
|
|
{/* )} */}
|
|
|
|
{/* Completed Work */}
|
|
{/* {ISselectedActivity && ( */}
|
|
<div className="col-5 col-md-5">
|
|
<label className="form-label" htmlFor="completedWork">
|
|
Completed Work
|
|
</label>
|
|
<input
|
|
{...register("completedWork", { valueAsNumber: true })}
|
|
type="number"
|
|
className="form-control form-control-sm me-2"
|
|
placeholder="Completed Work"
|
|
/>
|
|
{errors.completedWork && (
|
|
<p className="danger-text">{errors.completedWork.message}</p>
|
|
)}
|
|
</div>
|
|
{/* )} */}
|
|
|
|
{/* Unit */}
|
|
{/* {ISselectedActivity && ( */}
|
|
<div className="col-2 col-md-2">
|
|
<label className="form-label" htmlFor="unit">
|
|
Unit
|
|
</label>
|
|
<input
|
|
type="text"
|
|
disabled
|
|
className="form-control form-control-sm me-2"
|
|
value={selectedActivity?.unitOfMeasurement || ""}
|
|
/>
|
|
</div>
|
|
{/* )} */}
|
|
|
|
<div className="col-12 text-center">
|
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
|
{isSubmitting ? "Please Wait.." : "Edit Task"}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className="btn btn-sm btn-label-secondary"
|
|
onClick={onClose}
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default EditActivityModal;
|