Merge branch '17426-plug-ins' refs #17426
[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 workbench plugin.  The entry point is the "register" method.
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 { Route, matchPath } from "react-router";
13 import { RootStore } from '~/store/store';
14 import { activateSidePanelTreeItem } from '~/store/side-panel-tree/side-panel-tree-actions';
15 import { setSidePanelBreadcrumbs } from '~/store/breadcrumbs/breadcrumbs-actions';
16 import { Location } from 'history';
17 import { handleFirstTimeLoad } from '~/store/workbench/workbench-actions';
18 import {
19     ExampleDialog,
20     ExamplePluginMainPanel,
21     ExampleMenuComponent,
22     ExampleDialogMenuComponent
23 } from './exampleComponents';
24
25 const categoryName = "Plugin Example";
26 export const routePath = "/examplePlugin";
27
28 export const register = (pluginConfig: PluginConfig) => {
29
30     // Add this component to the main panel.  When the app navigates
31     // to '/examplePlugin' it will render ExamplePluginMainPanel.
32     pluginConfig.centerPanelList.push((elms) => {
33         elms.push(<Route path={routePath} component={ExamplePluginMainPanel} />);
34         return elms;
35     });
36
37     // Add ExampleDialogMenuComponent to the upper-right user account menu
38     pluginConfig.accountMenuList.push((elms, menuItemClass) => {
39         elms.push(<ExampleDialogMenuComponent className={menuItemClass} />);
40         return elms;
41     });
42
43     // Add ExampleMenuComponent to the "New" button dropdown.
44     pluginConfig.newButtonMenuList.push((elms, menuItemClass) => {
45         elms.push(<ExampleMenuComponent className={menuItemClass} />);
46         return elms;
47     });
48
49     // Add a hook so that when the 'Plugin Example' entry in the left
50     // hand tree view is clicked, which calls navigateTo('Plugin Example'),
51     // it will be implemented by navigating to '/examplePlugin'
52     pluginConfig.navigateToHandlers.push((dispatch: Dispatch, getState: () => RootState, uuid: string) => {
53         if (uuid === categoryName) {
54             dispatch(push(routePath));
55             return true;
56         }
57         return false;
58     });
59
60     // Adds 'Plugin Example' to the left hand tree view.
61     pluginConfig.sidePanelCategories.push((cats: string[]): string[] => { cats.push(categoryName); return cats; });
62
63     // When the location changes to '/examplePlugin', make sure
64     // 'Plugin Example' in the left hand tree view is selected, and
65     // make sure the breadcrumbs are updated.
66     pluginConfig.locationChangeHandlers.push((store: RootStore, pathname: string): boolean => {
67         if (matchPath(pathname, { path: routePath, exact: true })) {
68             store.dispatch(handleFirstTimeLoad(
69                 (dispatch: Dispatch) => {
70                     dispatch<any>(activateSidePanelTreeItem(categoryName));
71                     dispatch<any>(setSidePanelBreadcrumbs(categoryName));
72                 }));
73             return true;
74         }
75         return false;
76     });
77
78     // The "New" button can enabled or disabled based on the current
79     // context or selection.  This adds a new callback to that will
80     // enable the "New" button when the location is '/examplePlugin'
81     pluginConfig.enableNewButtonMatchers.push((location: Location) => (!!matchPath(location.pathname, { path: routePath, exact: true })));
82
83     // Add the example dialog box to the list of dialog box controls.
84     pluginConfig.dialogs.push(<ExampleDialog />);
85 };