From 22e06bf41cf71243212b98582191ac5119e8a785 Mon Sep 17 00:00:00 2001 From: Edgar Buttner Date: Thu, 12 Mar 2026 15:23:52 -0400 Subject: [PATCH 1/5] #3909 Reworking filtering in Gantt chart page --- .../ProjectGanttChart/GanttChartFilters.tsx | 255 +++++++++--------- .../GanttChartFiltersButton.tsx | 10 + 2 files changed, 145 insertions(+), 120 deletions(-) diff --git a/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx b/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx index 09999ad714..72e9fd7ec6 100644 --- a/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx +++ b/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx @@ -3,71 +3,86 @@ * See the LICENSE file in the repository root folder for details. */ -import { Box, Checkbox, Chip, IconButton, Typography, useTheme } from '@mui/material'; -import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore'; -import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; -import RestartAltIcon from '@mui/icons-material/RestartAlt'; -import { ChangeEvent } from 'react'; +import { + Box, + Checkbox, + Typography, + useTheme, + Accordion, + AccordionSummary, + AccordionDetails, + FormControlLabel, + IconButton +} from '@mui/material'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import CloseIcon from '@mui/icons-material/Close'; +import { ChangeEvent, useState } from 'react'; -const FilterChipButton = ({ - buttonText, - onChange, - defaultChecked, - checked +const FilterCheckboxes = ({ + handlers }: { - buttonText: string; - onChange: (event: ChangeEvent) => void; - defaultChecked: boolean; - checked: boolean; -}) => { - const theme = useTheme(); - - return ( - ) => void; defaultChecked: boolean }[]; +}) => ( + + {handlers.map((handler) => ( + } - }} - icon={} - checkedIcon={ - - } - defaultChecked={defaultChecked} - checked={checked} - /> - ); -}; + label={handler.filterLabel} + /> + ))} + +); -const FilterRow = ({ +const FilterAccordion = ({ label, - buttons + children, + expanded, + onChange }: { label: string; - buttons: { filterLabel: string; handler: (event: ChangeEvent) => void; defaultChecked: boolean }[]; + children: React.ReactNode; + expanded: boolean; + onChange: () => void; }) => { - const checkedMap: { [filterLabel: string]: boolean } = {}; + const theme = useTheme(); - buttons.forEach((button) => { - checkedMap[button.filterLabel] = button.defaultChecked; - }); return ( - - - {label} - - - {buttons.map((button) => ( - - ))} - - + + } + sx={{ + minHeight: '36px', + px: 0, + flexDirection: 'row-reverse', + gap: 1, + '& .MuiAccordionSummary-expandIconWrapper': { marginRight: 0, marginLeft: 0 }, + '& .MuiAccordionSummary-content': { margin: '6px 0' } + }} + > + + {label} + + + {children} + ); }; @@ -92,88 +107,88 @@ interface GanttChartFiltersProps { resetHandler: () => void; collapseHandler: () => void; expandHandler: () => void; + onClose: () => void; } const GanttChartFilters = ({ carHandlers, teamTypeHandlers, teamHandlers, - overdueHandler, - hideTasksHandler, resetHandler, - collapseHandler, - expandHandler + onClose }: GanttChartFiltersProps) => { - const FilterButtons = () => { - return ( - - - - - - Expand - - - - - - Collapse + const theme = useTheme(); + + const [expanded, setExpanded] = useState({ + car: true, + division: true, + team: true + }); + + const [resetKey, setResetKey] = useState(0); + + const handleReset = () => { + setResetKey((prev) => prev + 1); + resetHandler(); + }; + + const toggle = (section: keyof typeof expanded) => { + setExpanded((prev) => ({ ...prev, [section]: !prev[section] })); + }; + + return ( + + + + Filters - - + + - + + + + Reset - - - Overdue + + setExpanded({ car: true, division: true, team: true })} + > + Expand All - - - Hide Tasks + + setExpanded({ car: false, division: false, team: false })} + > + Collapse All - ); - }; - return ( - - - - - + toggle('car')}> + + + + toggle('division')}> + + + + toggle('team')}> + + ); }; - export default GanttChartFilters; diff --git a/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFiltersButton.tsx b/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFiltersButton.tsx index 1dfb774e40..06d3d144e9 100644 --- a/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFiltersButton.tsx +++ b/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFiltersButton.tsx @@ -2,6 +2,7 @@ import { ChangeEvent, useState } from 'react'; import { IconButton, Popover } from '@mui/material'; import GanttChartFilters from './GanttChartFilters'; import { Tune } from '@mui/icons-material'; +import { useTheme } from '@mui/material'; interface GanttChartFiltersButtonProps { carHandlers: { filterLabel: string; handler: (event: ChangeEvent) => void; defaultChecked: boolean }[]; @@ -64,6 +65,14 @@ const GanttChartFiltersButton = ({ horizontal: 'right' }} sx={{ maxWidth: '100rem' }} + slotProps={{ + paper: { + sx: { + backgroundColor: useTheme().palette.background.paper, + borderRadius: 2 + } + } + }} > From c1366921e0e8cbd3e847bf22d9f8dbeb5d647638 Mon Sep 17 00:00:00 2001 From: Edgar Buttner Date: Thu, 12 Mar 2026 17:03:14 -0400 Subject: [PATCH 2/5] #3909 Final Changes and Small Fixes --- .../ProjectGanttChart/GanttChartFilters.tsx | 16 ++---------- .../GanttChartFiltersButton.tsx | 25 +++---------------- 2 files changed, 5 insertions(+), 36 deletions(-) diff --git a/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx b/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx index 72e9fd7ec6..43766dda8a 100644 --- a/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx +++ b/src/frontend/src/pages/GanttPage/ProjectGanttChart/GanttChartFilters.tsx @@ -94,19 +94,7 @@ interface GanttChartFiltersProps { defaultChecked: boolean; }[]; teamHandlers: { filterLabel: string; handler: (event: ChangeEvent) => void; defaultChecked: boolean }[]; - overdueHandler: { - filterLabel: string; - handler: (event: ChangeEvent) => void; - defaultChecked?: boolean; - }[]; - hideTasksHandler: { - filterLabel: string; - handler: (event: ChangeEvent) => void; - defaultChecked?: boolean; - }[]; resetHandler: () => void; - collapseHandler: () => void; - expandHandler: () => void; onClose: () => void; } @@ -159,7 +147,7 @@ const GanttChartFilters = ({ > Reset - + Expand All - + ) => void; defaultChecked: boolean }[]; - overdueHandler: { - filterLabel: string; - handler: (event: ChangeEvent) => void; - defaultChecked?: boolean; - }[]; - hideTasksHandler: { - filterLabel: string; - handler: (event: ChangeEvent) => void; - defaultChecked?: boolean; - }[]; resetHandler: () => void; - collapseHandler: () => void; - expandHandler: () => void; } const GanttChartFiltersButton = ({ carHandlers, teamTypeHandlers, teamHandlers, - overdueHandler, - hideTasksHandler, - resetHandler, - collapseHandler, - expandHandler + resetHandler }: GanttChartFiltersButtonProps) => { + const theme = useTheme(); const [anchorFilterEl, setAnchorFilterEl] = useState(null); const handleFilterClick = (event: React.MouseEvent) => { setAnchorFilterEl(event.currentTarget); @@ -68,7 +53,7 @@ const GanttChartFiltersButton = ({ slotProps={{ paper: { sx: { - backgroundColor: useTheme().palette.background.paper, + backgroundColor: theme.palette.background.paper, borderRadius: 2 } } @@ -78,11 +63,7 @@ const GanttChartFiltersButton = ({ carHandlers={carHandlers} teamTypeHandlers={teamTypeHandlers} teamHandlers={teamHandlers} - overdueHandler={overdueHandler} - hideTasksHandler={hideTasksHandler} resetHandler={resetHandler} - collapseHandler={collapseHandler} - expandHandler={expandHandler} onClose={handleFilterClose} /> From 31ad2b7c96db4e28b224820b90a8590497326425 Mon Sep 17 00:00:00 2001 From: Edgar Buttner Date: Thu, 12 Mar 2026 18:54:16 -0400 Subject: [PATCH 3/5] #3909 Fixing issue with handlers --- .../GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx b/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx index 4d55984d9e..511cd5fdb7 100644 --- a/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx +++ b/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx @@ -656,11 +656,7 @@ const ProjectGanttChartPage: FC = () => { carHandlers={carHandlers} teamTypeHandlers={teamTypeHandlers} teamHandlers={teamHandlers} - overdueHandler={overdueHandler} - hideTasksHandler={hideTasksHandler} resetHandler={resetHandler} - collapseHandler={collapseHandler} - expandHandler={expandHandler} /> ); From aa05074f71d628a42ce0f06f199e38ff175756c9 Mon Sep 17 00:00:00 2001 From: Edgar Buttner Date: Thu, 12 Mar 2026 19:01:51 -0400 Subject: [PATCH 4/5] #3909 fixing more linter errors --- .../ProjectGanttChartPage.tsx | 30 ------------------- .../pages/RetrospectivePage/Retrospective.tsx | 4 --- 2 files changed, 34 deletions(-) diff --git a/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx b/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx index 511cd5fdb7..1689390aca 100644 --- a/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx +++ b/src/frontend/src/pages/GanttPage/ProjectGanttChart/ProjectGanttChartPage.tsx @@ -210,24 +210,6 @@ const ProjectGanttChartPage: FC = () => { }; }); - const overdueHandler = [ - { - filterLabel: 'Overdue', - handler: (event: ChangeEvent) => - handleSetGanttFilters({ ...filters, showOnlyOverdue: event.target.checked }), - defaultChecked: filters.showOnlyOverdue - } - ]; - - const hideTasksHandler = [ - { - filterLabel: 'Hide Tasks', - handler: (event: ChangeEvent) => - handleSetGanttFilters({ ...filters, hideTasks: event.target.checked }), - defaultChecked: filters.hideTasks - } - ]; - const carHandlers: { filterLabel: string; handler: (event: ChangeEvent) => void; @@ -633,18 +615,6 @@ const ProjectGanttChartPage: FC = () => { ) : add(Date.now(), { weeks: 15 }); - const collapseHandler = () => { - allProjects.forEach((project) => { - setShowWorkPackagesMap((prev) => new Map(prev.set(project.id, false))); - }); - }; - - const expandHandler = () => { - allProjects.forEach((project) => { - setShowWorkPackagesMap((prev) => new Map(prev.set(project.id, true))); - }); - }; - const toggleElementShowChildren = (element: WbsElementPreview | Task) => { setShowWorkPackagesMap((prev) => new Map(prev.set(getElementId(element), !prev.get(getElementId(element))))); }; diff --git a/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx b/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx index aee24ef8e7..9faf47e650 100644 --- a/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx +++ b/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx @@ -251,11 +251,7 @@ const RetrospectivePage = () => { carHandlers={carHandlers} teamTypeHandlers={teamTypeHandlers} teamHandlers={teamHandlers} - overdueHandler={overdueHandler} - hideTasksHandler={hideTasksHandler} resetHandler={resetHandler} - collapseHandler={collapseHandler} - expandHandler={expandHandler} /> ); From fbbb445b686b7bc30d6ffa47a53898a615dcf581 Mon Sep 17 00:00:00 2001 From: Edgar Buttner Date: Thu, 12 Mar 2026 19:09:04 -0400 Subject: [PATCH 5/5] Finishing linter errors --- .../pages/RetrospectivePage/Retrospective.tsx | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx b/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx index 9faf47e650..0d64560a40 100644 --- a/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx +++ b/src/frontend/src/pages/RetrospectivePage/Retrospective.tsx @@ -153,24 +153,6 @@ const RetrospectivePage = () => { }; }); - const overdueHandler = [ - { - filterLabel: 'Overdue', - handler: (event: ChangeEvent) => - handleSetGanttFilters({ ...filters, showOnlyOverdue: event.target.checked }), - defaultChecked: filters.showOnlyOverdue - } - ]; - - const hideTasksHandler = [ - { - filterLabel: 'Hide Tasks', - handler: (event: ChangeEvent) => - handleSetGanttFilters({ ...filters, hideTasks: event.target.checked }), - defaultChecked: filters.hideTasks - } - ]; - const carHandlers: { filterLabel: string; handler: (event: ChangeEvent) => void; @@ -220,18 +202,6 @@ const RetrospectivePage = () => { ) : add(Date.now(), { weeks: 15 }); - const collapseHandler = () => { - projects.forEach((project) => { - setShowWorkPackagesMap((prev) => new Map(prev.set(project.id, false))); - }); - }; - - const expandHandler = () => { - projects.forEach((project) => { - setShowWorkPackagesMap((prev) => new Map(prev.set(project.id, true))); - }); - }; - const elementId = (element: WbsElementPreview | Task) => (element as WbsElementPreview).id || (element as Task).taskId; const toggleElementShowChildren = (element: WbsElementPreview | Task) => {