[ARVADOS-WORKBENCH2] updated: 1.1.4-359-g10ce16c

Git user git at public.curoverse.com
Mon Jul 23 08:14:26 EDT 2018


Summary of changes:
 .env                                               |   1 +
 .licenseignore                                     |   2 +
 .npmrc                                             |   1 +
 .yarnrc                                            |   1 +
 Makefile                                           |   3 +-
 README.md                                          |  14 +-
 etc/arvados/workbench2/workbench2.example.json     |   3 +
 package.json                                       |  24 +-
 src/common/api/common-resource-service.test.ts     |   2 +-
 src/common/api/common-resource-service.ts          |   7 +-
 src/common/api/filter-builder.test.ts              |   2 +-
 src/common/api/filter-builder.ts                   |   4 +-
 src/common/api/order-builder.test.ts               |   2 +-
 src/common/api/order-builder.ts                    |   4 +-
 src/common/api/server-api.ts                       |   4 +
 src/common/api/url-builder.ts                      |  36 +-
 src/common/config.ts                               |  23 ++
 src/common/custom-theme.ts                         |  38 +-
 src/common/formatters.ts                           |   4 +-
 src/common/url.ts                                  |   6 +
 src/components/attribute/attribute.tsx             |  65 ----
 src/components/breadcrumbs/breadcrumbs.test.tsx    |   4 +-
 src/components/breadcrumbs/breadcrumbs.tsx         |  91 +++--
 .../column-selector/column-selector.test.tsx       |   2 +-
 src/components/column-selector/column-selector.tsx |  37 +-
 src/components/context-menu/context-menu.test.tsx  |  23 +-
 src/components/context-menu/context-menu.tsx       |  30 +-
 .../data-explorer/data-explorer.test.tsx           |  10 +-
 src/components/data-explorer/data-explorer.tsx     | 141 ++++----
 .../data-table-filters/data-table-filters.test.tsx |  12 +-
 .../data-table-filters/data-table-filters.tsx      | 255 +++++++------
 src/components/data-table/data-table.test.tsx      |   8 +-
 src/components/data-table/data-table.tsx           | 156 ++++----
 .../details-attribute/details-attribute.tsx        |  55 +++
 .../details-panel-factory.tsx                      |  27 --
 .../details-panel-factory/items/abstract-item.tsx  |  23 --
 .../items/collection-item.tsx                      |  33 --
 .../details-panel-factory/items/empty-item.tsx     |  21 --
 .../details-panel-factory/items/process-item.tsx   |  43 ---
 .../details-panel-factory/items/project-item.tsx   |  31 --
 .../dropdown-menu/dropdown-menu.test.tsx           |  19 +-
 src/components/dropdown-menu/dropdown-menu.tsx     |  25 +-
 src/components/empty-state/empty-state.tsx         |  46 ---
 src/components/icon/icon.tsx                       | 109 +++---
 .../list-item-text-icon/list-item-text-icon.tsx    |  62 ++++
 src/components/popover/helpers.ts                  |  10 +-
 src/components/popover/popover.test.tsx            |   6 +-
 src/components/popover/popover.tsx                 |   7 +-
 src/components/search-bar/search-bar.test.tsx      |  14 +-
 src/components/search-bar/search-bar.tsx           | 148 ++++----
 src/components/search-input/search-input.test.tsx  |  12 +-
 src/components/search-input/search-input.tsx       | 158 ++++----
 src/components/side-panel/side-panel.tsx           | 187 +++++-----
 src/components/tree/tree.test.tsx                  |   2 +-
 src/components/tree/tree.tsx                       | 133 +++----
 src/index.tsx                                      |  83 ++---
 src/models/container-request.ts                    |   3 +-
 src/models/details.ts                              |  10 +
 src/models/empty.ts                                |   4 +-
 src/services/auth-service/auth-service.ts          |   9 +-
 src/services/groups-service/groups-service.test.ts |   2 +-
 src/services/groups-service/groups-service.ts      |  10 +-
 .../project-service/project-service.test.ts        |   7 +-
 src/services/project-service/project-service.ts    |   8 +-
 src/services/services.ts                           |   8 +-
 src/store/auth/auth-action.ts                      |  10 +-
 src/store/auth/auth-reducer.test.ts                |  16 +-
 src/store/auth/auth-reducer.ts                     |   8 +-
 src/store/context-menu/context-menu-actions.ts     |  19 +-
 src/store/context-menu/context-menu-reducer.ts     |  49 +--
 src/store/data-explorer/data-explorer-action.ts    |   6 +-
 .../data-explorer/data-explorer-reducer.test.tsx   |  29 +-
 src/store/data-explorer/data-explorer-reducer.ts   |   8 +-
 src/store/details-panel/details-panel-action.ts    |  12 +-
 src/store/details-panel/details-panel-reducer.ts   |   8 +-
 src/store/navigation/navigation-action.ts          |   4 +-
 .../project-panel/project-panel-middleware.ts      |  39 +-
 src/store/project/project-action.ts                |  15 +-
 src/store/project/project-reducer.test.ts          |  12 +-
 src/store/project/project-reducer.ts               |  10 +-
 src/store/side-panel/side-panel-action.ts          |   5 +-
 src/store/side-panel/side-panel-reducer.test.ts    |  25 +-
 src/store/side-panel/side-panel-reducer.ts         |  22 +-
 src/store/store.ts                                 |  17 +-
 src/utils/dialog-validator.tsx                     |  74 ++++
 src/views-components/api-token/api-token.tsx       |  40 +--
 .../context-menu/action-sets/project-action-set.ts |  19 +
 .../action-sets/root-project-action-set.ts         |  15 +
 .../context-menu/context-menu-action-set.ts        |  13 +
 src/views-components/context-menu/context-menu.tsx |  60 ++++
 .../create-project-dialog.tsx                      |  10 +-
 .../data-explorer/data-explorer.tsx                |  20 +-
 .../details-panel/collection-details.tsx           |  35 ++
 .../details-panel/details-data.tsx                 |  21 ++
 .../details-panel/details-panel.tsx                | 192 +++++-----
 .../details-panel/empty-details.tsx                |  53 +++
 .../details-panel/process-details.tsx              |  45 +++
 .../details-panel/project-details.tsx              |  33 ++
 .../dialog-create/dialog-project-create.tsx        |   2 +-
 .../main-app-bar/main-app-bar.test.tsx             |  12 +-
 src/views-components/main-app-bar/main-app-bar.tsx |  27 +-
 src/views-components/project-list/project-list.tsx |  61 ----
 .../project-tree/project-tree.test.tsx             |  14 +-
 src/views-components/project-tree/project-tree.tsx |  85 ++---
 src/views/project-panel/project-panel.tsx          | 278 +++++++-------
 src/views/workbench/workbench.test.tsx             |   4 +-
 src/views/workbench/workbench.tsx                  | 365 ++++++++-----------
 tslint.json                                        |   3 +-
 yarn.lock                                          | 399 ++++++++++-----------
 109 files changed, 2337 insertions(+), 2187 deletions(-)
 create mode 100644 .npmrc
 create mode 100644 .yarnrc
 create mode 100644 etc/arvados/workbench2/workbench2.example.json
 create mode 100644 src/common/config.ts
 create mode 100644 src/common/url.ts
 delete mode 100644 src/components/attribute/attribute.tsx
 create mode 100644 src/components/details-attribute/details-attribute.tsx
 delete mode 100644 src/components/details-panel-factory/details-panel-factory.tsx
 delete mode 100644 src/components/details-panel-factory/items/abstract-item.tsx
 delete mode 100644 src/components/details-panel-factory/items/collection-item.tsx
 delete mode 100644 src/components/details-panel-factory/items/empty-item.tsx
 delete mode 100644 src/components/details-panel-factory/items/process-item.tsx
 delete mode 100644 src/components/details-panel-factory/items/project-item.tsx
 delete mode 100644 src/components/empty-state/empty-state.tsx
 create mode 100644 src/components/list-item-text-icon/list-item-text-icon.tsx
 create mode 100644 src/models/details.ts
 create mode 100644 src/utils/dialog-validator.tsx
 create mode 100644 src/views-components/context-menu/action-sets/project-action-set.ts
 create mode 100644 src/views-components/context-menu/action-sets/root-project-action-set.ts
 create mode 100644 src/views-components/context-menu/context-menu-action-set.ts
 create mode 100644 src/views-components/context-menu/context-menu.tsx
 create mode 100644 src/views-components/details-panel/collection-details.tsx
 create mode 100644 src/views-components/details-panel/details-data.tsx
 create mode 100644 src/views-components/details-panel/empty-details.tsx
 create mode 100644 src/views-components/details-panel/process-details.tsx
 create mode 100644 src/views-components/details-panel/project-details.tsx
 delete mode 100644 src/views-components/project-list/project-list.tsx

       via  10ce16c28de952f6533ca3cc9df909269e3d2a53 (commit)
       via  7df4149100f41cc8d4a5438630ba95a1d72409a1 (commit)
       via  b9da9116feeb510f5dae9da6e4f912ecf4aee298 (commit)
       via  de8c54604ff856456418f51c150b693845c29f49 (commit)
       via  47e0dc87fa82bac593c53518e556ba7c55410288 (commit)
       via  37ebbbd4f05f811582546823738619f1fbb97686 (commit)
       via  b6a5b173cd4e9f325f371d26204dfe156d911c20 (commit)
       via  ae691a976c8e505afba7cec6f8f316d1c5b175a7 (commit)
       via  4229645b39e3edfa288be826fb2cdcfa5fd90d38 (commit)
       via  180c2c37b635cbb7a33257d2ee9b4395553ce5e7 (commit)
       via  355aa79f1a2abb5e8142062d83f897d780cc8a8e (commit)
       via  6a8c680d938820bc497d0a5b0e6aa99c108ede14 (commit)
       via  b3ed96a047c8db5febae40b6f186a656589167d8 (commit)
       via  9230902521944497f96976064c5c7ae824786084 (commit)
       via  fef17c665b0d6acb4be97c9dcf4a6cb7a92ee6ef (commit)
       via  8dda39e1ac1e43d08881b8ac19db92c18d1cb4fe (commit)
       via  1a1007b664c6158c905a2fbfa998e7a5737ab7e1 (commit)
       via  1411549ab8347b21dc8efc1b208b98b85c186e12 (commit)
       via  6577b5404eef1061fc3f2fb1cfdc1775bd752132 (commit)
       via  5f5526dc9a8f06f82a4fe5c8f47a26ef6cab707e (commit)
       via  bc427c3f9f88acefbe12d7b9043d845acf5635a7 (commit)
       via  98937529d1e3e8a349fe11ed5cd75c56119990a7 (commit)
       via  5219b97601d3aee849081f81536f8edd91d9ad53 (commit)
       via  1d9efaa46b5e30f4b69fa8ebca99ea234a5d40c7 (commit)
       via  0a80eaa377a404c55660ecae52b495a9ed2e9167 (commit)
       via  082c172edc327afa52f9ec716f7702e3f29e58d6 (commit)
       via  9157a285ebb05c7ff0ae7a457ec5ffece17c3773 (commit)
       via  ea8725420ed2b4c3710925ac016ce10f288ab0aa (commit)
       via  46a41363f69391d4131180791f912329464d8a65 (commit)
       via  ea80145c5d632a647cf583cf0ebbf2a866d85549 (commit)
       via  9b390921232a4a3d1279d59da96f00dabeba1150 (commit)
       via  ff25c5d64dd7ba92f121726a31c56f50d4655d2a (commit)
       via  e6039bec0497aa7e1391958e5c4f84bbaeef653e (commit)
       via  ab08a8e2200157caaf73828b8459a641fff0d1e9 (commit)
       via  e3493974f91d07723008cdb8c7466a5ff8407cb5 (commit)
       via  7db89c862386851d1f37e12a301aebbe92c5c6f1 (commit)
       via  699f7cebc3057ddf22ca3c43c3d3534d605972ec (commit)
       via  017dcf25de396de8e382c9a288c62e21717aa600 (commit)
       via  dd4831ea08257f8891a9822fd29ad9b2dba1be5f (commit)
       via  9320734bb358e7148918da13e81ebba59ecf16e8 (commit)
       via  e046567a3f6fd8bec3113cec513d4a125054caf0 (commit)
       via  9ec2e259bd565aea710cdae34d8cba433b09a749 (commit)
       via  664fa00705ba7c1ee63d297afe6cdd0238c370e0 (commit)
       via  4d124b29e9f45d674c1cb784a4789ec980125bd1 (commit)
       via  ec802abaf641d5c0d6c0fda6893d0c3126e3cb65 (commit)
       via  06a7999b4f97b0ba5e7db1739f5a9531df724b86 (commit)
       via  22152102405a1407355d42a32385efd0d83bbc9c (commit)
       via  e21e064af352066148e4f45c5c4594ae4b05daf3 (commit)
       via  d44aed1e3141d8e5491b949415c99f594ee79c21 (commit)
       via  dca911684e2f09e518e976f9e1e3d3c2aec2c86a (commit)
       via  090241b266abe8558664a85b7e8e1b93c9ad60d0 (commit)
       via  0d71d490e24d2f1dae33360f194259bb597f2799 (commit)
       via  913eba4873631814daafa27d2474bb51e2378221 (commit)
       via  87dad7df1d3e32afccf7357df1b1d39af5a98154 (commit)
       via  8686e6aa3ba0f53b524898f8ef3a7214561cc6a4 (commit)
       via  a781af5eae4f4e7f6e07a2b205ad4e54e9e8ec7a (commit)
       via  e7253b56d761c939f1bc890a6b8c4087eab1410d (commit)
       via  99d2472afc89ca78a4fef46ac08ce520b3bcf17b (commit)
       via  b323a94f313671b44a066a2f91dea562e9464d10 (commit)
       via  5be1434f78d6dbcf2949918f7f042cab994ab0c5 (commit)
       via  2d35cbd012daca122052739564120863fefebfce (commit)
      from  b0de143e088973715681f7eb6c41f2dccb648c2b (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 10ce16c28de952f6533ca3cc9df909269e3d2a53
Merge: b0de143 7df4149
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date:   Mon Jul 23 14:14:16 2018 +0200

    merge conflicts
    
    Feature #13781
    
    Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>

diff --cc package.json
index a8c5617,0c06a6f..06fa893
--- a/package.json
+++ b/package.json
@@@ -3,12 -3,11 +3,12 @@@
    "version": "0.1.0",
    "private": true,
    "dependencies": {
-     "@material-ui/core": "1.2.1",
+     "@material-ui/core": "1.4.0",
      "@material-ui/icons": "1.1.0",
-     "@types/lodash": "4.14.109",
+     "@types/lodash": "4.14.112",
 +    "@types/redux-form": "^7.4.1",
      "axios": "0.18.0",
-     "classnames": "^2.2.6",
+     "classnames": "2.2.6",
      "lodash": "4.17.10",
      "react": "16.4.1",
      "react-dom": "16.4.1",
@@@ -41,13 -40,11 +41,13 @@@
      "@types/react-router-dom": "4.2.7",
      "@types/react-router-redux": "5.0.15",
      "@types/redux-devtools": "3.0.44",
 +    "@types/redux-form": "^7.4.1",
-     "axios-mock-adapter": "^1.15.0",
-     "enzyme": "^3.3.0",
-     "enzyme-adapter-react-16": "^1.1.1",
+     "axios-mock-adapter": "1.15.0",
+     "enzyme": "3.3.0",
+     "enzyme-adapter-react-16": "1.1.1",
      "jest-localstorage-mock": "2.2.0",
      "redux-devtools": "3.4.1",
 +    "redux-form": "^7.4.2",
      "typescript": "2.9.2"
    },
    "moduleNameMapper": {
diff --cc src/common/api/common-resource-service.ts
index 39825c0,2541fea..3956fb7
--- a/src/common/api/common-resource-service.ts
+++ b/src/common/api/common-resource-service.ts
@@@ -3,9 -3,9 +3,9 @@@
  // SPDX-License-Identifier: AGPL-3.0
  
  import * as _ from "lodash";
- import FilterBuilder from "./filter-builder";
- import OrderBuilder from "./order-builder";
+ import { FilterBuilder } from "./filter-builder";
+ import { OrderBuilder } from "./order-builder";
 -import { AxiosInstance } from "axios";
 +import { AxiosInstance, AxiosPromise } from "axios";
  import { Resource } from "../../models/resource";
  
  export interface ListArguments {
@@@ -26,12 -26,7 +26,12 @@@ export interface ListResults<T> 
      itemsAvailable: number;
  }
  
 +export interface Errors {
 +    errors: string[];
 +    errorToken: string;
 +}
 +
- export default class CommonResourceService<T extends Resource> {
+ export class CommonResourceService<T extends Resource> {
  
      static mapResponseKeys = (response: any): Promise<any> =>
          CommonResourceService.mapKeys(_.camelCase)(response.data)
diff --cc src/store/project/project-action.ts
index 3da60f6,2a7a5c1..075e77d
--- a/src/store/project/project-action.ts
+++ b/src/store/project/project-action.ts
@@@ -41,11 -42,11 +41,10 @@@ export const createProject = (project: 
      (dispatch: Dispatch, getState: () => RootState) => {
          const { ownerUuid } = getState().projects.creator;
          const projectData = { ownerUuid, ...project };
-         dispatch(actions.CREATE_PROJECT(projectData));
+         dispatch(projectActions.CREATE_PROJECT(projectData));
          return projectService
              .create(projectData)
-             .then(project => dispatch(actions.CREATE_PROJECT_SUCCESS(project)));
 -            .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)))
 -            .catch(() => dispatch(projectActions.CREATE_PROJECT_ERROR("Could not create a project")));
++            .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)));
      };
  
