Merge branch 'master' into 13853-collection-view-info-card
authorJanicki Artur <artur.janicki@contractors.roche.com>
Mon, 30 Jul 2018 11:28:09 +0000 (13:28 +0200)
committerJanicki Artur <artur.janicki@contractors.roche.com>
Mon, 30 Jul 2018 11:28:09 +0000 (13:28 +0200)
refs #13853

Arvados-DCO-1.1-Signed-off-by: Janicki Artur <artur.janicki@contractors.roche.com>

1  2 
src/models/collection.ts
src/models/project.ts
src/services/services.ts
src/store/collection-panel/collection-panel-action.ts
src/store/navigation/navigation-action.ts
src/views/project-panel/project-panel.tsx
src/views/workbench/workbench.tsx

diff --combined src/models/collection.ts
index 8ab319991cc91a0f130576f1d4f72f4292be48c0,9cb8bb84f6d0963ac59eaf1db2d3276211ceedd8..0e96f7fd3dd6f1473f62d8c2a2e3226aa42f6507
@@@ -5,7 -5,7 +5,7 @@@
  import { Resource, ResourceKind } from "./resource";
  
  export interface CollectionResource extends Resource {
-     kind: ResourceKind.Collection;
+     kind: ResourceKind.COLLECTION;
      name: string;
      description: string;
      properties: any;
@@@ -18,7 -18,3 +18,7 @@@
      deleteAt: string;
      isTrashed: boolean;
  }
 +
 +export const getCollectionUrl = (uuid: string) => {
 +    return `/collections/${uuid}`;
 +};
diff --combined src/models/project.ts
index d3626d3be9dd6f0f776b69a9a80f5748877de10c,eaf60904609974223e091bb244067e4da9b2b667..b919450774f687084a700d8b4d041772aa142669
@@@ -5,9 -5,5 +5,9 @@@
  import { GroupResource, GroupClass } from "./group";
  
  export interface ProjectResource extends GroupResource {
-     groupClass: GroupClass.Project;
+     groupClass: GroupClass.PROJECT;
  }
 +
 +export const getProjectUrl = (uuid: string) => {
 +    return `/projects/${uuid}`;
 +};
diff --combined src/services/services.ts
index f0afd76fc82f7158f3e85aa9ddcb95b0d1c2df65,a08ed3cb3de4bbb0a89caa858cd5c5b3163c3551..e0d15cc40a40b855e599a76d151c70c4ef5a17cb
@@@ -4,13 -4,13 +4,13 @@@
  
  import { AuthService } from "./auth-service/auth-service";
  import { GroupsService } from "./groups-service/groups-service";
- import { serverApi } from "../common/api/server-api";
+ import { authClient, apiClient } from "../common/api/server-api";
  import { ProjectService } from "./project-service/project-service";
  import { LinkService } from "./link-service/link-service";
  import { FavoriteService } from "./favorite-service/favorite-service";
  
- export const authService = new AuthService(serverApi);
- export const groupsService = new GroupsService(serverApi);
- export const projectService = new ProjectService(serverApi);
- export const linkService = new LinkService(serverApi);
- export const favoriteService = new FavoriteService(linkService, groupsService);
+ export const authService = new AuthService(authClient, apiClient);
+ export const groupsService = new GroupsService(apiClient);
+ export const projectService = new ProjectService(apiClient);
+ export const linkService = new LinkService(apiClient);
 -export const favoriteService = new FavoriteService(linkService, groupsService);
++export const favoriteService = new FavoriteService(linkService, groupsService);
index c2684e055b7b1e7a13831310969e2a113a4718da,0000000000000000000000000000000000000000..3c6601657083296a056f40f711ad331f579a516c
mode 100644,000000..100644
--- /dev/null
@@@ -1,30 -1,0 +1,30 @@@
- import { serverApi } from "../../common/api/server-api";
 +// 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";
-         return new CommonResourceService(serverApi, "collections")
 +import { ResourceKind } from "../../models/resource";
 +import { CollectionResource } from "../../models/collection";
 +
 +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(collectionPanelActions.LOAD_COLLECTION({ uuid, kind }));
++        return new CommonResourceService(apiClient, "collections")
 +            .get(uuid)
 +            .then(item => {
 +                dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: item as CollectionResource }));
 +            });
 +    };
 +
 +
 +
