made editactivitymodal form , user can modify activity
This commit is contained in:
parent
3677b80cfa
commit
be16c74a94
342
src/components/Project/Infrastructure/EditActivityModal.jsx
Normal file
342
src/components/Project/Infrastructure/EditActivityModal.jsx
Normal file
@ -0,0 +1,342 @@
|
||||
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 useSelect from "../../common/useSelect";
|
||||
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().optional(),
|
||||
})
|
||||
.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,
|
||||
};
|
||||
console.log(finalData)
|
||||
|
||||
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));
|
||||
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;
|
Loading…
x
Reference in New Issue
Block a user