17426: Pass through menu styling. Make example a card.
[arvados-workbench2.git] / src / plugins / example / index.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 // Example plugin.
6
7 import { PluginConfig } from '~/common/plugintypes';
8 import * as React from 'react';
9 import { Dispatch } from 'redux';
10 import { RootState } from '~/store/store';
11 import { push } from "react-router-redux";
12 import { Card, CardContent, Typography } from "@material-ui/core";
13 import { Route, matchPath } from "react-router";
14 import { RootStore } from '~/store/store';
15 import { activateSidePanelTreeItem } from '~/store/side-panel-tree/side-panel-tree-actions';
16 import { setSidePanelBreadcrumbs } from '~/store/breadcrumbs/breadcrumbs-actions';
17 import { DispatchProp, connect } from 'react-redux';
18 import { MenuItem } from "@material-ui/core";
19 import { propertiesActions } from '~/store/properties/properties-actions';
20 import { Location } from 'history';
21 import { handleFirstTimeLoad } from '~/store/workbench/workbench-actions';
22
23 const categoryName = "Plugin Example";
24 export const routePath = "/examplePlugin";
25 const propertyKey = "Example_menu_item_pressed_count";
26
27 interface ExampleProps {
28     pressedCount: number;
29     className?: string;
30 }
31
32 const exampleMapStateToProps = (state: RootState) => ({ pressedCount: state.properties[propertyKey] || 0 });
33
34 const incrementPressedCount = (dispatch: Dispatch, pressedCount: number) => {
35     dispatch(propertiesActions.SET_PROPERTY({ key: propertyKey, value: pressedCount + 1 }));
36 };
37
38 const ExampleMenuComponent = connect(exampleMapStateToProps)(
39     ({ pressedCount, dispatch, className }: ExampleProps & DispatchProp<any>) =>
40         <MenuItem className={className} onClick={() => incrementPressedCount(dispatch, pressedCount)}>Example menu item</MenuItem >
41 );
42
43 const ExamplePluginMainPanel = connect(exampleMapStateToProps)(
44     ({ pressedCount }: ExampleProps) =>
45         <Card>
46             <CardContent>
47                 <Typography>
48                     This is a example main panel plugin.  The example menu item has been pressed {pressedCount} times.
49                 </Typography>
50             </CardContent>
51         </Card>);
52
53 export const register = (pluginConfig: PluginConfig) => {
54
55     pluginConfig.centerPanelList.push((elms) => {
56         elms.push(<Route path={routePath} component={ExamplePluginMainPanel} />);
57         return elms;
58     });
59
60     pluginConfig.accountMenuList.push((elms, menuItemClass) => {
61         elms.push(<ExampleMenuComponent className={menuItemClass} />);
62         return elms;
63     });
64
65     pluginConfig.newButtonMenuList.push((elms, menuItemClass) => {
66         elms.push(<ExampleMenuComponent className={menuItemClass} />);
67         return elms;
68     });
69
70     pluginConfig.navigateToHandlers.push((dispatch: Dispatch, getState: () => RootState, uuid: string) => {
71         if (uuid === categoryName) {
72             dispatch(push(routePath));
73             return true;
74         }
75         return false;
76     });
77
78     pluginConfig.sidePanelCategories.push((cats: string[]): string[] => { cats.push(categoryName); return cats; });
79
80     pluginConfig.locationChangeHandlers.push((store: RootStore, pathname: string): boolean => {
81         if (matchPath(pathname, { path: routePath, exact: true })) {
82             store.dispatch(handleFirstTimeLoad(
83                 (dispatch: Dispatch) => {
84                     dispatch<any>(activateSidePanelTreeItem(categoryName));
85                     dispatch<any>(setSidePanelBreadcrumbs(categoryName));
86                 }));
87             return true;
88         }
89         return false;
90     });
91
92     pluginConfig.enableNewButtonMatchers.push((location: Location) => (!!matchPath(location.pathname, { path: routePath, exact: true })));
93 };