- export type ProjectAction = UnionOf<typeof actions>;
- export default actions;
+ export type ProjectAction = UnionOf<typeof projectActions>;
diff --cc src/store/project/project-reducer.ts
index a329e81,40356c0..94a451a
--- a/src/store/project/project-reducer.ts
+++ b/src/store/project/project-reducer.ts
@@@ -112,12 -111,13 +112,12 @@@ const initialState: ProjectState = 
  };
  
  
- const projectsReducer = (state: ProjectState = initialState, action: ProjectAction) => {
-     return actions.match(action, {
-         OPEN_PROJECT_CREATOR: ({ ownerUuid }) => updateCreator(state, { ownerUuid, opened: true }),
+ export const projectsReducer = (state: ProjectState = initialState, action: ProjectAction) => {
+     return projectActions.match(action, {
+         OPEN_PROJECT_CREATOR: ({ ownerUuid }) => updateCreator(state, { ownerUuid, opened: true, pending: false }),
          CLOSE_PROJECT_CREATOR: () => updateCreator(state, { opened: false }),
 -        CREATE_PROJECT: () => updateCreator(state, { opened: false, pending: true }),
 -        CREATE_PROJECT_SUCCESS: () => updateCreator(state, { ownerUuid: "", pending: false }),
 -        CREATE_PROJECT_ERROR: () => updateCreator(state, { ownerUuid: "", pending: false }),
 +        CREATE_PROJECT: () => updateCreator(state, { error: undefined }),
 +        CREATE_PROJECT_SUCCESS: () => updateCreator(state, { opened: false, ownerUuid: "" }),
          REMOVE_PROJECT: () => state,
          PROJECTS_REQUEST: itemId => {
              const items = _.cloneDeep(state.items);
diff --cc src/store/store.ts
index 956fb46,adb7ddd..01b06b9
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@@ -7,13 -7,13 +7,14 @@@ import { routerMiddleware, routerReduce
  import thunkMiddleware from 'redux-thunk';
  import { History } from "history";
  
- 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 detailsPanelReducer, { DetailsPanelState } from './details-panel/details-panel-reducer';
+ 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 './project-panel/project-panel-middleware';
+ import { detailsPanelReducer, DetailsPanelState } from './details-panel/details-panel-reducer';
+ import { contextMenuReducer, ContextMenuState } from './context-menu/context-menu-reducer';
 +import { reducer as formReducer } from 'redux-form';
  
  const composeEnhancers =
      (process.env.NODE_ENV === 'development' &&
@@@ -36,7 -37,7 +38,8 @@@ const rootReducer = combineReducers(
      dataExplorer: dataExplorerReducer,
      sidePanel: sidePanelReducer,
      detailsPanel: detailsPanelReducer,
 -    contextMenu: contextMenuReducer
++    contextMenu: contextMenuReducer,
 +    form: formReducer
  });
  
  
diff --cc src/views-components/create-project-dialog/create-project-dialog.tsx
index f75c459,2f3e0b7..43621bf
--- a/src/views-components/create-project-dialog/create-project-dialog.tsx
+++ b/src/views-components/create-project-dialog/create-project-dialog.tsx
@@@ -4,12 -4,10 +4,12 @@@
  
  import { connect } from "react-redux";
  import { Dispatch } from "redux";
 +import { SubmissionError } from "redux-form";
 +
  import { RootState } from "../../store/store";
- import DialogProjectCreate from "../dialog-create/dialog-project-create";
- import actions, { createProject, getProjectList } from "../../store/project/project-action";
- import dataExplorerActions from "../../store/data-explorer/data-explorer-action";
 -import { DialogProjectCreate as DialogProjectCreateComponent } from "../dialog-create/dialog-project-create";
++import  DialogProjectCreate from "../dialog-create/dialog-project-create";
+ import { projectActions, createProject, getProjectList } from "../../store/project/project-action";
+ import { dataExplorerActions } from "../../store/data-explorer/data-explorer-action";
  import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
  
  const mapStateToProps = (state: RootState) => ({
@@@ -27,14 -25,11 +27,14 @@@ export const addProject = (data: { name
  
  const mapDispatchToProps = (dispatch: Dispatch) => ({
      handleClose: () => {
-         dispatch(actions.CLOSE_PROJECT_CREATOR());
+         dispatch(projectActions.CLOSE_PROJECT_CREATOR());
      },
      onSubmit: (data: { name: string, description: string }) => {
 -        dispatch<any>(submit(data));
 +        return dispatch<any>(addProject(data))
 +            .catch((e: any) => {
 +                throw new SubmissionError({ name: e.errors.join("").includes("UniqueViolation") ? "Project with this name already exists." : "" });
 +            });
      }
  });
  
- export default connect(mapStateToProps, mapDispatchToProps)(DialogProjectCreate);
 -export const CreateProjectDialog = connect(mapStateToProps, mapDispatchToProps)(DialogProjectCreateComponent);
++export const CreateProjectDialog = connect(mapStateToProps, mapDispatchToProps)(DialogProjectCreate);
diff --cc src/views-components/dialog-create/dialog-project-create.tsx
index 6fb8a69,aefb815..34c655e
--- a/src/views-components/dialog-create/dialog-project-create.tsx
+++ b/src/views-components/dialog-create/dialog-project-create.tsx
@@@ -122,7 -37,106 +122,7 @@@ const styles: StyleRulesCallback<CssRul
      }
  });
  
 -interface ProjectCreateProps {
 -    open: boolean;
 -    handleClose: () => void;
 -    onSubmit: (data: { name: string, description: string }) => void;
 -}
 -
 -interface DialogState {
 -    name: string;
 -    description: string;
 -    isNameValid: boolean;
 -    isDescriptionValid: boolean;
 -}
 -
 -export const DialogProjectCreate = withStyles(styles)(
 -    class extends React.Component<ProjectCreateProps & WithStyles<CssRules>> {
 -        state: DialogState = {
 -            name: '',
 -            description: '',
 -            isNameValid: false,
 -            isDescriptionValid: true
 -        };
 -
 -        render() {
 -            const { name, description } = this.state;
 -            const { classes, open, handleClose } = this.props;
 -
 -            return (
 -                <Dialog
 -                    open={open}
 -                    onClose={handleClose}>
 -                    <div className={classes.dialog}>
 -                        <DialogTitle id="form-dialog-title" className={classes.dialogTitle}>Create a project</DialogTitle>
 -                        <DialogContent className={classes.dialogContent}>
 -                            <Validator
 -                                value={name}
 -                                onChange={e => this.isNameValid(e)}
 -                                isRequired={true}
 -                                render={hasError =>
 -                                    <TextField
 -                                        margin="dense"
 -                                        className={classes.textField}
 -                                        id="name"
 -                                        onChange={e => this.handleProjectName(e)}
 -                                        label="Project name"
 -                                        error={hasError}
 -                                        fullWidth/>}/>
 -                            <Validator
 -                                value={description}
 -                                onChange={e => this.isDescriptionValid(e)}
 -                                isRequired={false}
 -                                render={hasError =>
 -                                    <TextField
 -                                        margin="dense"
 -                                        className={classes.textField}
 -                                        id="description"
 -                                        onChange={e => this.handleDescriptionValue(e)}
 -                                        label="Description - optional"
 -                                        error={hasError}
 -                                        fullWidth/>}/>
 -                        </DialogContent>
 -                        <DialogActions>
 -                            <Button onClick={handleClose} className={classes.button} color="primary">CANCEL</Button>
 -                            <Button onClick={this.handleSubmit} className={classes.lastButton} color="primary"
 -                                    disabled={!this.state.isNameValid || (!this.state.isDescriptionValid && description.length > 0)}
 -                                    variant="raised">CREATE A PROJECT</Button>
 -                        </DialogActions>
 -                    </div>
 -                </Dialog>
 -            );
 -        }
 -
 -        handleSubmit = () => {
 -            this.props.onSubmit({
 -                name: this.state.name,
 -                description: this.state.description
 -            });
 -        }
 -
 -        handleProjectName(e: React.ChangeEvent<HTMLInputElement>) {
 -            this.setState({
 -                name: e.target.value,
 -            });
 -        }
 -
 -        handleDescriptionValue(e: React.ChangeEvent<HTMLInputElement>) {
 -            this.setState({
 -                description: e.target.value,
 -            });
 -        }
 -
 -        isNameValid(value: boolean | string) {
 -            this.setState({
 -                isNameValid: value,
 -            });
 -        }
 -
 -        isDescriptionValid(value: boolean | string) {
 -            this.setState({
 -                isDescriptionValid: value,
 -            });
 -        }
 -    }
 -);
 +export default compose(
 +    reduxForm({ form: 'projectCreateDialog' }),
 +    withStyles(styles)
- )(DialogProjectCreate);
++)(DialogProjectCreate);
diff --cc src/views/workbench/workbench.tsx
index b2bdac8,a62b713..b1e7cd7
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -111,207 -104,157 +104,157 @@@ interface WorkbenchState 
      };
  }
  
- 
- class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
-     state = {
-         contextMenu: {
-             anchorEl: undefined,
-             itemUuid: undefined
-         },
-         isCreationDialogOpen: false,
-         anchorEl: null,
-         searchText: "",
-         breadcrumbs: [],
-         menuItems: {
-             accountMenu: [
-                 {
-                     label: "Logout",
-                     action: () => this.props.dispatch(authActions.LOGOUT())
-                 },
-                 {
-                     label: "My account",
-                     action: () => this.props.dispatch(push("/my-account"))
-                 }
-             ],
-             helpMenu: [
-                 {
-                     label: "Help",
-                     action: () => this.props.dispatch(push("/help"))
+ export const Workbench = withStyles(styles)(
+     connect<WorkbenchDataProps>(
+         (state: RootState) => ({
+             projects: state.projects.items,
+             currentProjectId: state.projects.currentItemId,
+             user: state.auth.user,
+             sidePanelItems: state.sidePanel
+         })
+     )(
+         class extends React.Component<WorkbenchProps, WorkbenchState> {
+             state = {
+                 isCreationDialogOpen: false,
+                 anchorEl: null,
+                 searchText: "",
+                 breadcrumbs: [],
+                 menuItems: {
+                     accountMenu: [
+                         {
+                             label: "Logout",
+                             action: () => this.props.dispatch(authActions.LOGOUT())
+                         },
+                         {
+                             label: "My account",
+                             action: () => this.props.dispatch(push("/my-account"))
+                         }
+                     ],
+                     helpMenu: [
+                         {
+                             label: "Help",
+                             action: () => this.props.dispatch(push("/help"))
+                         }
+                     ],
+                     anonymousMenu: [
+                         {
+                             label: "Sign in",
+                             action: () => this.props.dispatch(authActions.LOGIN())
+                         }
+                     ]
                  }
-             ],
-             anonymousMenu: [
-                 {
-                     label: "Sign in",
-                     action: () => this.props.dispatch(authActions.LOGIN())
-                 }
-             ]
-         }
-     };
+             };
  
-     mainAppBarActions: MainAppBarActionProps = {
-         onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => {
-             this.props.dispatch<any>(setProjectItem(itemId, ItemMode.BOTH));
-             this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
-         },
-         onSearch: searchText => {
-             this.setState({ searchText });
-             this.props.dispatch(push(`/search?q=${searchText}`));
-         },
-         onMenuItemClick: (menuItem: NavMenuItem) => menuItem.action(),
-         onDetailsPanelToggle: () => {
-             this.props.dispatch(detailsPanelActions.TOGGLE_DETAILS_PANEL());
-         },
-         onContextMenu: (event: React.MouseEvent<HTMLElement>, breadcrumb: NavBreadcrumb) => {
-             this.openContextMenu(event, breadcrumb.itemId);
-         }
-     };
+             render() {
+                 const path = getTreePath(this.props.projects, this.props.currentProjectId);
+                 const breadcrumbs = path.map(item => ({
+                     label: item.data.name,
+                     itemId: item.data.uuid,
+                     status: item.status
+                 }));
  
-     toggleSidePanelOpen = (itemId: string) => {
-         this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(itemId));
-     }
+                 const { classes, user } = this.props;
+                 return (
+                     <div className={classes.root}>
+                         <div className={classes.appBar}>
+                             <MainAppBar
+                                 breadcrumbs={breadcrumbs}
+                                 searchText={this.state.searchText}
+                                 user={this.props.user}
+                                 menuItems={this.state.menuItems}
+                                 {...this.mainAppBarActions} />
+                         </div>
+                         {user &&
+                             <Drawer
+                                 variant="permanent"
+                                 classes={{
+                                     paper: classes.drawerPaper,
+                                 }}>
+                                 <div className={classes.toolbar} />
+                                 <SidePanel
+                                     toggleOpen={this.toggleSidePanelOpen}
+                                     toggleActive={this.toggleSidePanelActive}
+                                     sidePanelItems={this.props.sidePanelItems}
+                                     onContextMenu={(event) => this.openContextMenu(event, authService.getUuid() || "", ContextMenuKind.RootProject)}>
+                                     <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)}
+                                         toggleActive={itemId => {
+                                             this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
+                                             this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
+                                             this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects));
+                                         }} />
+                                 </SidePanel>
+                             </Drawer>}
+                         <main className={classes.contentWrapper}>
+                             <div className={classes.content}>
+                                 <Switch>
+                                     <Route path="/projects/:id" render={this.renderProjectPanel} />
+                                 </Switch>
+                             </div>
 -                            { user && <DetailsPanel /> }
++                            {user && <DetailsPanel />}
+                         </main>
+                         <ContextMenu />
+                         <CreateProjectDialog />
+                     </div>
+                 );
+             }
  
-     toggleSidePanelActive = (itemId: string) => {
-         this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(itemId));
-         this.props.dispatch(projectActions.RESET_PROJECT_TREE_ACTIVITY(itemId));
-         this.props.dispatch(push("/"));
-     }
+             renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
+                 onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
+                 onContextMenu={(event, item) => this.openContextMenu(event, item.uuid, ContextMenuKind.Project)}
+                 onDialogOpen={this.handleCreationDialogOpen}
+                 onItemClick={item => {
+                     this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
+                 }}
+                 onItemDoubleClick={item => {
+                     this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
+                     this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.Project));
+                 }}
+                 {...props} />
  
-     handleCreationDialogOpen = (itemUuid: string) => {
-         this.closeContextMenu();
-         this.props.dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: itemUuid }));
-     }
+             mainAppBarActions: MainAppBarActionProps = {
+                 onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => {
+                     this.props.dispatch<any>(setProjectItem(itemId, ItemMode.BOTH));
+                     this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
+                 },
+                 onSearch: searchText => {
+                     this.setState({ searchText });
+                     this.props.dispatch(push(`/search?q=${searchText}`));
+                 },
+                 onMenuItemClick: (menuItem: NavMenuItem) => menuItem.action(),
+                 onDetailsPanelToggle: () => {
+                     this.props.dispatch(detailsPanelActions.TOGGLE_DETAILS_PANEL());
+                 },
+                 onContextMenu: (event: React.MouseEvent<HTMLElement>, breadcrumb: NavBreadcrumb) => {
+                     this.openContextMenu(event, breadcrumb.itemId, ContextMenuKind.Project);
+                 }
+             };
  
