1b58f9e8b9f8d1aa24aa44ff998fe98f51faeb2e
[arvados-workbench2.git] / src / components / data-table-multiselect-popover / data-table-multiselect-popover.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React, { useEffect } from 'react';
6 import { WithStyles, withStyles, ButtonBase, StyleRulesCallback, Theme, Popover, Button, Card, CardActions, Tooltip, IconButton } from '@material-ui/core';
7 import classnames from 'classnames';
8 import { DefaultTransformOrigin } from 'components/popover/helpers';
9 import debounce from 'lodash/debounce';
10 import { grey } from '@material-ui/core/colors';
11 import { TCheckedList } from 'components/data-table/data-table';
12
13 export type CssRules = 'root' | 'icon' | 'iconButton' | 'optionsContainer' | 'option';
14
15 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
16     root: {
17         borderRadius: '7px',
18         '&:hover': {
19             backgroundColor: grey[200],
20         },
21         '&:focus': {
22             color: theme.palette.text.primary,
23         },
24     },
25     icon: {
26         cursor: 'pointer',
27         fontSize: 20,
28         userSelect: 'none',
29         '&:hover': {
30             color: theme.palette.text.primary,
31         },
32         paddingBottom: '5px',
33     },
34     iconButton: {
35         color: theme.palette.text.primary,
36         opacity: 0.6,
37         padding: 1,
38         paddingBottom: 5,
39     },
40     optionsContainer: {
41         padding: '1rem 0',
42         flex: 1,
43     },
44     option: {
45         cursor: 'pointer',
46         display: 'flex',
47         padding: '3px 2rem',
48         fontSize: '0.9rem',
49         alignItems: 'center',
50         '&:hover': {
51             backgroundColor: 'rgba(0, 0, 0, 0.08)',
52         },
53     },
54 });
55
56 export type DataTableMultiselectOption = {
57     name: string;
58     fn: (checkedList) => void;
59 };
60
61 export interface DataTableMultiselectProps {
62     name: string;
63     options: DataTableMultiselectOption[];
64     checkedList: TCheckedList;
65 }
66
67 interface DataTableFMultiselectPopState {
68     anchorEl?: HTMLElement;
69 }
70
71 export const DataTableMultiselectPopover = withStyles(styles)(
72     class extends React.Component<DataTableMultiselectProps & WithStyles<CssRules>, DataTableFMultiselectPopState> {
73         state: DataTableFMultiselectPopState = {
74             anchorEl: undefined,
75         };
76         icon = React.createRef<HTMLElement>();
77
78         render() {
79             const { classes, children, options, checkedList } = this.props;
80             return (
81                 <>
82                     <Tooltip disableFocusListener title='Select Options'>
83                         <ButtonBase className={classnames(classes.root)} component='span' onClick={this.open} disableRipple>
84                             {children}
85                             <IconButton component='span' classes={{ root: classes.iconButton }} tabIndex={-1}>
86                                 <i className={classnames(['fas fa-sort-down', classes.icon])} data-fa-transform='shrink-3' ref={this.icon} />
87                             </IconButton>
88                         </ButtonBase>
89                     </Tooltip>
90                     <Popover
91                         anchorEl={this.state.anchorEl}
92                         open={!!this.state.anchorEl}
93                         anchorOrigin={DefaultTransformOrigin}
94                         transformOrigin={DefaultTransformOrigin}
95                         onClose={this.close}
96                     >
97                         <Card>
98                             <div className={classes.optionsContainer}>
99                                 {options.length &&
100                                     options.map((option, i) => (
101                                         <div
102                                             key={i}
103                                             className={classes.option}
104                                             onClick={() => {
105                                                 option.fn(checkedList);
106                                                 this.close();
107                                             }}
108                                         >
109                                             {option.name}
110                                         </div>
111                                     ))}
112                             </div>
113                         </Card>
114                     </Popover>
115                     <this.MountHandler />
116                 </>
117             );
118         }
119
120         open = () => {
121             this.setState({ anchorEl: this.icon.current || undefined });
122         };
123
124         submit = debounce(() => {
125             // const { onChange } = this.props;
126             // if (onChange) {
127             //     onChange(this.state.filters);
128             // }
129         }, 1000);
130
131         MountHandler = () => {
132             useEffect(() => {
133                 return () => {
134                     this.submit.cancel();
135                 };
136             }, []);
137             return null;
138         };
139
140         close = () => {
141             this.setState((prev) => ({
142                 ...prev,
143                 anchorEl: undefined,
144             }));
145         };
146     }
147 );