1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from "react";
22 } from "@material-ui/core";
23 import * as classnames from "classnames";
24 import { DefaultTransformOrigin } from "../popover/helpers";
26 export interface DataTableFilterItem {
31 export interface DataTableFilterProps {
33 filters: DataTableFilterItem[];
34 onChange?: (filters: DataTableFilterItem[]) => void;
37 interface DataTableFilterState {
38 anchorEl?: HTMLElement;
39 filters: DataTableFilterItem[];
40 prevFilters: DataTableFilterItem[];
43 class DataTableFilter extends React.Component<DataTableFilterProps & WithStyles<CssRules>, DataTableFilterState> {
44 state: DataTableFilterState = {
49 icon = React.createRef<HTMLElement>();
52 const { name, classes, children } = this.props;
53 const isActive = this.state.filters.some(f => f.selected);
56 className={classnames([classes.root, { [classes.active]: isActive }])}
61 <i className={classnames(["fas fa-filter", classes.icon])}
62 data-fa-transform="shrink-3"
66 anchorEl={this.state.anchorEl}
67 open={!!this.state.anchorEl}
68 anchorOrigin={DefaultTransformOrigin}
69 transformOrigin={DefaultTransformOrigin}
70 onClose={this.cancel}>
73 <Typography variant="caption">
78 {this.state.filters.map((filter, index) =>
82 onClick={this.toggleFilter(filter)}>
86 checked={filter.selected}
87 className={classes.checkbox} />
99 onClick={this.submit}>
106 onClick={this.cancel}>
115 static getDerivedStateFromProps(props: DataTableFilterProps, state: DataTableFilterState): DataTableFilterState {
116 return props.filters !== state.prevFilters
117 ? { ...state, filters: props.filters, prevFilters: props.filters }
122 this.setState({ anchorEl: this.icon.current || undefined });
126 const { onChange } = this.props;
128 onChange(this.state.filters);
130 this.setState({ anchorEl: undefined });
134 this.setState(prev => ({
136 filters: prev.prevFilters,
141 toggleFilter = (toggledFilter: DataTableFilterItem) => () => {
142 this.setState(prev => ({
144 filters: prev.filters.map(filter =>
145 filter === toggledFilter
146 ? { ...filter, selected: !filter.selected }
153 export type CssRules = "root" | "icon" | "active" | "checkbox";
155 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
158 display: "inline-flex",
159 justifyContent: "flex-start",
160 flexDirection: "inherit",
161 alignItems: "center",
163 color: theme.palette.text.primary,
166 color: theme.palette.text.primary,
170 color: theme.palette.text.primary,
188 export default withStyles(styles)(DataTableFilter);