index d65685d296becd4bad5d9d6ed7c3ef8c30ce0e9b,52086231742d8d9f37925c11cd41e95ef4395603..f8687ed754ad51f4604b4541361c5e3aff318fb5
@@@ -11,13 -11,11 +11,13 @@@ import { dataExplorerActions } from "..
  import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
  import { RootState } from "../store";
  import { Resource, ResourceKind } from "../../models/resource";
 +import { getCollectionUrl } from "../../models/collection";
 +import { getProjectUrl } from "../../models/project";
  
  export const getResourceUrl = <T extends Resource>(resource: T): string => {
      switch (resource.kind) {
-         case ResourceKind.Project: return getProjectUrl(resource.uuid);
-         case ResourceKind.Collection: return getCollectionUrl(resource.uuid);
 -        case ResourceKind.PROJECT: return `/projects/${resource.uuid}`;
 -        case ResourceKind.COLLECTION: return `/collections/${resource.uuid}`;
++        case ResourceKind.PROJECT: return getProjectUrl(resource.uuid);
++        case ResourceKind.COLLECTION: return getCollectionUrl(resource.uuid);
          default: return resource.href;
      }
  };
@@@ -35,10 -33,6 +35,6 @@@ export const setProjectItem = (itemId: 
  
          if (treeItem) {
  
-             if (itemMode === ItemMode.OPEN || itemMode === ItemMode.BOTH) {
-                 dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN(treeItem.data.uuid));
-             }
              const resourceUrl = getResourceUrl(treeItem.data);
  
              if (itemMode === ItemMode.ACTIVE || itemMode === ItemMode.BOTH) {
                  dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_ACTIVE(treeItem.data.uuid));
              }
  
-             const promise = treeItem.status === TreeItemStatus.Loaded
+             const promise = treeItem.status === TreeItemStatus.LOADED
                  ? Promise.resolve()
                  : dispatch<any>(getProjectList(itemId));
  
              promise
                  .then(() => dispatch<any>(() => {
+                     if (itemMode === ItemMode.OPEN || itemMode === ItemMode.BOTH) {
+                         dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN(treeItem.data.uuid));
+                     }
                      dispatch(dataExplorerActions.RESET_PAGINATION({id: PROJECT_PANEL_ID}));
                      dispatch(dataExplorerActions.REQUEST_ITEMS({id: PROJECT_PANEL_ID}));
                  }));
index 2ddc1b05f714b57af76aaa3caff9fd07f8a6b02b,17b0fd723db9f07f2c5c05d7e905aa6b6823bb71..81d84990a41b7ba1b9c54a4aefb2aba9b4df3353
@@@ -38,7 -38,7 +38,7 @@@ const renderName = (item: ProjectPanelI
              {renderIcon(item)}
          </Grid>
          <Grid item>
 -            <Typography color="primary">
 +            <Typography color="default">
                  {item.name}
              </Typography>
          </Grid>
  
  const renderIcon = (item: ProjectPanelItem) => {
      switch (item.kind) {
-         case ResourceKind.Project:
+         case ResourceKind.PROJECT:
              return <ProjectIcon />;
-         case ResourceKind.Collection:
+         case ResourceKind.COLLECTION:
              return <CollectionIcon />;
-         case ResourceKind.Process:
+         case ResourceKind.PROCESS:
              return <ProcessIcon />;
          default:
              return <DefaultIcon />;
@@@ -104,7 -104,7 +104,7 @@@ export const columns: DataColumns<Proje
      {
          name: ProjectPanelColumnNames.NAME,
          selected: true,
-         sortDirection: SortDirection.Asc,
+         sortDirection: SortDirection.ASC,
          render: renderName,
          width: "450px"
      },
          selected: true,
          filters: [
              {
-                 name: ContainerRequestState.Committed,
+                 name: ContainerRequestState.COMMITTED,
                  selected: true,
-                 type: ContainerRequestState.Committed
+                 type: ContainerRequestState.COMMITTED
              },
              {
-                 name: ContainerRequestState.Final,
+                 name: ContainerRequestState.FINAL,
                  selected: true,
-                 type: ContainerRequestState.Final
+                 type: ContainerRequestState.FINAL
              },
              {
-                 name: ContainerRequestState.Uncommitted,
+                 name: ContainerRequestState.UNCOMMITTED,
                  selected: true,
-                 type: ContainerRequestState.Uncommitted
+                 type: ContainerRequestState.UNCOMMITTED
              }
          ],
          render: renderStatus,
          selected: true,
          filters: [
              {
-                 name: resourceLabel(ResourceKind.Collection),
+                 name: resourceLabel(ResourceKind.COLLECTION),
                  selected: true,
-                 type: ResourceKind.Collection
+                 type: ResourceKind.COLLECTION
              },
              {
-                 name: resourceLabel(ResourceKind.Process),
+                 name: resourceLabel(ResourceKind.PROCESS),
                  selected: true,
-                 type: ResourceKind.Process
+                 type: ResourceKind.PROCESS
              },
              {
-                 name: resourceLabel(ResourceKind.Project),
+                 name: resourceLabel(ResourceKind.PROJECT),
                  selected: true,
-                 type: ResourceKind.Project
+                 type: ResourceKind.PROJECT
              }
          ],
          render: item => renderType(item.kind),
      {
          name: ProjectPanelColumnNames.LAST_MODIFIED,
          selected: true,
-         sortDirection: SortDirection.None,
+         sortDirection: SortDirection.NONE,
          render: item => renderDate(item.lastModified),
          width: "150px"
      }
index 6c7f85d87faf4ed74b8a2ed4804dba51f508be85,3637528d49f8f8355dafe291a7b06e9155381e09..e25244018c8801f31f913c0af5aed526fdc6f49b
@@@ -28,7 -28,7 +28,7 @@@ import { authService } from '../../serv
  
  import { detailsPanelActions, loadDetails } from "../../store/details-panel/details-panel-action";
  import { contextMenuActions } from "../../store/context-menu/context-menu-actions";
 -import { sidePanelData, SidePanelIdentifiers } from '../../store/side-panel/side-panel-reducer';
 +import { SidePanelIdentifiers } from '../../store/side-panel/side-panel-reducer';
  import { ProjectResource } from '../../models/project';
  import { ResourceKind } from '../../models/resource';
  import { ContextMenu, ContextMenuKind } from "../../views-components/context-menu/context-menu";
@@@ -36,9 -36,6 +36,9 @@@ import { FavoritePanel, FAVORITE_PANEL_
  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 { CollectionPanel } from '../collection-panel/collection-panel';
 +import { loadCollection } from '../../store/collection-panel/collection-panel-action';
 +import { getCollectionUrl } from '../../models/collection';
  
  const drawerWidth = 240;
  const appBarHeight = 100;
@@@ -205,8 -202,8 +205,8 @@@ export const Workbench = withStyles(sty
                                          })}
                                          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));
