@@ -10,16 +10,15 @@ import UpIcon from '@mui/icons-material/ArrowDropUp';
1010import List from '@mui/material/List' ;
1111import ListItemText from '@mui/material/ListItemText' ;
1212import ListSubheader from '@mui/material/ListSubheader' ;
13+ import ListItem from '@mui/material/ListItem' ;
1314import ListItemButton from '@mui/material/ListItemButton' ;
1415import ListItemIcon from '@mui/material/ListItemIcon' ;
1516import Checkbox from '@mui/material/Checkbox' ;
16- import Divider from '@mui/material/Divider' ;
1717import CircularProgress from '@mui/material/CircularProgress' ;
1818import { URIToParentParams , currentUserHasAccess } from '../../common/utils'
1919import { FACET_ORDER } from './ResultConstants' ;
2020
21-
22- const SearchFilters = ( { filters, resource, onChange, kwargs, bgColor, appliedFilters, fieldOrder, noSubheader, disabledZero, filterDefinitions, nested, onSaveAsDefaultFilters, loading, repoDefaultFilters, propertyFilters} ) => {
21+ const SearchFilters = ( { filters, resource, onChange, kwargs, bgColor, appliedFilters, fieldOrder, noSubheader, disabledZero, filterDefinitions, nested, onSaveAsDefaultFilters, loading, repoDefaultFilters, propertyFilters, heightToSubtract, open} ) => {
2322 const { t } = useTranslation ( )
2423 const [ applied , setApplied ] = React . useState ( { } ) ;
2524 const [ count , setCount ] = React . useState ( 0 ) ;
@@ -30,6 +29,7 @@ const SearchFilters = ({filters, resource, onChange, kwargs, bgColor, appliedFil
3029 const isConcept = resource === 'concepts'
3130 const isMapping = resource === 'mappings'
3231 const isSourceChild = isConcept || isMapping
32+ let propertyFacets = { }
3333 const hasValidKwargs = ! isEmpty ( kwargs ) && isObject ( kwargs ) ;
3434 if ( hasValidKwargs ) {
3535 if ( kwargs . user || kwargs . org )
@@ -67,13 +67,11 @@ const SearchFilters = ({filters, resource, onChange, kwargs, bgColor, appliedFil
6767 uiFilters = orderedUIFilters
6868 }
6969 if ( isConcept ) {
70- const properties = pickBy ( filters , ( values , field ) => field . startsWith ( 'properties__' ) && ! isEmpty ( values ) )
71- if ( ! isEmpty ( properties ) ) {
72- uiFilters = omit ( uiFilters , [ 'conceptClass' , 'datatype' ] )
73- uiFilters = { ...properties , ...uiFilters }
70+ propertyFacets = pickBy ( filters , ( values , field ) => field . startsWith ( 'properties__' ) && ! isEmpty ( values ) )
71+ if ( ! isEmpty ( propertyFacets ) ) {
72+ uiFilters = omit ( uiFilters , [ 'conceptClass' , 'datatype' , ...keys ( propertyFacets ) ] )
7473 }
7574 }
76-
7775 const formattedName = ( field , name ) => {
7876 let label ;
7977 if ( includes ( [ 'locale' , 'version' , 'source_version' , 'nameTypes' , 'expansion' ] , field ) )
@@ -178,28 +176,104 @@ const SearchFilters = ({filters, resource, onChange, kwargs, bgColor, appliedFil
178176 onChange ( repoDefaultFilters )
179177 }
180178
179+
180+ const getFilterList = ( fieldFilters , field ) => {
181+ const shouldShowExpand = fieldFilters . length > 5
182+ const isExpanded = expanded . includes ( field )
183+ return (
184+ < ListItem key = { field } sx = { { padding : 0 , flexDirection : 'column' } } >
185+ < List
186+ dense
187+ sx = { {
188+ width : '100%' ,
189+ position : 'relative' ,
190+ padding : 0 ,
191+ display : 'inline-block' ,
192+ } }
193+ >
194+ {
195+ ! noSubheader &&
196+ < ListSubheader sx = { { padding : '0 8px 0 0px' , fontWeight : 'bold' , backgroundColor : bgColor , lineHeight : '30px' } } >
197+ { formattedListSubheader ( field ) }
198+ </ ListSubheader >
199+ }
200+ {
201+ map ( getFieldFilters ( field , fieldFilters ) , value => {
202+ const labelId = `checkbox-list-label-${ value [ 0 ] } ` ;
203+ const key = `${ field } -${ value [ 0 ] } `
204+
205+ return (
206+ < ListItemButton key = { key } onClick = { handleToggle ( field , value ) } sx = { { p : '0 12px 0 4px' } } disabled = { value [ 3 ] === true || ( disabledZero && value [ 1 ] === 0 ) } >
207+ < ListItemIcon sx = { { minWidth : '25px' } } >
208+ < Checkbox
209+ size = "small"
210+ edge = "start"
211+ checked = { isApplied ( field , value ) }
212+ tabIndex = { - 1 }
213+ disableRipple
214+ inputProps = { { 'aria-labelledby' : labelId } }
215+ sx = { { padding : '0px 8px' , '.MuiSvgIcon-root' : { fontSize : '1.1rem' } } }
216+ disabled = { ( disabledZero && value [ 1 ] === 0 ) }
217+ />
218+ </ ListItemIcon >
219+ < ListItemText
220+ id = { labelId }
221+ primary = {
222+ < span style = { { display : 'flex' , alignItems : 'center' } } >
223+ { formattedName ( field , value [ 0 ] ) }
224+ {
225+ get ( filterDefinitions , value [ 0 ] ) ?. tooltip &&
226+ < Tooltip title = { filterDefinitions [ value [ 0 ] ] . tooltip } >
227+ < InfoIcon sx = { { marginLeft : '4px' , fontSize : '1rem' } } color = 'primary' />
228+ </ Tooltip >
229+ }
230+ </ span >
231+ }
232+ primaryTypographyProps = { { style : { fontSize : '0.875rem' } } } style = { { margin : 0 } } />
233+ < span style = { { fontSize : '0.7rem' } } > { value [ 1 ] . toLocaleString ( ) } </ span >
234+ </ ListItemButton >
235+ ) ;
236+ } ) }
237+
238+ </ List >
239+ {
240+ shouldShowExpand &&
241+ < ListItem sx = { { padding : '4px 4px 0px 0px' } } >
242+ < Button size = 'small' onClick = { ( ) => toggleExpanded ( field ) } sx = { { textTransform : 'none' , fontSize : '11px' , padding : '0px 5px 2px 5px' } } color = 'secondary' startIcon = { isExpanded ? < UpIcon fontSize = 'inherit' /> : < DownIcon fontSize = 'inherit' /> } >
243+ { isExpanded ? t ( 'common.hide' ) : `${ t ( 'common.show' ) } ${ fieldFilters . length - 5 } ${ t ( 'common.more' ) . toLowerCase ( ) } ` }
244+ </ Button >
245+ </ ListItem >
246+ }
247+ </ ListItem >
248+ )
249+ }
250+
251+
181252 const isFixedConceptField = field => isConcept && [ 'conceptClass' , 'datatype' ] . includes ( field )
253+ const canUpdateDefaultFilters = nested && onSaveAsDefaultFilters && currentUserHasAccess ( )
254+ const topBarHeight = canUpdateDefaultFilters ? 60 : 30
255+ let totalFilters = { ...propertyFacets , ...uiFilters }
182256
183257 return (
184258 < div className = 'col-xs-12 padding-0' >
185- < div className = 'col-xs-12' style = { { zIndex : 2 , padding : '0px' } } >
186- < div className = 'col-xs-12' style = { { display : 'flex' , justifyContent : 'space-between' , alignItems : 'center' , padding : '0 8px' } } >
259+ < div className = 'col-xs-12' style = { { zIndex : 2 , padding : '0px' , position : open ? 'absolute' : undefined , top : 0 , display : open ? undefined : 'none' } } >
260+ < div className = 'col-xs-12' style = { { display : 'flex' , justifyContent : 'space-between' , alignItems : 'center' , padding : '0 8px 0 0' } } >
261+ < span >
262+ < Badge badgeContent = { count } color = 'primary' sx = { { '.MuiBadge-badge' : { top : '10px' , left : '36px' } } } >
263+ < b > { t ( 'search.filters' ) } </ b >
264+ </ Badge >
265+ </ span >
187266 < span >
188- < Badge badgeContent = { count } color = 'primary' sx = { { '.MuiBadge-badge' : { top : '10px' , left : '36px' } } } >
189- < b > { t ( 'search.filters' ) } </ b >
190- </ Badge >
191- </ span >
192- < span >
193267 < Button variant = 'text' color = 'primary' style = { { textTransform : 'none' } } onClick = { onApply } disabled = { ! unapplied } >
194268 { t ( 'common.apply' ) }
195269 </ Button >
196- < Button variant = 'text' style = { { textTransform : 'none' } } onClick = { onClear } disabled = { ! count } color = 'error' >
197- { t ( 'common.clear' ) }
198- </ Button >
199- </ span >
270+ < Button variant = 'text' style = { { textTransform : 'none' } } onClick = { onClear } disabled = { ! count } color = 'error' >
271+ { t ( 'common.clear' ) }
272+ </ Button >
273+ </ span >
200274 </ div >
201275 {
202- nested && onSaveAsDefaultFilters && currentUserHasAccess ( ) &&
276+ canUpdateDefaultFilters &&
203277 < div className = 'col-xs-12 padding-0' style = { { textAlign : 'right' } } >
204278 < Button size = 'small' sx = { { textTransform : 'none' } } onClick = { onSetDefaultFilters } disabled = { isEmpty ( applied ) || isEqual ( applied , repoDefaultFilters ) } >
205279 { t ( 'search.save_default_filters' ) }
@@ -210,86 +284,52 @@ const SearchFilters = ({filters, resource, onChange, kwargs, bgColor, appliedFil
210284 </ div >
211285 }
212286 </ div >
213- {
214- loading && isEmpty ( uiFilters ) &&
215- < div className = 'col-xs-12' style = { { textAlign : 'center' , padding : '16px' } } >
216- < CircularProgress />
217- </ div >
218- }
219- {
220- map ( uiFilters , ( fieldFilters , field ) => {
221- const shouldShowExpand = fieldFilters . length > 4
222- const isExpanded = expanded . includes ( field )
223- return (
224- < div className = 'col-xs-12 padding-0' key = { field } >
225- < List
226- dense
227- sx = { {
228- width : '100%' ,
229- position : 'relative' ,
230- padding : 0 ,
231- display : 'inline-block' ,
232- } }
233- >
234- {
235- ! noSubheader &&
236- < ListSubheader sx = { { padding : '0 8px' , fontWeight : 'bold' , backgroundColor : bgColor , lineHeight : '30px' } } >
237- { formattedListSubheader ( field ) }
238- </ ListSubheader >
239- }
240- {
241- map ( getFieldFilters ( field , fieldFilters ) , ( value , index ) => {
242- const labelId = `checkbox-list-label-${ value [ 0 ] } ` ;
243- const key = `${ field } -${ value [ 0 ] } `
244-
245- return (
246- < ListItemButton key = { key } onClick = { handleToggle ( field , value ) } sx = { { p : '0 12px' , paddingTop : index === 0 ? '4px' : undefined } } disabled = { value [ 3 ] === true || ( disabledZero && value [ 1 ] === 0 ) } >
247- < ListItemIcon sx = { { minWidth : '25px' } } >
248- < Checkbox
249- size = "small"
250- edge = "start"
251- checked = { isApplied ( field , value ) }
252- tabIndex = { - 1 }
253- disableRipple
254- inputProps = { { 'aria-labelledby' : labelId } }
255- sx = { { padding : '0px 8px' , '.MuiSvgIcon-root' : { fontSize : '1.1rem' } } }
256- disabled = { ( disabledZero && value [ 1 ] === 0 ) }
257-
258- />
259- </ ListItemIcon >
260- < ListItemText
261- id = { labelId }
262- primary = {
263- < span style = { { display : 'flex' , alignItems : 'center' } } >
264- { formattedName ( field , value [ 0 ] ) }
265- {
266- get ( filterDefinitions , value [ 0 ] ) ?. tooltip &&
267- < Tooltip title = { filterDefinitions [ value [ 0 ] ] . tooltip } >
268- < InfoIcon sx = { { marginLeft : '4px' , fontSize : '1rem' } } color = 'primary' />
269- </ Tooltip >
270- }
271- </ span >
272- }
273- primaryTypographyProps = { { style : { fontSize : '0.875rem' } } } style = { { margin : 0 } } />
274- < span style = { { fontSize : '0.7rem' } } > { value [ 1 ] . toLocaleString ( ) } </ span >
275- </ ListItemButton >
276- ) ;
277- } ) }
278- </ List >
287+ < div className = 'col-xs-12 padding-0' style = { { marginTop : `${ topBarHeight } px` , height : `calc(100vh - ${ heightToSubtract || 0 } px - ${ topBarHeight } px)` , overflowY : 'auto' } } >
288+ {
289+ loading && isEmpty ( totalFilters ) &&
290+ < div className = 'col-xs-12' style = { { textAlign : 'center' , padding : '16px' } } >
291+ < CircularProgress />
292+ </ div >
293+ }
294+ {
295+ ! isEmpty ( propertyFacets ) &&
296+ < List
297+ dense
298+ sx = { {
299+ width : '100%' ,
300+ position : 'relative' ,
301+ padding : 0 ,
302+ display : 'inline-block' ,
303+ marginTop : '8px'
304+ } } >
305+ < ListSubheader sx = { { padding : '0 8px 0 0px' , fontWeight : 'bold' , backgroundColor : bgColor , lineHeight : 'normal' , color : '#000' } } >
306+ { t ( 'repo.properties_filters_subheader' ) }
307+ </ ListSubheader >
308+ { map ( propertyFacets , getFilterList ) }
309+ </ List >
310+ }
311+ {
312+ ! isEmpty ( uiFilters ) &&
313+ < List
314+ dense
315+ sx = { {
316+ width : '100%' ,
317+ position : 'relative' ,
318+ padding : 0 ,
319+ display : 'inline-block' ,
320+ marginTop : isEmpty ( propertyFacets ) ? 0 : '14px'
321+ } }
322+ >
279323 {
280- shouldShowExpand &&
281- < Button size = 'small' onClick = { ( ) => toggleExpanded ( field ) } sx = { { textTransform : 'none ' , fontSize : '11px ' , padding : '0px 5px 2px 5px' } } color = 'secondary' startIcon = { isExpanded ? < UpIcon fontSize = 'inherit' /> : < DownIcon fontSize = 'inherit' /> } >
282- { isExpanded ? t ( 'common.hide' ) : ` ${ t ( 'common.show' ) } ${ fieldFilters . length - 4 } ${ t ( 'common.more' ) . toLowerCase ( ) } ` }
283- </ Button >
324+ ! isEmpty ( propertyFacets ) &&
325+ < ListSubheader sx = { { padding : '0 8px 0 0px ' , fontWeight : 'bold ' , backgroundColor : bgColor , lineHeight : 'normal' , color : '#000' } } >
326+ { t ( 'repo.additional_metadata_filters_subheader' ) }
327+ </ ListSubheader >
284328 }
285- {
286- ! noSubheader &&
287- < Divider />
288- }
289- </ div >
290- )
291- } )
292- }
329+ { map ( uiFilters , getFilterList ) }
330+ </ List >
331+ }
332+ </ div >
293333 </ div >
294334 )
295335}
0 commit comments