Merge branch 'master'
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Sun, 16 Dec 2018 21:44:03 +0000 (22:44 +0100)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Sun, 16 Dec 2018 21:44:03 +0000 (22:44 +0100)
Feature #14505

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

1  2 
src/index.tsx
src/models/link.ts
src/routes/route-change-handlers.ts
src/routes/routes.ts
src/store/navigation/navigation-action.ts
src/store/store.ts
src/store/workbench/workbench-actions.ts
src/views-components/context-menu/context-menu.tsx
src/views-components/main-app-bar/account-menu.tsx
src/views/workbench/workbench.tsx

diff --cc src/index.tsx
index f64e076a892cbf6ef18a1b4a8cf087df11502ba8,e73f08c46ba8b48d2fab54bd5cbe0de89fb3b753..508fa7c3dad5cb140246352cb821b56c98d49d7a
@@@ -56,8 -56,7 +56,9 @@@ import { virtualMachineActionSet } fro
  import { userActionSet } from '~/views-components/context-menu/action-sets/user-action-set';
  import { computeNodeActionSet } from '~/views-components/context-menu/action-sets/compute-node-action-set';
  import { apiClientAuthorizationActionSet } from '~/views-components/context-menu/action-sets/api-client-authorization-action-set';
 +import { groupActionSet } from '~/views-components/context-menu/action-sets/group-action-set';
 +import { groupMemberActionSet } from '~/views-components/context-menu/action-sets/group-member-action-set';
+ import { linkActionSet } from '~/views-components/context-menu/action-sets/link-action-set';
  
  console.log(`Starting arvados [${getBuildInfo()}]`);
  
