diff --git a/webui/src/list/FilterToolbar.js b/webui/src/list/FilterToolbar.js
index 9f5f14c5..4d0b52b1 100644
--- a/webui/src/list/FilterToolbar.js
+++ b/webui/src/list/FilterToolbar.js
@@ -1,10 +1,17 @@
import { makeStyles } from '@material-ui/styles';
+import { useQuery } from '@apollo/react-hooks';
+import gql from 'graphql-tag';
import React from 'react';
import Toolbar from '@material-ui/core/Toolbar';
import ErrorOutline from '@material-ui/icons/ErrorOutline';
import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline';
import Filter, { parse, stringify } from './Filter';
+// simple pipe operator
+// pipe(o, f, g, h) <=> h(g(f(o)))
+// TODO: move this out?
+const pipe = (initial, ...funcs) => funcs.reduce((acc, f) => f(acc), initial);
+
const useStyles = makeStyles(theme => ({
toolbar: {
backgroundColor: theme.palette.grey['100'],
@@ -18,40 +25,85 @@ const useStyles = makeStyles(theme => ({
},
}));
+const BUG_COUNT_QUERY = gql`
+ query($query: String) {
+ defaultRepository {
+ bugs: allBugs(query: $query) {
+ totalCount
+ }
+ }
+ }
+`;
+
+// This prepends the filter text with a count
+function CountingFilter({ query, children, ...props }) {
+ const { data, loading, error } = useQuery(BUG_COUNT_QUERY, {
+ variables: { query },
+ });
+
+ var prefix;
+ if (loading) prefix = '...';
+ else if (error) prefix = '???';
+ // TODO: better prefixes & error handling
+ else prefix = data.defaultRepository.bugs.totalCount;
+
+ return (
+
+ {prefix} {children}
+
+ );
+}
+
function FilterToolbar({ query, queryLocation }) {
const classes = useStyles();
const params = parse(query);
+
const hasKey = key => params[key] && params[key].length > 0;
const hasValue = (key, value) => hasKey(key) && params[key].includes(value);
- const replaceParam = (key, value) => {
- const p = {
- ...params,
- [key]: [value],
- };
- return queryLocation(stringify(p));
- };
+ const loc = params => pipe(params, stringify, queryLocation);
+ const replaceParam = (key, value) => params => ({
+ ...params,
+ [key]: [value],
+ });
+ const clearParam = key => params => ({
+ ...params,
+ [key]: [],
+ });
- // TODO: open/closed count
// TODO: author/label filters
return (
-
open
-
-
+
closed
-
+
+ {/*
Author
Label
+ */}
hasValue('sort', key)}
- to={key => replaceParam('sort', key)}
+ to={key => pipe(params, replaceParam('sort', key), loc)}
>
Sort
diff --git a/webui/src/list/ListQuery.js b/webui/src/list/ListQuery.js
index 01113f6c..8eeec240 100644
--- a/webui/src/list/ListQuery.js
+++ b/webui/src/list/ListQuery.js
@@ -187,7 +187,7 @@ function ListQuery() {
const location = useLocation();
const history = useHistory();
const params = new URLSearchParams(location.search);
- const query = params.get('q');
+ const query = params.get('q') || '';
const [input, setInput] = useState(query);