diff --git a/src/components/Project/AssignRole.jsx b/src/components/Project/AssignRole.jsx index 46de8044..00e308db 100644 --- a/src/components/Project/AssignRole.jsx +++ b/src/components/Project/AssignRole.jsx @@ -5,6 +5,7 @@ import useMaster from "../../hooks/masterHook/useMaster"; import { employee } from "../../data/masters"; import { useForm, Controller } from "react-hook-form"; import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; import { getCachedData } from "../../slices/apiDataManager"; import { useModal } from "../../ModalContext"; import { useProjects } from "../../hooks/useProjects"; @@ -12,14 +13,30 @@ import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees"; import { TasksRepository } from "../../repositories/ProjectRepository"; import showToast from "../../services/toastService"; -const schema = z.object({ - selectedEmployees: z - .array(z.number()) - .min(1, { message: "At least one employee must be selected" }), - description: z.string().min(1, { message: "description required" }), -}); - const AssignRoleModel = ({ assignData, onClose }) => { + const maxPlanned = + assignData?.workItem?.workItem?.plannedWork - + assignData?.workItem?.workItem?.completedWork; + + const schema = z.object({ + selectedEmployees: z + .array(z.number()) + .min(1, { message: "At least one employee must be selected" }), + description: z.string().min(1, { message: "Description is required" }), + plannedTask: z.preprocess( + (val) => parseInt(val, 10), + z + .number({ + required_error: "Planned task is required", + invalid_type_error: "Planned task must be a number", + }) + .int() + .positive({ message: "Planned task must be a positive number" }) + .max(maxPlanned, { + message: `Planned task cannot exceed ${maxPlanned}`, + }) + ), + }); const [plannedTask, setPlannedTask] = useState(); const { openModal, closeModal } = useModal(); const selectedProject = useSelector( @@ -45,28 +62,21 @@ const AssignRoleModel = ({ assignData, onClose }) => { defaultValues: { selectedEmployees: [], description: "", + plannedTask: "", }, - resolver: (data) => { - const validation = schema.safeParse(data); - if (validation.success) return { values: data, errors: {} }; - return { values: {}, errors: validation.error.formErrors.fieldErrors }; - }, + resolver: zodResolver(schema), }); - const handleRoleChange = ( event ) => - { - reset() - setSelectedEmployees( [] ) + const handleRoleChange = (event) => { + reset(); + setSelectedEmployees([]); setSelectedRole(event.target.value); }; const filteredEmployees = selectedRole === "all" ? employees - : employees.filter((emp) => - String(emp.jobRoleId || "") === selectedRole - ); - + : employees.filter((emp) => String(emp.jobRoleId || "") === selectedRole); const handleEmployeeSelection = (employeeId, field) => { setSelectedEmployees((prevSelected) => { @@ -92,17 +102,17 @@ const AssignRoleModel = ({ assignData, onClose }) => { const onSubmit = async (data) => { const formattedData = { taskTeam: data.selectedEmployees, - plannedTask: parseInt(plannedTask, 10), + plannedTask: data.plannedTask, description: data.description, assignmentDate: new Date().toISOString(), workItemId: assignData?.workItem?.workItem.id, }; try { let response = await TasksRepository.assignTask(formattedData); - showToast( "Task Successfully Assigend", "success" ); - setSelectedEmployees([]) + showToast("Task Successfully Assigend", "success"); + setSelectedEmployees([]); reset(); - onClose(); + onClose(); } catch (error) { showToast("something wrong", "error"); } @@ -112,8 +122,12 @@ const AssignRoleModel = ({ assignData, onClose }) => { return () => setSelectedRole("all"); }, [dispatch]); + const closedModel = () => { + reset(); + onClose(); + }; return ( -
@@ -125,234 +139,264 @@ const AssignRoleModel = ({ assignData, onClose }) => { onClick={onClose} aria-label="Close" > -
-
-

- {[ - assignData?.building?.name, - assignData?.floor?.floorName, - assignData?.workArea?.areaName, - assignData?.workItem?.workItem?.activityMaster?.activityName, - ] - .filter(Boolean) - .map((item, index, array) => ( - - {item} - {index < array.length - 1 && ( - - )} - - ))} -

+
+
+

+ {[ + assignData?.building?.name, + assignData?.floor?.floorName, + assignData?.workArea?.areaName, + assignData?.workItem?.workItem?.activityMaster?.activityName, + ] + .filter(Boolean) + .map((item, index, array) => ( + + {item} + {index < array.length - 1 && ( + + )} + + ))} +

-
-
-
-
Select Role
-
- -
-
-
-
-
Employee
-
- {( filteredEmployees?.length === 0 && employees ) &&
No employees found
} - -
-
- {selectedRole !== "" && ( -
-
-
- {filteredEmployees?.map((emp) => { - const jobRole = jobRoleData?.find( - (role) => role?.id === emp?.jobRoleId - ); - - return ( -
-
-
- ( - { - handleEmployeeSelection(emp.id, field); - }} - /> - )} - /> -
-

- {emp.firstName} {emp.lastName} -

- - {loading && ( -

- )} - {data && - !loading && - (jobRole ? jobRole.name : "Unknown Role")} -
-
-
-
-
- ); - })} + +
+
+
Select Role
+
+ +
-
- )} -
-
- - {selectedEmployees.length > 0 && ( -
-
- {selectedEmployees.map((empId) => { - const emp = employees.find((emp) => emp.id === empId); - return ( - - {emp.firstName} {emp.lastName} -

{ - removeEmployee(empId); - setValue( - "selectedEmployees", - selectedEmployees.filter((id) => id !== empId) - ); - }} - > - -

-
- ); - })} +
+
Employee
-
- )} -
-
- + {filteredEmployees?.length === 0 && employees && ( +
No employees found
+ )} +
+
+ {selectedRole !== "" && ( +
+
+
+ {filteredEmployees?.map((emp) => { + const jobRole = jobRoleData?.find( + (role) => role?.id === emp?.jobRoleId + ); -
-
-
+
+
+ )} +
+
+ {selectedEmployees.length > 0 && ( +
+
+ {selectedEmployees.map((empId) => { + const emp = employees.find( + (emp) => emp.id === empId + ); + return ( + + {emp.firstName} {emp.lastName} +

{ + removeEmployee(empId); + setValue( + "selectedEmployees", + selectedEmployees.filter( + (id) => id !== empId + ) + ); + }} + > + +

+
+ ); + })} +
+
+ )} +
+
+ +
+
+ + +
+
+ + ( + + )} + /> +
+ {errors.plannedTask && ( +
+ {errors.plannedTask.message} +
+ )} +
+ {errors.selectedEmployees && ( +
+

{errors.selectedEmployees.message}

+
+ )} + + - -
-
- - setPlannedTask(e.target.value)} - id="defaultFormControlInput" - aria-describedby="defaultFormControlHelp" + ( +