cb53edbc4eead8a244cd9f0fef843d290b4c9853
[arvados-workbench2.git] / src / components / context-menu / context-menu.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4 import React from "react";
5 import { Popover, List, ListItem, ListItemIcon, ListItemText, Divider } from "@material-ui/core";
6 import { DefaultTransformOrigin } from "../popover/helpers";
7 import { IconType } from "../icon/icon";
8
9 export interface ContextMenuItem {
10     name?: string | React.ComponentType;
11     icon?: IconType;
12     component?: React.ComponentType<any>;
13     adminOnly?: boolean;
14 }
15
16 export type ContextMenuItemGroup = ContextMenuItem[];
17
18 export interface ContextMenuProps {
19     anchorEl?: HTMLElement;
20     items: ContextMenuItemGroup[];
21     open: boolean;
22     onItemClick: (action: ContextMenuItem) => void;
23     onClose: () => void;
24 }
25
26 export class ContextMenu extends React.PureComponent<ContextMenuProps> {
27     render() {
28         const { anchorEl, items, open, onClose, onItemClick } = this.props;
29         return <Popover
30             anchorEl={anchorEl}
31             open={open}
32             onClose={onClose}
33             transformOrigin={DefaultTransformOrigin}
34             anchorOrigin={DefaultTransformOrigin}
35             onContextMenu={this.handleContextMenu}>
36             <List data-cy='context-menu' dense>
37                 {items.map((group, groupIndex) =>
38                     <React.Fragment key={groupIndex}>
39                         {group.map((item, actionIndex) =>
40                             item.component
41                                 ? <item.component
42                                     key={actionIndex}
43                                     onClick={() => onItemClick(item)} />
44                                 : <ListItem
45                                     button
46                                     key={actionIndex}
47                                     onClick={() => onItemClick(item)}>
48                                     {item.icon &&
49                                         <ListItemIcon>
50                                             <item.icon />
51                                         </ListItemIcon>}
52                                     {item.name &&
53                                         <ListItemText>
54                                             {item.name}
55                                         </ListItemText>}
56                                 </ListItem>)}
57                         {
58                             items[groupIndex + 1] &&
59                             items[groupIndex + 1].length > 0 &&
60                             <Divider />
61                         }
62                     </React.Fragment>)}
63             </List>
64         </Popover>;
65     }
66
67     handleContextMenu = (event: React.MouseEvent<HTMLElement>) => {
68         event.preventDefault();
69         this.props.onClose();
70     }
71 }