Skip to content

Commit fc9c0f9

Browse files
committed
OpenConceptLab/ocl_issues#2211 | Search Filters groups
1 parent 36ef4d6 commit fc9c0f9

File tree

7 files changed

+151
-106
lines changed

7 files changed

+151
-106
lines changed

src/components/orgs/OrgHome.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const OrgHome = () => {
107107
defaultFiltersOpen={false}
108108
nested
109109
noTabs
110-
filtersHeight='calc(100vh - 280px)'
110+
filtersHeightToSubtract={280}
111111
resultContainerStyle={{height: 'calc(100vh - 368px)', overflow: 'auto'}}
112112
containerStyle={{padding: 0}}
113113
/>

src/components/repos/RepoHome.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ const RepoHome = () => {
243243
repoDefaultFilters={(!tab || tab === 'concepts') ? repo?.meta?.display?.default_filter : {}}
244244
onShowItem={onShowItem}
245245
showItem={showItem}
246-
filtersHeight='calc(100vh - 300px)'
247-
resultContainerStyle={{height: 'calc(100vh - 388px)', overflow: 'auto', maxWidth: 'calc(100vw - 300px)'}}
246+
filtersHeightToSubtract={268}
247+
resultContainerStyle={{height: 'calc(100vh - 356px)', overflow: 'auto', maxWidth: 'calc(100vw - 300px)'}}
248248
containerStyle={{padding: 0}}
249249
properties={(!tab || tab === 'concepts') ? repo?.meta?.display?.concept_summary_properties : []}
250250
propertyFilters={(!tab || tab === 'concepts') ? repo?.filters : []}
@@ -257,7 +257,7 @@ const RepoHome = () => {
257257
</div>
258258
{
259259
!isSplitView &&
260-
<Paper component="div" className='col-xs-12' sx={{backgroundColor: 'surface.main', boxShadow: 'none', padding: '16px', borderLeft: 'solid 0.5px', borderTop: 'solid 0.5px', borderColor: 'surface.nv80', width: '272px !important', height: 'calc(100vh - 250px)', borderRadius: '0 0 10px 0'}}>
260+
<Paper component="div" className='col-xs-12' sx={{backgroundColor: 'surface.main', boxShadow: 'none', padding: '16px', borderLeft: 'solid 0.5px', borderTop: 'solid 0.5px', borderColor: 'surface.nv80', width: '272px !important', height: 'calc(100vh - 218px)', borderRadius: '0 0 10px 0'}}>
261261
<RepoSummary repo={repo} summary={repoSummary} />
262262
</Paper>
263263
}
@@ -267,7 +267,7 @@ const RepoHome = () => {
267267
!loading && status && <Error40X status={status} />
268268
}
269269
</Paper>
270-
<div className={'col-xs-5 padding-0' + (isSplitView ? ' split-appear' : '')} style={{marginLeft: '16px', width: isSplitView ? 'calc(41.66666667% - 16px)' : 0, backgroundColor: WHITE, borderRadius: '10px', height: isSplitView ? 'calc(100vh - 95px)' : 0, opacity: isSplitView ? 1 : 0, overflow: 'auto'}}>
270+
<div className={'col-xs-5 padding-0' + (isSplitView ? ' split-appear' : '')} style={{marginLeft: '16px', width: isSplitView ? 'calc(41.66666667% - 16px)' : 0, backgroundColor: WHITE, borderRadius: '10px', height: isSplitView ? 'calc(100vh - 102px)' : 0, opacity: isSplitView ? 1 : 0, overflow: 'auto'}}>
271271
{
272272
Boolean(showConceptURL && !conceptForm) &&
273273
<ConceptHome repoSummary={repoSummary} source={repo} repo={repo} url={showConceptURL} concept={showItem} onClose={() => setShowItem(false)} nested />

src/components/search/Search.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,9 @@ const Search = props => {
367367
}
368368
<div className='col-xs-12 padding-0' style={{height: '100%'}}>
369369
<div className='col-xs-12 padding-0' style={{height: '100%'}}>
370-
<div className='col-xs-3 split padding-0' style={{width: showFilters ? `${FILTERS_WIDTH}px` : 0, padding: showFilters ? '0 8px' : 0, height: props.filtersHeight || 'calc(100vh - 175px)', overflow: 'auto', ...(showFilters ? {borderRight: '0.3px solid', borderColor: COLORS.surface.n90} : {})}}>
370+
<div className='col-xs-3 split padding-0' style={{width: showFilters ? `${FILTERS_WIDTH}px` : 0, padding: showFilters ? '0 8px' : 0, ...(showFilters ? {borderRight: '0.3px solid', borderColor: COLORS.surface.n90} : {})}}>
371371
<SearchFilters
372+
open={showFilters}
372373
loading={loadingFacets}
373374
resource={resource}
374375
filters={result[resource]?.facets || {}}
@@ -379,6 +380,7 @@ const Search = props => {
379380
onSaveAsDefaultFilters={props.onSaveAsDefaultFilters ? filters => props.onSaveAsDefaultFilters(getFacetQueryParam(filters)) : false}
380381
repoDefaultFilters={getAppliedFacetFromQueryParam(props.repoDefaultFilters || {})}
381382
propertyFilters={props.propertyFilters}
383+
heightToSubtract={props.filtersHeightToSubtract || 175}
382384
/>
383385
</div>
384386
<div className='col-xs-9 split' style={{width: getSearchResultsWidth(), paddingRight: 0, paddingLeft: 0, float: 'right', height: '100%'}}>

src/components/search/SearchFilters.jsx

Lines changed: 137 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ import UpIcon from '@mui/icons-material/ArrowDropUp';
1010
import List from '@mui/material/List';
1111
import ListItemText from '@mui/material/ListItemText';
1212
import ListSubheader from '@mui/material/ListSubheader';
13+
import ListItem from '@mui/material/ListItem';
1314
import ListItemButton from '@mui/material/ListItemButton';
1415
import ListItemIcon from '@mui/material/ListItemIcon';
1516
import Checkbox from '@mui/material/Checkbox';
16-
import Divider from '@mui/material/Divider';
1717
import CircularProgress from '@mui/material/CircularProgress';
1818
import { URIToParentParams, currentUserHasAccess } from '../../common/utils'
1919
import { 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', 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'}} 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 4px'}}>
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'}}>
259+
<div className='col-xs-12' style={{zIndex: 2, padding: '0px', position: open ? 'absolute' : undefined, top: 0, display: open ? undefined : 'none'}}>
186260
<div className='col-xs-12' style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '0 8px'}}>
187261
<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>
262+
<Badge badgeContent={count} color='primary' sx={{'.MuiBadge-badge': {top: '10px', left: '36px'}}}>
263+
<b>{t('search.filters')}</b>
264+
</Badge>
265+
</span>
266+
<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,85 +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-
</ListItemIcon>
259-
<ListItemText
260-
id={labelId}
261-
primary={
262-
<span style={{display: 'flex', alignItems: 'center'}}>
263-
{formattedName(field, value[0])}
264-
{
265-
get(filterDefinitions, value[0])?.tooltip &&
266-
<Tooltip title={filterDefinitions[value[0]].tooltip}>
267-
<InfoIcon sx={{marginLeft: '4px', fontSize: '1rem'}} color='primary' />
268-
</Tooltip>
269-
}
270-
</span>
271-
}
272-
primaryTypographyProps={{style: {fontSize: '0.875rem'}}} style={{margin: 0}} />
273-
<span style={{fontSize: '0.7rem'}}>{value[1].toLocaleString()}</span>
274-
</ListItemButton>
275-
);
276-
})}
277-
</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', 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+
>
278323
{
279-
shouldShowExpand &&
280-
<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'/>}>
281-
{isExpanded ? t('common.hide') : `${t('common.show')} ${fieldFilters.length - 4} ${t('common.more').toLowerCase()}`}
282-
</Button>
324+
!isEmpty(propertyFacets) &&
325+
<ListSubheader sx={{padding: '0 8px', fontWeight: 'bold', backgroundColor: bgColor, lineHeight: 'normal', color: '#000'}}>
326+
{t('repo.additional_metadata_filters_subheader')}
327+
</ListSubheader>
283328
}
284-
{
285-
!noSubheader &&
286-
<Divider />
287-
}
288-
</div>
289-
)
290-
})
291-
}
329+
{map(uiFilters, getFilterList)}
330+
</List>
331+
}
332+
</div>
292333
</div>
293334
)
294335
}

