X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/750b2c391b5418bfd3db88e59429abad9fde6c1e..2a0558ceed0332333908344cd1274d2827716d87:/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx diff --git a/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx b/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx index 74b083a9..0248c826 100644 --- a/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx +++ b/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx @@ -2,58 +2,33 @@ // // SPDX-License-Identifier: AGPL-3.0 -import React, { useEffect } from 'react'; -import { - WithStyles, - withStyles, - ButtonBase, - StyleRulesCallback, - Theme, - Popover, - Button, - Card, - CardActions, - Typography, - CardContent, - Tooltip, - IconButton, -} from '@material-ui/core'; -import classnames from 'classnames'; -import { DefaultTransformOrigin } from 'components/popover/helpers'; -import { createTree } from 'models/tree'; -import { DataTableFilters, DataTableFiltersTree } from './data-table-multiselect-tree'; -import { getNodeDescendants } from 'models/tree'; -import debounce from 'lodash/debounce'; -import { green, grey } from '@material-ui/core/colors'; +import React from "react"; +import { WithStyles, withStyles, ButtonBase, StyleRulesCallback, Theme, Popover, Card, Tooltip, IconButton } from "@material-ui/core"; +import classnames from "classnames"; +import { DefaultTransformOrigin } from "components/popover/helpers"; +import { grey } from "@material-ui/core/colors"; +import { TCheckedList } from "components/data-table/data-table"; -export type CssRules = 'root' | 'icon' | 'iconButton' | 'active' | 'checkbox'; +export type CssRules = "root" | "icon" | "iconButton" | "disabled" | "optionsContainer" | "option"; const styles: StyleRulesCallback = (theme: Theme) => ({ root: { - // border: '1px dashed green', - margin: 0, - borderRadius: '7px', - '&:hover': { + borderRadius: "7px", + "&:hover": { backgroundColor: grey[200], }, - '&:focus': { + "&:focus": { color: theme.palette.text.primary, }, }, - active: { - color: theme.palette.text.primary, - '& $iconButton': { - opacity: 1, - }, - }, icon: { - // border: '1px solid red', - cursor: 'pointer', + cursor: "pointer", fontSize: 20, - userSelect: 'none', - '&:hover': { + userSelect: "none", + "&:hover": { color: theme.palette.text.primary, }, + paddingBottom: "5px", }, iconButton: { color: theme.palette.text.primary, @@ -61,59 +36,73 @@ const styles: StyleRulesCallback = (theme: Theme) => ({ padding: 1, paddingBottom: 5, }, - checkbox: { - width: 24, - height: 24, + disabled: { + color: grey[500], + }, + optionsContainer: { + padding: "1rem 0", + flex: 1, + }, + option: { + cursor: "pointer", + display: "flex", + padding: "3px 2rem", + fontSize: "0.9rem", + alignItems: "center", + "&:hover": { + backgroundColor: "rgba(0, 0, 0, 0.08)", + }, }, }); -enum SelectionMode { - ALL = 'all', - NONE = 'none', -} - -export interface DataTableFilterProps { +export type DataTableMultiselectOption = { name: string; - filters: DataTableFilters; - onChange?: (filters: DataTableFilters) => void; - - /** - * When set to true, only one filter can be selected at a time. - */ - mutuallyExclusive?: boolean; + fn: (checkedList) => void; +}; - /** - * By default `all` filters selection means that label should be grayed out. - * Use `none` when label is supposed to be grayed out when no filter is selected. - */ - defaultSelection?: SelectionMode; +export interface DataTableMultiselectProps { + name: string; + disabled: boolean; + options: DataTableMultiselectOption[]; + checkedList: TCheckedList; } -interface DataTableFilterState { +interface DataTableFMultiselectPopState { anchorEl?: HTMLElement; - filters: DataTableFilters; - prevFilters: DataTableFilters; } export const DataTableMultiselectPopover = withStyles(styles)( - class extends React.Component, DataTableFilterState> { - state: DataTableFilterState = { + class extends React.Component, DataTableFMultiselectPopState> { + state: DataTableFMultiselectPopState = { anchorEl: undefined, - filters: createTree(), - prevFilters: createTree(), }; icon = React.createRef(); render() { - const { name, classes, defaultSelection = SelectionMode.ALL, children } = this.props; - const isActive = getNodeDescendants('')(this.state.filters).some((f) => (defaultSelection === SelectionMode.ALL ? !f.selected : f.selected)); + const { classes, children, options, checkedList, disabled } = this.props; return ( <> - - + + {} : this.open} + disableRipple + > {children} - - + + @@ -125,65 +114,33 @@ export const DataTableMultiselectPopover = withStyles(styles)( onClose={this.close} > - - {'foo'} - - - {this.props.mutuallyExclusive || ( - - - - )} +
+ {options.length && + options.map((option, i) => ( +
{ + option.fn(checkedList); + this.close(); + }} + > + {option.name} +
+ ))} +
- ); } - static getDerivedStateFromProps(props: DataTableFilterProps, state: DataTableFilterState): DataTableFilterState { - return props.filters !== state.prevFilters ? { ...state, filters: props.filters, prevFilters: props.filters } : state; - } - open = () => { this.setState({ anchorEl: this.icon.current || undefined }); }; - onChange = (filters) => { - this.setState({ filters }); - if (this.props.mutuallyExclusive) { - // Mutually exclusive filters apply immediately - const { onChange } = this.props; - if (onChange) { - onChange(filters); - } - this.close(); - } else { - // Non-mutually exclusive filters are debounced - this.submit(); - } - }; - - submit = debounce(() => { - const { onChange } = this.props; - if (onChange) { - onChange(this.state.filters); - } - }, 1000); - - MountHandler = () => { - useEffect(() => { - return () => { - this.submit.cancel(); - }; - }, []); - return null; - }; - close = () => { - this.setState((prev) => ({ + this.setState(prev => ({ ...prev, anchorEl: undefined, }));