toolbar accurately selects for appropriate buttons Arvados-DCO-1.1-Signed-off-by...
[arvados-workbench2.git] / src / components / multiselectToolbar / MultiselectToolbar.tsx
index 0338d6102c26d5d6c0a0073352ea0bfdea091ef9..bd01b36161479c2b54ee814564d87920338dce2f 100644 (file)
@@ -14,6 +14,7 @@ import { openRemoveProcessDialog, openRemoveManyProcessesDialog } from 'store/pr
 import { processResourceActionSet } from '../../views-components/context-menu/action-sets/process-resource-action-set';
 import { ContextMenuResource } from 'store/context-menu/context-menu-actions';
 import { toggleTrashed } from 'store/trash/trash-actions';
+import { ResourceKind, extractUuidKind } from 'models/resource';
 
 type CssRules = 'root' | 'expanded' | 'button';
 
@@ -21,26 +22,20 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
     root: {
         display: 'flex',
         flexDirection: 'row',
-        justifyContent: 'start',
-        width: '0px',
+        width: 0,
         padding: 0,
-        marginTop: '0.5rem',
-        marginLeft: '0.5rem',
+        margin: '1rem auto auto 0.5rem',
         overflow: 'hidden',
-        transition: 'width 150ms',
-        transitionTimingFunction: 'ease',
     },
     expanded: {
         transition: 'width 150ms',
-        transitionTimingFunction: 'ease-in',
-        width: '40%',
     },
     button: {
         backgroundColor: '#017ead',
         color: 'white',
         fontSize: '0.75rem',
-        width: 'fit-content',
-        margin: '2px',
+        width: 'auto',
+        margin: 'auto',
         padding: '1px',
     },
 });
@@ -48,29 +43,39 @@ const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
 type MultiselectToolbarAction = {
     name: string;
     action: string;
+    relevantKinds: Array<ResourceKind>;
 };
 
 export const defaultActions: Array<MultiselectToolbarAction> = [
     {
         name: 'copy',
         action: 'copySelected',
+        relevantKinds: [ResourceKind.COLLECTION],
     },
     {
         name: 'move',
         action: 'moveSelected',
+        relevantKinds: [ResourceKind.COLLECTION, ResourceKind.PROCESS],
     },
     {
         name: 'remove',
         action: 'removeSelected',
+        relevantKinds: [ResourceKind.COLLECTION, ResourceKind.PROCESS, ResourceKind.PROJECT],
+    },
+    {
+        name: 'foo',
+        action: 'barSelected',
+        relevantKinds: [ResourceKind.COLLECTION, ResourceKind.PROJECT],
     },
 ];
 
 export type MultiselectToolbarProps = {
-    buttons: Array<MultiselectToolbarAction>;
+    actions: Array<MultiselectToolbarAction>;
     isVisible: boolean;
     checkedList: TCheckedList;
     copySelected: () => void;
     moveSelected: () => void;
+    barSelected: () => void;
     removeSelected: (selectedList: TCheckedList) => void;
 };
 
@@ -80,14 +85,25 @@ export const MultiselectToolbar = connect(
 )(
     withStyles(styles)((props: MultiselectToolbarProps & WithStyles<CssRules>) => {
         // console.log(props);
-        const { classes, buttons, isVisible, checkedList } = props;
+        const { classes, actions, isVisible, checkedList } = props;
+
+        const currentResourceKinds = selectedToArray(checkedList).map((element) => extractUuidKind(element));
+
+        const buttons = actions.filter(
+            (action) => currentResourceKinds.length && currentResourceKinds.every((kind) => action.relevantKinds.includes(kind as ResourceKind))
+        );
+
         return (
-            <Toolbar className={isVisible ? `${classes.root} ${classes.expanded}` : classes.root}>
-                {buttons.map((btn) => (
-                    <Button key={btn.name} className={`${classes.button} ${classes.expanded}`} onClick={() => props[btn.action](checkedList)}>
-                        {btn.name}
-                    </Button>
-                ))}
+            <Toolbar className={isVisible && buttons.length ? `${classes.root} ${classes.expanded}` : classes.root} style={{ width: `${buttons.length * 5.5}rem` }}>
+                {buttons.length ? (
+                    buttons.map((btn) => (
+                        <Button key={btn.name} className={`${classes.button} ${classes.expanded}`} onClick={() => props[btn.action](checkedList)}>
+                            {btn.name}
+                        </Button>
+                    ))
+                ) : (
+                    <></>
+                )}
             </Toolbar>
         );
     })
@@ -103,8 +119,8 @@ function selectedToString(checkedList: TCheckedList) {
     return stringifiedSelectedList.slice(0, -1);
 }
 
-function selectedToArray<T>(checkedList: TCheckedList): Array<T | string> {
-    const arrayifiedSelectedList: Array<T | string> = [];
+function selectedToArray<T>(checkedList: TCheckedList): Array<string> {
+    const arrayifiedSelectedList: Array<string> = [];
     for (const [key, value] of Object.entries(checkedList)) {
         if (value === true) {
             arrayifiedSelectedList.push(key);
@@ -114,12 +130,10 @@ function selectedToArray<T>(checkedList: TCheckedList): Array<T | string> {
 }
 
 function mapStateToProps(state: RootState) {
-    // console.log(state.resources, state.multiselect.checkedList);
     const { isVisible, checkedList } = state.multiselect;
     return {
         isVisible: isVisible,
         checkedList: checkedList as TCheckedList,
-        // selectedList: state.multiselect.checkedList.forEach(processUUID=>containerRequestUUID)
     };
 }
 
@@ -127,10 +141,12 @@ function mapDispatchToProps(dispatch: Dispatch) {
     return {
         copySelected: () => {},
         moveSelected: () => {},
-        removeSelected: (checkedList: TCheckedList) => removeMany(dispatch, checkedList),
+        barSelected: () => {},
+        removeSelected: (checkedList: TCheckedList) => removeMulti(dispatch, checkedList),
     };
 }
 
-function removeMany(dispatch: Dispatch, checkedList: TCheckedList): void {
-    dispatch<any>(openRemoveManyProcessesDialog(selectedToArray(checkedList)));
+function removeMulti(dispatch: Dispatch, checkedList: TCheckedList): void {
+    const list: Array<string> = selectedToArray(checkedList);
+    dispatch<any>(list.length === 1 ? openRemoveProcessDialog(list[0]) : openRemoveManyProcessesDialog(list));
 }