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;
55 className={classnames([
57 { [classes.active]: this.state.filters.filter(({ selected }) => !selected).length > 0 }])}
62 <i className={classnames(["fas fa-filter", classes.icon])}
63 data-fa-transform="shrink-3"
67 anchorEl={this.state.anchorEl}
68 open={!!this.state.anchorEl}
69 anchorOrigin={DefaultTransformOrigin}
70 transformOrigin={DefaultTransformOrigin}
71 onClose={this.cancel}>
74 <Typography variant="caption">
79 {this.state.filters.map((filter, index) =>
83 onClick={this.toggleFilter(filter)}>
87 checked={filter.selected}
88 className={classes.checkbox} />
100 onClick={this.submit}>
107 onClick={this.cancel}>
116 static getDerivedStateFromProps(props: DataTableFilterProps, state: DataTableFilterState): DataTableFilterState {
117 return props.filters !== state.prevFilters
118 ? { ...state, filters: props.filters, prevFilters: props.filters }
123 this.setState({ anchorEl: this.icon.current || undefined });
127 const { onChange } = this.props;
129 onChange(this.state.filters);
131 this.setState({ anchorEl: undefined });
135 this.setState(prev => ({
137 filters: prev.prevFilters,
142 toggleFilter = (toggledFilter: DataTableFilterItem) => () => {
143 this.setState(prev => ({
145 filters: prev.filters.map(filter =>
146 filter === toggledFilter
147 ? { ...filter, selected: !filter.selected }
154 export type CssRules = "root" | "icon" | "active" | "checkbox";
156 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
159 display: "inline-flex",
160 justifyContent: "flex-start",
161 flexDirection: "inherit",
162 alignItems: "center",
164 color: theme.palette.text.primary,
167 color: theme.palette.text.primary,
171 color: theme.palette.text.primary,
189 export default withStyles(styles)(DataTableFilter);