Filter Applied Without Clicking on "Apply" Button in Daily Progress Report #367

Merged
pramod.mahajan merged 1 commits from Kartik_Bug#1037 into Issues_Aug_2W 2025-09-01 08:56:21 +00:00
2 changed files with 93 additions and 46 deletions

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
const FilterIcon = ({
taskListData,
@ -7,15 +8,26 @@ const FilterIcon = ({
currentSelectedFloors,
currentSelectedActivities,
}) => {
const selectedProject = useSelector((store) => store.localVariables.projectId);
const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || "");
const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []);
const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities || []);
const [appliedBuilding, setAppliedBuilding] = useState(currentSelectedBuilding || "");
const [appliedFloors, setAppliedFloors] = useState(currentSelectedFloors || []);
const [appliedActivities, setAppliedActivities] = useState(currentSelectedActivities || []);
// Reset filters whenever inputs OR projectId changes
useEffect(() => {
setSelectedBuilding(currentSelectedBuilding || "");
setSelectedFloors(currentSelectedFloors || []);
setSelectedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities]);
setAppliedBuilding(currentSelectedBuilding || "");
setAppliedFloors(currentSelectedFloors || []);
setAppliedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities, selectedProject]);
const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => {
if (!taskListData) return [];
@ -61,12 +73,11 @@ const FilterIcon = ({
} else if (filterType === "floor") {
if (updatedFloors.includes(value)) {
updatedFloors = updatedFloors.filter((floor) => floor !== value);
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
} else {
updatedFloors.push(value);
}
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);
@ -78,12 +89,20 @@ const FilterIcon = ({
setSelectedBuilding(updatedBuilding);
setSelectedFloors(updatedFloors);
setSelectedActivities(updatedActivities);
};
const applyFilters = () => {
setAppliedBuilding(selectedBuilding);
setAppliedFloors(selectedFloors);
setAppliedActivities(selectedActivities);
onApplyFilters({
selectedBuilding: updatedBuilding,
selectedFloors: updatedFloors,
selectedActivities: updatedActivities,
selectedBuilding,
selectedFloors,
selectedActivities,
});
document.getElementById("filterDropdown").click();
};
const clearAllFilters = () => {
@ -91,6 +110,10 @@ const FilterIcon = ({
setSelectedFloors([]);
setSelectedActivities([]);
setAppliedBuilding("");
setAppliedFloors([]);
setAppliedActivities([]);
onApplyFilters({
selectedBuilding: "",
selectedFloors: [],
@ -98,21 +121,51 @@ const FilterIcon = ({
});
};
// Count applied filters
const appliedFilterCount =
(appliedBuilding ? 1 : 0) + appliedFloors.length + appliedActivities.length;
return (
<div className="dropdown" style={{marginLeft:"-14px"}}>
<div className="dropdown" style={{ marginLeft: "-14px", position: "relative" }}>
<a
className="dropdown-toggle hide-arrow cursor-pointer"
id="filterDropdown"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{/* <i className="bx bx-slider-alt ms-1" /> */}
<i
className="bx bx-slider-alt"
style={{ color: selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0 ? "#7161EF" : "gray" }}
></i>
<div style={{ position: "relative", display: "inline-block" }}>
<i
className="bx bx-slider-alt"
style={{
color: appliedFilterCount > 0 ? "#7161EF" : "gray",
fontSize: "20px",
}}
></i>
{appliedFilterCount > 0 && (
<span
style={{
position: "absolute",
top: "-11px",
right: "-6px",
backgroundColor: "#FFC107", // yellow
color: "white",
fontSize: "10px",
fontWeight: "bold",
borderRadius: "50%",
width: "18px",
height: "18px",
display: "flex",
alignItems: "center",
justifyContent: "center",
border: "1px solid white",
}}
>
{appliedFilterCount}
</span>
)}
</div>
</a>
<ul
className="dropdown-menu p-2 mt-2"
aria-labelledby="filterDropdown"
@ -205,45 +258,30 @@ const FilterIcon = ({
)}
{/* Action Buttons */}
<li><hr className="my-1" /></li>
{(selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0) && (
<li className="d-flex justify-content-end gap-2 px-2">
<li>
<hr className="my-1" />
</li>
{(appliedFilterCount > 0 ||
selectedBuilding ||
selectedFloors.length > 0 ||
selectedActivities.length > 0) && (
<li className="d-flex justify-content-end gap-2 px-2 mt-2 mb-2">
<button
type="button"
className="btn btn-sm"
style={{
backgroundColor: "#7161EF",
color: "white",
fontSize: "13px",
padding: "4px 16px",
borderRadius: "8px",
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
}}
className="btn btn-secondary btn-sm py-0 px-2"
onClick={clearAllFilters}
>
Clear
</button>
<button
type="button"
className="btn btn-sm"
style={{
backgroundColor: "#7161EF",
color: "white",
fontSize: "13px",
padding: "4px 16px",
borderRadius: "8px",
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
}}
onClick={() => {
document.getElementById("filterDropdown").click();
}}
className="btn btn-primary btn-sm py-0 px-2"
onClick={applyFilters}
>
Apply
</button>
</li>
)}
</ul>
</div>
);

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import React, { useEffect, useMemo, useState } from "react";
import { useDispatch } from "react-redux";
import { useTaskList } from "../../hooks/useTasks";
import { useProjectName } from "../../hooks/useProjects";
@ -14,7 +14,6 @@ import { formatNumber, formatUTCToLocalTime } from "../../utils/dateUtils";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { APPROVE_TASK, ASSIGN_REPORT_TASK } from "../../utils/constants";
import { useSelectedproject } from "../../slices/apiDataManager";
import moment from "moment";
import Loader from "../../components/common/Loader";
const DailyTask = () => {
@ -45,6 +44,15 @@ const DailyTask = () => {
}
}, [selectedProject, projectNames, dispatch]);
// 🔹 Reset filters when project changes
useEffect(() => {
setFilters({
selectedBuilding: "",
selectedFloors: [],
selectedActivities: [],
});
}, [selectedProject]);
// Memoized filtering
const filteredTasks = useMemo(() => {
if (!TaskList) return [];
@ -91,8 +99,8 @@ const DailyTask = () => {
data-bs-content={`
<div class="border border-secondary rounded custom-popover p-2 px-3">
${task.teamMembers
.map(
(m) => `
.map(
(m) => `
<div class="d-flex align-items-center gap-2 mb-2">
<div class="avatar avatar-xs">
<span class="avatar-initial rounded-circle bg-label-primary">
@ -101,8 +109,8 @@ const DailyTask = () => {
</div>
<span>${m.firstName} ${m.lastName}</span>
</div>`
)
.join("")}
)
.join("")}
</div>
`}
>
@ -163,6 +171,7 @@ const DailyTask = () => {
currentSelectedBuilding={filters.selectedBuilding}
currentSelectedFloors={filters.selectedFloors}
currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject}
/>
</div>