1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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 { ResourceKind, extractUuidKind } from 'models/resource';
17 import { openMoveProcessDialog } from 'store/processes/process-move-actions';
18 import { openCopyProcessDialog } from 'store/processes/process-copy-actions';
19 import { getResource } from 'store/resources/resources';
20 import { ResourceName } from 'views-components/data-explorer/renderers';
21 import { ProcessResource } from 'models/process';
22 import { ResourcesState } from 'store/resources/resources';
23 import { Resource } from 'models/resource';
24 import { getProcess } from 'store/processes/process';
26 type CssRules = 'root' | 'button';
28 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
34 margin: '1rem auto auto 0.5rem',
36 transition: 'width 150ms',
39 backgroundColor: '#017ead',
48 type MultiselectToolbarAction = {
51 relevantKinds: Set<ResourceKind>;
54 //gleaned from src/views-components/context-menu/action-sets
55 export const defaultActions: Array<MultiselectToolbarAction> = [
57 name: 'copy and re-run',
58 funcName: 'copySelected',
59 relevantKinds: new Set([ResourceKind.PROCESS]),
63 funcName: 'moveSelected',
64 relevantKinds: new Set([ResourceKind.PROCESS, ResourceKind.PROJECT]),
68 funcName: 'removeSelected',
69 relevantKinds: new Set([ResourceKind.PROCESS, ResourceKind.COLLECTION]),
73 funcName: 'favoriteSelected',
74 relevantKinds: new Set([ResourceKind.PROCESS, ResourceKind.PROJECT, ResourceKind.COLLECTION]),
78 export type MultiselectToolbarProps = {
79 actions: Array<MultiselectToolbarAction>;
81 checkedList: TCheckedList;
82 resources: ResourcesState;
83 copySelected: (checkedList: TCheckedList, resources: ResourcesState) => void;
84 moveSelected: (resource) => void;
85 barSelected: () => void;
86 removeSelected: (checkedList: TCheckedList) => void;
89 export const MultiselectToolbar = connect(
93 withStyles(styles)((props: MultiselectToolbarProps & WithStyles<CssRules>) => {
94 // console.log(props);
95 const { classes, actions, isVisible, checkedList, resources } = props;
97 const currentResourceKinds = Array.from(selectedToKindSet(checkedList));
98 const buttons = actions.filter((action) => currentResourceKinds.length && currentResourceKinds.every((kind) => action.relevantKinds.has(kind as ResourceKind)));
101 <Toolbar className={classes.root} style={{ width: `${buttons.length * 5.5}rem` }}>
103 buttons.map((btn) => (
104 <Button key={btn.name} className={classes.button} onClick={() => props[btn.funcName](checkedList, resources)}>
116 function selectedToArray(checkedList: TCheckedList): Array<string> {
117 const arrayifiedSelectedList: Array<string> = [];
118 for (const [key, value] of Object.entries(checkedList)) {
119 if (value === true) {
120 arrayifiedSelectedList.push(key);
123 return arrayifiedSelectedList;
126 function selectedToKindSet(checkedList: TCheckedList): Set<string> {
127 const setifiedList = new Set<string>();
128 for (const [key, value] of Object.entries(checkedList)) {
129 if (value === true) {
130 setifiedList.add(extractUuidKind(key) as string);
136 function mapStateToProps(state: RootState) {
137 // console.log(state);
138 // console.log(getResource<ProcessResource>('tordo-dz642-0p7xefqdr4nw4pw')(state.resources));
139 const { isVisible, checkedList } = state.multiselect;
141 isVisible: isVisible,
142 checkedList: checkedList as TCheckedList,
143 resources: state.resources,
147 function mapDispatchToProps(dispatch: Dispatch) {
149 copySelected: (checkedList: TCheckedList, resources: ResourcesState) => copyMoveMulti(dispatch, checkedList, resources),
150 moveSelected: (checkedList: TCheckedList) => {},
151 barSelected: () => {},
152 removeSelected: (checkedList: TCheckedList) => removeMultiProcesses(dispatch, checkedList),
156 function copyMoveMulti(dispatch: Dispatch, checkedList: TCheckedList, resources: ResourcesState) {
157 const selectedList: Array<string> = selectedToArray(checkedList);
158 const single = getProcess(selectedList[0])(resources)?.containerRequest;
160 const { name, uuid } = single as any;
161 console.log(name, uuid);
162 dispatch<any>(openCopyProcessDialog({ name, uuid }));
165 function moveMultiProcesses(dispatch: Dispatch, checkedList: TCheckedList): void {
166 const selectedList: Array<string> = selectedToArray(checkedList);
167 // if (selectedList.length === 1) dispatch<any>(openMoveProcessDialog(selectedList[0]));
170 const RemoveFunctions = {
171 ONE_PROCESS: (uuid: string) => openRemoveProcessDialog(uuid),
172 MANY_PROCESSES: (list: Array<string>) => openRemoveManyProcessesDialog(list),
175 function removeMultiProcesses(dispatch: Dispatch, checkedList: TCheckedList): void {
176 const selectedList: Array<string> = selectedToArray(checkedList);
177 dispatch<any>(selectedList.length === 1 ? RemoveFunctions.ONE_PROCESS(selectedList[0]) : RemoveFunctions.MANY_PROCESSES(selectedList));
181 //go through the array of selected and choose the appropriate removal function
182 //have a constant with [ResourceKind]: different removal methods