+             toggleSidePanelOpen = (itemId: string) => {
+                 this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(itemId));
+             }
  
-     openContextMenu = (event: React.MouseEvent<HTMLElement>, itemUuid: string) => {
-         event.preventDefault();
-         this.setState({
-             contextMenu: {
-                 anchorEl: mockAnchorFromMouseEvent(event),
-                 itemUuid
+             toggleSidePanelActive = (itemId: string) => {
+                 this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(itemId));
+                 this.props.dispatch(projectActions.RESET_PROJECT_TREE_ACTIVITY(itemId));
+                 this.props.dispatch(push("/"));
              }
-         });
-     }
  
-     closeContextMenu = () => {
-         this.setState({ contextMenu: {} });
-     }
+             handleCreationDialogOpen = (itemUuid: string) => {
+                 this.props.dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: itemUuid }));
+             }
  
-     openCreateDialog = (item: ContextMenuAction) => {
-         const { itemUuid } = this.state.contextMenu;
-         if (item.openCreateDialog && itemUuid) {
-             this.handleCreationDialogOpen(itemUuid);
+             openContextMenu = (event: React.MouseEvent<HTMLElement>, itemUuid: string, kind: ContextMenuKind) => {
+                 event.preventDefault();
+                 this.props.dispatch(
+                     contextMenuActions.OPEN_CONTEXT_MENU({
+                         position: { x: event.clientX, y: event.clientY },
+                         resource: { uuid: itemUuid, kind }
+                     })
+                 );
+             }
          }
-     }
- 
-     render() {
-         const path = getTreePath(this.props.projects, this.props.currentProjectId);
-         const breadcrumbs = path.map(item => ({
-             label: item.data.name,
-             itemId: item.data.uuid,
-             status: item.status
-         }));
- 
-         const { classes, user } = this.props;
-         return (
-             <div className={classes.root}>
-                 <div className={classes.appBar}>
-                     <MainAppBar
-                         breadcrumbs={breadcrumbs}
-                         searchText={this.state.searchText}
-                         user={this.props.user}
-                         menuItems={this.state.menuItems}
-                         {...this.mainAppBarActions} />
-                 </div>
-                 {user &&
-                     <Drawer
-                         variant="permanent"
-                         classes={{
-                             paper: classes.drawerPaper,
-                         }}>
-                         <div className={classes.toolbar} />
-                         <SidePanel
-                             toggleOpen={this.toggleSidePanelOpen}
-                             toggleActive={this.toggleSidePanelActive}
-                             sidePanelItems={this.props.sidePanelItems}
-                             onContextMenu={(event) => this.openContextMenu(event, authService.getUuid() || "")}>
-                             <ProjectTree
-                                 projects={this.props.projects}
-                                 toggleOpen={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.OPEN))}
-                                 onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid)}
-                                 toggleActive={itemId => {
-                                     this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
-                                     this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
-                                     this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.Projects));
-                                 }} />
-                         </SidePanel>
-                     </Drawer>}
-                 <main className={classes.contentWrapper}>
-                     <div className={classes.content}>
-                         <Switch>
-                             <Route path="/projects/:id" render={this.renderProjectPanel} />
-                         </Switch>
-                     </div>
-                     <DetailsPanel />
-                 </main>
-                 <ContextMenu
-                     anchorEl={this.state.contextMenu.anchorEl}
-                     actions={contextMenuActions}
-                     onActionClick={this.openCreateDialog}
-                     onClose={this.closeContextMenu} />
-                 <DialogProjectCreate />
-             </div>
-         );
-     }
- 
-     renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
-         onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
-         onContextMenu={(event, item) => this.openContextMenu(event, item.uuid)}
-         onDialogOpen={this.handleCreationDialogOpen}
-         onItemClick={item => {
-             this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
-         }}
-         onItemDoubleClick={item => {
-             this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
-             this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.Project));
-         }}
-         {...props} />
- }
- 
- const contextMenuActions = [[{
-     icon: "fas fa-plus fa-fw",
-     name: "New project",
-     openCreateDialog: true
- }, {
-     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"
- }
- ]];
- 
- export default connect<WorkbenchDataProps>(
-     (state: RootState) => ({
-         projects: state.projects.items,
-         currentProjectId: state.projects.currentItemId,
-         user: state.auth.user,
-         sidePanelItems: state.sidePanel
-     })
- )(
-     withStyles(styles)(Workbench)
+     )
  );
diff --cc yarn.lock
index 0034169,6960aaf..3557ebe
--- a/yarn.lock
+++ b/yarn.lock
@@@ -3347,13 -3334,9 +3345,13 @@@ hmac-drbg@^1.0.0
      minimalistic-crypto-utils "^1.0.1"
  
  hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0:
-   version "2.5.4"
-   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.4.tgz#fc3b1ac05d2ae3abedec84eba846511b0d4fcc4f"
+   version "2.5.5"
+   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
  
 +hoist-non-react-statics@^2.5.4:
 +  version "2.5.5"
 +  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
 +
  home-or-tmp@^2.0.0:
    version "2.0.0"
    resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list