From e2f38149346b4b81b3a964421dad404bb9b37d1e Mon Sep 17 00:00:00 2001 From: Umesh Desai Date: Mon, 9 Jun 2025 16:15:18 +0530 Subject: [PATCH 1/2] Implement a spinner in the Daily Progress Report to indicate when data is being loaded. --- src/pages/Activities/DailyTask.jsx | 105 ++++++++++++------ .../authentication/ResetPasswordPage.jsx | 6 +- 2 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/pages/Activities/DailyTask.jsx b/src/pages/Activities/DailyTask.jsx index b8d6e096..55947684 100644 --- a/src/pages/Activities/DailyTask.jsx +++ b/src/pages/Activities/DailyTask.jsx @@ -37,6 +37,7 @@ const DailyTask = () => { if (projectIdFromUrl) { dispatch(setProjectId(projectIdFromUrl)); } else if (selectedProject === 1 || selectedProject === undefined) { + // If no project from URL or default/undefined, pick the first project dispatch(setProjectId(projects[0].id)); } setInitialized(true); @@ -47,7 +48,7 @@ const DailyTask = () => { const { TaskList, - loading: task_loading, + loading: task_loading, // This `loading` state indicates if task data is being fetched error: task_error, refetch, } = useTaskList( @@ -56,34 +57,40 @@ const DailyTask = () => { initialized ? dateRange.endDate : null ); - const [TaskLists, setTaskLists] = useState([]); + const [TaskLists, setTaskLists] = useState([]); // This state holds the *filtered* tasks for display const [dates, setDates] = useState([]); const popoverRefs = useRef([]); - // Effect to apply filters (now using filters from FilterIcon) + // Effect to apply filters to TaskList (from useTaskList) and update TaskLists (filtered display) useEffect(() => { - let filteredTasks = TaskList; + // Only filter if TaskList is available (not null or undefined) + if (TaskList) { + let filteredTasks = TaskList; - if (filters.selectedBuilding) { - filteredTasks = filteredTasks.filter(task => - task?.workItem?.workArea?.floor?.building?.name === filters.selectedBuilding - ); + if (filters.selectedBuilding) { + filteredTasks = filteredTasks.filter(task => + task?.workItem?.workArea?.floor?.building?.name === filters.selectedBuilding + ); + } + + if (filters.selectedFloors.length > 0) { + filteredTasks = filteredTasks.filter(task => + filters.selectedFloors.includes(task?.workItem?.workArea?.floor?.floorName) + ); + } + + if (filters.selectedActivities.length > 0) { + filteredTasks = filteredTasks.filter(task => + filters.selectedActivities.includes(task?.workItem?.activityMaster?.activityName) + ); + } + setTaskLists(filteredTasks); + } else { + // If TaskList is null (e.g., during initial load or project change before data arrives), + // ensure TaskLists is also empty to avoid displaying stale data. + setTaskLists([]); } - - if (filters.selectedFloors.length > 0) { - filteredTasks = filteredTasks.filter(task => - filters.selectedFloors.includes(task?.workItem?.workArea?.floor?.floorName) - ); - } - - if (filters.selectedActivities.length > 0) { - filteredTasks = filteredTasks.filter(task => - filters.selectedActivities.includes(task?.workItem?.activityMaster?.activityName) - ); - } - - setTaskLists(filteredTasks); - }, [TaskList, filters.selectedBuilding, filters.selectedFloors, filters.selectedActivities]); // Depend on filters state + }, [TaskList, filters.selectedBuilding, filters.selectedFloors, filters.selectedActivities]); useEffect(() => { const AssignmentDates = [ @@ -113,6 +120,11 @@ const DailyTask = () => { // Ensure Bootstrap's Popover is initialized correctly popoverRefs.current.forEach((el) => { if (el && window.bootstrap && typeof window.bootstrap.Popover === 'function') { + // Dispose existing popovers to prevent duplicates if component re-renders + const existingPopover = window.bootstrap.Popover.getInstance(el); + if (existingPopover) { + existingPopover.dispose(); + } new window.bootstrap.Popover(el, { trigger: "focus", placement: "left", @@ -121,12 +133,27 @@ const DailyTask = () => { }); } }); - }, [dates, TaskLists]); + + // Cleanup function for popovers when component unmounts or dependencies change + return () => { + popoverRefs.current.forEach((el) => { + if (el && window.bootstrap && typeof window.bootstrap.Popover === 'function') { + const existingPopover = window.bootstrap.Popover.getInstance(el); + if (existingPopover) { + existingPopover.dispose(); + } + } + }); + popoverRefs.current = []; // Clear the refs array + }; + }, [dates, TaskLists]); // Re-initialize popovers when tasks or dates change // Handler for project selection const handleProjectChange = (e) => { const newProjectId = e.target.value; dispatch(setProjectId(newProjectId)); + // --- IMPORTANT: Clear old data immediately to show loading state --- + setTaskLists([]); // This makes the table empty, allowing the spinner to show // Reset filters when project changes (communicate to FilterIcon to clear) setFilters({ selectedBuilding: '', selectedFloors: [], selectedActivities: [] }); }; @@ -135,7 +162,7 @@ const DailyTask = () => { <> {/* Report Task Modal */}
{ closeModal={closeModal} refetch={refetch} /> + {isModalOpen &&
} {/* Add backdrop */}
{/* Report Task Comments Modal */}
{ commentsData={comments} closeModal={closeCommentModal} /> + {isModalOpenComment &&
} {/* Add backdrop */}
@@ -172,7 +201,6 @@ const DailyTask = () => {
-
{ currentSelectedBuilding={filters.selectedBuilding} currentSelectedFloors={filters.selectedFloors} currentSelectedActivities={filters.selectedActivities} + // You can pass the project_loading state here if you want to disable filter during project load + // isProjectLoading={project_loading} />
@@ -197,6 +227,7 @@ const DailyTask = () => { value={selectedProject || ""} onChange={handleProjectChange} aria-label="Select Project" + disabled={project_loading} // Disable dropdown while projects are loading > {project_loading && (
- {" "}