Implement base distinction between context menu kind
[arvados.git] / src / views-components / context-menu / context-menu.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { connect, Dispatch, DispatchProp } from "react-redux";
6 import { RootState } from "../../store/store";
7 import actions from "../../store/context-menu/context-menu-actions";
8 import ContextMenu, { ContextMenuAction, ContextMenuProps } from "../../components/context-menu/context-menu";
9 import { createAnchorAt } from "../../components/popover/helpers";
10 import projectActions from "../../store/project/project-action";
11 import { ContextMenuResource, ContextMenuKind } from "../../store/context-menu/context-menu-reducer";
12
13
14 type DataProps = Pick<ContextMenuProps, "anchorEl" | "actions"> & { resource?: ContextMenuResource };
15 const mapStateToProps = (state: RootState): DataProps => {
16     const { position, resource } = state.contextMenu;
17     return {
18         anchorEl: resource ? createAnchorAt(position) : undefined,
19         actions: resource ? menuActions[resource.kind] : [],
20         resource
21     };
22 };
23
24 type ActionProps = Pick<ContextMenuProps, "onClose"> & { onActionClick: (action: ContextMenuAction, resource?: ContextMenuResource) => void };
25 const mapDispatchToProps = (dispatch: Dispatch): ActionProps => ({
26     onClose: () => {
27         dispatch(actions.CLOSE_CONTEXT_MENU());
28     },
29     onActionClick: (action: ContextMenuAction, resource?: ContextMenuResource) => {
30         dispatch(actions.CLOSE_CONTEXT_MENU());
31         if (resource) {
32             if (action.name === "New project") {
33                 dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid }));
34             }
35         }
36     }
37 });
38
39 const mergeProps = ({ resource, ...dataProps }: DataProps, actionProps: ActionProps): ContextMenuProps => ({
40     ...dataProps,
41     ...actionProps,
42     onActionClick: (action: ContextMenuAction) => {
43         actionProps.onActionClick(action, resource);
44     }
45 });
46
47 export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(ContextMenu);
48
49 const menuActions = {
50     [ContextMenuKind.RootProject]: [[{
51         icon: "fas fa-plus fa-fw",
52         name: "New project"
53     }]],
54     [ContextMenuKind.Project]: [[{
55         icon: "fas fa-plus fa-fw",
56         name: "New project"
57     }, {
58         icon: "fas fa-users fa-fw",
59         name: "Share"
60     }, {
61         icon: "fas fa-sign-out-alt fa-fw",
62         name: "Move to"
63     }, {
64         icon: "fas fa-star fa-fw",
65         name: "Add to favourite"
66     }, {
67         icon: "fas fa-edit fa-fw",
68         name: "Rename"
69     }, {
70         icon: "fas fa-copy fa-fw",
71         name: "Make a copy"
72     }, {
73         icon: "fas fa-download fa-fw",
74         name: "Download"
75     }], [{
76         icon: "fas fa-trash-alt fa-fw",
77         name: "Remove"
78     }
79     ]],
80     [ContextMenuKind.Collection]: [[{
81         icon: "fas fa-users fa-fw",
82         name: "Share"
83     }, {
84         icon: "fas fa-sign-out-alt fa-fw",
85         name: "Move to"
86     }, {
87         icon: "fas fa-star fa-fw",
88         name: "Add to favourite"
89     }, {
90         icon: "fas fa-edit fa-fw",
91         name: "Rename"
92     }, {
93         icon: "fas fa-copy fa-fw",
94         name: "Make a copy"
95     }, {
96         icon: "fas fa-download fa-fw",
97         name: "Download"
98     }], [{
99         icon: "fas fa-trash-alt fa-fw",
100         name: "Remove"
101     }
102     ]]
103 };