[ARVADOS-WORKBENCH2] updated: 1.1.4-473-gfbec771

Git user git at public.curoverse.com
Fri Aug 3 01:49:00 EDT 2018


Summary of changes:
 src/common/custom-theme.ts                         |  28 ++-
 .../column-selector/column-selector.test.tsx       |  15 +-
 src/components/column-selector/column-selector.tsx |   8 +-
 src/components/data-explorer/data-explorer.tsx     |   4 +-
 src/components/data-table/data-column.ts           |  10 +-
 src/components/icon/icon.tsx                       |   9 +-
 src/index.tsx                                      |   2 +
 src/models/collection.ts                           |   4 +
 src/models/project.ts                              |   4 +
 .../collection-service.ts}                         |   6 +-
 src/services/services.ts                           |   3 +-
 .../collection-panel/collection-panel-action.ts    |  31 +++
 .../collection-panel/collection-panel-reducer.ts   |  21 +++
 .../creator/collection-creator-action.ts           |  32 ++++
 .../creator/collection-creator-reducer.test.ts     |  45 +++++
 .../creator/collection-creator-reducer.ts          |  39 ++++
 src/store/context-menu/context-menu-reducer.ts     |   1 -
 src/store/data-explorer/data-explorer-action.ts    |  23 +++
 .../data-explorer-middleware-service.ts            |  20 ++
 .../data-explorer/data-explorer-middleware.test.ts | 210 +++++++++++++++++++++
 .../data-explorer/data-explorer-middleware.ts      |  44 +++++
 src/store/data-explorer/data-explorer-reducer.ts   |   6 +-
 src/store/favorite-panel/favorite-panel-action.ts  |   8 +
 .../favorite-panel-middleware-service.ts           |  70 +++++++
 .../favorite-panel/favorite-panel-middleware.ts    | 125 ------------
 src/store/navigation/navigation-action.ts          |  13 +-
 src/store/project-panel/project-panel-action.ts    |   8 +
 .../project-panel-middleware-service.ts            |  96 ++++++++++
 .../project-panel/project-panel-middleware.ts      | 129 -------------
 src/store/project/project-reducer.test.ts          |  13 +-
 src/store/project/project-reducer.ts               |   4 +-
 src/store/side-panel/side-panel-reducer.ts         |   7 +-
 src/store/store.ts                                 |  48 +++--
 .../create-project/create-project-validator.tsx    |   2 +
 .../action-sets/collection-action-set.ts           |  77 ++++++++
 .../action-sets/favorite-action-set.ts             |   7 +-
 .../context-menu/action-sets/project-action-set.ts |   7 +-
 .../action-sets/resource-action-set.ts             |   2 +-
 .../{action-sets => actions}/favorite-action.tsx   |   2 +-
 src/views-components/context-menu/context-menu.tsx |   3 +-
 .../create-collection-dialog.tsx                   |  44 +++++
 .../create-project-dialog.tsx                      |  10 +-
 .../data-explorer/data-explorer.tsx                |  51 ++---
 src/views-components/data-explorer/renderers.tsx   |  67 +++++++
 ...ect-create.tsx => dialog-collection-create.tsx} |  31 +--
 .../dialog-create/dialog-project-create.tsx        |   6 +-
 src/views/collection-panel/collection-panel.tsx    | 103 ++++++++++
 src/views/favorite-panel/favorite-panel.tsx        |  71 +------
 src/views/project-panel/project-panel.tsx          |  81 ++------
 src/views/workbench/workbench.tsx                  |  59 +++++-
 50 files changed, 1199 insertions(+), 510 deletions(-)
 copy src/services/{link-service/link-service.ts => collection-service/collection-service.ts} (59%)
 create mode 100644 src/store/collection-panel/collection-panel-action.ts
 create mode 100644 src/store/collection-panel/collection-panel-reducer.ts
 create mode 100644 src/store/collections/creator/collection-creator-action.ts
 create mode 100644 src/store/collections/creator/collection-creator-reducer.test.ts
 create mode 100644 src/store/collections/creator/collection-creator-reducer.ts
 create mode 100644 src/store/data-explorer/data-explorer-middleware-service.ts
 create mode 100644 src/store/data-explorer/data-explorer-middleware.test.ts
 create mode 100644 src/store/data-explorer/data-explorer-middleware.ts
 create mode 100644 src/store/favorite-panel/favorite-panel-action.ts
 create mode 100644 src/store/favorite-panel/favorite-panel-middleware-service.ts
 delete mode 100644 src/store/favorite-panel/favorite-panel-middleware.ts
 create mode 100644 src/store/project-panel/project-panel-action.ts
 create mode 100644 src/store/project-panel/project-panel-middleware-service.ts
 delete mode 100644 src/store/project-panel/project-panel-middleware.ts
 create mode 100644 src/views-components/context-menu/action-sets/collection-action-set.ts
 rename src/views-components/context-menu/{action-sets => actions}/favorite-action.tsx (89%)
 create mode 100644 src/views-components/create-collection-dialog/create-collection-dialog.tsx
 create mode 100644 src/views-components/data-explorer/renderers.tsx
 copy src/views-components/dialog-create/{dialog-project-create.tsx => dialog-collection-create.tsx} (80%)
 create mode 100644 src/views/collection-panel/collection-panel.tsx

       via  fbec771115f1872bdadc0572a5c5059be68f1aca (commit)
       via  6cb43ce8d9ab8345a1b2a5abd961c7c134f5c607 (commit)
       via  5b38ed263a3efd88a215c0911dc969303001645c (commit)
       via  aa45c97670b9726e7afe66c3e747ccab4b82fa6d (commit)
       via  711d39ce13e6662e7823485f13a6e94a748cecf8 (commit)
       via  c384037883732764d73829804aabee0ccfc8aa61 (commit)
       via  7bbaab130034613a1191d692c9ce5596a5acd427 (commit)
       via  b92f9ebb833ad1a868f9cad6e6b1cf9076fe7c9f (commit)
       via  e4c3defe5d79926d86f49ba83cfe3125261481cb (commit)
       via  378c6a3a18cd9849bf4233e130a9ffdf250de35e (commit)
       via  7ae86efd9905582df4191910528c3803a68ba81b (commit)
       via  83d2d86a40a316eb332b9962f9fac2eae3259cc2 (commit)
       via  3ee31ce16470660d90fb870e048c2de9fcde6e47 (commit)
       via  ae85f32b449562726c0fd3d30447c799069a0bbb (commit)
       via  d6044c2155e8a59a09de9f581b34573f94f1827a (commit)
       via  ccc52fb9e9a880f8b8e9b15b09c2ebd513575bd4 (commit)
       via  6d13a683ff5ce887bfd4c20b0bdbd18298dd86b2 (commit)
       via  46460de37ddbc61a296d3a393bce332d856664a6 (commit)
       via  c01f42311966c4d13413ee34dd6c97d5e5ac8b7f (commit)
       via  2b53e4a7bf1516c1b4fe9d42abd15cdc865cd87d (commit)
       via  b3593d28da32bdcf35ec91a6e0dd9099b7bd43b2 (commit)
       via  ffac6f1051efb642db49c4c4a5d2f3f477ca6d34 (commit)
       via  3eba091748f10f981d48f44eed14115b4fcee0ce (commit)
       via  6d0382ab90d7ac8ddcfcd291dc78c15194a25c28 (commit)
       via  e8f8e90d6c0f9f595d0a140ea6e73eb3b7fd29f5 (commit)
       via  ff08c9fee3c8cbb0c54092b6e17dc7bbf476dd30 (commit)
       via  71b7de8657caf1776c082a350e1a55cbe01bf21d (commit)
       via  b62944772ff96019c1e497426784690978bb9c96 (commit)
       via  da83b00c6627076d927ac9983bfa35808e9c5f43 (commit)
       via  e484aaf10e5cf9a49368e74724f3967b103525e4 (commit)
       via  eb1af55955e792abcdfd5a77d80c01d9a708ce8b (commit)
      from  cba00eaa2d205b13cfa696f866a31452c6511cf3 (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 fbec771115f1872bdadc0572a5c5059be68f1aca
Merge: cba00ea 6cb43ce
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Fri Aug 3 07:48:51 2018 +0200

    refs #master Merge branch 'origin/master' into 13901-services-repo
    
    # Conflicts:
    #       src/services/services.ts
    #       src/store/favorite-panel/favorite-panel-middleware.ts
    #       src/store/project-panel/project-panel-middleware.ts
    #       src/store/store.ts
    #       src/views/workbench/workbench.tsx
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --cc src/services/services.ts
index e137176,69157f8..1f0e23a
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@@ -7,41 -7,12 +7,42 @@@ import { GroupsService } from "./groups
  import { ProjectService } from "./project-service/project-service";
  import { LinkService } from "./link-service/link-service";
  import { FavoriteService } from "./favorite-service/favorite-service";
 +import { AxiosInstance } from "axios";
 +import { CommonResourceService } from "../common/api/common-resource-service";
 +import { CollectionResource } from "../models/collection";
 +import { Resource } from "../models/resource";
+ import { CollectionService } from "./collection-service/collection-service";
 +import Axios from "axios";
  
 -export const authService = new AuthService(authClient, apiClient);
 -export const groupsService = new GroupsService(apiClient);
 -export const projectService = new ProjectService(apiClient);
 -export const collectionService = new CollectionService(apiClient);
 -export const linkService = new LinkService(apiClient);
 -export const favoriteService = new FavoriteService(linkService, groupsService);
 +export interface ServiceRepository {
 +    apiClient: AxiosInstance;
 +
 +    authService: AuthService;
 +    groupsService: GroupsService;
 +    projectService: ProjectService;
 +    linkService: LinkService;
 +    favoriteService: FavoriteService;
 +    collectionService: CommonResourceService<Resource>;
 +}
 +
 +export const createServices = (baseUrl: string): ServiceRepository => {
 +    const apiClient = Axios.create();
 +    apiClient.defaults.baseURL = `${baseUrl}/arvados/v1`;
 +
 +    const authService = new AuthService(apiClient, baseUrl);
 +    const groupsService = new GroupsService(apiClient);
 +    const projectService = new ProjectService(apiClient);
 +    const linkService = new LinkService(apiClient);
 +    const favoriteService = new FavoriteService(linkService, groupsService);
-     const collectionService = new CommonResourceService<CollectionResource>(apiClient, "collections");
++    const collectionService = new CollectionService(apiClient);
 +
 +    return {
 +        apiClient,
 +        authService,
 +        groupsService,
 +        projectService,
 +        linkService,
 +        favoriteService,
 +        collectionService
 +    };
 +};
diff --cc src/store/collection-panel/collection-panel-action.ts
index 0000000,3c66016..1a23fbe
mode 000000,100644..100644
--- a/src/store/collection-panel/collection-panel-action.ts
+++ b/src/store/collection-panel/collection-panel-action.ts
@@@ -1,0 -1,30 +1,31 @@@
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+ 
+ import { unionize, ofType, UnionOf } from "unionize";
+ import { CommonResourceService } from "../../common/api/common-resource-service";
 -import { apiClient } from "../../common/api/server-api";
+ import { Dispatch } from "redux";
+ import { ResourceKind } from "../../models/resource";
+ import { CollectionResource } from "../../models/collection";
++import { RootState } from "../store";
++import { ServiceRepository } from "../../services/services";
+ 
+ export const collectionPanelActions = unionize({
+     LOAD_COLLECTION: ofType<{ uuid: string, kind: ResourceKind }>(),
+     LOAD_COLLECTION_SUCCESS: ofType<{ item: CollectionResource }>(),
+ }, { tag: 'type', value: 'payload' });
+ 
+ export type CollectionPanelAction = UnionOf<typeof collectionPanelActions>;
+ 
+ export const loadCollection = (uuid: string, kind: ResourceKind) =>
 -    (dispatch: Dispatch) => {
++    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+         dispatch(collectionPanelActions.LOAD_COLLECTION({ uuid, kind }));
 -        return new CommonResourceService(apiClient, "collections")
++        return new CommonResourceService(services.apiClient, "collections")
+             .get(uuid)
+             .then(item => {
+                 dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: item as CollectionResource }));
+             });
+     };
+ 
+ 
+ 
diff --cc src/store/collections/creator/collection-creator-action.ts
index 0000000,b30f8b8..1dc8236
mode 000000,100644..100644
--- a/src/store/collections/creator/collection-creator-action.ts
+++ b/src/store/collections/creator/collection-creator-action.ts
@@@ -1,0 -1,32 +1,32 @@@
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+ 
+ import { default as unionize, ofType, UnionOf } from "unionize";
+ import { Dispatch } from "redux";
+ 
+ import { RootState } from "../../store";
 -import { collectionService } from '../../../services/services';
