1- import React , { useEffect , useRef , useState } from 'react' ;
1+ import React , { useContext , useEffect , useRef , useState } from 'react' ;
22import { IconButton , Stack , useTheme } from '@mui/material' ;
33import Grid from '@mui/material/Grid2' ;
44import { DeletableFilterChip } from './DeletableFilterChip' ;
@@ -9,21 +9,28 @@ import { faXmark } from '@fortawesome/pro-regular-svg-icons/faXmark';
99import { faSliders } from '@fortawesome/pro-regular-svg-icons/faSliders' ;
1010import { MetadataFilter } from 'components/metadataManagement/types' ;
1111import { debounce } from 'lodash' ;
12- import { EngagementDisplayStatus } from 'constants/engagementStatus' ;
1312import { useAppTranslation } from 'hooks' ;
1413import { Button } from 'components/common/Input/Button' ;
1514import { colors } from '../common' ;
1615import { CustomTextField , Select } from 'components/common/Input' ;
1716import { When } from 'react-if' ;
1817import { BodyText } from 'components/common/Typography/Body' ;
19- import { FilterBlockProps } from './types' ;
18+ import { LandingDataContext } from '.' ;
19+ import { tryParse } from 'engagements/admin/create/authoring/utils' ;
20+ import { getSearchParamObject , updateSearchParams } from './utils' ;
21+ import { EngagementDisplayStatus } from 'constants/engagementStatus' ;
2022
21- const FilterBlock = ( props : FilterBlockProps ) => {
22- const { searchFilters, setSearchFilters, clearFilters, setFiltersOpen } = props ;
23- const selectedValue = searchFilters . engagement_status . length === 0 ? - 1 : searchFilters . engagement_status [ 0 ] ;
23+ const FilterBlock = ( ) => {
24+ const { searchParams, setSearchParams, clearFilters, setFiltersOpen } = useContext ( LandingDataContext ) ;
25+
26+ const selectedValue =
27+ getSearchParamObject ( 'engagement_status' , searchParams ) ?. length === 0
28+ ? - 1
29+ : Number ( getSearchParamObject ( 'engagement_status' , searchParams ) ?. [ 0 ] ) ;
2430
2531 const tileBlockRef = useRef < HTMLDivElement > ( null ) ;
2632 const [ didMount , setDidMount ] = useState ( false ) ;
33+ const [ searchText , setSearchText ] = useState ( '' ) ;
2734
2835 const theme = useTheme ( ) ;
2936 const { t : translate } = useAppTranslation ( ) ;
@@ -37,10 +44,11 @@ const FilterBlock = (props: FilterBlockProps) => {
3744
3845 const debounceSetSearchFilters = useRef (
3946 debounce ( ( searchText : string ) => {
40- setSearchFilters ( {
41- ...searchFilters ,
47+ const newSearchParams = new URLSearchParams ( {
48+ ...searchParams ,
4249 search_text : searchText ,
4350 } ) ;
51+ setSearchParams ( newSearchParams ) ;
4452 } , 300 ) ,
4553 ) . current ;
4654
@@ -54,12 +62,13 @@ const FilterBlock = (props: FilterBlockProps) => {
5462 const yOffset = tileBlockRef ?. current ?. offsetTop ;
5563 globalThis . scrollTo ( { top : yOffset || 0 , behavior : 'smooth' } ) ;
5664 }
57- } , [ searchFilters . page ] ) ;
58-
59- const [ searchText , setSearchText ] = useState ( '' ) ;
65+ } , [ searchParams . get ( 'page' ) ] ) ;
6066
6167 const handleDeleteFilterChip = ( taxonId : number , value : string ) => {
62- const newMetadataFilters = searchFilters . metadata
68+ const metaParams = searchParams . get ( 'meta_filters' ) ;
69+ const metaFilters = metaParams && tryParse ( metaParams ) ? JSON . parse ( metaParams ) : { } ;
70+ if ( ! metaFilters ) return ;
71+ const newMetaFilters = metaFilters
6372 . map ( ( filter : MetadataFilter ) => {
6473 if ( filter . taxon_id === taxonId ) {
6574 // Remove the value
@@ -69,8 +78,12 @@ const FilterBlock = (props: FilterBlockProps) => {
6978 return filter ;
7079 } )
7180 . filter ( ( filter : MetadataFilter ) => filter . values . length > 0 ) ; // Remove any filters with no values left
72-
73- setSearchFilters ( { ...searchFilters , metadata : newMetadataFilters , page : 1 } ) ;
81+ const newMetaFilterParams = new URLSearchParams ( {
82+ ...searchParams ,
83+ meta_filters : JSON . stringify ( newMetaFilters ) ,
84+ page : '1' ,
85+ } ) ;
86+ setSearchParams ( newMetaFilterParams ) ;
7487 } ;
7588
7689 return (
@@ -120,10 +133,7 @@ const FilterBlock = (props: FilterBlockProps) => {
120133 title = "Clear search"
121134 sx = { { color : '#9F9D9C' } }
122135 onClick = { ( ) => {
123- setSearchFilters ( {
124- ...searchFilters ,
125- search_text : '' ,
126- } ) ;
136+ setSearchParams ( updateSearchParams ( { search_text : '' } , searchParams ) ) ;
127137 setSearchText ( '' ) ;
128138 } }
129139 >
@@ -162,41 +172,55 @@ const FilterBlock = (props: FilterBlockProps) => {
162172 rowGap = { 1 }
163173 width = "100%"
164174 >
165- < Select
166- style = { { margin : 0 } }
167- value = { selectedValue }
168- id = "status-filter"
169- aria-label = { `Filtering by ${ selectableStatuses . get (
170- selectedValue ,
171- ) } . Change this filter value by expanding to view all options.` }
172- onChange = { ( event ) => {
173- const selectedValue = Number ( event . target . value ) ;
174- setSearchFilters ( {
175- ... searchFilters ,
176- engagement_status : selectedValue === - 1 ? [ ] : [ selectedValue ] ,
177- page : 1 ,
178- } ) ;
179- } }
180- renderValue = { ( value ) => selectableStatuses . get ( value as number ) ?? '' }
181- displayEmpty
182- inputProps = { {
183- 'aria-label' : `Status Filter - ${ selectableStatuses . get ( selectedValue ) ?? '' } ` ,
184- } }
185- options = { Array . from ( selectableStatuses ) . map ( ( [ status , label ] ) => ( {
186- value : status ,
187- label : label ,
188- } ) ) }
189- />
190- { searchFilters . metadata . map ( ( filter : MetadataFilter ) =>
191- filter . values . map ( ( value ) => (
192- < DeletableFilterChip
193- key = { ` ${ filter . taxon_id } - ${ value } ` }
194- name = { value }
195- onDelete = { ( ) => handleDeleteFilterChip ( filter . taxon_id , value ) }
175+ { selectedValue !== undefined && selectableStatuses && (
176+ < >
177+ < Select
178+ style = { { margin : 0 } }
179+ value = { selectedValue }
180+ id = "status-filter"
181+ aria-label = { `Filtering by ${ selectableStatuses . get (
182+ selectedValue ,
183+ ) } . Change this filter value by expanding to view all options.` }
184+ onChange = { ( event ) => {
185+ const selectedValue = Number ( event . target . value ) ;
186+ const newParams = updateSearchParams (
187+ {
188+ engagement_status : selectedValue === - 1 ? [ ] : [ selectedValue ] ,
189+ page : 1 ,
190+ } ,
191+ searchParams ,
192+ ) ;
193+ setSearchParams ( newParams ) ;
194+ } }
195+ renderValue = { ( value ) => {
196+ return selectableStatuses . get ( value as number ) ?? '' ;
197+ } }
198+ displayEmpty
199+ inputProps = { {
200+ 'aria-label' : `Status Filter - ${ selectableStatuses . get ( selectedValue ) ?? '' } ` ,
201+ } }
202+ options = { Array . from ( selectableStatuses ) . map ( ( [ status , label ] ) => ( {
203+ value : status ,
204+ label : label ,
205+ } ) ) }
196206 />
197- ) ) ,
207+ { getSearchParamObject ( 'meta_filters' , searchParams ) ?. map ( ( filter : MetadataFilter ) =>
208+ filter . values . map ( ( value ) => (
209+ < DeletableFilterChip
210+ key = { `${ filter . taxon_id } -${ value } ` }
211+ name = { value }
212+ onDelete = { ( ) => handleDeleteFilterChip ( filter . taxon_id , value ) }
213+ />
214+ ) ) ,
215+ ) }
216+ </ >
198217 ) }
199- < When condition = { searchFilters . engagement_status . length || searchFilters . metadata . length } >
218+ < When
219+ condition = {
220+ getSearchParamObject ( 'engagement_status' , searchParams ) ?. length ||
221+ getSearchParamObject ( 'meta_filters' , searchParams ) ?. length
222+ }
223+ >
200224 < Button
201225 variant = "tertiary"
202226 onClick = { clearFilters }
0 commit comments