Merge pull request 'Filter Applied Without Clicking on "Apply" Button in Daily Progress Report' (#367) from Kartik_Bug#1037 into Issues_Aug_2W

Reviewed-on: #367
Merged
This commit is contained in:
pramod.mahajan 2025-09-01 08:56:20 +00:00
commit 73c6ccc0d6
2 changed files with 93 additions and 46 deletions

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
const FilterIcon = ({ const FilterIcon = ({
taskListData, taskListData,
@ -7,15 +8,26 @@ const FilterIcon = ({
currentSelectedFloors, currentSelectedFloors,
currentSelectedActivities, currentSelectedActivities,
}) => { }) => {
const selectedProject = useSelector((store) => store.localVariables.projectId);
const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || ""); const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || "");
const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []); const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []);
const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities || []); 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(() => { useEffect(() => {
setSelectedBuilding(currentSelectedBuilding || ""); setSelectedBuilding(currentSelectedBuilding || "");
setSelectedFloors(currentSelectedFloors || []); setSelectedFloors(currentSelectedFloors || []);
setSelectedActivities(currentSelectedActivities || []); setSelectedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities]);
setAppliedBuilding(currentSelectedBuilding || "");
setAppliedFloors(currentSelectedFloors || []);
setAppliedActivities(currentSelectedActivities || []);
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities, selectedProject]);
const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => { const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => {
if (!taskListData) return []; if (!taskListData) return [];
@ -61,12 +73,11 @@ const FilterIcon = ({
} else if (filterType === "floor") { } else if (filterType === "floor") {
if (updatedFloors.includes(value)) { if (updatedFloors.includes(value)) {
updatedFloors = updatedFloors.filter((floor) => floor !== value); updatedFloors = updatedFloors.filter((floor) => floor !== value);
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
} else { } else {
updatedFloors.push(value); updatedFloors.push(value);
} }
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
} else if (filterType === "activity") { } else if (filterType === "activity") {
if (updatedActivities.includes(value)) { if (updatedActivities.includes(value)) {
updatedActivities = updatedActivities.filter((act) => act !== value); updatedActivities = updatedActivities.filter((act) => act !== value);
@ -78,12 +89,20 @@ const FilterIcon = ({
setSelectedBuilding(updatedBuilding); setSelectedBuilding(updatedBuilding);
setSelectedFloors(updatedFloors); setSelectedFloors(updatedFloors);
setSelectedActivities(updatedActivities); setSelectedActivities(updatedActivities);
};
const applyFilters = () => {
setAppliedBuilding(selectedBuilding);
setAppliedFloors(selectedFloors);
setAppliedActivities(selectedActivities);
onApplyFilters({ onApplyFilters({
selectedBuilding: updatedBuilding, selectedBuilding,
selectedFloors: updatedFloors, selectedFloors,
selectedActivities: updatedActivities, selectedActivities,
}); });
document.getElementById("filterDropdown").click();
}; };
const clearAllFilters = () => { const clearAllFilters = () => {
@ -91,6 +110,10 @@ const FilterIcon = ({
setSelectedFloors([]); setSelectedFloors([]);
setSelectedActivities([]); setSelectedActivities([]);
setAppliedBuilding("");
setAppliedFloors([]);
setAppliedActivities([]);
onApplyFilters({ onApplyFilters({
selectedBuilding: "", selectedBuilding: "",
selectedFloors: [], selectedFloors: [],
@ -98,21 +121,51 @@ const FilterIcon = ({
}); });
}; };
// Count applied filters
const appliedFilterCount =
(appliedBuilding ? 1 : 0) + appliedFloors.length + appliedActivities.length;
return ( return (
<div className="dropdown" style={{marginLeft:"-14px"}}> <div className="dropdown" style={{ marginLeft: "-14px", position: "relative" }}>
<a <a
className="dropdown-toggle hide-arrow cursor-pointer" className="dropdown-toggle hide-arrow cursor-pointer"
id="filterDropdown" id="filterDropdown"
data-bs-toggle="dropdown" data-bs-toggle="dropdown"
aria-expanded="false" aria-expanded="false"
> >
{/* <i className="bx bx-slider-alt ms-1" /> */} <div style={{ position: "relative", display: "inline-block" }}>
<i <i
className="bx bx-slider-alt" className="bx bx-slider-alt"
style={{ color: selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0 ? "#7161EF" : "gray" }} style={{
></i> 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> </a>
<ul <ul
className="dropdown-menu p-2 mt-2" className="dropdown-menu p-2 mt-2"
aria-labelledby="filterDropdown" aria-labelledby="filterDropdown"
@ -205,45 +258,30 @@ const FilterIcon = ({
)} )}
{/* Action Buttons */} {/* Action Buttons */}
<li><hr className="my-1" /></li> <li>
{(selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0) && ( <hr className="my-1" />
<li className="d-flex justify-content-end gap-2 px-2"> </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 <button
type="button" type="button"
className="btn btn-sm" className="btn btn-secondary btn-sm py-0 px-2"
style={{
backgroundColor: "#7161EF",
color: "white",
fontSize: "13px",
padding: "4px 16px",
borderRadius: "8px",
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
}}
onClick={clearAllFilters} onClick={clearAllFilters}
> >
Clear Clear
</button> </button>
<button <button
type="button" type="button"
className="btn btn-sm" className="btn btn-primary btn-sm py-0 px-2"
style={{ onClick={applyFilters}
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();
}}
> >
Apply Apply
</button> </button>
</li> </li>
)} )}
</ul> </ul>
</div> </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 { useDispatch } from "react-redux";
import { useTaskList } from "../../hooks/useTasks"; import { useTaskList } from "../../hooks/useTasks";
import { useProjectName } from "../../hooks/useProjects"; import { useProjectName } from "../../hooks/useProjects";
@ -14,7 +14,6 @@ import { formatNumber, formatUTCToLocalTime } from "../../utils/dateUtils";
import { useHasUserPermission } from "../../hooks/useHasUserPermission"; import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { APPROVE_TASK, ASSIGN_REPORT_TASK } from "../../utils/constants"; import { APPROVE_TASK, ASSIGN_REPORT_TASK } from "../../utils/constants";
import { useSelectedproject } from "../../slices/apiDataManager"; import { useSelectedproject } from "../../slices/apiDataManager";
import moment from "moment";
import Loader from "../../components/common/Loader"; import Loader from "../../components/common/Loader";
const DailyTask = () => { const DailyTask = () => {
@ -45,6 +44,15 @@ const DailyTask = () => {
} }
}, [selectedProject, projectNames, dispatch]); }, [selectedProject, projectNames, dispatch]);
// 🔹 Reset filters when project changes
useEffect(() => {
setFilters({
selectedBuilding: "",
selectedFloors: [],
selectedActivities: [],
});
}, [selectedProject]);
// Memoized filtering // Memoized filtering
const filteredTasks = useMemo(() => { const filteredTasks = useMemo(() => {
if (!TaskList) return []; if (!TaskList) return [];
@ -91,8 +99,8 @@ const DailyTask = () => {
data-bs-content={` data-bs-content={`
<div class="border border-secondary rounded custom-popover p-2 px-3"> <div class="border border-secondary rounded custom-popover p-2 px-3">
${task.teamMembers ${task.teamMembers
.map( .map(
(m) => ` (m) => `
<div class="d-flex align-items-center gap-2 mb-2"> <div class="d-flex align-items-center gap-2 mb-2">
<div class="avatar avatar-xs"> <div class="avatar avatar-xs">
<span class="avatar-initial rounded-circle bg-label-primary"> <span class="avatar-initial rounded-circle bg-label-primary">
@ -101,8 +109,8 @@ const DailyTask = () => {
</div> </div>
<span>${m.firstName} ${m.lastName}</span> <span>${m.firstName} ${m.lastName}</span>
</div>` </div>`
) )
.join("")} .join("")}
</div> </div>
`} `}
> >
@ -163,6 +171,7 @@ const DailyTask = () => {
currentSelectedBuilding={filters.selectedBuilding} currentSelectedBuilding={filters.selectedBuilding}
currentSelectedFloors={filters.selectedFloors} currentSelectedFloors={filters.selectedFloors}
currentSelectedActivities={filters.selectedActivities} currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject}
/> />
</div> </div>