@@@ -79,10 -78,9 +80,11 @@@ addMenuActionSet(ContextMenuKind.SSH_KE
  addMenuActionSet(ContextMenuKind.VIRTUAL_MACHINE, virtualMachineActionSet);
  addMenuActionSet(ContextMenuKind.KEEP_SERVICE, keepServiceActionSet);
  addMenuActionSet(ContextMenuKind.USER, userActionSet);
+ addMenuActionSet(ContextMenuKind.LINK, linkActionSet);
  addMenuActionSet(ContextMenuKind.NODE, computeNodeActionSet);
  addMenuActionSet(ContextMenuKind.API_CLIENT_AUTHORIZATION, apiClientAuthorizationActionSet);
 +addMenuActionSet(ContextMenuKind.GROUPS, groupActionSet);
 +addMenuActionSet(ContextMenuKind.GROUP_MEMBER, groupMemberActionSet);
  
  fetchConfig()
      .then(({ config, apiHost }) => {
index 1798e4477634418248b4de38b399b121561df595,d931f7f21898b394b2b2efb73349838e533532a8..785d531cf7d609fec3af696d16c3fbb9028753a4
@@@ -2,8 -2,9 +2,8 @@@
  //
  // SPDX-License-Identifier: AGPL-3.0
  
- import { Resource, ResourceKind } from "./resource";
 -import { Resource } from "./resource";
  import { TagProperty } from "~/models/tag";
 -import { ResourceKind } from '~/models/resource';
++import { Resource, ResourceKind } from '~/models/resource';
  
  export interface LinkResource extends Resource {
      headUuid: string;
index cbfbfd381b55beae88e84c87e9f9621b39798ff5,655c806f3a3b0337cc1a89eccae6b7a29ddaa832..7b37509f90b94be0cd053e3052e52ef438bac8fc
@@@ -34,8 -37,9 +37,11 @@@ const handleLocationChange = (store: Ro
      const apiClientAuthorizationsMatch = Routes.matchApiClientAuthorizationsRoute(pathname);
      const myAccountMatch = Routes.matchMyAccountRoute(pathname);
      const userMatch = Routes.matchUsersRoute(pathname);
 +    const groupsMatch = Routes.matchGroupsRoute(pathname);
 +    const groupDetailsMatch = Routes.matchGroupDetailsRoute(pathname);
+     const linksMatch = Routes.matchLinksRoute(pathname);
+     store.dispatch(dialogActions.CLOSE_ALL_DIALOGS());
  
      if (projectMatch) {
          store.dispatch(WorkbenchActions.loadProject(projectMatch.params.id));
          store.dispatch(WorkbenchActions.loadApiClientAuthorizations);
      } else if (myAccountMatch) {
          store.dispatch(WorkbenchActions.loadMyAccount);
-     }else if (userMatch) {
+     } else if (userMatch) {
          store.dispatch(WorkbenchActions.loadUsers);
 +    } else if (groupsMatch) {
 +        store.dispatch(WorkbenchActions.loadGroupsPanel);
 +    } else if (groupDetailsMatch) {
 +        store.dispatch(WorkbenchActions.loadGroupDetailsPanel(groupDetailsMatch.params.id));
+     } else if (linksMatch) {
+         store.dispatch(WorkbenchActions.loadLinks);
      }
  };
index 6d44725ce1bc0406d4cc446905f5745d1650a890,05f6663fe3c2bbb8021423249e5e045263ab3be7..661a065eb35848bbfaef168d58af2781960f92ad
@@@ -28,8 -30,7 +30,9 @@@ export const Routes = 
      COMPUTE_NODES: `/nodes`,
      USERS: '/users',
      API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
 +    GROUPS: '/groups',
 +    GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
+     LINKS: '/links'
  };
  
  export const getResourceUrl = (uuid: string) => {
@@@ -113,8 -118,5 +122,11 @@@ export const matchComputeNodesRoute = (
  export const matchApiClientAuthorizationsRoute = (route: string) =>
      matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
  
 -    matchPath(route, { path: Routes.LINKS });
 +export const matchGroupsRoute = (route: string) =>
 +    matchPath(route, { path: Routes.GROUPS });
 +
 +export const matchGroupDetailsRoute = (route: string) =>
 +    matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
++    
+ export const matchLinksRoute = (route: string) =>
++    matchPath(route, { path: Routes.LINKS });
index 9aa4a32c7a07537d435c695186aaf5d15e6129a1,92443c02dc1cf90800a50418d167c72f253d92b5..c53c55e89287212f91715481a8998fe429fddaf2
@@@ -81,6 -84,4 +87,8 @@@ export const navigateToUsers = push(Rou
  
  export const navigateToApiClientAuthorizations = push(Routes.API_CLIENT_AUTHORIZATIONS);
  
 -export const navigateToLinks = push(Routes.LINKS);
 +export const navigateToGroups = push(Routes.GROUPS);
 +
 +export const navigateToGroupDetails = compose(push, getGroupUrl);
++
++export const navigateToLinks = push(Routes.LINKS);
index ad70868e0c62a830367f8e289337abd637915de8,792224d240f7434595f409db117a85744fbf528a..3aef8f500013fb301d6e6089296b9a05909a561e
@@@ -50,10 -50,8 +50,12 @@@ import { UserMiddlewareService } from '
  import { USERS_PANEL_ID } from '~/store/users/users-actions';
  import { computeNodesReducer } from '~/store/compute-nodes/compute-nodes-reducer';
  import { apiClientAuthorizationsReducer } from '~/store/api-client-authorizations/api-client-authorizations-reducer';
 +import { GroupsPanelMiddlewareService } from '~/store/groups-panel/groups-panel-middleware-service';
 +import { GROUPS_PANEL_ID } from '~/store/groups-panel/groups-panel-actions';
 +import { GroupDetailsPanelMiddlewareService } from '~/store/group-details-panel/group-details-panel-middleware-service';
 +import { GROUP_DETAILS_PANEL_ID } from '~/store/group-details-panel/group-details-panel-actions';
+ import { LINK_PANEL_ID } from '~/store/link-panel/link-panel-actions';
+ import { LinkMiddlewareService } from '~/store/link-panel/link-panel-middleware-service';
  
  const composeEnhancers =
      (process.env.NODE_ENV === 'development' &&
@@@ -88,13 -86,9 +90,16 @@@ export function configureStore(history
      const userPanelMiddleware = dataExplorerMiddleware(
          new UserMiddlewareService(services, USERS_PANEL_ID)
      );
 +    const groupsPanelMiddleware = dataExplorerMiddleware(
 +        new GroupsPanelMiddlewareService(services, GROUPS_PANEL_ID)
 +    );
 +    const groupDetailsPanelMiddleware = dataExplorerMiddleware(
 +        new GroupDetailsPanelMiddlewareService(services, GROUP_DETAILS_PANEL_ID)
 +    );
 +
+     const linkPanelMiddleware = dataExplorerMiddleware(
+         new LinkMiddlewareService(services, LINK_PANEL_ID)
+     );
      const middlewares: Middleware[] = [
          routerMiddleware(history),
          thunkMiddleware.withExtraArgument(services),
          sharedWithMePanelMiddleware,
          workflowPanelMiddleware,
          userPanelMiddleware,
 +        groupsPanelMiddleware,
 +        groupDetailsPanelMiddleware,
+         linkPanelMiddleware
      ];
      const enhancer = composeEnhancers(applyMiddleware(...middlewares));
      return createStore(rootReducer, enhancer);
index e185e8cfd471d48ddc6697aee6f69ba8bd9351a6,85540f0b434ac90826b93aba3561f726d3325578..af2afab29f53ba33b2a06bed69e6174ddf085e9b
@@@ -100,8 -98,7 +102,9 @@@ export const loadWorkbench = () =
                  dispatch(workflowPanelActions.SET_COLUMNS({ columns: workflowPanelColumns }));
                  dispatch(searchResultsPanelActions.SET_COLUMNS({ columns: searchResultsPanelColumns }));
                  dispatch(userBindedActions.SET_COLUMNS({ columns: userPanelColumns }));
 +                dispatch(groupPanelActions.GroupsPanelActions.SET_COLUMNS({ columns: groupsPanelColumns }));
 +                dispatch(groupDetailsPanelActions.GroupDetailsPanelActions.SET_COLUMNS({columns: groupDetailsPanelColumns}));
+                 dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
                  dispatch<any>(initSidePanelTree());
                  if (router.location) {
                      const match = matchRootRoute(router.location.pathname);
index e148a78a8c2c13086845eefa6caf9c8a3ed25c03,a9200ebb363df15541e6da5abe641c8200d98309..4ce2f5214d5f337d2488f0acb232d6d1ea5f1b0d
@@@ -75,7 -75,6 +75,8 @@@ export enum ContextMenuKind 
      VIRTUAL_MACHINE = "VirtualMachine",
      KEEP_SERVICE = "KeepService",
      USER = "User",
-     GROUP_MEMBER = "GroupMember"
 +    NODE = "Node",
 +    GROUPS = "Group",
 -    NODE = "Node"
++    GROUP_MEMBER = "GroupMember",
+     LINK = "Link",
  }
index cb8fd5665c692f62aa2afec07c7c6a7d3c07db44,1609aafa0849a277432f343dbe39e788de788bf7..a1116540226a5e2d543fd48aba1718468481e55a
@@@ -12,12 -12,8 +12,13 @@@ import { logout } from '~/store/auth/au
  import { RootState } from "~/store/store";
  import { openCurrentTokenDialog } from '~/store/current-token-dialog/current-token-dialog-actions';
  import { openRepositoriesPanel } from "~/store/repositories/repositories-actions";
- import { 
-     navigateToSshKeys, navigateToKeepServices, navigateToComputeNodes,
-     navigateToApiClientAuthorizations, navigateToMyAccount, navigateToGroups
++import {
++    navigateToKeepServices, navigateToComputeNodes,
++    navigateToApiClientAuthorizations, navigateToGroups
 +} from '~/store/navigation/navigation-action';
- import { openVirtualMachines } from "~/store/virtual-machines/virtual-machines-actions";
 +import { navigateToUsers } from '~/store/navigation/navigation-action';
+ import { navigateToSshKeysUser, navigateToMyAccount } from '~/store/navigation/navigation-action';
+ import { openUserVirtualMachines } from "~/store/virtual-machines/virtual-machines-actions";
  
  interface AccountMenuProps {
      user?: User;
@@@ -37,15 -33,10 +38,15 @@@ export const AccountMenu = connect(mapS
                  <MenuItem>
                      {getUserFullname(user)}
                  </MenuItem>
-                 <MenuItem onClick={() => dispatch(openVirtualMachines())}>Virtual Machines</MenuItem>
-                 <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>
+                 <MenuItem onClick={() => dispatch(openUserVirtualMachines())}>Virtual Machines</MenuItem>
+                 {!user.isAdmin && <MenuItem onClick={() => dispatch(openRepositoriesPanel())}>Repositories</MenuItem>}
                  <MenuItem onClick={() => dispatch(openCurrentTokenDialog)}>Current token</MenuItem>
-                 <MenuItem onClick={() => dispatch(navigateToSshKeys)}>Ssh Keys</MenuItem>
 +                <MenuItem onClick={() => dispatch(navigateToUsers)}>Users</MenuItem>
-                 { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToGroups)}>Groups</MenuItem> }
-                 { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToApiClientAuthorizations)}>Api Tokens</MenuItem> }
-                 { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToKeepServices)}>Keep Services</MenuItem> }
-                 { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToComputeNodes)}>Compute Nodes</MenuItem> }
++                {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToGroups)}>Groups</MenuItem>}
++                {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToApiClientAuthorizations)}>Api Tokens</MenuItem>}
++                {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToKeepServices)}>Keep Services</MenuItem>}
++                {user.isAdmin && <MenuItem onClick={() => dispatch(navigateToComputeNodes)}>Compute Nodes</MenuItem>}
+                 <MenuItem onClick={() => dispatch(navigateToSshKeysUser)}>Ssh Keys</MenuItem>
                  <MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
                  <MenuItem onClick={() => dispatch(logout())}>Logout</MenuItem>
              </DropdownMenu>
