import React, { useState, useEffect, useRef, useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { changeMaster } from "../../slices/localVariablesSlice"; import useMaster from "../../hooks/masterHook/useMaster"; import { useForm, Controller } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { clearCacheKey, getCachedData } from "../../slices/apiDataManager"; import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees"; 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 = assignData?.workItem?.plannedWork - assignData?.workItem?.completedWork; const schema = z.object({ selectedEmployees: z .array(z.string()) .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: "Target for Today must be a number", }) .int() .positive({ message: "Planned task must be a positive number" }) .max(maxPlanned, { message: `Planned task cannot exceed ${maxPlanned}`, }) ), }); const [isHelpVisibleTarget, setIsHelpVisibleTarget] = useState(false); const helpPopupRefTarget = useRef(null); const [isHelpVisible, setIsHelpVisible] = useState(false); const { mutate: assignTask, isPending: isSubmitting } = useCreateTask({ onSuccessCallback: () => { closedModel(); }, }); const infoRef = useRef(null); const infoRef1 = useRef(null); // State for search term const [searchTerm, setSearchTerm] = useState(""); useEffect(() => { if (typeof bootstrap !== "undefined") { if (infoRef.current) { new bootstrap.Popover(infoRef.current, { trigger: "focus", placement: "right", html: true, content: `
Total Pending tasks of the Activity
`, }); } if (infoRef1.current) { new bootstrap.Popover(infoRef1.current, { trigger: "focus", placement: "right", html: true, content: `
Target task for today
`, }); } } else { console.warn("Bootstrap is not available. Popovers might not function."); } }, []); const selectedProject = useSelector( (store) => store.localVariables.projectId ); const { employees, loading: employeeLoading, recallEmployeeData, } = useEmployeesAllOrByProjectId(false, selectedProject, false); const dispatch = useDispatch(); const { loading } = useMaster(); const { data: jobRoleData } = useMaster(); // Changed to an array to hold multiple selected roles const [selectedRoles, setSelectedRoles] = useState(["all"]); const [displayedSelection, setDisplayedSelection] = useState(""); const { handleSubmit, control, setValue, watch, formState: { errors }, reset, trigger, } = useForm({ defaultValues: { selectedEmployees: [], description: "", plannedTask: "", }, resolver: zodResolver(schema), }); const handleCheckboxChange = (event, user) => { const isChecked = event.target.checked; let updatedSelectedEmployees = watch("selectedEmployees") || []; if (isChecked) { if (!updatedSelectedEmployees.includes(user.id)) { updatedSelectedEmployees = [...updatedSelectedEmployees, user.id]; } } else { updatedSelectedEmployees = updatedSelectedEmployees?.filter( (id) => id !== user.id ); } setValue("selectedEmployees", updatedSelectedEmployees); trigger("selectedEmployees"); }; useEffect(() => { dispatch(changeMaster("Job Role")); // Initial state should reflect "All Roles" selected setSelectedRoles(["all"]); }, [dispatch]); const handleRoleChange = (event) => { setSelectedRole(event.target.value); }; const handleSearchChange = (event) => { setSearchTerm(event.target.value); }; // Filter employees first by role, then by search term AND job role name const filteredEmployees = employees?.filter((emp) => { const matchesRole = selectedRole === "all" || String(emp.jobRoleId || "") === selectedRole; // Convert both first and last names and job role name to lowercase for case-insensitive matching const fullName = `${emp.firstName} ${emp.lastName}`.toLowerCase(); const jobRoleName = jobRoleData?.find((role) => role.id === emp.jobRoleId)?.name?.toLowerCase() || ""; const searchLower = searchTerm.toLowerCase(); // Check if the full name OR job role name includes the search term const matchesSearch = fullName.includes(searchLower) || jobRoleName.includes(searchLower); return matchesRole && matchesSearch; }); 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(), workItemId: assignData?.workItem.id, }; assignTask({ payload: formattedData, workAreaId: assignData?.workArea?.id, }); }; const closedModel = () => { reset(); onClose(); }; return (

Assign Task

Work Location : {[ assignData?.building?.buildingName, assignData?.floor?.floorName, assignData?.workArea?.areaName, assignData?.workItem?.activityMaster?.activityName, ] .filter(Boolean) // Filter out any undefined/null values .map((item, index, array) => ( {item} {index < array.length - 1 && ( )} ))}

Select Team
{displayedSelection}
  • handleRoleChange(e, e.target.value) } />
  • {jobRolesForDropdown?.map((role) => (
  • handleRoleChange(e, e.target.value) } />
  • ))}
{/* Search Field for Employees - Moved inline and pushed to the right */}
{selectedRoles?.length > 0 && (
{employeeLoading ? (

Loading employees...

) : filteredEmployees?.length > 0 ? ( filteredEmployees.map((emp) => { const jobRole = jobRoleData?.find( (role) => role?.id === emp?.jobRoleId ); return (
( { handleCheckboxChange(e, emp); }} /> )} />

{emp.firstName} {emp.lastName}

{loading ? ( ) : ( jobRole?.name || "Unknown Role" )}
); }) ) : (

No employees found for the selected role or search term.

)}
)}
{watch("selectedEmployees")?.length > 0 && (
{watch("selectedEmployees")?.map((empId) => { const emp = employees.find((emp) => emp.id === empId); return ( emp && ( {emp.firstName} {emp.lastName}

{ const updatedSelected = watch( "selectedEmployees" ).filter((id) => id !== empId); setValue( "selectedEmployees", updatedSelected ); trigger("selectedEmployees"); }} >

) ); })}
)}
{!loading && errors.selectedEmployees && (

{errors.selectedEmployees.message}

{" "}
)}
{/* Target for Today input and validation */}
(
{ assignData?.workItem?.activityMaster ?.unitOfMeasurement }
 
)} />
{errors.plannedTask && (
{errors.plannedTask.message}
)} {isHelpVisible && (

Enter the target value for today's task.

)}
(