src/components/url-registry/URLRegistry.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ const URLRegistry = () => {
5656
</div>
5757
<div className='col-xs-12 padding-0' style={{backgroundColor: WHITE, borderRadius: '10px'}}>
5858
<Search
59-
filtersHeight={`calc(100vh - 275px)`}
60-
resultContainerStyle={{height: `calc(100vh - 363px)`, overflow: 'auto'}}
59+
filtersHeightToSubtract={275}
60+
resultContainerStyle={{height: `calc(100vh - 373px)`, overflow: 'auto'}}
6161
resource='url_registry'
6262
url={owner + 'url-registry/'}
6363
nested

src/components/users/UserHome.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ const UserHome = () => {
121121
url={user?.url + 'repos/'}
122122
nested
123123
noTabs
124-
filtersHeight={`calc(100vh - ${baseHeightToDeduct}px)`}
124+
filtersHeightToSubtract={baseHeightToDeduct}
125125
resultContainerStyle={{height: `calc(100vh - ${baseHeightToDeduct}px - 88px)`, overflow: 'auto'}}
126126
containerStyle={{padding: 0}}
127127
defaultFiltersOpen={false}

src/i18n/locales/en/translations.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,9 @@
338338
"properties": "Properties",
339339
"property": "Property",
340340
"filters": "Filters",
341-
"version_changelog_request_accepted": "Versions compare request is accepted, please come back in few minutes."
341+
"version_changelog_request_accepted": "Versions compare request is accepted, please come back in few minutes.",
342+
"properties_filters_subheader": "Repository Properties",
343+
"additional_metadata_filters_subheader": "Additional Metadata"
342344
},
343345
"org": {
344346
"my": "My Organizations",

0 commit comments

Comments
 (0)