index 695834a69bf1aecb8ebcfaa5196ebc373a81e744,025540e22ed89c6bab5ecd1a9dee6ddc11281a94..bff328e8c8c6ff448bc271d36068925a8b0cc81d
@@@ -160,8 -158,7 +166,9 @@@ export const WorkbenchPanel 
                                  <Route path={Routes.COMPUTE_NODES} component={ComputeNodePanel} />
                                  <Route path={Routes.API_CLIENT_AUTHORIZATIONS} component={ApiClientAuthorizationPanel} />
                                  <Route path={Routes.MY_ACCOUNT} component={MyAccountPanel} />
 +                                <Route path={Routes.GROUPS} component={GroupsPanel} />
 +                                <Route path={Routes.GROUP_DETAILS} component={GroupDetailsPanel} />
+                                 <Route path={Routes.LINKS} component={LinkPanel} />
                              </Switch>
                          </Grid>
                      </Grid>
              <ProjectPropertiesDialog />
              <RemoveApiClientAuthorizationDialog />
              <RemoveComputeNodeDialog />
 +            <RemoveGroupDialog />
 +            <RemoveGroupMemberDialog />
              <RemoveKeepServiceDialog />
+             <RemoveLinkDialog />
              <RemoveProcessDialog />
              <RemoveRepositoryDialog />
              <RemoveSshKeyDialog />