diff --git a/src/components/Project/AssignRole.jsx b/src/components/Project/AssignRole.jsx
index 58d162bb..a639abc8 100644
--- a/src/components/Project/AssignRole.jsx
+++ b/src/components/Project/AssignRole.jsx
@@ -2,71 +2,78 @@ import React, { useState, useEffect, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import { changeMaster } from "../../slices/localVariablesSlice";
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 { useProjects } from "../../hooks/useProjects";
import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
import { TasksRepository } from "../../repositories/ProjectRepository";
import showToast from "../../services/toastService";
const AssignRoleModel = ({ assignData, onClose }) => {
+ // Calculate maxPlanned based on assignData
const maxPlanned =
assignData?.workItem?.workItem?.plannedWork -
assignData?.workItem?.workItem?.completedWork;
+
+ // Zod schema for form validation
const schema = z.object({
selectedEmployees: z
.array(z.string())
- .min(1, { message: "At least one employee must be selected" }),
+ .min(1, { message: "At least one employee must be selected" }), // Added custom message here for consistency
description: z.string().min(1, { message: "Description is required" }),
plannedTask: z.preprocess(
- (val) => parseInt(val, 10),
+ (val) => parseInt(val, 10), // Preprocess value to integer
z
.number({
required_error: "Planned task is required",
- invalid_type_error: "Planned task must be a number",
+ invalid_type_error: "Target for Today must be a number",
})
- .int()
- .positive({ message: "Planned task must be a positive number" })
+ .int() // Ensure it's an integer
+ .positive({ message: "Planned task must be a positive number" }) // Must be positive
.max(maxPlanned, {
+ // Max value validation
message: `Planned task cannot exceed ${maxPlanned}`,
})
),
});
+ // State for help popovers (though not fully implemented in provided snippets)
const [isHelpVisibleTarget, setIsHelpVisibleTarget] = useState(false);
const helpPopupRefTarget = useRef(null);
-
const [isHelpVisible, setIsHelpVisible] = useState(false);
+ // Refs for Bootstrap Popovers
const infoRef = useRef(null);
const infoRef1 = useRef(null);
+ // Initialize Bootstrap Popovers on component mount
useEffect(() => {
-
- if (infoRef.current) {
- new bootstrap.Popover(infoRef.current, {
- trigger: 'focus',
- placement: 'right',
- html: true,
- content: `
Pending Task assign for today
`,
- });
+ // Check if Bootstrap is available globally
+ 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.");
}
+ }, []); // Empty dependency array ensures this runs once on mount
- if (infoRef1.current) {
- new bootstrap.Popover(infoRef1.current, {
- trigger: 'focus',
- placement: 'right',
- html: true,
- content: `Target task for today
`,
- });
- }
- }, []);
-
-
- const [plannedTask, setPlannedTask] = useState();
+ // Redux state and hooks
const selectedProject = useSelector(
(store) => store.localVariables.projectId
);
@@ -74,15 +81,15 @@ const AssignRoleModel = ({ assignData, onClose }) => {
selectedProject,
false
);
-
const dispatch = useDispatch();
- const { data, loading } = useMaster();
+ const { loading } = useMaster(); // Assuming this is for jobRoleData loading
const jobRoleData = getCachedData("Job Role");
+ // Local component states
const [selectedRole, setSelectedRole] = useState("all");
- const [selectedEmployees, setSelectedEmployees] = useState([]);
- const [displayedSelection, setDisplayedSelection] = useState("");
+ const [displayedSelection, setDisplayedSelection] = useState(""); // This state is not updated in the provided code, consider if it's still needed or how it should be updated
+ // React Hook Form setup
const {
handleSubmit,
control,
@@ -90,84 +97,90 @@ const AssignRoleModel = ({ assignData, onClose }) => {
watch,
formState: { errors },
reset,
+ trigger, // <--- IMPORTANT: Destructure 'trigger' here
} = useForm({
defaultValues: {
selectedEmployees: [],
description: "",
plannedTask: "",
},
- resolver: zodResolver(schema),
+ resolver: zodResolver(schema), // Integrate Zod schema with react-hook-form
});
+ // Handler for employee checkbox changes
const handleCheckboxChange = (event, user) => {
const isChecked = event.target.checked;
- let updatedSelectedEmployees = watch("selectedEmployees") || [];
+ let updatedSelectedEmployees = watch("selectedEmployees") || []; // Get current selected employees from form state
if (isChecked) {
+ // Add employee if checked and not already in the list
if (!updatedSelectedEmployees.includes(user.id)) {
updatedSelectedEmployees = [...updatedSelectedEmployees, user.id];
}
} else {
+ // Remove employee if unchecked
updatedSelectedEmployees = updatedSelectedEmployees.filter(
(id) => id !== user.id
);
}
-
+ // Update the form state with the new list of selected employees
setValue("selectedEmployees", updatedSelectedEmployees);
+ trigger("selectedEmployees"); // <--- IMPORTANT: Trigger validation here
};
+ // Effect to dispatch action for Job Role master data
useEffect(() => {
dispatch(changeMaster("Job Role"));
+ // Cleanup function to reset selected role when component unmounts or dispatch changes
return () => setSelectedRole("all");
}, [dispatch]);
+ // Handler for role filter change
const handleRoleChange = (event) => {
setSelectedRole(event.target.value);
};
+ // Filter employees based on selected role
const filteredEmployees =
selectedRole === "all"
? employees
: employees?.filter(
- (emp) => String(emp.jobRoleId || "") === selectedRole
- );
+ (emp) => String(emp.jobRoleId || "") === selectedRole
+ );
+ // Form submission handler
const onSubmit = async (data) => {
const selectedEmployeeIds = data.selectedEmployees;
+ // Prepare taskTeam data (only IDs are needed for the backend based on previous context)
const taskTeamWithDetails = selectedEmployeeIds
.map((empId) => {
- const employee = employees.find((e) => e.id === empId);
- const jobRole = jobRoleData?.find((r) => r.id === employee?.jobRoleId);
- return employee
- ? employee.id
- : null;
+ return empId; // Return just the ID as per previous discussions
})
- .filter(Boolean);
+ .filter(Boolean); // Ensure no nulls if employee not found (though unlikely with current logic)
+ // Format data for API call
const formattedData = {
taskTeam: taskTeamWithDetails,
plannedTask: data.plannedTask,
description: data.description,
- assignmentDate: new Date().toISOString(),
+ assignmentDate: new Date().toISOString(), // Current date/time
workItemId: assignData?.workItem?.workItem.id,
};
try {
- let response = await TasksRepository.assignTask(formattedData);
- showToast("Task Successfully Assigned", "success");
- reset();
- onClose();
+ // Call API to assign task
+ await TasksRepository.assignTask(formattedData);
+ showToast("Task Successfully Assigned", "success"); // Show success toast
+ reset(); // Reset form fields
+ onClose(); // Close the modal
} catch (error) {
- console.log(error.response);
- showToast("something wrong", "error");
+ console.error("Error assigning task:", error); // Log the full error for debugging
+ showToast("Something went wrong. Please try again.", "error"); // Show generic error toast
}
};
- useEffect(() => {
- dispatch(changeMaster("Job Role"));
- return () => setSelectedRole("all");
- }, [dispatch]);
+ // Handler to close the modal and reset form
const closedModel = () => {
reset();
onClose();
@@ -200,7 +213,7 @@ const AssignRoleModel = ({ assignData, onClose }) => {
assignData?.workItem?.workItem?.activityMaster
?.activityName,
]
- .filter(Boolean)
+ .filter(Boolean) // Filter out any undefined/null values
.map((item, index, array) => (
{item}
@@ -232,7 +245,7 @@ const AssignRoleModel = ({ assignData, onClose }) => {