18559: Add adminOnly context menu item flag
[arvados-workbench2.git] / src / components / context-menu / context-menu.tsx
index c86c5177a319945cd45635a28bb650d1041cd249..cb53edbc4eead8a244cd9f0fef843d290b4c9853 100644 (file)
@@ -1,52 +1,71 @@
 // Copyright (C) The Arvados Authors. All rights reserved.
 //
 // SPDX-License-Identifier: AGPL-3.0
-import * as React from "react";
+import React from "react";
 import { Popover, List, ListItem, ListItemIcon, ListItemText, Divider } from "@material-ui/core";
 import { DefaultTransformOrigin } from "../popover/helpers";
+import { IconType } from "../icon/icon";
 
-export interface ContextMenuAction<T> {
-    name: string;
-    icon: string;
-    onClick: (item: T) => void;
+export interface ContextMenuItem {
+    name?: string | React.ComponentType;
+    icon?: IconType;
+    component?: React.ComponentType<any>;
+    adminOnly?: boolean;
 }
 
-export type ContextMenuActionGroup<T> = Array<ContextMenuAction<T>>;
+export type ContextMenuItemGroup = ContextMenuItem[];
 
-export interface ContextMenuProps<T> {
+export interface ContextMenuProps {
     anchorEl?: HTMLElement;
-    item?: T;
+    items: ContextMenuItemGroup[];
+    open: boolean;
+    onItemClick: (action: ContextMenuItem) => void;
     onClose: () => void;
-    actions: Array<ContextMenuActionGroup<T>>;
 }
 
-export default class ContextMenu<T> extends React.PureComponent<ContextMenuProps<T>> {
+export class ContextMenu extends React.PureComponent<ContextMenuProps> {
     render() {
-        const { anchorEl, onClose, actions, item } = this.props;
+        const { anchorEl, items, open, onClose, onItemClick } = this.props;
         return <Popover
             anchorEl={anchorEl}
-            open={Boolean(anchorEl)}
+            open={open}
             onClose={onClose}
             transformOrigin={DefaultTransformOrigin}
-            anchorOrigin={DefaultTransformOrigin}>
-            <List dense>
-                {actions.map((group, groupIndex) =>
+            anchorOrigin={DefaultTransformOrigin}
+            onContextMenu={this.handleContextMenu}>
+            <List data-cy='context-menu' dense>
+                {items.map((group, groupIndex) =>
                     <React.Fragment key={groupIndex}>
-                        {group.map((action, actionIndex) =>
-                            <ListItem
-                                button
-                                key={actionIndex}
-                                onClick={() => item && action.onClick(item)}>
-                                <ListItemIcon>
-                                    <i className={action.icon} />
-                                </ListItemIcon>
-                                <ListItemText>
-                                    {action.name}
-                                </ListItemText>
-                            </ListItem>)}
-                        {groupIndex < actions.length - 1 && <Divider />}
+                        {group.map((item, actionIndex) =>
+                            item.component
+                                ? <item.component
+                                    key={actionIndex}
+                                    onClick={() => onItemClick(item)} />
+                                : <ListItem
+                                    button
+                                    key={actionIndex}
+                                    onClick={() => onItemClick(item)}>
+                                    {item.icon &&
+                                        <ListItemIcon>
+                                            <item.icon />
+                                        </ListItemIcon>}
+                                    {item.name &&
+                                        <ListItemText>
+                                            {item.name}
+                                        </ListItemText>}
+                                </ListItem>)}
+                        {
+                            items[groupIndex + 1] &&
+                            items[groupIndex + 1].length > 0 &&
+                            <Divider />
+                        }
                     </React.Fragment>)}
             </List>
         </Popover>;
     }
+
+    handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
+        event.preventDefault();
+        this.props.onClose();
+    }
 }