From 54c5b66271f4f3d95881a186c8124e7e5dcdb6d4 Mon Sep 17 00:00:00 2001 From: Aien Saidi Date: Thu, 18 Mar 2021 18:00:16 +0100 Subject: feat: use author to filter the list --- webui/src/pages/list/FilterToolbar.tsx | 28 ++++++++++++++++++++++++++-- webui/src/pages/list/ListIdentities.graphql | 13 +++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 webui/src/pages/list/ListIdentities.graphql (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index 74eefe4c..92154ad2 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -8,14 +8,15 @@ import CheckCircleOutline from '@material-ui/icons/CheckCircleOutline'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; import { + Filter, FilterDropdown, FilterProps, - Filter, parse, - stringify, Query, + stringify, } from './Filter'; import { useBugCountQuery } from './FilterToolbar.generated'; +import { useListIdentitiesQuery } from './ListIdentities.generated'; const useStyles = makeStyles((theme) => ({ toolbar: { @@ -35,6 +36,7 @@ type CountingFilterProps = { query: string; // the query used as a source to count the number of element children: React.ReactNode; } & FilterProps; + function CountingFilter({ query, children, ...props }: CountingFilterProps) { const { data, loading, error } = useBugCountQuery({ variables: { query }, @@ -57,9 +59,24 @@ type Props = { query: string; queryLocation: (query: string) => LocationDescriptor; }; + function FilterToolbar({ query, queryLocation }: Props) { const classes = useStyles(); const params: Query = parse(query); + const { data } = useListIdentitiesQuery(); + + let identities: any = []; + + if ( + data?.repository && + data.repository.allIdentities && + data.repository.allIdentities.nodes + ) { + identities = data.repository.allIdentities.nodes.map((node) => [ + node.name, + node.name, + ]); + } const hasKey = (key: string): boolean => params[key] && params[key].length > 0; @@ -115,6 +132,13 @@ function FilterToolbar({ query, queryLocation }: Props) { Author Label */} + hasValue('author', key)} + to={(key) => pipe(replaceParam('author', key), loc)(params)} + > + Author + Date: Thu, 18 Mar 2021 18:09:03 +0100 Subject: feat: add filter by label --- webui/src/pages/list/FilterToolbar.tsx | 31 ++++++++++++++++++++++++++----- webui/src/pages/list/ListLabels.graphql | 9 +++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 webui/src/pages/list/ListLabels.graphql (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index 92154ad2..37f63b98 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -17,6 +17,7 @@ import { } from './Filter'; import { useBugCountQuery } from './FilterToolbar.generated'; import { useListIdentitiesQuery } from './ListIdentities.generated'; +import { useListLabelsQuery } from './ListLabels.generated'; const useStyles = makeStyles((theme) => ({ toolbar: { @@ -63,16 +64,29 @@ type Props = { function FilterToolbar({ query, queryLocation }: Props) { const classes = useStyles(); const params: Query = parse(query); - const { data } = useListIdentitiesQuery(); + const { data: identitiesData } = useListIdentitiesQuery(); + const { data: labelsData } = useListLabelsQuery() let identities: any = []; + let labels: any = []; if ( - data?.repository && - data.repository.allIdentities && - data.repository.allIdentities.nodes + identitiesData?.repository && + identitiesData.repository.allIdentities && + identitiesData.repository.allIdentities.nodes ) { - identities = data.repository.allIdentities.nodes.map((node) => [ + identities = identitiesData.repository.allIdentities.nodes.map((node) => [ + node.name, + node.name, + ]); + } + + if ( + labelsData?.repository && + labelsData.repository.validLabels && + labelsData.repository.validLabels.nodes + ) { + labels = labelsData.repository.validLabels.nodes.map((node) => [ node.name, node.name, ]); @@ -139,6 +153,13 @@ function FilterToolbar({ query, queryLocation }: Props) { > Author + hasValue('label', key)} + to={(key) => pipe(replaceParam('label', key), loc)(params)} + > + Label + Date: Thu, 18 Mar 2021 18:17:18 +0100 Subject: feat: check if there are labels --- webui/src/pages/list/FilterToolbar.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index 37f63b98..3046d9d8 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -65,7 +65,7 @@ function FilterToolbar({ query, queryLocation }: Props) { const classes = useStyles(); const params: Query = parse(query); const { data: identitiesData } = useListIdentitiesQuery(); - const { data: labelsData } = useListLabelsQuery() + const { data: labelsData } = useListLabelsQuery(); let identities: any = []; let labels: any = []; @@ -153,13 +153,15 @@ function FilterToolbar({ query, queryLocation }: Props) { > Author - hasValue('label', key)} - to={(key) => pipe(replaceParam('label', key), loc)(params)} - > - Label - + {labels.length ? ( + hasValue('label', key)} + to={(key) => pipe(replaceParam('label', key), loc)(params)} + > + Label + + ) : null} Date: Wed, 24 Mar 2021 00:37:04 +0100 Subject: feat: multiple label filter - add search functionality in menu items --- webui/src/pages/list/Filter.tsx | 60 ++++++++++++++++++++++++++-------- webui/src/pages/list/FilterToolbar.tsx | 34 +++++++++++++------ 2 files changed, 71 insertions(+), 23 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/Filter.tsx b/webui/src/pages/list/Filter.tsx index 66702078..154d0f94 100644 --- a/webui/src/pages/list/Filter.tsx +++ b/webui/src/pages/list/Filter.tsx @@ -1,14 +1,26 @@ import clsx from 'clsx'; import { LocationDescriptor } from 'history'; -import React, { useState, useRef } from 'react'; +import React, { useRef, useState } from 'react'; import { Link } from 'react-router-dom'; import Menu from '@material-ui/core/Menu'; import MenuItem from '@material-ui/core/MenuItem'; import { SvgIconProps } from '@material-ui/core/SvgIcon'; -import { makeStyles } from '@material-ui/core/styles'; +import TextField from '@material-ui/core/TextField'; +import { makeStyles, withStyles } from '@material-ui/core/styles'; import ArrowDropDown from '@material-ui/icons/ArrowDropDown'; +const CustomTextField = withStyles({ + root: { + margin: '0 8px 12px 8px', + '& label.Mui-focused': { + margin: '0 2px', + }, + }, +})(TextField); + +const ITEM_HEIGHT = 48; + export type Query = { [key: string]: string[] }; function parse(query: string): Query { @@ -90,6 +102,7 @@ type FilterDropdownProps = { itemActive: (key: string) => boolean; icon?: React.ComponentType; to: (key: string) => LocationDescriptor; + hasFilter?: boolean; } & React.ButtonHTMLAttributes; function FilterDropdown({ @@ -98,9 +111,11 @@ function FilterDropdown({ itemActive, icon: Icon, to, + hasFilter, ...props }: FilterDropdownProps) { const [open, setOpen] = useState(false); + const [filter, setFilter] = useState(''); const buttonRef = useRef(null); const classes = useStyles({ active: false }); @@ -135,18 +150,36 @@ function FilterDropdown({ open={open} onClose={() => setOpen(false)} anchorEl={buttonRef.current} + PaperProps={{ + style: { + maxHeight: ITEM_HEIGHT * 4.5, + width: '20ch', + }, + }} > - {dropdown.map(([key, value]) => ( - setOpen(false)} - key={key} - > - {value} - - ))} + {hasFilter && ( + { + const { value } = e.target; + setFilter(value); + }} + value={filter} + label={`Filter ${children}`} + /> + )} + {dropdown + .filter((d) => d[1].toLowerCase().includes(filter.toLowerCase())) + .map(([key, value]) => ( + setOpen(false)} + key={key} + > + {value} + + ))} ); @@ -158,6 +191,7 @@ export type FilterProps = { icon?: React.ComponentType; children: React.ReactNode; }; + function Filter({ active, to, children, icon: Icon }: FilterProps) { const classes = useStyles(); diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index 3046d9d8..1af96d0f 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -109,6 +109,20 @@ function FilterToolbar({ query, queryLocation }: Props) { ...params, [key]: params[key] && params[key].includes(value) ? [] : [value], }); + const toggleOrAddParam = (key: string, value: string) => ( + params: Query + ): Query => { + const values = params[key]; + return { + ...params, + [key]: + params[key] && params[key].includes(value) + ? values.filter((v) => v !== value) + : values + ? [...values, value] + : [value], + }; + }; const clearParam = (key: string) => (params: Query): Query => ({ ...params, [key]: [], @@ -150,18 +164,18 @@ function FilterToolbar({ query, queryLocation }: Props) { dropdown={identities} itemActive={(key) => hasValue('author', key)} to={(key) => pipe(replaceParam('author', key), loc)(params)} + hasFilter > Author - {labels.length ? ( - hasValue('label', key)} - to={(key) => pipe(replaceParam('label', key), loc)(params)} - > - Label - - ) : null} + hasValue('label', key)} + to={(key) => pipe(toggleOrAddParam('label', key), loc)(params)} + hasFilter + > + Label + hasValue('sort', key)} - to={(key) => pipe(replaceParam('sort', key), loc)(params)} + to={(key) => pipe(toggleParam('sort', key), loc)(params)} > Sort -- cgit From f82071a3d7140a1e21c02b27f03871794116af8a Mon Sep 17 00:00:00 2001 From: Aien Saidi Date: Wed, 24 Mar 2021 01:16:51 +0100 Subject: feat: use predefined filters --- webui/src/pages/list/Filter.tsx | 2 +- webui/src/pages/list/ListQuery.tsx | 65 +++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/Filter.tsx b/webui/src/pages/list/Filter.tsx index 154d0f94..54b2262b 100644 --- a/webui/src/pages/list/Filter.tsx +++ b/webui/src/pages/list/Filter.tsx @@ -153,7 +153,7 @@ function FilterDropdown({ PaperProps={{ style: { maxHeight: ITEM_HEIGHT * 4.5, - width: '20ch', + width: '25ch', }, }} > diff --git a/webui/src/pages/list/ListQuery.tsx b/webui/src/pages/list/ListQuery.tsx index 500ccf77..58cc7519 100644 --- a/webui/src/pages/list/ListQuery.tsx +++ b/webui/src/pages/list/ListQuery.tsx @@ -1,19 +1,23 @@ import { ApolloError } from '@apollo/client'; +import { pipe } from '@arrows/composition'; import React, { useState, useEffect, useRef } from 'react'; import { useLocation, useHistory, Link } from 'react-router-dom'; -import { Button } from '@material-ui/core'; +import { Button, FormControl, Menu, MenuItem } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton'; import InputBase from '@material-ui/core/InputBase'; import Paper from '@material-ui/core/Paper'; import { makeStyles, Theme } from '@material-ui/core/styles'; +import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; import Skeleton from '@material-ui/lab/Skeleton'; +import { useCurrentIdentityQuery } from '../../components/CurrentIdentity/CurrentIdentity.generated'; import IfLoggedIn from 'src/components/IfLoggedIn/IfLoggedIn'; +import { parse, Query, stringify } from './Filter'; import FilterToolbar from './FilterToolbar'; import List from './List'; import { useListBugsQuery } from './ListQuery.generated'; @@ -192,6 +196,8 @@ function ListQuery() { const query = params.has('q') ? params.get('q') || '' : 'status:open'; const [input, setInput] = useState(query); + const [filterMenuIsOpen, setFilterMenuIsOpen] = useState(false); + const filterButtonRef = useRef(null); const classes = useStyles({ searching: !!input }); @@ -293,14 +299,65 @@ function ListQuery() { history.push(queryLocation(input)); }; + const { + loading: ciqLoading, + error: ciqError, + data: ciqData, + } = useCurrentIdentityQuery(); + if (ciqError || ciqLoading || !ciqData?.repository?.userIdentity) { + return null; + } + const user = ciqData.repository.userIdentity; + + const loc = pipe(stringify, queryLocation); + const qparams: Query = parse(query); + const replaceParam = (key: string, value: string) => ( + params: Query + ): Query => ({ + ...params, + [key]: [value], + }); + return (
- + + + setFilterMenuIsOpen(false)} + getContentAnchorEl={null} + anchorEl={filterButtonRef.current} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'left', + }} + > + setFilterMenuIsOpen(false)} + > + Your newest issues + + + Date: Wed, 24 Mar 2021 17:13:20 +0100 Subject: fix: issue with toggling the author --- webui/src/pages/list/FilterToolbar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index 1af96d0f..59a09226 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -163,7 +163,7 @@ function FilterToolbar({ query, queryLocation }: Props) { hasValue('author', key)} - to={(key) => pipe(replaceParam('author', key), loc)(params)} + to={(key) => pipe(toggleParam('author', key), loc)(params)} hasFilter > Author @@ -174,7 +174,7 @@ function FilterToolbar({ query, queryLocation }: Props) { to={(key) => pipe(toggleOrAddParam('label', key), loc)(params)} hasFilter > - Label + Labels Date: Wed, 24 Mar 2021 18:12:05 +0100 Subject: fix: issue with regex --- webui/src/pages/list/Filter.tsx | 6 +++--- webui/src/pages/list/FilterToolbar.tsx | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/Filter.tsx b/webui/src/pages/list/Filter.tsx index 54b2262b..2ba6ffaf 100644 --- a/webui/src/pages/list/Filter.tsx +++ b/webui/src/pages/list/Filter.tsx @@ -28,7 +28,7 @@ function parse(query: string): Query { const params: Query = {}; // TODO: support escaping without quotes - const re = /(\w+):([A-Za-z0-9-]+|(["'])(([^\3]|\\.)*)\3)+/g; + const re = /(\w+):([A-Za-z0-9-]+|"([^"]*)")/g; let matches; while ((matches = re.exec(query)) !== null) { if (!params[matches[1]]) { @@ -36,8 +36,8 @@ function parse(query: string): Query { } let value; - if (matches[4]) { - value = matches[4]; + if (matches[3]) { + value = matches[3]; } else { value = matches[2]; } diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index 59a09226..cf5994ab 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -96,6 +96,8 @@ function FilterToolbar({ query, queryLocation }: Props) { params[key] && params[key].length > 0; const hasValue = (key: string, value: string): boolean => hasKey(key) && params[key].includes(value); + const containsValue = (key: string, value: string): boolean => + hasKey(key) && params[key].indexOf(value) !== -1; const loc = pipe(stringify, queryLocation); const replaceParam = (key: string, value: string) => ( params: Query @@ -170,7 +172,10 @@ function FilterToolbar({ query, queryLocation }: Props) { hasValue('label', key)} + itemActive={(key) => { + console.log(params, params[key], key); + return containsValue('label', key); + }} to={(key) => pipe(toggleOrAddParam('label', key), loc)(params)} hasFilter > -- cgit From 1216fb1e27919c58c3df81950adaf556bdb73594 Mon Sep 17 00:00:00 2001 From: Aien Saidi Date: Wed, 24 Mar 2021 18:13:05 +0100 Subject: chore: returning value --- webui/src/pages/list/FilterToolbar.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/FilterToolbar.tsx b/webui/src/pages/list/FilterToolbar.tsx index cf5994ab..cfb93dc2 100644 --- a/webui/src/pages/list/FilterToolbar.tsx +++ b/webui/src/pages/list/FilterToolbar.tsx @@ -172,10 +172,7 @@ function FilterToolbar({ query, queryLocation }: Props) { { - console.log(params, params[key], key); - return containsValue('label', key); - }} + itemActive={(key) => containsValue('label', key)} to={(key) => pipe(toggleOrAddParam('label', key), loc)(params)} hasFilter > -- cgit From 72fc0ef73e6c8063075a77bcf37fc8bd7e4c8baf Mon Sep 17 00:00:00 2001 From: Aien Saidi Date: Wed, 24 Mar 2021 18:49:17 +0100 Subject: fix: issue with keyDown propagation --- webui/src/pages/list/Filter.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/Filter.tsx b/webui/src/pages/list/Filter.tsx index 2ba6ffaf..782c2041 100644 --- a/webui/src/pages/list/Filter.tsx +++ b/webui/src/pages/list/Filter.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx'; import { LocationDescriptor } from 'history'; -import React, { useRef, useState } from 'react'; +import React, { useRef, useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; import Menu from '@material-ui/core/Menu'; @@ -117,8 +117,13 @@ function FilterDropdown({ const [open, setOpen] = useState(false); const [filter, setFilter] = useState(''); const buttonRef = useRef(null); + const searchRef = useRef(null); const classes = useStyles({ active: false }); + useEffect(() => { + searchRef && searchRef.current && searchRef.current.focus(); + }, [filter]); + const content = ( <> {Icon && } @@ -139,6 +144,7 @@ function FilterDropdown({ e.stopPropagation()} value={filter} label={`Filter ${children}`} /> -- cgit From d2845605c2152738e37d13b7067fedac91ccf225 Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 24 Mar 2021 20:16:25 +0100 Subject: Fix readability of filter input field in dark mode --- webui/src/pages/list/Filter.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/Filter.tsx b/webui/src/pages/list/Filter.tsx index 782c2041..42375dea 100644 --- a/webui/src/pages/list/Filter.tsx +++ b/webui/src/pages/list/Filter.tsx @@ -10,14 +10,21 @@ import TextField from '@material-ui/core/TextField'; import { makeStyles, withStyles } from '@material-ui/core/styles'; import ArrowDropDown from '@material-ui/icons/ArrowDropDown'; -const CustomTextField = withStyles({ +const CustomTextField = withStyles((theme) => ({ root: { margin: '0 8px 12px 8px', '& label.Mui-focused': { margin: '0 2px', + color: theme.palette.text.secondary, + }, + '& .MuiInput-underline::before': { + borderBottomColor: theme.palette.divider, + }, + '& .MuiInput-underline::after': { + borderBottomColor: theme.palette.divider, }, }, -})(TextField); +}))(TextField); const ITEM_HEIGHT = 48; -- cgit From 41ee97a4f6e6b6c5c76d6b3f61fdeda5fbabe053 Mon Sep 17 00:00:00 2001 From: Aien Saidi Date: Tue, 30 Mar 2021 19:10:23 +0200 Subject: fix: regex issue --- webui/src/pages/list/Filter.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/Filter.tsx b/webui/src/pages/list/Filter.tsx index 42375dea..2e99eedf 100644 --- a/webui/src/pages/list/Filter.tsx +++ b/webui/src/pages/list/Filter.tsx @@ -35,7 +35,7 @@ function parse(query: string): Query { const params: Query = {}; // TODO: support escaping without quotes - const re = /(\w+):([A-Za-z0-9-]+|"([^"]*)")/g; + const re = /(\w+):([A-Za-z0-9-]+|(["'])(([^\3]|\\.)*)\3)+/g; let matches; while ((matches = re.exec(query)) !== null) { if (!params[matches[1]]) { @@ -43,8 +43,8 @@ function parse(query: string): Query { } let value; - if (matches[3]) { - value = matches[3]; + if (matches[4]) { + value = matches[4]; } else { value = matches[2]; } -- cgit From 3380135182d5c9b1abd6188eb85382db45c7f4ff Mon Sep 17 00:00:00 2001 From: Sascha Date: Fri, 26 Mar 2021 12:52:55 +0100 Subject: Make filter/search input full width --- webui/src/pages/list/ListQuery.tsx | 117 +++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 63 deletions(-) (limited to 'webui/src/pages') diff --git a/webui/src/pages/list/ListQuery.tsx b/webui/src/pages/list/ListQuery.tsx index 58cc7519..4cd75c8d 100644 --- a/webui/src/pages/list/ListQuery.tsx +++ b/webui/src/pages/list/ListQuery.tsx @@ -39,24 +39,17 @@ const useStyles = makeStyles((theme) => ({ }, header: { display: 'flex', - padding: theme.spacing(2), - '& > h1': { - ...theme.typography.h6, - margin: theme.spacing(0, 2), - }, - alignItems: 'center', - justifyContent: 'space-between', + padding: theme.spacing(1), }, filterissueLabel: { fontSize: '14px', fontWeight: 'bold', paddingRight: '12px', }, - filterissueContainer: { + form: { display: 'flex', - flexDirection: 'row', - alignItems: 'flex-start', - justifyContents: 'left', + flexGrow: 1, + marginRight: theme.spacing(1), }, search: { borderRadius: theme.shape.borderRadius, @@ -66,7 +59,7 @@ const useStyles = makeStyles((theme) => ({ borderWidth: '1px', backgroundColor: theme.palette.primary.light, padding: theme.spacing(0, 1), - width: ({ searching }) => (searching ? '20rem' : '15rem'), + width: '100%', transition: theme.transitions.create([ 'width', 'borderColor', @@ -321,58 +314,56 @@ function ListQuery() { return (
-
- - - - setFilterMenuIsOpen(false)} - getContentAnchorEl={null} - anchorEl={filterButtonRef.current} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'left', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'left', - }} - > - setFilterMenuIsOpen(false)} - > - Your newest issues - - - - setInput(e.target.value)} - classes={{ - root: classes.search, - focused: classes.searchFocused, + + + + setFilterMenuIsOpen(false)} + getContentAnchorEl={null} + anchorEl={filterButtonRef.current} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', }} - /> - - -
+ transformOrigin={{ + vertical: 'top', + horizontal: 'left', + }} + > + setFilterMenuIsOpen(false)} + > + Your newest issues + +
+ + setInput(e.target.value)} + classes={{ + root: classes.search, + focused: classes.searchFocused, + }} + /> + + {() => (