Commit 67e4bb05 authored by Matija Obreza's avatar Matija Obreza

Merge branch '252-explore-filter-suggestions' into 'master'

Resolve "Explore: Filter suggestions"

Closes #252

See merge request genesys-pgr/genesys-ui!258
parents 12ec1698 d018fe51
......@@ -66,7 +66,9 @@
"createdDate": "Created on",
"lastModifiedDate": "Last modified",
"textSearch": "Text search",
"keyword": "Keyword search"
"keyword": "Keyword search",
"noFilters": "No available filters",
"suggestedFilters": "Suggested filters"
},
"fileUploader": {
"chooseFiles": "Choose files to upload",
......
......@@ -36,7 +36,8 @@
"gt": "{{what}} >",
"accessions": {
"crop": "Crop",
"acceNumb": "Accession number",
"crops": "Crops",
"accessionNumber": "Accession number",
"seqNo": "Sequential number",
"sampStat": "Biological status",
"storage": "Storage",
......@@ -52,14 +53,14 @@
"bio15": "Precipitation seasonality"
}
},
"holder": {
"institute": {
"code": "Holder",
"networks": "Network",
"owner": {
"uuid": "Data provider"
},
"country": {
"iso3": "Holder country",
"code3": "Holder country",
"region": "Holder region"
}
},
......@@ -68,8 +69,11 @@
"species": "Species",
"subtaxa": "Subtaxa"
},
"origin": {
"iso3": "Provenance"
"owner": {
"uuid": "Data provider"
},
"countryOfOrigin": {
"code3": "Provenance"
},
"taxonomy": {
"genus": "Genus",
......@@ -107,17 +111,20 @@
},
"subsets": {
"title": "Title",
"crop": "Crop",
"crops": "Crop",
"institutes": "Institute code",
"description": "Description",
"state": "Status",
"dateCreated": "Date created"
"dateCreated": "Date created",
"owner": {
"uuid": "Data provider"
}
},
"wiews": {
"code": "Institute code",
"accessions": "Accessions in Genesys",
"country": {
"iso3": "Country code"
"code3": "Country code"
},
"owner": {
"uuid": "Data provider"
......@@ -139,14 +146,14 @@
},
"datasets": {
"_text": "Keywords",
"accessionRef": {
"accessionRefs": {
"acceNumb": "Accession number",
"doi": "Accession DOI",
"genus": "Accession genus",
"instCode": "Accession holder"
},
"description": "Description",
"descriptor": {
"descriptors": {
"_text": "Descriptor keywords",
"title": "Descriptor title"
},
......@@ -155,7 +162,7 @@
"shortName": "Provider short name",
"wiewsCodes": "Owner WIEWS institute code"
},
"location": {
"locations": {
"country": "Evaluated in",
"latitude": "Latitude",
"longitude": "Longitude"
......@@ -163,7 +170,7 @@
"published": "Published",
"title": "Title",
"rights": "License",
"crop": "Crop",
"crops": "Crop",
"state": "Status"
},
"partner": {
......@@ -196,7 +203,7 @@
"category": "Category",
"columnName": "Column name",
"key": "Key crop descriptor",
"list": {
"descriptorLists": {
"uuid": "Descriptor list"
},
"owner": {
......
......@@ -16,6 +16,7 @@ import {
RECEIVE_ACCESSION_AUDIT_LOG,
RECEIVE_TILE_LAYER,
APPEND_ACCESSIONS,
APPEND_ACCESSIONS_WITH_SUGGESTIONS,
} from 'accessions/constants';
import AccessionService from 'service/genesys/AccessionService';
import ClimateService from 'service/genesys/ClimateService';
......@@ -32,6 +33,7 @@ const receiveAccessionMapInfo = (apiCall: ApiCall<any>) => ({
// Wrapped API calls
const apiListAccessions = createApiCaller(AccessionService.list, APPEND_ACCESSIONS);
const apiListAccessionSugestions = createApiCaller(AccessionService.listSuggestions, APPEND_ACCESSIONS_WITH_SUGGESTIONS);
const apiAccessionsOverview = createApiCaller(AccessionService.listOverview, RECEIVE_ACCESSION_OVERVIEW);
const apiAccessionsMapInfo = createApiCaller(AccessionService.mapInfo, RECEIVE_ACCESSION_MAPINFO);
......@@ -63,7 +65,7 @@ export const applyFilters = (filters: string | AccessionFilter, page: IPageReque
console.log('Applying new filter', filters);
dispatch(showSnackbar('Applying filters...'));
return dispatch(apiListAccessions(filters, page))
return dispatch(apiListAccessionSugestions(filters, page))
.then((paged) => {
dispatch(updateRoute(paged));
dispatch(showSnackbar(`Filters applied.`));
......
export const APPEND_ACCESSIONS = 'accessions/APPEND_ACCESSIONS';
export const APPEND_ACCESSIONS_WITH_SUGGESTIONS = 'accessions/APPEND_ACCESSIONS_WITH_SUGGESTIONS';
export const RECEIVE_ACCESSION_OVERVIEW = 'accessions/RECEIVE_ACCESSION_OVERVIEW';
export const RECEIVE_TILE_LAYER = 'accessions/RECEIVE_TILE_LAYER';
export const RECEIVE_ACCESSION_AUDIT_LOG = 'accessions/RECEIVE_ACCESSION_AUDIT_LOG';
......
......@@ -7,7 +7,7 @@ import {
APPEND_ACCESSIONS,
RECEIVE_ACCESSION_MAPINFO,
RECEIVE_ACCESSION_AUDIT_LOG,
RECEIVE_TILE_LAYER,
RECEIVE_TILE_LAYER, APPEND_ACCESSIONS_WITH_SUGGESTIONS,
} from 'accessions/constants';
import FilteredPage from 'model/FilteredPage';
......@@ -22,6 +22,7 @@ const INITIAL_STATE: {
accession: ApiCall<Accession>;
auditLog: ApiCall<AccessionAuditLog>,
paged: ApiCall<FilteredPage<Accession>>;
suggestions: any;
overview: ApiCall<AccessionOverview>;
mapInfo: ApiCall<AccessionMapInfo>;
mapLayers: MapLayer[]
......@@ -29,6 +30,7 @@ const INITIAL_STATE: {
accession: null,
auditLog: null,
paged: null,
suggestions: null,
overview: null,
mapInfo: null,
mapLayers: AVAILABLE_LAYERS,
......@@ -78,6 +80,7 @@ function publicAccessions(state = INITIAL_STATE, action: IReducerAction) {
timestamp,
data: data !== undefined ? data : state.overview && state.overview.data,
} },
suggestions: {$set: data ? data.suggestions : state.suggestions},
// paged: { $set: null },
// mapInfo: { $set: null },
});
......@@ -96,6 +99,22 @@ function publicAccessions(state = INITIAL_STATE, action: IReducerAction) {
// overview: { $set: null },
});
}
case APPEND_ACCESSIONS_WITH_SUGGESTIONS: {
const {apiCall: {loading, error, timestamp, data}} = action.payload;
return update(state, {
paged: {
$set: {
loading,
error,
timestamp,
data: FilteredPage.merge(state.paged && state.paged.data, data),
},
},
suggestions: {$set: data ? data.suggestions : state.suggestions},
// mapInfo: { $set: null },
// overview: { $set: null },
});
}
case RECEIVE_ACCESSION_MAPINFO: {
const { apiCall } = action.payload;
......@@ -103,6 +122,7 @@ function publicAccessions(state = INITIAL_STATE, action: IReducerAction) {
return update(state, {
mapInfo: { $set: apiCall },
suggestions: {$set: apiCall.data ? apiCall.data.suggestions : state.suggestions},
// paged: {$set: null},
// overview: {$set: null},
});
......
......@@ -42,15 +42,27 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
}
public render() {
const { paged, loadMoreData, filterCode, currentTab, loading, t} = this.props;
const { paged, loadMoreData, filterCode, currentTab, loading, suggestions, crops, t} = this.props;
const slug: string = this.state.authenticated ? 'download-authenticated' : 'download-anonymous';
const renderAccession = (s: Accession, index: number) => {
return <AccessionCard key={ s.uuid } index={ index } accession={ s } />;
};
const suggestionTerms = new Map();
if (suggestions) {
Object.keys(suggestions).forEach((key) => {
const overviewEl = suggestions[key];
const terms = new Map();
overviewEl.terms.forEach((term) => terms.set(term.term, term.count));
suggestionTerms.set(key, terms);
});
}
return (
<PageLayout sidebar={
<AccessionFilters initialValues={ paged && paged.filter || {} } onSubmit={ this.myApplyFilters } />
<AccessionFilters initialValues={ paged && paged.filter || {} } onSubmit={ this.myApplyFilters } terms={ suggestionTerms } crops={ crops }/>
}>
<PageTitle title={ t('accessions.public.p.browse.title') }/>
<ContentHeader title={ t('accessions.public.p.browse.title') } subTitle={ t('accessions.public.p.browse.subTitle') } />
......@@ -100,6 +112,8 @@ class BrowsePage extends BrowsePageTemplate<Accession> {
}
const mapStateToProps = (state, ownProps) => ({
suggestions: state.accessions.public.suggestions,
crops: state.crop.public.list ? state.crop.public.list.data : undefined,
paged: state.accessions.public.paged ? state.accessions.public.paged.data : undefined,
loading: state.accessions.public.paged ? state.accessions.public.paged.loading : false,
filterCode: ownProps.match.params.filterCode,
......
......@@ -19,7 +19,7 @@ import ButtonBar from 'ui/common/buttons/ButtonBar';
import ContentLayout from 'ui/layout/ContentLayout';
import MapConfigSection from './c/MapConfigSection';
import MapAccessionsFilters from 'accessions/ui/c/MapAccessionsFilters';
import AccessionsFilters from 'accessions/ui/c/Filters';
import BioClimateDisplay from 'accessions/ui/c/BioClimateDisplay';
import {Dialog, Drawer} from '@material-ui/core';
import PageTitle from 'ui/common/PageTitle';
......@@ -32,7 +32,7 @@ import FilterIcon from '@material-ui/icons/PermDataSetting';
import CancelIcon from '@material-ui/icons/Cancel';
let Map;
let MapComponent;
let TileLayer;
let Popup;
let Rectangle;
......@@ -46,6 +46,7 @@ interface IMapPageProps {
apiUrl: string;
mapInfo: AccessionMapInfo;
suggestions: any;
currentTab: string;
filterCode: string;
loadAccessionsMapInfo: any;
......@@ -162,7 +163,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
constructor(props, context) {
super(props, context);
if (typeof window !== 'undefined') {
Map = require('react-leaflet').Map;
MapComponent = require('react-leaflet').Map;
TileLayer = require('react-leaflet').TileLayer;
Popup = require('react-leaflet').Popup;
Rectangle = require('react-leaflet').Rectangle;
......@@ -305,7 +306,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
public render() {
const { searchBox, geoData, otherCount, sidebarOpened, trackClickPos, dialogOpened, climateData, layersControlsIsOpen} = this.state;
const { mapInfo, mapLayers, currentTab, classes, filterCode, loading, t, loadAccessionsMapInfo, initialPosition, initialZoom } = this.props;
const { mapInfo, mapLayers, currentTab, classes, filterCode, loading, suggestions, t, loadAccessionsMapInfo, initialPosition, initialZoom } = this.props;
const position = initialPosition[0] && initialPosition[1] ? initialPosition : [30, 0];
......@@ -313,6 +314,18 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
return <Loading />;
}
const suggestionTerms = new Map();
if (suggestions) {
Object.keys(suggestions).forEach((key) => {
const overviewEl = suggestions[key];
const terms = new Map();
overviewEl.terms.forEach((term) => terms.set(term.term, term.count));
suggestionTerms.set(key, terms);
});
}
console.log(suggestionTerms);
// const color = 'f00ba0';
const layerUrl = `{s}/acn/tile/{z}/{x}/{y}?f=${filterCode ? filterCode : ''}`; // `&color=${color}`;
......@@ -322,7 +335,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
<ContentHeader title={ t('accessions.public.p.browse.title') } subTitle={ t('accessions.public.p.browse.subTitle') } />
<Drawer variant="temporary" open={ sidebarOpened } onClose={ this.closeSidebar }>
<MapAccessionsFilters onSubmit={ loadAccessionsMapInfo } initialValues={ mapInfo && mapInfo.filter }/>
<AccessionsFilters terms={ suggestionTerms } onSubmit={ loadAccessionsMapInfo } initialValues={ mapInfo && mapInfo.filter }/>
</Drawer>
......@@ -357,7 +370,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
<div className={ `${classes.leafletContainer} ${trackClickPos && classes.crosshair}` }>
{ loading && <Loading /> }
{ mapInfo && typeof window !== 'undefined' &&
<Map
<MapComponent
onMoveend={ this.handleMoveEnd }
onClick={ this.onMapClick }
center={ position }
......@@ -452,7 +465,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
</Popup>
</Rectangle>
}
</Map>
</MapComponent>
}
</div>
</ContentLayout>
......@@ -461,6 +474,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
}
const mapStateToProps = (state, ownProps) => ({
suggestions: state.accessions.public.suggestions,
mapInfo: state.accessions.public.mapInfo ? state.accessions.public.mapInfo.data : undefined,
loading: state.accessions.public.mapInfo ? state.accessions.public.mapInfo.loading : false,
mapLayers: state.accessions.public.mapLayers,
......
......@@ -32,6 +32,7 @@ import Button from '@material-ui/core/Button';
interface IOverviewPageProps extends React.ClassAttributes<any> {
overview: AccessionOverview;
suggestions: any;
loading: boolean;
filterCode: string;
showSnackbar: (snack: string) => void;
......@@ -89,11 +90,11 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
switch (property) {
case 'crop':
case 'sampStat':
case 'holder.code':
case 'holder.country.iso3':
case 'origin.iso3':
case 'taxa.genus':
case 'taxa.species':
case 'institute.code':
case 'institute.country.code3':
case 'countryOfOrigin.code3':
case 'taxonomy.genus':
case 'taxonomy.species':
case 'storage':
_.set(updatedFilter, property, _.concat(_.get(updatedFilter, property), term).filter(x => x != null));
break;
......@@ -115,7 +116,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
};
public render() {
const { filterCode, currentTab, applyOverviewFilters, overview: overviewWrapper, loading, t } = this.props;
const { filterCode, currentTab, applyOverviewFilters, overview: overviewWrapper, loading, suggestions, t } = this.props;
const overview = overviewWrapper && overviewWrapper.overview || null;
const overviewKeys = ['institute.code', 'institute.country.code3', 'cropName', 'crop.shortName', 'sampStat', 'taxonomy.genus', 'taxonomy.genusSpecies',
......@@ -132,6 +133,16 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
});
}
const suggestionTerms = new Map();
if (suggestions) {
Object.keys(suggestions).forEach((key) => {
const overviewEl = suggestions[key];
const terms = new Map();
overviewEl.terms.forEach((term) => terms.set(term.term, term.count));
suggestionTerms.set(key, terms);
});
}
const filterByTerm = (property, term, count) => {
return (
skipTerms.indexOf(term.term) === -1
......@@ -143,7 +154,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
return (
<PageLayout
sidebar={
<AccessionFilters initialValues={ overviewWrapper && overviewWrapper.filter || {} } onSubmit={ applyOverviewFilters }/>
<AccessionFilters terms={ suggestionTerms } initialValues={ overviewWrapper && overviewWrapper.filter || {} } onSubmit={ applyOverviewFilters }/>
}
withFooter
>
......@@ -174,10 +185,10 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
<PageContents className="pt-1rem">
<GridContainer>
{ overviewsTerms && overviewsTerms.get('institute.code') && overviewsTerms.get('institute.code').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('institute.code').map((term) => ({title: term.term, value: filterByTerm('holder.code', term, term.count) })) } title={ t(`accessions.common.overview.institute code`) } small propertyItemProps={ { numeric: true } } />
<PropertiesCard propertiesList={ overviewsTerms.get('institute.code').map((term) => ({title: term.term, value: filterByTerm('institute.code', term, term.count) })) } title={ t(`accessions.common.overview.institute code`) } small propertyItemProps={ { numeric: true } } />
}
{ overviewsTerms && overviewsTerms.get('institute.country.code3') && overviewsTerms.get('institute.country.code3').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('institute.country.code3').map((term) => ({title: term.term, value: filterByTerm('holder.country.iso3', term, term.count) })) } title={ t(`accessions.common.overview.institute country code3`) } small propertyItemProps={ { numeric: true } } />
<PropertiesCard propertiesList={ overviewsTerms.get('institute.country.code3').map((term) => ({title: term.term, value: filterByTerm('institute.country.code3', term, term.count) })) } title={ t(`accessions.common.overview.institute country code3`) } small propertyItemProps={ { numeric: true } } />
}
{ overviewsTerms && overviewsTerms.get('crop.shortName') && overviewsTerms.get('crop.shortName').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('crop.shortName').map((term) => ({title: term.term, value: filterByTerm('crop', term, term.count)})) } title={ t(`accessions.common.overview.crop shortName`) } small propertyItemProps={ { numeric: true } } />
......@@ -186,7 +197,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
<PropertiesCard propertiesList={ overviewsTerms.get('cropName').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.cropName`) } small propertyItemProps={ { numeric: true } } />
}
{ overviewsTerms && overviewsTerms.get('taxonomy.genus') && overviewsTerms.get('taxonomy.genus').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genus').map((term) => ({title: term.term, value: filterByTerm('taxa.genus', term, term.count) })) } title={ t(`accessions.common.overview.taxonomy genus`) } small propertyItemProps={ { numeric: true, classes: {propertiesRowLabel: 'font-italic'} } } />
<PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genus').map((term) => ({title: term.term, value: filterByTerm('taxonomy.genus', term, term.count) })) } title={ t(`accessions.common.overview.taxonomy genus`) } small propertyItemProps={ { numeric: true, classes: {propertiesRowLabel: 'font-italic'} } } />
}
{ overviewsTerms && overviewsTerms.get('taxonomy.genusSpecies') && overviewsTerms.get('taxonomy.genusSpecies').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('taxonomy.genusSpecies').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.taxonomy genusSpecies`) } small propertyItemProps={ { numeric: true, classes: {propertiesRowLabel: 'font-italic'} } } />
......@@ -199,7 +210,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
<PropertiesCard propertiesList={ overviewsTerms.get('storage').map((term) => ({title: t([`accessions.common.storage.${term.term}`, `accessions.common.overview.${term.term}`]), value: filterByTerm('storage', term, term.count) })) } title={ t(`accessions.common.overview.storage`) } small propertyItemProps={ { numeric: true } } />
}
{ overviewsTerms && overviewsTerms.get('countryOfOrigin.code3') && overviewsTerms.get('countryOfOrigin.code3').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('countryOfOrigin.code3').map((term) => ({title: term.term, value: filterByTerm('origin.iso3', term, term.count)})) } title={ t(`accessions.common.overview.countryOfOrigin code3`) } small propertyItemProps={ { numeric: true } } />
<PropertiesCard propertiesList={ overviewsTerms.get('countryOfOrigin.code3').map((term) => ({title: term.term, value: filterByTerm('countryOfOrigin.code3', term, term.count)})) } title={ t(`accessions.common.overview.countryOfOrigin code3`) } small propertyItemProps={ { numeric: true } } />
}
{ overviewsTerms && overviewsTerms.get('donorCode') && overviewsTerms.get('donorCode').length > 2 &&
<PropertiesCard propertiesList={ overviewsTerms.get('donorCode').map((term) => ({title: term.term, value: term.count })) } title={ t(`accessions.common.overview.donorCode`) } small propertyItemProps={ { numeric: true } } />
......@@ -232,6 +243,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
}
const mapStateToProps = (state, ownProps) => ({
suggestions: state.accessions.public.suggestions,
overview: state.accessions.public.overview ? state.accessions.public.overview.data : undefined,
loading: state.accessions.public.overview ? state.accessions.public.overview.loading : false,
filterCode: ownProps.match.params.filterCode || '',
......
import * as React from 'react';
import { connect } from 'react-redux';
import { reduxForm } from 'redux-form';
import {translate} from 'react-i18next';
......@@ -6,25 +7,27 @@ import { ACCESSION_FILTERFORM } from 'accessions/constants';
import FiltersBlock from 'ui/common/filter/FiltersBlock';
import CollapsibleComponentSearch from 'ui/common/filter/CollapsibleComponentSearch';
import BooleanFilter from 'ui/common/filter/BooleanFilter';
import NumberFilter from 'ui/common/filter/NumberFilter';
import StringFilter from 'ui/common/filter/StringFilter';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import Accession from 'model/accession/Accession';
import DateFilter from 'ui/common/filter/DateFilter';
import CropFilter from 'crop/ui/c/CropFilter';
import BooleanFilter from 'ui/common/filter/BooleanFilter';
const AccessionFilters = ({handleSubmit, initialValues, initialize, t, ...other}) => {
const AccessionFilters = ({handleSubmit, initialValues, initialize, terms, crops, t, ...other}) => {
// console.log('AccessionFilters', initialValues);
return (
<FiltersBlock title={ t('accessions.public.f.filtersTitle') } handleSubmit={ handleSubmit } initialize={ initialize } { ...other }>
<CollapsibleComponentSearch title={ t('accessions.public.f.historic') }>
<BooleanFilter name="historic"/>
<BooleanFilter
name="historic"
terms={ terms && terms.get('historic') }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('common:f.textSearch') }>
<StringArrFilter name="holder.code" label={ t('accessions.common.instituteCode') } placeholder="NGA039"/>
<StringArrFilter name="holder.country.iso3" label={ t('accessions.model.institute.country.iso3') } placeholder="NGA"/>
<StringFilter name="acceNumb" searchType="contains" label={ t('accessions.common.acceNumb') } placeholder="IRGC"/>
<StringArrFilter name="institute.code" terms={ terms && terms.get('institute.code') } label={ t('accessions.common.instituteCode') } placeholder="NGA039"/>
<StringArrFilter name="institute.country.code3" label={ t('accessions.model.institute.country.iso3') } placeholder="NGA"/>
<StringFilter name="accessionNumber" searchType="contains" label={ t('accessions.common.acceNumb') } placeholder="IRGC"/>
<NumberFilter name="seqNo" label={ t('accessions.public.f.seqNumber') } />
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('common:f.dateSearch') }>
......@@ -32,59 +35,102 @@ const AccessionFilters = ({handleSubmit, initialValues, initialize, t, ...other}
<DateFilter name="lastModifiedDate" label={ t('common:f.lastModifiedDate') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.public.f.crop') }>
<CropFilter/>
<StringArrFilter
name="crop"
valueField="shortName"
labelField="name"
options={ crops }
terms={ terms && terms.get('crop.shortName') }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.common.taxonomy') }>
<StringArrFilter name="taxa.genus" label={ t('accessions.common.genus') } placeholder="Hordeum"/>
<StringArrFilter name="taxa.species" label={ t('accessions.common.species') } placeholder="vulgare"/>
<StringFilter name="taxa.subtaxa" searchType="contains" label={ t('accessions.public.f.subtaxon') } placeholder=""/>
<StringArrFilter
name="taxonomy.genus"
terms={ terms && terms.get('taxonomy.genus') }
label={ t('accessions.common.genus') }
placeholder="Hordeum"
classes={ {propertiesRowLabel: 'font-italic'} }
/>
<StringArrFilter name="taxonomy.species" label={ t('accessions.common.species') } placeholder="vulgare"/>
<StringFilter name="taxonomy.subtaxa" searchType="contains" label={ t('accessions.public.f.subtaxon') } placeholder=""/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.public.f.originOfMaterial') }>
<StringArrFilter name="origin.iso3" label={ t('accessions.common.countryOfOrigin') } placeholder="SVN"/>
<StringArrFilter name="countryOfOrigin.code3" terms={ terms && terms.get('countryOfOrigin.code3') } label={ t('accessions.common.countryOfOrigin') } placeholder="SVN"/>
<NumberFilter name="geo.latitude" label={ t('geo.common.latitude') } />
<NumberFilter name="geo.longitude" label={ t('geo.common.longitude') } />
<NumberFilter name="geo.elevation" label={ t('accessions.public.f.elevation') } />
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.public.f.climate') }>
<NumberFilter name="geo.climate.bio1" label={ t('accessions.climate.bio1') } />
<NumberFilter name="geo.climate.bio2" label={ t('accessions.climate.bio2') } />
<NumberFilter name="geo.climate.bio3" label={ t('accessions.climate.bio3') } />
<NumberFilter name="geo.climate.bio4" label={ t('accessions.climate.bio4') } />
<NumberFilter name="geo.climate.bio5" label={ t('accessions.climate.bio5') } />
<NumberFilter name="geo.climate.bio6" label={ t('accessions.climate.bio6') } />
<NumberFilter name="geo.climate.bio7" label={ t('accessions.climate.bio7') } />
<NumberFilter name="geo.climate.bio8" label={ t('accessions.climate.bio8') } />
<NumberFilter name="geo.climate.bio9" label={ t('accessions.climate.bio9') } />
<NumberFilter name="geo.climate.bio10" label={ t('accessions.climate.bio10') } />
<NumberFilter name="geo.climate.bio11" label={ t('accessions.climate.bio11') } />
<NumberFilter name="geo.climate.bio12" label={ t('accessions.climate.bio12') } />
<NumberFilter name="geo.climate.bio13" label={ t('accessions.climate.bio13') } />
<NumberFilter name="geo.climate.bio14" label={ t('accessions.climate.bio14') } />
<NumberFilter name="geo.climate.bio15" label={ t('accessions.climate.bio15') } />
<NumberFilter name="geo.climate.bio16" label={ t('accessions.climate.bio16') } />
<NumberFilter name="geo.climate.bio17" label={ t('accessions.climate.bio17') } />
<NumberFilter name="geo.climate.bio18" label={ t('accessions.climate.bio18') } />
<NumberFilter name="geo.climate.bio19" label={ t('accessions.climate.bio19') } />
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.common.sampStat') }>
<StringArrFilter name="sampStat" options={ Accession.SAMPSTAT } />
<StringArrFilter
name="sampStat"
options={ Accession.SAMPSTAT }
byKey
terms={ terms && terms.get('sampStat') }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.common.storageType') }>
<StringArrFilter name="storage" options={ Accession.STORAGE } />
<StringArrFilter
name="storage"
options={ Accession.STORAGE }
byKey
terms={ terms && terms.get('storage') }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('accessions.public.f.status') }>
<BooleanFilter name="historic" label={ t('accessions.public.f.historic') } />
<BooleanFilter name="available" label={ t('accessions.public.f.available') } />
<BooleanFilter name="mlsStatus" label={ t('accessions.public.f.mlsStatus') } />
<BooleanFilter name="sgsv" label={ t('accessions.public.f.sgsv') } />
<BooleanFilter name="images" label={ t('accessions.public.f.images') } />
<BooleanFilter
name="available"
label={ t('accessions.public.f.available') }
terms={ terms && terms.get('available') }
/>
<BooleanFilter
name="mlsStatus"
label={ t('accessions.public.f.mlsStatus') }
terms={ terms && terms.get('mlsStatus') }
/>
<BooleanFilter
name="sgsv"
label={ t('accessions.public.f.sgsv') }