From: Michal Klobukowski Date: Tue, 20 Nov 2018 13:32:55 +0000 (+0100) Subject: CopyDataTableFilters to DataTableFiltersPopover X-Git-Tag: 1.3.0~12^2^2~1^2~5^2~3 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/4ff3ff000c1a0132d29ea4829907f484467b6275 CopyDataTableFilters to DataTableFiltersPopover Feature #14258 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- diff --git a/src/components/data-table-filters/data-table-filters-popover.tsx b/src/components/data-table-filters/data-table-filters-popover.tsx new file mode 100644 index 00000000..7033d369 --- /dev/null +++ b/src/components/data-table-filters/data-table-filters-popover.tsx @@ -0,0 +1,208 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from "react"; +import { + WithStyles, + withStyles, + ButtonBase, + StyleRulesCallback, + Theme, + Popover, + List, + ListItem, + Checkbox, + ListItemText, + Button, + Card, + CardActions, + Typography, + CardContent, + Tooltip +} from "@material-ui/core"; +import * as classnames from "classnames"; +import { DefaultTransformOrigin } from "../popover/helpers"; +import { createTree, initTreeNode, mapTree } from '~/models/tree'; +import { DataTableFilters as DataTableFiltersModel, DataTableFiltersTree } from "./data-table-filters-tree"; +import { pipe } from 'lodash/fp'; +import { setNode } from '~/models/tree'; + +export type CssRules = "root" | "icon" | "active" | "checkbox"; + +const styles: StyleRulesCallback = (theme: Theme) => ({ + root: { + cursor: "pointer", + display: "inline-flex", + justifyContent: "flex-start", + flexDirection: "inherit", + alignItems: "center", + "&:hover": { + color: theme.palette.text.primary, + }, + "&:focus": { + color: theme.palette.text.primary, + }, + }, + active: { + color: theme.palette.text.primary, + '& $icon': { + opacity: 1, + }, + }, + icon: { + marginRight: 4, + marginLeft: 4, + opacity: 0.7, + userSelect: "none", + width: 16 + }, + checkbox: { + width: 24, + height: 24 + } +}); + +export interface DataTableFilterItem { + name: string; + selected: boolean; +} + +export interface DataTableFilterProps { + name: string; + filters: DataTableFilterItem[]; + onChange?: (filters: DataTableFilterItem[]) => void; +} + +interface DataTableFilterState { + anchorEl?: HTMLElement; + filters: DataTableFilterItem[]; + prevFilters: DataTableFilterItem[]; + filtersTree: DataTableFiltersModel; +} + +const filters: DataTableFiltersModel = pipe( + createTree, + setNode(initTreeNode({ id: 'Project', value: { name: 'Project' } })), + setNode(initTreeNode({ id: 'Process', value: { name: 'Process' } })), + setNode(initTreeNode({ id: 'Data collection', value: { name: 'Data collection' } })), + setNode(initTreeNode({ id: 'General', parent: 'Data collection', value: { name: 'General' } })), + setNode(initTreeNode({ id: 'Output', parent: 'Data collection', value: { name: 'Output' } })), + setNode(initTreeNode({ id: 'Log', parent: 'Data collection', value: { name: 'Log' } })), + mapTree(node => ({...node, selected: true})), +)(); + +export const DataTableFilters = withStyles(styles)( + class extends React.Component, DataTableFilterState> { + state: DataTableFilterState = { + anchorEl: undefined, + filters: [], + prevFilters: [], + filtersTree: filters, + }; + icon = React.createRef(); + + render() { + const { name, classes, children } = this.props; + const isActive = this.state.filters.some(f => f.selected); + return <> + + + {children} + + + + + + + + {name} + + + + {this.state.filters.map((filter, index) => + + + + {filter.name} + + + )} + + this.setState({ filtersTree })} /> + + + + + + + ; + } + + 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 }); + } + + submit = () => { + const { onChange } = this.props; + if (onChange) { + onChange(this.state.filters); + } + this.setState({ anchorEl: undefined }); + } + + cancel = () => { + this.setState(prev => ({ + ...prev, + filters: prev.prevFilters, + anchorEl: undefined + })); + } + + toggleFilter = (toggledFilter: DataTableFilterItem) => () => { + this.setState(prev => ({ + ...prev, + filters: prev.filters.map(filter => + filter === toggledFilter + ? { ...filter, selected: !filter.selected } + : filter) + })); + } + } +);