[ARVADOS-WORKBENCH2] updated: 1.1.4-293-ga781af5
Git user
git at public.curoverse.com
Fri Jul 13 10:18:21 EDT 2018
Summary of changes:
src/common/api/common-resource-service.test.ts | 2 +-
src/components/attribute/attribute.tsx | 2 +-
src/components/context-menu/context-menu.tsx | 23 +++---
src/components/data-explorer/data-explorer.tsx | 8 +-
src/components/empty-state/empty-state.tsx | 2 +-
src/services/groups-service/groups-service.test.ts | 2 +-
.../project-service/project-service.test.ts | 2 +-
src/store/context-menu/context-menu-reducer.ts | 8 +-
.../project-panel/project-panel-middleware.ts | 6 +-
src/store/store.ts | 2 +-
.../context-menu/context-menu-item-set.ts | 12 +++
src/views-components/context-menu/context-menu.tsx | 89 +++++-----------------
.../context-menu/empty-item-set.ts | 13 ++++
src/views-components/context-menu/index.ts | 17 +++++
.../context-menu/project-item-set.ts | 43 +++++++++++
.../context-menu/root-project-item-set.ts | 21 +++++
.../create-project-dialog.tsx | 2 +-
src/views/workbench/workbench.tsx | 5 +-
18 files changed, 155 insertions(+), 104 deletions(-)
create mode 100644 src/views-components/context-menu/context-menu-item-set.ts
create mode 100644 src/views-components/context-menu/empty-item-set.ts
create mode 100644 src/views-components/context-menu/index.ts
create mode 100644 src/views-components/context-menu/project-item-set.ts
create mode 100644 src/views-components/context-menu/root-project-item-set.ts
via a781af5eae4f4e7f6e07a2b205ad4e54e9e8ec7a (commit)
from e7253b56d761c939f1bc890a6b8c4087eab1410d (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit a781af5eae4f4e7f6e07a2b205ad4e54e9e8ec7a
Author: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
Date: Fri Jul 13 16:18:05 2018 +0200
Implement better pattern for hanling actions in context menu
Feature #13805
Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski at contractors.roche.com>
diff --git a/src/common/api/common-resource-service.test.ts b/src/common/api/common-resource-service.test.ts
index 7093b59..b8b1f44 100644
--- a/src/common/api/common-resource-service.test.ts
+++ b/src/common/api/common-resource-service.test.ts
@@ -4,7 +4,7 @@
import CommonResourceService from "./common-resource-service";
import axios from "axios";
-import MockAdapter from "axios-mock-adapter";
+import MockAdapter from "axios-mock-adapter/types";
describe("CommonResourceService", () => {
const axiosInstance = axios.create();
diff --git a/src/components/attribute/attribute.tsx b/src/components/attribute/attribute.tsx
index ea35f5b..c0874f7 100644
--- a/src/components/attribute/attribute.tsx
+++ b/src/components/attribute/attribute.tsx
@@ -5,7 +5,7 @@
import * as React from 'react';
import Typography from '@material-ui/core/Typography';
import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles';
-import { ArvadosTheme } from 'src/common/custom-theme';
+import { ArvadosTheme } from '../../common/custom-theme';
interface AttributeDataProps {
label: string;
diff --git a/src/components/context-menu/context-menu.tsx b/src/components/context-menu/context-menu.tsx
index 5626181..49b6592 100644
--- a/src/components/context-menu/context-menu.tsx
+++ b/src/components/context-menu/context-menu.tsx
@@ -5,24 +5,23 @@ import * as React from "react";
import { Popover, List, ListItem, ListItemIcon, ListItemText, Divider } from "@material-ui/core";
import { DefaultTransformOrigin } from "../popover/helpers";
-export interface ContextMenuAction {
+export interface ContextMenuItem {
name: string;
icon: string;
- openCreateDialog?: boolean;
}
-export type ContextMenuActionGroup = ContextMenuAction[];
+export type ContextMenuItemGroup = ContextMenuItem[];
export interface ContextMenuProps {
anchorEl?: HTMLElement;
- actions: ContextMenuActionGroup[];
- onActionClick: (action: ContextMenuAction) => void;
+ items: ContextMenuItemGroup[];
+ onItemClick: (action: ContextMenuItem) => void;
onClose: () => void;
}
export default class ContextMenu extends React.PureComponent<ContextMenuProps> {
render() {
- const { anchorEl, actions, onClose, onActionClick } = this.props;
+ const { anchorEl, items, onClose, onItemClick } = this.props;
return <Popover
anchorEl={anchorEl}
open={!!anchorEl}
@@ -31,21 +30,21 @@ export default class ContextMenu extends React.PureComponent<ContextMenuProps> {
anchorOrigin={DefaultTransformOrigin}
onContextMenu={this.handleContextMenu}>
<List dense>
- {actions.map((group, groupIndex) =>
+ {items.map((group, groupIndex) =>
<React.Fragment key={groupIndex}>
- {group.map((action, actionIndex) =>
+ {group.map((item, actionIndex) =>
<ListItem
button
key={actionIndex}
- onClick={() => onActionClick(action)}>
+ onClick={() => onItemClick(item)}>
<ListItemIcon>
- <i className={action.icon} />
+ <i className={item.icon} />
</ListItemIcon>
<ListItemText>
- {action.name}
+ {item.name}
</ListItemText>
</ListItem>)}
- {groupIndex < actions.length - 1 && <Divider />}
+ {groupIndex < items.length - 1 && <Divider />}
</React.Fragment>)}
</List>
</Popover>;
diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx
index e851ca9..1073ddd 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/components/data-explorer/data-explorer.tsx
@@ -5,10 +5,10 @@
import * as React from 'react';
import { Grid, Paper, Toolbar, StyleRulesCallback, withStyles, Theme, WithStyles, TablePagination, IconButton } from '@material-ui/core';
import MoreVertIcon from "@material-ui/icons/MoreVert";
-import ColumnSelector from "../../components/column-selector/column-selector";
-import DataTable, { DataColumns } from "../../components/data-table/data-table";
-import { DataColumn } from "../../components/data-table/data-column";
-import { DataTableFilterItem } from '../../components/data-table-filters/data-table-filters';
+import ColumnSelector from "../column-selector/column-selector";
+import DataTable, { DataColumns } from "../data-table/data-table";
+import { DataColumn } from "../data-table/data-column";
+import { DataTableFilterItem } from '../data-table-filters/data-table-filters';
import SearchInput from '../search-input/search-input';
interface DataExplorerProps<T> {
diff --git a/src/components/empty-state/empty-state.tsx b/src/components/empty-state/empty-state.tsx
index 205053b..9ab3063 100644
--- a/src/components/empty-state/empty-state.tsx
+++ b/src/components/empty-state/empty-state.tsx
@@ -5,7 +5,7 @@
import * as React from 'react';
import Typography from '@material-ui/core/Typography';
import { WithStyles, withStyles, StyleRulesCallback } from '@material-ui/core/styles';
-import { ArvadosTheme } from 'src/common/custom-theme';
+import { ArvadosTheme } from '../../common/custom-theme';
import IconBase, { IconTypes } from '../icon/icon';
export interface EmptyStateDataProps {
diff --git a/src/services/groups-service/groups-service.test.ts b/src/services/groups-service/groups-service.test.ts
index 2562a59..92d2277 100644
--- a/src/services/groups-service/groups-service.test.ts
+++ b/src/services/groups-service/groups-service.test.ts
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0
import axios from "axios";
-import MockAdapter from "axios-mock-adapter";
+import MockAdapter from "axios-mock-adapter/types";
import GroupsService from "./groups-service";
describe("GroupsService", () => {
diff --git a/src/services/project-service/project-service.test.ts b/src/services/project-service/project-service.test.ts
index 68df245..76da3d8 100644
--- a/src/services/project-service/project-service.test.ts
+++ b/src/services/project-service/project-service.test.ts
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0
import axios from "axios";
-import MockAdapter from "axios-mock-adapter";
+import MockAdapter from "axios-mock-adapter/types";
import ProjectService from "./project-service";
import FilterBuilder from "../../common/api/filter-builder";
import { ProjectResource } from "../../models/project";
diff --git a/src/store/context-menu/context-menu-reducer.ts b/src/store/context-menu/context-menu-reducer.ts
index 129c2af..147f094 100644
--- a/src/store/context-menu/context-menu-reducer.ts
+++ b/src/store/context-menu/context-menu-reducer.ts
@@ -17,13 +17,7 @@ export interface ContextMenuPosition {
export interface ContextMenuResource {
uuid: string;
- kind: ContextMenuKind;
-}
-
-export enum ContextMenuKind {
- RootProject = "RootProject",
- Project = "Project",
- Collection = "Collection"
+ kind: string;
}
const initialState = {
diff --git a/src/store/project-panel/project-panel-middleware.ts b/src/store/project-panel/project-panel-middleware.ts
index e72b6c1..80fb7fa 100644
--- a/src/store/project-panel/project-panel-middleware.ts
+++ b/src/store/project-panel/project-panel-middleware.ts
@@ -3,11 +3,11 @@
// SPDX-License-Identifier: AGPL-3.0
import { Middleware } from "redux";
-import actions from "../../store/data-explorer/data-explorer-action";
+import actions from "../data-explorer/data-explorer-action";
import { PROJECT_PANEL_ID, columns, ProjectPanelFilter, ProjectPanelColumnNames } from "../../views/project-panel/project-panel";
import { groupsService } from "../../services/services";
-import { RootState } from "../../store/store";
-import { getDataExplorer, DataExplorerState } from "../../store/data-explorer/data-explorer-reducer";
+import { RootState } from "../store";
+import { getDataExplorer, DataExplorerState } from "../data-explorer/data-explorer-reducer";
import { resourceToDataItem, ProjectPanelItem } from "../../views/project-panel/project-panel-item";
import FilterBuilder from "../../common/api/filter-builder";
import { DataColumns } from "../../components/data-table/data-table";
diff --git a/src/store/store.ts b/src/store/store.ts
index 130028a..d87c803 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -11,7 +11,7 @@ import projectsReducer, { ProjectState } from "./project/project-reducer";
import sidePanelReducer, { SidePanelState } from './side-panel/side-panel-reducer';
import authReducer, { AuthState } from "./auth/auth-reducer";
import dataExplorerReducer, { DataExplorerState } from './data-explorer/data-explorer-reducer';
-import { projectPanelMiddleware } from '../store/project-panel/project-panel-middleware';
+import { projectPanelMiddleware } from './project-panel/project-panel-middleware';
import detailsPanelReducer, { DetailsPanelState } from './details-panel/details-panel-reducer';
import contextMenuReducer, { ContextMenuState } from './context-menu/context-menu-reducer';
diff --git a/src/views-components/context-menu/context-menu-item-set.ts b/src/views-components/context-menu/context-menu-item-set.ts
new file mode 100644
index 0000000..0b207ad
--- /dev/null
+++ b/src/views-components/context-menu/context-menu-item-set.ts
@@ -0,0 +1,12 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { ContextMenuItemGroup, ContextMenuItem } from "../../components/context-menu/context-menu";
+import { ContextMenuResource } from "../../store/context-menu/context-menu-reducer";
+
+export interface ContextMenuItemSet {
+ handleItem (dispatch: Dispatch, action: ContextMenuItem, resource: ContextMenuResource): void;
+ getItems (): ContextMenuItemGroup[];
+}
diff --git a/src/views-components/context-menu/context-menu.tsx b/src/views-components/context-menu/context-menu.tsx
index bfd833a..93cb644 100644
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@ -5,33 +5,31 @@
import { connect, Dispatch, DispatchProp } from "react-redux";
import { RootState } from "../../store/store";
import actions from "../../store/context-menu/context-menu-actions";
-import ContextMenu, { ContextMenuAction, ContextMenuProps } from "../../components/context-menu/context-menu";
+import ContextMenu, { ContextMenuProps, ContextMenuItem } from "../../components/context-menu/context-menu";
import { createAnchorAt } from "../../components/popover/helpers";
-import projectActions from "../../store/project/project-action";
-import { ContextMenuResource, ContextMenuKind } from "../../store/context-menu/context-menu-reducer";
+import { ContextMenuResource } from "../../store/context-menu/context-menu-reducer";
+import { ContextMenuItemSet } from "./context-menu-item-set";
+import { emptyItemSet } from "./empty-item-set";
-
-type DataProps = Pick<ContextMenuProps, "anchorEl" | "actions"> & { resource?: ContextMenuResource };
+type DataProps = Pick<ContextMenuProps, "anchorEl" | "items"> & { resource?: ContextMenuResource };
const mapStateToProps = (state: RootState): DataProps => {
const { position, resource } = state.contextMenu;
return {
anchorEl: resource ? createAnchorAt(position) : undefined,
- actions: resource ? menuActions[resource.kind] : [],
+ items: getMenuItemSet(resource).getItems(),
resource
};
};
-type ActionProps = Pick<ContextMenuProps, "onClose"> & { onActionClick: (action: ContextMenuAction, resource?: ContextMenuResource) => void };
+type ActionProps = Pick<ContextMenuProps, "onClose"> & { onItemClick: (item: ContextMenuItem, resource?: ContextMenuResource) => void };
const mapDispatchToProps = (dispatch: Dispatch): ActionProps => ({
onClose: () => {
dispatch(actions.CLOSE_CONTEXT_MENU());
},
- onActionClick: (action: ContextMenuAction, resource?: ContextMenuResource) => {
+ onItemClick: (item: ContextMenuItem, resource?: ContextMenuResource) => {
dispatch(actions.CLOSE_CONTEXT_MENU());
if (resource) {
- if (action.name === "New project") {
- dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid }));
- }
+ getMenuItemSet(resource).handleItem(dispatch, item, resource);
}
}
});
@@ -39,65 +37,20 @@ const mapDispatchToProps = (dispatch: Dispatch): ActionProps => ({
const mergeProps = ({ resource, ...dataProps }: DataProps, actionProps: ActionProps): ContextMenuProps => ({
...dataProps,
...actionProps,
- onActionClick: (action: ContextMenuAction) => {
- actionProps.onActionClick(action, resource);
+ onItemClick: item => {
+ actionProps.onItemClick(item, resource);
}
});
-export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(ContextMenu);
+export const ContextMenuHOC = connect(mapStateToProps, mapDispatchToProps, mergeProps)(ContextMenu);
-const menuActions = {
- [ContextMenuKind.RootProject]: [[{
- icon: "fas fa-plus fa-fw",
- name: "New project"
- }]],
- [ContextMenuKind.Project]: [[{
- icon: "fas fa-plus fa-fw",
- name: "New project"
- }, {
- icon: "fas fa-users fa-fw",
- name: "Share"
- }, {
- icon: "fas fa-sign-out-alt fa-fw",
- name: "Move to"
- }, {
- icon: "fas fa-star fa-fw",
- name: "Add to favourite"
- }, {
- icon: "fas fa-edit fa-fw",
- name: "Rename"
- }, {
- icon: "fas fa-copy fa-fw",
- name: "Make a copy"
- }, {
- icon: "fas fa-download fa-fw",
- name: "Download"
- }], [{
- icon: "fas fa-trash-alt fa-fw",
- name: "Remove"
- }
- ]],
- [ContextMenuKind.Collection]: [[{
- icon: "fas fa-users fa-fw",
- name: "Share"
- }, {
- icon: "fas fa-sign-out-alt fa-fw",
- name: "Move to"
- }, {
- icon: "fas fa-star fa-fw",
- name: "Add to favourite"
- }, {
- icon: "fas fa-edit fa-fw",
- name: "Rename"
- }, {
- icon: "fas fa-copy fa-fw",
- name: "Make a copy"
- }, {
- icon: "fas fa-download fa-fw",
- name: "Download"
- }], [{
- icon: "fas fa-trash-alt fa-fw",
- name: "Remove"
- }
- ]]
+const menuItemSets = new Map<string, ContextMenuItemSet>();
+
+export const addMenuItemsSet = (name: string, itemSet: ContextMenuItemSet) => {
+ menuItemSets.set(name, itemSet);
};
+
+const getMenuItemSet = (resource?: ContextMenuResource): ContextMenuItemSet => {
+ return resource ? menuItemSets.get(resource.kind) || emptyItemSet : emptyItemSet;
+};
+
diff --git a/src/views-components/context-menu/empty-item-set.ts b/src/views-components/context-menu/empty-item-set.ts
new file mode 100644
index 0000000..209b75c
--- /dev/null
+++ b/src/views-components/context-menu/empty-item-set.ts
@@ -0,0 +1,13 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ContextMenuItemGroup } from "../../components/context-menu/context-menu";
+import { ContextMenuItemSet } from "./context-menu-item-set";
+
+export const emptyItemSet: ContextMenuItemSet = {
+ getItems: () => items,
+ handleItem: () => { return; }
+};
+
+const items: ContextMenuItemGroup[] = [];
\ No newline at end of file
diff --git a/src/views-components/context-menu/index.ts b/src/views-components/context-menu/index.ts
new file mode 100644
index 0000000..9293330
--- /dev/null
+++ b/src/views-components/context-menu/index.ts
@@ -0,0 +1,17 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ContextMenuHOC, addMenuItemsSet } from "./context-menu";
+import { projectItemSet } from "./project-item-set";
+import { rootProjectItemSet } from "./root-project-item-set";
+
+export default ContextMenuHOC;
+
+export enum ContextMenuKind {
+ RootProject = "RootProject",
+ Project = "Project"
+}
+
+addMenuItemsSet(ContextMenuKind.RootProject, rootProjectItemSet);
+addMenuItemsSet(ContextMenuKind.Project, projectItemSet);
\ No newline at end of file
diff --git a/src/views-components/context-menu/project-item-set.ts b/src/views-components/context-menu/project-item-set.ts
new file mode 100644
index 0000000..583bbaa
--- /dev/null
+++ b/src/views-components/context-menu/project-item-set.ts
@@ -0,0 +1,43 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ContextMenuItemGroup } from "../../components/context-menu/context-menu";
+import { ContextMenuItemSet } from "./context-menu-item-set";
+import actions from "../../store/project/project-action";
+
+export const projectItemSet: ContextMenuItemSet = {
+ getItems: () => items,
+ handleItem: (dispatch, item, resource) => {
+ if (item.name === "New project") {
+ dispatch(actions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid }));
+ }
+ }
+};
+
+const items: ContextMenuItemGroup[] = [[{
+ icon: "fas fa-plus fa-fw",
+ name: "New project"
+}, {
+ icon: "fas fa-users fa-fw",
+ name: "Share"
+}, {
+ icon: "fas fa-sign-out-alt fa-fw",
+ name: "Move to"
+}, {
+ icon: "fas fa-star fa-fw",
+ name: "Add to favourite"
+}, {
+ icon: "fas fa-edit fa-fw",
+ name: "Rename"
+}, {
+ icon: "fas fa-copy fa-fw",
+ name: "Make a copy"
+}, {
+ icon: "fas fa-download fa-fw",
+ name: "Download"
+}], [{
+ icon: "fas fa-trash-alt fa-fw",
+ name: "Remove"
+}
+]];
\ No newline at end of file
diff --git a/src/views-components/context-menu/root-project-item-set.ts b/src/views-components/context-menu/root-project-item-set.ts
new file mode 100644
index 0000000..ae760f0
--- /dev/null
+++ b/src/views-components/context-menu/root-project-item-set.ts
@@ -0,0 +1,21 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { ContextMenuItemGroup } from "../../components/context-menu/context-menu";
+import { ContextMenuItemSet } from "./context-menu-item-set";
+import actions from "../../store/project/project-action";
+
+export const rootProjectItemSet: ContextMenuItemSet = {
+ getItems: () => items,
+ handleItem: (dispatch, item, resource) => {
+ if (item.name === "New project") {
+ dispatch(actions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid }));
+ }
+ }
+};
+
+const items: ContextMenuItemGroup[] = [[{
+ icon: "fas fa-plus fa-fw",
+ name: "New project"
+}]];
\ No newline at end of file
diff --git a/src/views-components/create-project-dialog/create-project-dialog.tsx b/src/views-components/create-project-dialog/create-project-dialog.tsx
index 701ceee..6b69b79 100644
--- a/src/views-components/create-project-dialog/create-project-dialog.tsx
+++ b/src/views-components/create-project-dialog/create-project-dialog.tsx
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: AGPL-3.0
import { connect } from "react-redux";
-import { Dispatch } from "../../../node_modules/redux";
+import { Dispatch } from "redux";
import { RootState } from "../../store/store";
import DialogProjectCreate from "../dialog-create/dialog-project-create";
import actions, { createProject, getProjectList } from "../../store/project/project-action";
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index 52332e8..13e22d8 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -26,7 +26,7 @@ import projectActions from "../../store/project/project-action";
import ProjectPanel from "../project-panel/project-panel";
import DetailsPanel from '../../views-components/details-panel/details-panel';
import { ArvadosTheme } from '../../common/custom-theme';
-import ContextMenu from "../../views-components/context-menu/context-menu";
+import ContextMenu, { ContextMenuKind } from "../../views-components/context-menu";
import CreateProjectDialog from "../../views-components/create-project-dialog/create-project-dialog";
import { authService } from '../../services/services';
@@ -35,7 +35,6 @@ import contextMenuActions from "../../store/context-menu/context-menu-actions";
import { SidePanelIdentifiers } from '../../store/side-panel/side-panel-reducer';
import { ProjectResource } from '../../models/project';
import { ResourceKind } from '../../models/resource';
-import { ContextMenuKind } from '../../store/context-menu/context-menu-reducer';
const drawerWidth = 240;
const appBarHeight = 100;
@@ -217,7 +216,7 @@ class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
<ProjectTree
projects={this.props.projects}
toggleOpen={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.OPEN))}
- onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid, ContextMenuKind.Project)}
+ onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid, ContextMenuKind.Project)}
toggleActive={itemId => {
this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list