From adb28885a368e4ccffe7bfccdf45931e37f66a72 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Thu, 30 Jan 2020 23:38:25 +0100 Subject: webui: add open/closed issues count --- webui/src/list/FilterToolbar.js | 82 +++++++++++++++++++++++++++++++++-------- webui/src/list/ListQuery.js | 2 +- 2 files changed, 68 insertions(+), 16 deletions(-) (limited to 'webui') 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); -- cgit