+                                             this.props.dispatch<any>(loadDetails(itemId, ResourceKind.PROJECT));
+                                             this.props.dispatch<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
                                          }} />
                                  </SidePanel>
                              </Drawer>}
                                  <Switch>
                                      <Route path="/projects/:id" render={this.renderProjectPanel} />
                                      <Route path="/favorites" render={this.renderFavoritePanel} />
 +                                    <Route path="/collections/:id" render={this.renderCollectionPanel} />
                                  </Switch>
                              </div>
                              {user && <DetailsPanel />}
                  );
              }
  
-                 onItemRouteChange={(collectionId) => this.props.dispatch<any>(loadCollection(collectionId, ResourceKind.Collection))}
 +            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))}
                  onContextMenu={(event, item) => {
-                     const kind = item.kind === ResourceKind.Project ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
++
+                     const kind = item.kind === ResourceKind.PROJECT ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
                      this.openContextMenu(event, {
                          uuid: item.uuid,
                          name: item.name,
                      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));
 +                    switch (item.kind) {
-                         case ResourceKind.Collection:
++                        case ResourceKind.COLLECTION:
 +                            this.props.dispatch<any>(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));
 +                    }
++
                  }}
                  {...props} />
  
              renderFavoritePanel = (props: RouteComponentProps<{ id: string }>) => <FavoritePanel
                  onItemRouteChange={() => this.props.dispatch<any>(dataExplorerActions.REQUEST_ITEMS({ id: FAVORITE_PANEL_ID }))}
                  onContextMenu={(event, item) => {
-                     const kind = item.kind === ResourceKind.Project ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
+                     const kind = item.kind === ResourceKind.PROJECT ? ContextMenuKind.PROJECT : ContextMenuKind.RESOURCE;
                      this.openContextMenu(event, {
                          uuid: item.uuid,
                          name: item.name,
                      this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
                  }}
                  onItemDoubleClick={item => {
 -                    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));
 +                    switch (item.kind) {
-                         case ResourceKind.Collection:
++                        case ResourceKind.COLLECTION:
 +                            this.props.dispatch<any>(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>(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<any>(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_ACTIVE(SidePanelIdentifiers.PROJECTS));
 +                    }
++
                  }}
                  {...props} />
  
              mainAppBarActions: MainAppBarActionProps = {
                  onBreadcrumbClick: ({ itemId }: NavBreadcrumb) => {
                      this.props.dispatch<any>(setProjectItem(itemId, ItemMode.BOTH));
-                     this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
+                     this.props.dispatch<any>(loadDetails(itemId, ResourceKind.PROJECT));
                  },
                  onSearch: searchText => {
                      this.setState({ searchText });