+ import { CollectionResource } from '../../../models/collection';
++import { ServiceRepository } from "../../../services/services";
+ 
+ export const collectionCreateActions = unionize({
+     OPEN_COLLECTION_CREATOR: ofType<{ ownerUuid: string }>(),
+     CLOSE_COLLECTION_CREATOR: ofType<{}>(),
+     CREATE_COLLECTION: ofType<{}>(),
+     CREATE_COLLECTION_SUCCESS: ofType<{}>(),
+ }, {
+         tag: 'type',
+         value: 'payload'
+     });
+ 
+ export const createCollection = (collection: Partial<CollectionResource>) =>
 -    (dispatch: Dispatch, getState: () => RootState) => {
++    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+         const { ownerUuid } = getState().collectionCreation.creator;
+         const collectiontData = { ownerUuid, ...collection };
+         dispatch(collectionCreateActions.CREATE_COLLECTION(collectiontData));
 -        return collectionService
++        return services.collectionService
+             .create(collectiontData)
+             .then(collection => dispatch(collectionCreateActions.CREATE_COLLECTION_SUCCESS(collection)));
+     };
+ 
 -export type CollectionCreateAction = UnionOf<typeof collectionCreateActions>;
++export type CollectionCreateAction = UnionOf<typeof collectionCreateActions>;
diff --cc src/store/favorite-panel/favorite-panel-middleware-service.ts
index 0000000,8908fff..62d9ae2
mode 000000,100644..100644
--- a/src/store/favorite-panel/favorite-panel-middleware-service.ts
+++ b/src/store/favorite-panel/favorite-panel-middleware-service.ts
@@@ -1,0 -1,70 +1,70 @@@
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+ 
+ import { DataExplorerMiddlewareService } from "../data-explorer/data-explorer-middleware-service";
+ import { FavoritePanelFilter, FavoritePanelColumnNames } from "../../views/favorite-panel/favorite-panel";
+ import { RootState } from "../store";
+ import { DataColumns } from "../../components/data-table/data-table";
+ import { FavoritePanelItem, resourceToDataItem } from "../../views/favorite-panel/favorite-panel-item";
+ import { FavoriteOrderBuilder } from "../../services/favorite-service/favorite-order-builder";
 -import { favoriteService, authService } from "../../services/services";
