Commit 6e30f379 authored by Markus Scheidgen's avatar Markus Scheidgen
Browse files

Merged new searchbar. Rewrote searchbar to use quantity search instead of statistics.

parent f60f18cc
......@@ -6,6 +6,7 @@
"dependencies": {
"@material-ui/core": "^4.0.0",
"@material-ui/icons": "^4.0.0",
"@material-ui/lab": "^4.0.0-alpha.49",
"@navjobs/upload": "^3.1.3",
"autosuggest-highlight": "^3.1.1",
"base-64": "^0.1.0",
......
......@@ -462,6 +462,25 @@ class Api {
.finally(this.onFinishLoading)
}
async quantity_search(quantity, search, size, noLoadingIndicator) {
if (!noLoadingIndicator) {
this.onStartLoading()
}
return this.swagger()
.then(client => client.apis.repo.quantity_search({
size: size || 20,
quantity: quantity,
...search
}))
.catch(handleApiError)
.then(response => response.body)
.finally(() => {
if (!noLoadingIndicator) {
this.onFinishLoading()
}
})
}
async deleteUpload(uploadId) {
this.onStartLoading()
return this.swagger()
......
......@@ -4,7 +4,8 @@ import { makeStyles } from '@material-ui/core/styles'
import { Card, Button, Tooltip, Tabs, Tab, Paper, FormControl,
FormGroup, Checkbox, FormControlLabel, CardContent, IconButton, FormLabel, Select, MenuItem } from '@material-ui/core'
import { useQueryParam, useQueryParams, StringParam, NumberParam } from 'use-query-params'
import SearchBar from './SearchBar'
// import SearchBar from './SearchBar'
import SearchBar from './SearchBarNew'
import EntryList from './EntryList'
import DatasetList from './DatasetList'
import { DisableOnLoading } from '../api'
......@@ -143,7 +144,7 @@ const useSearchEntryStyles = makeStyles(theme => ({
marginRight: 0
},
searchBar: {
width: '100%'
marginTop: theme.spacing(1)
},
selectButton: {
margin: theme.spacing(1)
......@@ -197,7 +198,10 @@ function SearchEntry({initialTab, initialOwner, ownerTypes, initialDomain, initi
<MetricSelect classes={{root: classes.metricButton}} initialMetric={initialMetric}/>
</FormGroup>
<SearchBar classes={{autosuggestRoot: classes.searchBar}} />
{/* <SearchBar classes={{autosuggestRoot: classes.searchBar}} /> */}
<div className={classes.searchBar}>
<SearchBar />
</div>
</div>
<div className={classes.visualizations}>
......
import React from 'react'
import {searchContext} from './SearchContext'
import Autocomplete from '@material-ui/lab/Autocomplete'
import TextField from '@material-ui/core/TextField'
import { CircularProgress } from '@material-ui/core'
import * as searchQuantities from '../../searchQuantities.json'
import { apiContext } from '../api'
const defaultOptions = Object.keys(searchQuantities).map(quantity => searchQuantities[quantity].name)
export default function SearchBar() {
const [open, setOpen] = React.useState(false)
const [options, setOptions] = React.useState(defaultOptions)
const [loading, setLoading] = React.useState(false)
const [inputValue, setInputValue] = React.useState('')
const {response: {statistics, pagination}, domain, query, setQuery} = React.useContext(searchContext)
const {api} = React.useContext(apiContext)
const autocompleteValue = Object.keys(query).map(quantity => `${quantity}=${query[quantity]}`)
let helperText = ''
if (pagination && statistics) {
if (pagination.total === 0) {
helperText = <span>There are no more entries matching your criteria.</span>
} else {
helperText = <span>
There {pagination.total === 1 ? 'is' : 'are'} {Object.keys(domain.searchMetrics).filter(key => statistics.total.all[key]).map(key => {
return <span key={key}>
{domain.searchMetrics[key].renderResultString(statistics.total.all[key])}
</span>
})}{Object.keys(query).length ? ' left' : ''}.
</span>
}
}
const loadValues = (quantity, value) => {
setLoading(true)
const size = searchQuantities[quantity].statistic_size || 20
api.quantity_search(quantity, query, size, true)
.then(response => {
setLoading(false)
const options = Object.keys(response.quantity.values).map(value => `${quantity}=${value}`)
setOptions(options)
setOpen(true)
})
.catch(() => {
setLoading(false)
})
}
const handleInputChange = (event, value, reason) => {
if (reason === 'input') {
setInputValue(value)
const [quantity, quantityValue] = value.split('=')
if (!quantityValue) {
if (searchQuantities[quantity]) {
loadValues(quantity, quantityValue)
} else {
setOptions(defaultOptions)
}
}
}
}
const handleChange = (event, entries, reason) => {
const newQuery = entries.reduce((query, entry) => {
if (entry) {
const [quantity, value] = entry.split('=')
if (query[quantity]) {
if (searchQuantities[quantity].many) {
if (Array.isArray(query[quantity])) {
query[quantity].push(value)
} else {
query[quantity] = [query[quantity], value]
}
} else {
query[quantity] = value
}
} else {
query[quantity] = value
}
}
return query
}, {})
setQuery(newQuery, true)
if (entries.length !== 0) {
const entry = entries[entries.length - 1]
const [quantity, value] = entry.split('=')
if (value) {
setInputValue('')
} else {
setInputValue(`${entry}=`)
loadValues(quantity)
}
}
}
React.useEffect(() => {
if (!open) {
setOptions(defaultOptions)
}
}, [open])
return <Autocomplete
multiple
freeSolo
inputValue={inputValue}
value={autocompleteValue}
limitTags={4}
id='search-bar'
open={open}
onOpen={() => {
setOpen(true)
}}
onClose={() => {
setOpen(false)
}}
onChange={handleChange}
onInputChange={handleInputChange}
getOptionSelected={(option, value) => option === value}
getOptionLabel={(option) => option}
options={options}
loading={loading}
renderInput={(params) => (
<TextField
{...params}
helperText={helperText}
label='Search with quantity=value'
variant='outlined'
InputProps={{
...params.InputProps,
endAdornment: (
<React.Fragment>
{loading ? <CircularProgress color='inherit' size={20} /> : null}
{params.InputProps.endAdornment}
</React.Fragment>
)
}}
/>
)}
/>
}
......@@ -25,8 +25,8 @@ export const Dates = {
buckets: 50
}
searchQuantities['from_time'] = true
searchQuantities['until_time'] = true
searchQuantities['from_time'] = {name: 'from_time'}
searchQuantities['until_time'] = {name: 'until_time'}
/**
* A custom hook that reads and writes search parameters from the current URL.
*/
......
......@@ -81,7 +81,6 @@ export default function UploadsHistogram({title = 'Uploads over time', initialSc
const fromTime = item.time
const untilTime = Dates.addSeconds(fromTime, interval)
setQuery({
...query,
from_time: Dates.APIDate(fromTime),
until_time: Dates.APIDate(untilTime)
})
......@@ -200,7 +199,7 @@ export default function UploadsHistogram({title = 'Uploads over time', initialSc
return
}
const value = Dates.APIDate(new Date(event.target.value))
setQuery({...query, [key]: value})
setQuery({[key]: value})
} catch (error) {
}
})
......
......@@ -966,6 +966,17 @@
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/lab@^4.0.0-alpha.49":
version "4.0.0-alpha.49"
resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.49.tgz#da2bd29ecad3620924f078c0bab8f4483e821475"
integrity sha512-Shx+wktDCj7YDlNSkgMeFhijTyqWT0CGn7wDBMck36kZlh3GQhNwaj1y5p219sCYJY44SPgnrDaCxBStlzj8KQ==
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/utils" "^4.9.6"
clsx "^1.0.4"
prop-types "^15.7.2"
react-is "^16.8.0"
"@material-ui/styles@^4.9.10":
version "4.9.10"
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.9.10.tgz#182ccdd0bc8525a459486499bbaebcd92b0db3ab"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment