15768: differentiate between remove one ane remove many dialog Arvados-DCO-1.1-Signed...
[arvados.git] / src / components / multiselectToolbar / MultiselectToolbar.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React, { ReactElement } from 'react';
6 import { connect } from 'react-redux';
7 import { StyleRulesCallback, withStyles, WithStyles, Toolbar, Button } from '@material-ui/core';
8 import { ArvadosTheme } from 'common/custom-theme';
9 import { RootState } from 'store/store';
10 import { Dispatch } from 'redux';
11 import { CopyToClipboardSnackbar } from 'components/copy-to-clipboard-snackbar/copy-to-clipboard-snackbar';
12 import { TCheckedList } from 'components/data-table/data-table';
13 import { openRemoveProcessDialog, openRemoveManyProcessesDialog } from 'store/processes/processes-actions';
14 import { processResourceActionSet } from '../../views-components/context-menu/action-sets/process-resource-action-set';
15 import { ContextMenuResource } from 'store/context-menu/context-menu-actions';
16 import { toggleTrashed } from 'store/trash/trash-actions';
17
18 type CssRules = 'root' | 'expanded' | 'button';
19
20 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
21     root: {
22         display: 'flex',
23         flexDirection: 'row',
24         justifyContent: 'start',
25         width: '0px',
26         padding: 0,
27         margin: '1rem auto auto 0.5rem',
28         overflow: 'hidden',
29         transition: 'width 150ms',
30         transitionTimingFunction: 'ease',
31     },
32     expanded: {
33         transition: 'width 150ms',
34         transitionTimingFunction: 'ease-in',
35         width: '40%',
36     },
37     button: {
38         backgroundColor: '#017ead',
39         color: 'white',
40         fontSize: '0.75rem',
41         width: 'fit-content',
42         margin: '2px',
43         padding: '1px',
44     },
45 });
46
47 type MultiselectToolbarAction = {
48     name: string;
49     action: string;
50 };
51
52 export const defaultActions: Array<MultiselectToolbarAction> = [
53     {
54         name: 'copy',
55         action: 'copySelected',
56     },
57     {
58         name: 'move',
59         action: 'moveSelected',
60     },
61     {
62         name: 'remove',
63         action: 'removeSelected',
64     },
65 ];
66
67 export type MultiselectToolbarProps = {
68     buttons: Array<MultiselectToolbarAction>;
69     isVisible: boolean;
70     checkedList: TCheckedList;
71     copySelected: () => void;
72     moveSelected: () => void;
73     removeSelected: (selectedList: TCheckedList) => void;
74 };
75
76 export const MultiselectToolbar = connect(
77     mapStateToProps,
78     mapDispatchToProps
79 )(
80     withStyles(styles)((props: MultiselectToolbarProps & WithStyles<CssRules>) => {
81         // console.log(props);
82         const { classes, buttons, isVisible, checkedList } = props;
83         return (
84             <Toolbar className={isVisible ? `${classes.root} ${classes.expanded}` : classes.root}>
85                 {buttons.map((btn) => (
86                     <Button key={btn.name} className={`${classes.button} ${classes.expanded}`} onClick={() => props[btn.action](checkedList)}>
87                         {btn.name}
88                     </Button>
89                 ))}
90             </Toolbar>
91         );
92     })
93 );
94
95 function selectedToString(checkedList: TCheckedList) {
96     let stringifiedSelectedList: string = '';
97     for (const [key, value] of Object.entries(checkedList)) {
98         if (value === true) {
99             stringifiedSelectedList += key + ',';
100         }
101     }
102     return stringifiedSelectedList.slice(0, -1);
103 }
104
105 function selectedToArray<T>(checkedList: TCheckedList): Array<T | string> {
106     const arrayifiedSelectedList: Array<T | string> = [];
107     for (const [key, value] of Object.entries(checkedList)) {
108         if (value === true) {
109             arrayifiedSelectedList.push(key);
110         }
111     }
112     return arrayifiedSelectedList;
113 }
114
115 function mapStateToProps(state: RootState) {
116     // console.log(state.resources, state.multiselect.checkedList);
117     const { isVisible, checkedList } = state.multiselect;
118     return {
119         isVisible: isVisible,
120         checkedList: checkedList as TCheckedList,
121         // selectedList: state.multiselect.checkedList.forEach(processUUID=>containerRequestUUID)
122     };
123 }
124
125 function mapDispatchToProps(dispatch: Dispatch) {
126     return {
127         copySelected: () => {},
128         moveSelected: () => {},
129         removeSelected: (checkedList: TCheckedList) => removeMulti(dispatch, checkedList),
130     };
131 }
132
133 function removeMulti(dispatch: Dispatch, checkedList: TCheckedList): void {
134     const list: Array<string> = selectedToArray(checkedList);
135     dispatch<any>(list.length === 1 ? openRemoveProcessDialog(list[0]) : openRemoveManyProcessesDialog(list));
136 }