diff options
Diffstat (limited to 'webui/src/list/Filter.js')
-rw-r--r-- | webui/src/list/Filter.js | 154 |
1 files changed, 0 insertions, 154 deletions
diff --git a/webui/src/list/Filter.js b/webui/src/list/Filter.js deleted file mode 100644 index a6cf3633..00000000 --- a/webui/src/list/Filter.js +++ /dev/null @@ -1,154 +0,0 @@ -import React, { useState, useRef } from 'react'; -import { Link } from 'react-router-dom'; -import { makeStyles } from '@material-ui/styles'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import ArrowDropDown from '@material-ui/icons/ArrowDropDown'; - -function parse(query) { - // TODO: extract the rest of the query? - const params = {}; - - // TODO: support escaping without quotes - const re = /(\w+):([A-Za-z0-9-]+|(["'])(([^\3]|\\.)*)\3)+/g; - let matches; - while ((matches = re.exec(query)) !== null) { - if (!params[matches[1]]) { - params[matches[1]] = []; - } - - let value; - if (matches[4]) { - value = matches[4]; - } else { - value = matches[2]; - } - value = value.replace(/\\(.)/g, '$1'); - params[matches[1]].push(value); - } - return params; -} - -function quote(value) { - const hasSingle = value.includes("'"); - const hasDouble = value.includes('"'); - const hasSpaces = value.includes(' '); - if (!hasSingle && !hasDouble && !hasSpaces) { - return value; - } - - if (!hasDouble) { - return `"${value}"`; - } - - if (!hasSingle) { - return `'${value}'`; - } - - value = value.replace(/"/g, '\\"'); - return `"${value}"`; -} - -function stringify(params) { - const parts = Object.entries(params).map(([key, values]) => { - return values.map(value => `${key}:${quote(value)}`); - }); - return [].concat(...parts).join(' '); -} - -const useStyles = makeStyles(theme => ({ - element: { - ...theme.typography.body2, - color: ({ active }) => (active ? '#333' : '#444'), - padding: theme.spacing(0, 1), - fontWeight: ({ active }) => (active ? 600 : 400), - textDecoration: 'none', - display: 'flex', - background: 'none', - border: 'none', - }, - itemActive: { - fontWeight: 600, - }, - icon: { - paddingRight: theme.spacing(0.5), - }, -})); - -function Dropdown({ children, dropdown, itemActive, to, ...props }) { - const [open, setOpen] = useState(false); - const buttonRef = useRef(); - const classes = useStyles(); - - return ( - <> - <button ref={buttonRef} onClick={() => setOpen(!open)} {...props}> - {children} - <ArrowDropDown fontSize="small" /> - </button> - <Menu - getContentAnchorEl={null} - anchorOrigin={{ - vertical: 'bottom', - horizontal: 'left', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'left', - }} - open={open} - onClose={() => setOpen(false)} - anchorEl={buttonRef.current} - > - {dropdown.map(([key, value]) => ( - <MenuItem - component={Link} - to={to(key)} - className={itemActive(key) ? classes.itemActive : null} - onClick={() => setOpen(false)} - key={key} - > - {value} - </MenuItem> - ))} - </Menu> - </> - ); -} - -function Filter({ active, to, children, icon: Icon, dropdown, ...props }) { - const classes = useStyles({ active }); - - const content = ( - <> - {Icon && <Icon fontSize="small" classes={{ root: classes.icon }} />} - <div>{children}</div> - </> - ); - - if (dropdown) { - return ( - <Dropdown - {...props} - to={to} - dropdown={dropdown} - className={classes.element} - > - {content} - </Dropdown> - ); - } - - if (to) { - return ( - <Link to={to} {...props} className={classes.element}> - {content} - </Link> - ); - } - - return <div className={classes.element}>{content}</div>; -} - -export default Filter; -export { parse, stringify, quote }; |