++import { ServiceRepository } from "../../services/services";
+ import { SortDirection } from "../../components/data-table/data-column";
+ import { FilterBuilder } from "../../common/api/filter-builder";
+ import { LinkResource } from "../../models/link";
+ import { checkPresenceInFavorites } from "../favorites/favorites-actions";
+ import { favoritePanelActions } from "./favorite-panel-action";
+ import { Dispatch, MiddlewareAPI } from "redux";
+ 
+ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareService {
 -    constructor(id: string) {
++    constructor(private services: ServiceRepository, id: string) {
+         super(id);
+     }
+ 
+     requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
+         const dataExplorer = api.getState().dataExplorer[this.getId()];
+         const columns = dataExplorer.columns as DataColumns<FavoritePanelItem, FavoritePanelFilter>;
+         const sortColumn = dataExplorer.columns.find(
+             ({ sortDirection }) => sortDirection !== undefined && sortDirection !== "none"
+         );
+         const typeFilters = getColumnFilters(columns, FavoritePanelColumnNames.TYPE);
+         const order = FavoriteOrderBuilder.create();
+         if (typeFilters.length > 0) {
 -            favoriteService
 -                .list(authService.getUuid()!, {
++            this.services.favoriteService
++                .list(this.services.authService.getUuid()!, {
+                     limit: dataExplorer.rowsPerPage,
+                     offset: dataExplorer.page * dataExplorer.rowsPerPage,
+                     order: sortColumn!.name === FavoritePanelColumnNames.NAME
+                         ? sortColumn!.sortDirection === SortDirection.ASC
+                             ? order.addDesc("name")
+                             : order.addAsc("name")
+                         : order,
+                     filters: FilterBuilder
+                         .create<LinkResource>()
+                         .addIsA("headUuid", typeFilters.map(filter => filter.type))
+                         .addILike("name", dataExplorer.searchValue)
+                 })
+                 .then(response => {
+                     api.dispatch(favoritePanelActions.SET_ITEMS({
+                         items: response.items.map(resourceToDataItem),
+                         itemsAvailable: response.itemsAvailable,
+                         page: Math.floor(response.offset / response.limit),
+                         rowsPerPage: response.limit
+                     }));
+                     api.dispatch<any>(checkPresenceInFavorites(response.items.map(item => item.uuid)));
+                 });
+         } else {
+             api.dispatch(favoritePanelActions.SET_ITEMS({
+                 items: [],
+                 itemsAvailable: 0,
+                 page: 0,
+                 rowsPerPage: dataExplorer.rowsPerPage
+             }));
+         }
+     }
+ }
+ 
+ const getColumnFilters = (columns: DataColumns<FavoritePanelItem, FavoritePanelFilter>, columnName: string) => {
+     const column = columns.find(c => c.name === columnName);
+     return column && column.filters ? column.filters.filter(f => f.selected) : [];
+ };
diff --cc src/store/project-panel/project-panel-middleware-service.ts
index 0000000,761ec18..8d3f06a
mode 000000,100644..100644
--- a/src/store/project-panel/project-panel-middleware-service.ts
+++ b/src/store/project-panel/project-panel-middleware-service.ts
@@@ -1,0 -1,96 +1,96 @@@
+ // Copyright (C) The Arvados Authors. All rights reserved.
+ //
+ // SPDX-License-Identifier: AGPL-3.0
+ 
+ import { DataExplorerMiddlewareService } from "../data-explorer/data-explorer-middleware-service";
+ import { ProjectPanelColumnNames, ProjectPanelFilter } from "../../views/project-panel/project-panel";
+ import { RootState } from "../store";
+ import { DataColumns } from "../../components/data-table/data-table";
 -import { groupsService } from "../../services/services";
++import { ServiceRepository } from "../../services/services";
+ import { ProjectPanelItem, resourceToDataItem } from "../../views/project-panel/project-panel-item";
+ import { SortDirection } from "../../components/data-table/data-column";
+ import { OrderBuilder } from "../../common/api/order-builder";
+ import { FilterBuilder } from "../../common/api/filter-builder";
+ import { ProcessResource } from "../../models/process";
+ import { GroupContentsResourcePrefix, GroupContentsResource } from "../../services/groups-service/groups-service";
+ import { checkPresenceInFavorites } from "../favorites/favorites-actions";
+ import { projectPanelActions } from "./project-panel-action";
+ import { Dispatch, MiddlewareAPI } from "redux";
+ 
+ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService {
 -    constructor(id: string) {
++    constructor(private services: ServiceRepository, id: string) {
+         super(id);
+     }
+ 
+     requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
+         const state = api.getState();
+         const dataExplorer = state.dataExplorer[this.getId()];
+         const columns = dataExplorer.columns as DataColumns<ProjectPanelItem, ProjectPanelFilter>;
+         const typeFilters = getColumnFilters(columns, ProjectPanelColumnNames.TYPE);
+         const statusFilters = getColumnFilters(columns, ProjectPanelColumnNames.STATUS);
+         const sortColumn = dataExplorer.columns.find(({ sortDirection }) => Boolean(sortDirection && sortDirection !== "none"));
+         const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.ASC ? SortDirection.ASC : SortDirection.DESC;
+         if (typeFilters.length > 0) {
 -            groupsService
++            this.services.groupsService
+                 .contents(state.projects.currentItemId, {
+                     limit: dataExplorer.rowsPerPage,
+                     offset: dataExplorer.page * dataExplorer.rowsPerPage,
+                     order: sortColumn
+                         ? sortColumn.name === ProjectPanelColumnNames.NAME
+                             ? getOrder("name", sortDirection)
+                             : getOrder("createdAt", sortDirection)
+                         : OrderBuilder.create(),
+                     filters: FilterBuilder
+                         .create()
+                         .concat(FilterBuilder
+                             .create()
+                             .addIsA("uuid", typeFilters.map(f => f.type)))
+                         .concat(FilterBuilder
+                             .create<ProcessResource>(GroupContentsResourcePrefix.PROCESS)
+                             .addIn("state", statusFilters.map(f => f.type)))
+                         .concat(getSearchFilter(dataExplorer.searchValue))
+                 })
+                 .then(response => {
+                     api.dispatch(projectPanelActions.SET_ITEMS({
+                         items: response.items.map(resourceToDataItem),
+                         itemsAvailable: response.itemsAvailable,
+                         page: Math.floor(response.offset / response.limit),
+                         rowsPerPage: response.limit
+                     }));
+                     api.dispatch<any>(checkPresenceInFavorites(response.items.map(item => item.uuid)));
+                 });
+         } else {
+             api.dispatch(projectPanelActions.SET_ITEMS({
+                 items: [],
+                 itemsAvailable: 0,
+                 page: 0,
+                 rowsPerPage: dataExplorer.rowsPerPage
+             }));
+         }
+     }
+ }
+ 
+ const getColumnFilters = (columns: DataColumns<ProjectPanelItem, ProjectPanelFilter>, columnName: string) => {
+     const column = columns.find(c => c.name === columnName);
+     return column && column.filters ? column.filters.filter(f => f.selected) : [];
+ };
+ 
+ const getOrder = (attribute: "name" | "createdAt", direction: SortDirection) =>
+     [
+         OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION),
+         OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS),
+         OrderBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROJECT)
+     ].reduce((acc, b) =>
+         acc.concat(direction === SortDirection.ASC
+             ? b.addAsc(attribute)
+             : b.addDesc(attribute)), OrderBuilder.create());
+ 
+ const getSearchFilter = (searchValue: string) =>
+     searchValue
+         ? [
+             FilterBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION),
+             FilterBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS),
+             FilterBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROJECT)]
+             .reduce((acc, b) =>
+                 acc.concat(b.addILike("name", searchValue)), FilterBuilder.create())
+         : FilterBuilder.create();
diff --cc src/store/store.ts
index 2154b3b,53a01e2..3734361
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@@ -17,8 -16,13 +16,14 @@@ import { contextMenuReducer, ContextMen
  import { reducer as formReducer } from 'redux-form';
  import { FavoritesState, favoritesReducer } from './favorites/favorites-reducer';
  import { snackbarReducer, SnackbarState } from './snackbar/snackbar-reducer';
+ import { dataExplorerMiddleware } from "./data-explorer/data-explorer-middleware";
+ import { FAVORITE_PANEL_ID } from "./favorite-panel/favorite-panel-action";
+ import { PROJECT_PANEL_ID } from "./project-panel/project-panel-action";
+ import { ProjectPanelMiddlewareService } from "./project-panel/project-panel-middleware-service";
+ import { FavoritePanelMiddlewareService } from "./favorite-panel/favorite-panel-middleware-service";
+ import { CollectionCreatorState, collectionCreationReducer } from './collections/creator/collection-creator-reducer';
+ import { CollectionPanelState, collectionPanelReducer } from './collection-panel/collection-panel-reducer';
 +import { ServiceRepository } from "../services/services";
  
  const composeEnhancers =
      (process.env.NODE_ENV === 'development' &&
@@@ -37,27 -43,34 +44,36 @@@ export interface RootState 
      snackbar: SnackbarState;
  }
  
 -const rootReducer = combineReducers({
 -    auth: authReducer,
 -    projects: projectsReducer,
 -    collectionCreation: collectionCreationReducer,
 -    router: routerReducer,
 -    dataExplorer: dataExplorerReducer,
 -    sidePanel: sidePanelReducer,
 -    collectionPanel: collectionPanelReducer,
 -    detailsPanel: detailsPanelReducer,
 -    contextMenu: contextMenuReducer,
 -    form: formReducer,
 -    favorites: favoritesReducer,
 -    snackbar: snackbarReducer,
 -});
 +export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
 +
 +export function configureStore(history: History, services: ServiceRepository): RootStore {
-     const rootReducer = combineReducers({
-         auth: authReducer(services),
-         projects: projectsReducer,
-         router: routerReducer,
-         dataExplorer: dataExplorerReducer,
-         sidePanel: sidePanelReducer,
-         detailsPanel: detailsPanelReducer,
-         contextMenu: contextMenuReducer,
-         form: formReducer,
-         favorites: favoritesReducer,
-         snackbar: snackbarReducer,
-     });
++	const rootReducer = combineReducers({
++	    auth: authReducer(services),
++	    projects: projectsReducer,
++	    collectionCreation: collectionCreationReducer,
++	    router: routerReducer,
++	    dataExplorer: dataExplorerReducer,
++	    sidePanel: sidePanelReducer,
++	    collectionPanel: collectionPanelReducer,
++	    detailsPanel: detailsPanelReducer,
++	    contextMenu: contextMenuReducer,
++	    form: formReducer,
++	    favorites: favoritesReducer,
++	    snackbar: snackbarReducer,
++	});
+ 
 -export function configureStore(history: History) {
+     const projectPanelMiddleware = dataExplorerMiddleware(
 -        new ProjectPanelMiddlewareService(PROJECT_PANEL_ID)
++        new ProjectPanelMiddlewareService(services, PROJECT_PANEL_ID)
+     );
+     const favoritePanelMiddleware = dataExplorerMiddleware(
 -        new FavoritePanelMiddlewareService(FAVORITE_PANEL_ID)
++        new FavoritePanelMiddlewareService(services, FAVORITE_PANEL_ID)
+     );
  
      const middlewares: Middleware[] = [
          routerMiddleware(history),
 -        thunkMiddleware,
 +        thunkMiddleware.withExtraArgument(services),
-         projectPanelMiddleware(services),
-         favoritePanelMiddleware(services)
+         projectPanelMiddleware,
+         favoritePanelMiddleware
      ];
      const enhancer = composeEnhancers(applyMiddleware(...middlewares));
      return createStore(rootReducer, enhancer);
diff --cc src/views/workbench/workbench.tsx
index a7d8cba,96398c7..f0067aa
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -35,10 -37,14 +36,15 @@@ import { FavoritePanel } from "../favor
  import { CurrentTokenDialog } from '../../views-components/current-token-dialog/current-token-dialog';
  import { dataExplorerActions } from '../../store/data-explorer/data-explorer-action';
  import { Snackbar } from '../../views-components/snackbar/snackbar';
+ import { favoritePanelActions } from '../../store/favorite-panel/favorite-panel-action';
+ import { CreateCollectionDialog } from '../../views-components/create-collection-dialog/create-collection-dialog';
+ import { CollectionPanel } from '../collection-panel/collection-panel';
+ import { loadCollection } from '../../store/collection-panel/collection-panel-action';
+ import { getCollectionUrl } from '../../models/collection';
 +import { AuthService } from "../../services/auth-service/auth-service";
  
 -const drawerWidth = 240;
 -const appBarHeight = 100;
 +const DRAWER_WITDH = 240;
 +const APP_BAR_HEIGHT = 100;
  
  type CssRules = 'root' | 'appBar' | 'drawerPaper' | 'content' | 'contentWrapper' | 'toolbar';
  
@@@ -231,9 -235,21 +239,21 @@@ export const Workbench = withStyles(sty
                  );
              }
  
+             renderCollectionPanel = (props: RouteComponentProps<{ id: string }>) => <CollectionPanel 
+                 onItemRouteChange={(collectionId) => this.props.dispatch<any>(loadCollection(collectionId, ResourceKind.COLLECTION))}
+                 onContextMenu={(event, item) => {
+                     this.openContextMenu(event, {
+                         uuid: item.uuid,
+                         name: item.name,
+                         kind: ContextMenuKind.COLLECTION
+                     });
+                 }}
+                 {...props} />
+ 
              renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
 -                onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
 +                onItemRouteChange={itemId => this.props.dispatch(setProjectItem(itemId, ItemMode.ACTIVE))}
                  onContextMenu={(event, item) => {
+ 
                      const kind = item.kind === ResourceKind.PROJECT ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
                      this.openContextMenu(event, {
                          uuid: item.uuid,
@@@ -241,18 -257,26 +261,26 @@@
                          kind
                      });
                  }}
-                 onDialogOpen={this.handleCreationDialogOpen}
+                 onProjectCreationDialogOpen={this.handleProjectCreationDialogOpen}
+                 onCollectionCreationDialogOpen={this.handleCollectionCreationDialogOpen}
                  onItemClick={item => {
 -                    this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
 +                    this.props.dispatch(loadDetails(item.uuid, item.kind as ResourceKind));
                  }}
                  onItemDoubleClick={item => {
-                     this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE));
-                     this.props.dispatch(loadDetails(item.uuid, ResourceKind.PROJECT));
+                     switch (item.kind) {
+                         case ResourceKind.COLLECTION:
 -                            this.props.dispatch<any>(loadCollection(item.uuid, item.kind as ResourceKind));
++                            this.props.dispatch(loadCollection(item.uuid, item.kind as ResourceKind));
+                             this.props.dispatch(push(getCollectionUrl(item.uuid)));
+                         default: 
 -                            this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
 -                            this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
++                            this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE));
++                            this.props.dispatch(loadDetails(item.uuid, item.kind as ResourceKind));
+                     }
+ 
                  }}
                  {...props} />
  
              renderFavoritePanel = (props: RouteComponentProps<{ id: string }>) => <FavoritePanel
