1- import type { ReactNode } from 'react' ;
1+ import { memo , type ReactNode , useMemo } from 'react' ;
22
33import type { Icon } from '@primer/octicons-react' ;
44import { Stack , Text } from '@primer/react' ;
@@ -8,31 +8,45 @@ import { useAppContext } from '../../hooks/useAppContext';
88import { Checkbox } from '../fields/Checkbox' ;
99import { Title } from '../primitives/Title' ;
1010
11- import type { FilterSettingsState , FilterSettingsValue } from '../../types' ;
12-
11+ import { type FiltersState , useFiltersStore } from '../../stores' ;
1312import type { Filter } from '../../utils/notifications/filters' ;
1413import { RequiresDetailedNotificationWarning } from './RequiresDetailedNotificationsWarning' ;
1514
16- export interface FilterSectionProps < T extends FilterSettingsValue > {
15+ export interface FilterSectionProps < K extends keyof FiltersState > {
1716 id : string ;
1817 title : string ;
1918 icon : Icon ;
20- filter : Filter < T > ;
21- filterSetting : keyof FilterSettingsState ;
19+ filter : Filter < FiltersState [ K ] [ number ] > ;
20+ filterSetting : K ;
2221 tooltip ?: ReactNode ;
2322 layout ?: 'horizontal' | 'vertical' ;
2423}
2524
26- export const FilterSection = < T extends FilterSettingsValue > ( {
25+ const FilterSectionComponent = < K extends keyof FiltersState > ( {
2726 id,
2827 title,
2928 icon,
3029 filter,
3130 filterSetting,
3231 tooltip,
3332 layout = 'vertical' ,
34- } : FilterSectionProps < T > ) => {
35- const { updateFilter, settings, notifications } = useAppContext ( ) ;
33+ } : FilterSectionProps < K > ) => {
34+ const { notifications, settings } = useAppContext ( ) ;
35+ const updateFilter = useFiltersStore ( ( s ) => s . updateFilter ) ;
36+
37+ // Subscribe to the specific filter state so component re-renders when filters change
38+ useFiltersStore ( ( s ) => s [ filterSetting ] ) ;
39+
40+ // Memoize filter counts to avoid recalculating on every render
41+ const filterCounts = useMemo ( ( ) => {
42+ const counts = new Map < FiltersState [ K ] [ number ] , number > ( ) ;
43+ for ( const type of Object . keys (
44+ filter . FILTER_TYPES ,
45+ ) as FiltersState [ K ] [ number ] [ ] ) {
46+ counts . set ( type , filter . getFilterCount ( notifications , type ) ) ;
47+ }
48+ return counts ;
49+ } , [ notifications , filter ] ) ;
3650
3751 return (
3852 < fieldset id = { id } >
@@ -56,7 +70,7 @@ export const FilterSection = <T extends FilterSettingsValue>({
5670 direction = { layout }
5771 gap = { layout === 'horizontal' ? 'normal' : 'condensed' }
5872 >
59- { ( Object . keys ( filter . FILTER_TYPES ) as T [ ] )
73+ { ( Object . keys ( filter . FILTER_TYPES ) as FiltersState [ K ] [ number ] [ ] )
6074 . sort ( ( a , b ) =>
6175 filter
6276 . getTypeDetails ( a )
@@ -69,8 +83,8 @@ export const FilterSection = <T extends FilterSettingsValue>({
6983 const typeDetails = filter . getTypeDetails ( type ) ;
7084 const typeTitle = typeDetails . title ;
7185 const typeDescription = typeDetails . description ;
72- const isChecked = filter . isFilterSet ( settings , type ) ;
73- const count = filter . getFilterCount ( notifications , type ) ;
86+ const isChecked = filter . isFilterSet ( type ) ;
87+ const count = filterCounts . get ( type ) ?? 0 ;
7488
7589 return (
7690 < Checkbox
@@ -94,3 +108,8 @@ export const FilterSection = <T extends FilterSettingsValue>({
94108 </ fieldset >
95109 ) ;
96110} ;
111+
112+ // Memoize the component to prevent unnecessary re-renders
113+ export const FilterSection = memo (
114+ FilterSectionComponent ,
115+ ) as typeof FilterSectionComponent ;
0 commit comments