diff --git a/src/components/common/FilterIcon.jsx b/src/components/common/FilterIcon.jsx
index 7f448f4e..1ac8d892 100644
--- a/src/components/common/FilterIcon.jsx
+++ b/src/components/common/FilterIcon.jsx
@@ -1,90 +1,98 @@
import React, { useState, useEffect } from "react";
-const FilterIcon = ({ taskListData, onApplyFilters, currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities }) => {
- // State for filters, now managed within FilterIcon
- const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding);
- const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors);
- const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities);
+const FilterIcon = ({
+ taskListData,
+ onApplyFilters,
+ currentSelectedBuilding,
+ currentSelectedFloors,
+ currentSelectedActivities,
+}) => {
+ const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || "");
+ const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []);
+ const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities || []);
- // Update internal state when props change (e.g., project selection in DailyTask clears filters)
useEffect(() => {
- setSelectedBuilding(currentSelectedBuilding);
- setSelectedFloors(currentSelectedFloors);
- setSelectedActivities(currentSelectedActivities);
+ setSelectedBuilding(currentSelectedBuilding || "");
+ setSelectedFloors(currentSelectedFloors || []);
+ setSelectedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities]);
- // Helper to get unique values for filters based on current selections
- const getUniqueFilterValues = (key) => {
+ const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => {
if (!taskListData) return [];
- let relevantTasks = taskListData;
- // Filter tasks based on selected building for floors and activities
- if (selectedBuilding) {
- relevantTasks = relevantTasks.filter(task =>
- task?.workItem?.workArea?.floor?.building?.name === selectedBuilding
+ let filteredTasks = [...taskListData];
+
+ if (overrideBuilding) {
+ filteredTasks = filteredTasks.filter(
+ (task) =>
+ task?.workItem?.workArea?.floor?.building?.name === overrideBuilding
);
}
- // Filter tasks based on selected floors for activities
- if (selectedFloors.length > 0) {
- relevantTasks = relevantTasks.filter(task =>
- selectedFloors.includes(task?.workItem?.workArea?.floor?.floorName)
+ if (overrideFloors?.length > 0) {
+ filteredTasks = filteredTasks.filter((task) =>
+ overrideFloors.includes(task?.workItem?.workArea?.floor?.floorName)
);
}
- const values = relevantTasks.map(task => {
- if (key === 'building') return task?.workItem?.workArea?.floor?.building?.name;
- if (key === 'floor') return task?.workItem?.workArea?.floor?.floorName;
- if (key === 'activity') return task?.workItem?.activityMaster?.activityName;
+ const values = filteredTasks.map((task) => {
+ if (key === "building") return task?.workItem?.workArea?.floor?.building?.name;
+ if (key === "floor") return task?.workItem?.workArea?.floor?.floorName;
+ if (key === "activity") return task?.workItem?.activityMaster?.activityName;
return null;
- }).filter(Boolean); // Remove null or undefined values
- return [...new Set(values)].sort(); // Sort for consistent order
+ });
+
+ return [...new Set(values.filter(Boolean))].sort();
};
- const uniqueBuildings = getUniqueFilterValues('building');
- const uniqueFloors = getUniqueFilterValues('floor');
- const uniqueActivities = getUniqueFilterValues('activity');
+ const uniqueBuildings = getUniqueFilterValues("building");
+ const uniqueFloors = getUniqueFilterValues("floor", selectedBuilding);
+ const uniqueActivities = getUniqueFilterValues("activity", selectedBuilding, selectedFloors);
- // Handle filter selection with dependency logic
const handleFilterChange = (filterType, value) => {
- let newSelectedBuilding = selectedBuilding;
- let newSelectedFloors = [...selectedFloors];
- let newSelectedActivities = [...selectedActivities];
+ let updatedBuilding = selectedBuilding;
+ let updatedFloors = [...selectedFloors];
+ let updatedActivities = [...selectedActivities];
- if (filterType === 'building') {
- if (selectedBuilding !== value) {
- newSelectedFloors = [];
- newSelectedActivities = [];
+ if (filterType === "building") {
+ updatedBuilding = value;
+ updatedFloors = [];
+ updatedActivities = [];
+ } else if (filterType === "floor") {
+ if (updatedFloors.includes(value)) {
+ updatedFloors = updatedFloors.filter((floor) => floor !== value);
+ } else {
+ updatedFloors.push(value);
}
- newSelectedBuilding = value;
- } else if (filterType === 'floor') {
- newSelectedFloors = selectedFloors.includes(value) ? selectedFloors.filter(item => item !== value) : [...selectedFloors, value];
- if (!newSelectedFloors.includes(value) && selectedFloors.includes(value)) {
- newSelectedActivities = [];
+
+ const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
+ updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
+ } else if (filterType === "activity") {
+ if (updatedActivities.includes(value)) {
+ updatedActivities = updatedActivities.filter((act) => act !== value);
+ } else {
+ updatedActivities.push(value);
}
- } else if (filterType === 'activity') {
- newSelectedActivities = selectedActivities.includes(value) ? selectedActivities.filter(item => item !== value) : [...selectedActivities, value];
}
- setSelectedBuilding(newSelectedBuilding);
- setSelectedFloors(newSelectedFloors);
- setSelectedActivities(newSelectedActivities);
+ setSelectedBuilding(updatedBuilding);
+ setSelectedFloors(updatedFloors);
+ setSelectedActivities(updatedActivities);
- // Communicate the updated filter states back to the parent
onApplyFilters({
- selectedBuilding: newSelectedBuilding,
- selectedFloors: newSelectedFloors,
- selectedActivities: newSelectedActivities,
+ selectedBuilding: updatedBuilding,
+ selectedFloors: updatedFloors,
+ selectedActivities: updatedActivities,
});
};
const clearAllFilters = () => {
- setSelectedBuilding('');
+ setSelectedBuilding("");
setSelectedFloors([]);
setSelectedActivities([]);
- // Communicate cleared filters back to the parent
+
onApplyFilters({
- selectedBuilding: '',
+ selectedBuilding: "",
selectedFloors: [],
selectedActivities: [],
});
@@ -98,20 +106,19 @@ const FilterIcon = ({ taskListData, onApplyFilters, currentSelectedBuilding, cur
data-bs-toggle="dropdown"
aria-expanded="false"
>
-
-
+ 0 || selectedActivities.length > 0 ? "#7161EF" : "gray" }}
+ >
+
e.stopPropagation()}
>
- {/* Building Filter - Now a Dropdown */}
+ {/* Building */}
-
Building
@@ -122,33 +129,26 @@ const FilterIcon = ({ taskListData, onApplyFilters, currentSelectedBuilding, cur
onChange={(e) => handleFilterChange("building", e.target.value)}
>
- {uniqueBuildings.length > 0 ? (
- uniqueBuildings.map((building, idx) => (
-
- ))
- ) : (
-
- )}
+ {uniqueBuildings.map((building, idx) => (
+
+ ))}
- {/* Floor Filter - Visible only if a building is selected */}
+ {/* Floor */}
{selectedBuilding && (
<>
+
-
-
-
-
- -
-
Floor
+ Floors
{uniqueFloors.length > 0 ? (
uniqueFloors.map((floor, idx) => (
-
+
))
) : (
-
No floors for selected building.
+
No floors found.
)}
>
)}
- {/* Activity Filter - Visible only if a floor is selected */}
+ {/* Activity */}
{selectedFloors.length > 0 && (
<>
+
-
-
-
-
-
-
-
Activity
+ Activities
{uniqueActivities.length > 0 ? (
uniqueActivities.map((activity, idx) => (
-
+
))
) : (
-
No activities for selected floor(s).
+
No activities found.
)}
>
)}
- {/* Clear Filters */}
- {(selectedBuilding ||
- selectedFloors.length > 0 ||
- selectedActivities.length > 0) && (
- <>
-
-
-
-
-
-
-
-
- >
- )}
+ {/* Action Buttons */}
+
+ {(selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0) && (
+
-
+
+
+
+ )}
+
+
);
diff --git a/src/pages/Activities/DailyTask.jsx b/src/pages/Activities/DailyTask.jsx
index 41e7ff9e..a194a41b 100644
--- a/src/pages/Activities/DailyTask.jsx
+++ b/src/pages/Activities/DailyTask.jsx
@@ -26,20 +26,17 @@ const DailyTask = () => {
const [initialized, setInitialized] = useState(false);
const dispatch = useDispatch();
- // State for filters (moved to FilterIcon, but we need to receive them here)
const [filters, setFilters] = useState({
selectedBuilding: "",
selectedFloors: [],
selectedActivities: [],
});
- // Sync projectId (either from URL or pick first accessible one)
useEffect(() => {
if (!project_loading && projects.length > 0 && !initialized) {
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);
@@ -57,7 +54,7 @@ const DailyTask = () => {
const {
TaskList,
- loading: task_loading, // This `loading` state indicates if task data is being fetched
+ loading: task_loading,
error: task_error,
refetch,
} = useTaskList(
@@ -66,13 +63,11 @@ const DailyTask = () => {
initialized ? dateRange.endDate : null
);
- const [TaskLists, setTaskLists] = useState([]); // This state holds the *filtered* tasks for display
+ const [TaskLists, setTaskLists] = useState([]);
const [dates, setDates] = useState([]);
const popoverRefs = useRef([]);
- // Effect to apply filters to TaskList (from useTaskList) and update TaskLists (filtered display)
useEffect(() => {
- // Only filter if TaskList is available (not null or undefined)
if (TaskList) {
let filteredTasks = TaskList;
@@ -101,8 +96,6 @@ const DailyTask = () => {
}
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([]);
}
}, [
@@ -137,52 +130,22 @@ const DailyTask = () => {
};
useEffect(() => {
- // 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, {
+ if (el) {
+ new bootstrap.Popover(el, {
trigger: "focus",
placement: "left",
html: true,
- content: el.getAttribute("data-bs-content"),
+ content: el.getAttribute("data-bs-content"),
});
}
});
-
- // 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
+ },[dates, TaskLists]);
+
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)
+ setTaskLists([]);
setFilters({
selectedBuilding: "",
selectedFloors: [],
@@ -192,7 +155,6 @@ const DailyTask = () => {
return (
<>
- {/* Report Task Modal */}
{
refetch={refetch}
/>
{isModalOpen &&
}{" "}
- {/* Add backdrop */}
- {/* Report Task Comments Modal */}
{
closeModal={closeCommentModal}
/>
{isModalOpenComment &&
}{" "}
- {/* Add backdrop */}
@@ -242,15 +201,12 @@ const DailyTask = () => {
DateDifference="6"
dateFormat="DD-MM-YYYY"
/>
- {/* FilterIcon component now manages its own filter states and logic */}
@@ -261,7 +217,7 @@ const DailyTask = () => {
value={selectedProject || ""}
onChange={handleProjectChange}
aria-label="Select Project"
- disabled={project_loading} // Disable dropdown while projects are loading
+ disabled={project_loading}
>
{project_loading && (