-                 onItemRouteChange={() => this.props.dispatch(dataExplorerActions.REQUEST_ITEMS({ id: FAVORITE_PANEL_ID }))}
 -                onItemRouteChange={() => this.props.dispatch<any>(favoritePanelActions.REQUEST_ITEMS())}
++                onItemRouteChange={() => this.props.dispatch(favoritePanelActions.REQUEST_ITEMS())}
                  onContextMenu={(event, item) => {
                      const kind = item.kind === ResourceKind.PROJECT ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
                      this.openContextMenu(event, {
@@@ -261,14 -285,21 +289,21 @@@
                          kind,
                      });
                  }}
-                 onDialogOpen={this.handleCreationDialogOpen}
+                 onDialogOpen={this.handleProjectCreationDialogOpen}
                  onItemClick={item => {
 -                    this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
 +                    this.props.dispatch(loadDetails(item.uuid, item.kind as ResourceKind));
                  }}
                  onItemDoubleClick={item => {
-                     this.props.dispatch(loadDetails(item.uuid, ResourceKind.PROJECT));
-                     this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE));
-                     this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
+                     switch (item.kind) {
+                         case ResourceKind.COLLECTION:
 -                            this.props.dispatch<any>(loadCollection(item.uuid, item.kind as ResourceKind));
++                            this.props.dispatch(loadCollection(item.uuid, item.kind as ResourceKind));
+                             this.props.dispatch(push(getCollectionUrl(item.uuid)));
+                         default:
 -                            this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.PROJECT));
 -                            this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
 -                            this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
++                            this.props.dispatch(loadDetails(item.uuid, ResourceKind.PROJECT));
++                            this.props.dispatch(setProjectItem(item.uuid, ItemMode.ACTIVE));
++                            this.props.dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
+                     }
+ 
                  }}
                  {...props} />
  

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list