[ARVADOS-WORKBENCH2] updated: 1.3.0-66-g7a6743e

Git user git at public.curoverse.com
Fri Dec 7 04:43:59 EST 2018


Summary of changes:
 package.json                                       |   2 +-
 src/common/formatters.ts                           |  11 +
 src/common/objects.ts                              |  18 ++
 src/components/autocomplete/autocomplete.tsx       |  60 ++++-
 src/components/text-field/text-field.tsx           |   4 +-
 src/index.tsx                                      |   2 +
 src/models/node.ts                                 |  37 +++
 src/models/resource.ts                             |   6 +-
 src/models/search-bar.ts                           |  11 +-
 src/models/user.ts                                 |  22 +-
 src/routes/route-change-handlers.ts                |  83 +++---
 src/routes/routes.ts                               |   8 +
 src/services/api/filter-builder.ts                 |   8 +-
 src/services/auth-service/auth-service.ts          |  23 +-
 .../node-service.ts}                               |   8 +-
 src/services/search-service/search-service.ts      |   2 +-
 src/services/services.ts                           |   3 +
 src/store/advanced-tab/advanced-tab.ts             |  57 +++-
 src/store/auth/auth-action.ts                      |   7 +-
 src/store/auth/auth-reducer.test.ts                |   4 +
 .../collection-panel-files-actions.ts              |   7 +-
 src/store/collections/collection-copy-actions.ts   |   7 +-
 src/store/collections/collection-create-actions.ts |   6 +-
 src/store/collections/collection-move-actions.ts   |   4 +-
 .../collections/collection-partial-copy-actions.ts |   4 +-
 src/store/collections/collection-update-actions.ts |   4 +-
 .../compute-nodes-actions.ts}                      |  46 ++--
 src/store/compute-nodes/compute-nodes-reducer.ts   |  17 ++
 src/store/context-menu/context-menu-actions.ts     |  12 +
 src/store/my-account/my-account-panel-actions.ts   |  31 +++
 src/store/navigation/navigation-action.ts          |   6 +-
 src/store/processes/process-move-actions.ts        |   6 +-
 src/store/processes/process-update-actions.ts      |   6 +-
 src/store/projects/project-create-actions.ts       |   6 +-
 src/store/projects/project-move-actions.ts         |   6 +-
 src/store/projects/project-update-actions.ts       |   4 +-
 src/store/repositories/repositories-actions.ts     |  10 +-
 src/store/search-bar/search-bar-actions.test.ts    | 137 ++++++++++
 src/store/search-bar/search-bar-actions.ts         | 297 +++++++++++++++++++--
 src/store/search-bar/search-bar-reducer.ts         |   8 +-
 src/store/search-bar/search-bar-tree-actions.ts    | 101 +++++++
 .../search-results-middleware-service.ts           |   2 +-
 src/store/store.ts                                 |   4 +-
 src/store/users/users-actions.ts                   |   6 +-
 src/store/workbench/workbench-actions.ts           |  14 +-
 src/validators/validators.tsx                      |   2 +
 .../compute-nodes-dialog/attributes-dialog.tsx     | 115 ++++++++
 .../remove-dialog.tsx}                             |  10 +-
 ...ey-action-set.ts => compute-node-action-set.ts} |  10 +-
 src/views-components/context-menu/context-menu.tsx |   3 +-
 .../form-fields/search-bar-form-fields.tsx         |  16 +-
 src/views-components/main-app-bar/account-menu.tsx |   7 +-
 .../main-content-bar/main-content-bar.tsx          |   9 +-
 .../search-bar-advanced-properties-view.tsx        |  19 +-
 .../search-bar/search-bar-advanced-view.tsx        |  20 +-
 .../search-bar/search-bar-basic-view.tsx           |  11 +-
 .../search-bar/search-bar-save-queries.tsx         |   7 +-
 .../search-bar/search-bar-view.tsx                 |  47 +++-
 src/views-components/search-bar/search-bar.tsx     |  10 +-
 .../sharing-management-form-component.tsx          |  10 +-
 .../compute-node-panel/compute-node-panel-root.tsx |  85 ++++++
 .../compute-node-panel/compute-node-panel.tsx      |  29 ++
 .../keep-service-panel/keep-service-panel.tsx      |   1 -
 .../my-account-panel/my-account-panel-root.tsx     | 161 +++++++++++
 src/views/my-account-panel/my-account-panel.tsx    |  26 ++
 src/views/workbench/workbench.tsx                  |  10 +-
 yarn.lock                                          |   8 +-
 67 files changed, 1502 insertions(+), 241 deletions(-)
 create mode 100644 src/common/objects.ts
 create mode 100644 src/models/node.ts
 copy src/services/{workflow-service/workflow-service.ts => node-service/node-service.ts} (66%)
 copy src/store/{keep-services/keep-services-actions.ts => compute-nodes/compute-nodes-actions.ts} (52%)
 create mode 100644 src/store/compute-nodes/compute-nodes-reducer.ts
 create mode 100644 src/store/my-account/my-account-panel-actions.ts
 create mode 100644 src/store/search-bar/search-bar-actions.test.ts
 create mode 100644 src/store/search-bar/search-bar-tree-actions.ts
 create mode 100644 src/views-components/compute-nodes-dialog/attributes-dialog.tsx
 copy src/views-components/{process-remove-dialog/process-remove-dialog.tsx => compute-nodes-dialog/remove-dialog.tsx} (65%)
 copy src/views-components/context-menu/action-sets/{ssh-key-action-set.ts => compute-node-action-set.ts} (69%)
 create mode 100644 src/views/compute-node-panel/compute-node-panel-root.tsx
 create mode 100644 src/views/compute-node-panel/compute-node-panel.tsx
 create mode 100644 src/views/my-account-panel/my-account-panel-root.tsx
 create mode 100644 src/views/my-account-panel/my-account-panel.tsx

       via  7a6743eacc2ef5ce99ceca5acbaff8b00fb7e7d1 (commit)
       via  4a055bfc98a5fc05cc311e2de1ab2213eec5497e (commit)
       via  663ddeefc6a120d6dba213b1392805146d659721 (commit)
       via  fa1f1c301a58d163e452ca9d14d326934a403f17 (commit)
       via  a29cf3418b6c301c0f531cecb7db4c721e7eb014 (commit)
       via  5ecee04a6186627bd1875b2dabcc31489569ff71 (commit)
       via  f9dafeec8d45f0cb19d71326b7fa877891a7eb9e (commit)
       via  f83344568cb070f716527288abe88a4ec5b0c305 (commit)
       via  88bc5b67b64644ac164698f35bcd867dbb463cd6 (commit)
       via  6d7c7e9ed34aec3d30324ff544b17b7e39872f54 (commit)
       via  425cafe27cbfd822af1e7640c2a18efb3796d4c6 (commit)
       via  88d3dba97a29f7188c3bda8be965fb18f97f4b4d (commit)
       via  025c6ba35cb5b7e7b386e3cbc7bee59c4a652b36 (commit)
       via  a1e2b8ba77e4a7273940a3fc542bc42e282618a7 (commit)
       via  e8e0182d65a74b1a222127eb8b36f31a906b14c8 (commit)
       via  ceda57340f34d71fb4289b344e6ca839db06f5e7 (commit)
       via  e5e090c801a015f04c04327a176faf54ba3650b7 (commit)
       via  e032ee615c409d084d84e35ae6d572999105dd22 (commit)
       via  dfef56fe2729c6cf89cb51aa40438e3adae698b0 (commit)
       via  a738a3bda2cd15740388f97488aaeb04edfd2385 (commit)
       via  85d29bbab95a2c63314a5f637503548106c56de6 (commit)
       via  b7a4d46fe2b011cdb6e38ed42e9f886fee8290b8 (commit)
       via  4ea2ff188ec745966387ce8bbe14880bfeede863 (commit)
       via  519b431a41a9ab4815a1e4180ee78395b74a85de (commit)
       via  7e323d0c3e6734e6ca698c6bffcb9c24ef5acd13 (commit)
       via  92dd5d32b573b5c90f3ce72dc207f6d0e7f21178 (commit)
       via  1e18043c06c85a015a90d32b3da167eebb760b18 (commit)
       via  438ecfac2b8ef24f767bbca14d9004a9ec06c1b5 (commit)
       via  52b507cead2443e6566fb8679df71ef9cf8dbe5c (commit)
       via  2b3f667039ba2e7efe0852d58ae2c62899b773f0 (commit)
       via  78b19f14709d84ba099f36a6b11b4fd64912e039 (commit)
       via  2340918b3b75be5e9c60ced6136265216eac2d74 (commit)
       via  56ee0a472ab8c77df51f6bb19d616d5f81ffde96 (commit)
       via  89c3c647797787377f4d950b38d320ee3b28e92c (commit)
       via  72b6c853b95b1ef3da2a0beca3a31e4838a17896 (commit)
       via  34399d176adae18bd42d70129c0a51f740afeb8e (commit)
      from  0c0daef87be8abcbcc3498d817e453d7336554f8 (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 7a6743eacc2ef5ce99ceca5acbaff8b00fb7e7d1
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date:   Fri Dec 7 10:43:40 2018 +0100

    deleted-unnecessary-code
    
    Feature #14504
    
    Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>

diff --git a/src/store/users/users-actions.ts b/src/store/users/users-actions.ts
index f39c753..64c3646 100644
--- a/src/store/users/users-actions.ts
+++ b/src/store/users/users-actions.ts
@@ -59,11 +59,7 @@ export const createUser = (user: UserCreateFormDialogData) =>
             dispatch(userBindedActions.REQUEST_ITEMS());
             return newUser;
         } catch (e) {
-            const error = getCommonResourceServiceError(e);
-            if (error === CommonResourceServiceError.NAME_HAS_ALREADY_BEEN_TAKEN) {
-                dispatch(stopSubmit(USER_CREATE_FORM_NAME, { name: 'User with the same name already exists.' }));
-            }
-            return undefined;
+            return ;
         }
     };
 

commit 4a055bfc98a5fc05cc311e2de1ab2213eec5497e
Merge: 0c0daef 663ddee
Author: Pawel Kowalczyk <pawel.kowalczyk at contractors.roche.com>
Date:   Fri Dec 7 10:21:57 2018 +0100

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

diff --cc src/index.tsx
index 96df16c,fbd6c9a..87af8f1
--- a/src/index.tsx
+++ b/src/index.tsx
@@@ -53,7 -53,7 +53,8 @@@ import { sshKeyActionSet } from '~/view
  import { keepServiceActionSet } from '~/views-components/context-menu/action-sets/keep-service-action-set';
  import { loadVocabulary } from '~/store/vocabulary/vocabulary-actions';
  import { virtualMachineActionSet } from '~/views-components/context-menu/action-sets/virtual-machine-action-set';
 +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';
  
  console.log(`Starting arvados [${getBuildInfo()}]`);
  
@@@ -74,7 -74,7 +75,8 @@@ addMenuActionSet(ContextMenuKind.REPOSI
  addMenuActionSet(ContextMenuKind.SSH_KEY, sshKeyActionSet);
  addMenuActionSet(ContextMenuKind.VIRTUAL_MACHINE, virtualMachineActionSet);
  addMenuActionSet(ContextMenuKind.KEEP_SERVICE, keepServiceActionSet);
 +addMenuActionSet(ContextMenuKind.USER, userActionSet);
+ addMenuActionSet(ContextMenuKind.NODE, computeNodeActionSet);
  
  fetchConfig()
      .then(({ config, apiHost }) => {
diff --cc src/routes/route-change-handlers.ts
index 1cea993,68de310..5b281b8
--- a/src/routes/route-change-handlers.ts
+++ b/src/routes/route-change-handlers.ts
@@@ -24,54 -15,57 +15,60 @@@ export const addRouteChangeHandlers = (
  };
  
  const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
-     const rootMatch = matchRootRoute(pathname);
-     const projectMatch = matchProjectRoute(pathname);
-     const collectionMatch = matchCollectionRoute(pathname);
-     const favoriteMatch = matchFavoritesRoute(pathname);
-     const trashMatch = matchTrashRoute(pathname);
-     const processMatch = matchProcessRoute(pathname);
-     const processLogMatch = matchProcessLogRoute(pathname);
-     const repositoryMatch = matchRepositoriesRoute(pathname);
-     const searchResultsMatch = matchSearchResultsRoute(pathname);
-     const sharedWithMeMatch = matchSharedWithMeRoute(pathname);
-     const runProcessMatch = matchRunProcessRoute(pathname);
-     const virtualMachineMatch = matchVirtualMachineRoute(pathname);
-     const workflowMatch = matchWorkflowRoute(pathname);
-     const sshKeysMatch = matchSshKeysRoute(pathname);
-     const keepServicesMatch = matchKeepServicesRoute(pathname);
-     const userMatch = matchUsersRoute(pathname);
+     const rootMatch = Routes.matchRootRoute(pathname);
+     const projectMatch = Routes.matchProjectRoute(pathname);
+     const collectionMatch = Routes.matchCollectionRoute(pathname);
+     const favoriteMatch = Routes.matchFavoritesRoute(pathname);
+     const trashMatch = Routes.matchTrashRoute(pathname);
+     const processMatch = Routes.matchProcessRoute(pathname);
+     const processLogMatch = Routes.matchProcessLogRoute(pathname);
+     const repositoryMatch = Routes.matchRepositoriesRoute(pathname);
+     const searchResultsMatch = Routes.matchSearchResultsRoute(pathname);
+     const sharedWithMeMatch = Routes.matchSharedWithMeRoute(pathname);
+     const runProcessMatch = Routes.matchRunProcessRoute(pathname);
+     const virtualMachineMatch = Routes.matchVirtualMachineRoute(pathname);
+     const workflowMatch = Routes.matchWorkflowRoute(pathname);
+     const sshKeysMatch = Routes.matchSshKeysRoute(pathname);
+     const keepServicesMatch = Routes.matchKeepServicesRoute(pathname);
+     const computeNodesMatch = Routes.matchComputeNodesRoute(pathname);
+     const myAccountMatch = Routes.matchMyAccountRoute(pathname);
++    const userMatch = Routes.matchUsersRoute(pathname);
  
      if (projectMatch) {
-         store.dispatch(loadProject(projectMatch.params.id));
+         store.dispatch(WorkbenchActions.loadProject(projectMatch.params.id));
      } else if (collectionMatch) {
-         store.dispatch(loadCollection(collectionMatch.params.id));
+         store.dispatch(WorkbenchActions.loadCollection(collectionMatch.params.id));
      } else if (favoriteMatch) {
-         store.dispatch(loadFavorites());
+         store.dispatch(WorkbenchActions.loadFavorites());
      } else if (trashMatch) {
-         store.dispatch(loadTrash());
+         store.dispatch(WorkbenchActions.loadTrash());
      } else if (processMatch) {
-         store.dispatch(loadProcess(processMatch.params.id));
+         store.dispatch(WorkbenchActions.loadProcess(processMatch.params.id));
      } else if (processLogMatch) {
-         store.dispatch(loadProcessLog(processLogMatch.params.id));
+         store.dispatch(WorkbenchActions.loadProcessLog(processLogMatch.params.id));
      } else if (rootMatch) {
          store.dispatch(navigateToRootProject);
      } else if (sharedWithMeMatch) {
-         store.dispatch(loadSharedWithMe);
+         store.dispatch(WorkbenchActions.loadSharedWithMe);
      } else if (runProcessMatch) {
-         store.dispatch(loadRunProcess);
+         store.dispatch(WorkbenchActions.loadRunProcess);
      } else if (workflowMatch) {
-         store.dispatch(loadWorkflow);
+         store.dispatch(WorkbenchActions.loadWorkflow);
      } else if (searchResultsMatch) {
-         store.dispatch(loadSearchResults);
+         store.dispatch(WorkbenchActions.loadSearchResults);
      } else if (virtualMachineMatch) {
-         store.dispatch(loadVirtualMachines);
+         store.dispatch(WorkbenchActions.loadVirtualMachines);
      } else if(repositoryMatch) {
-         store.dispatch(loadRepositories);
+         store.dispatch(WorkbenchActions.loadRepositories);
      } else if (sshKeysMatch) {
-         store.dispatch(loadSshKeys);
+         store.dispatch(WorkbenchActions.loadSshKeys);
      } else if (keepServicesMatch) {
-         store.dispatch(loadKeepServices);
-     } else if (userMatch) {
-         store.dispatch(loadUsers);
+         store.dispatch(WorkbenchActions.loadKeepServices);
+     } else if (computeNodesMatch) {
+         store.dispatch(WorkbenchActions.loadComputeNodes);
+     } else if (myAccountMatch) {
+         store.dispatch(WorkbenchActions.loadMyAccount);
++    }else if (userMatch) {
++        store.dispatch(WorkbenchActions.loadUsers);
      }
  };
diff --cc src/routes/routes.ts
index 2c4337d,71d920a..dabb9bf
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@@ -23,8 -23,9 +23,10 @@@ export const Routes = 
      WORKFLOWS: '/workflows',
      SEARCH_RESULTS: '/search-results',
      SSH_KEYS: `/ssh-keys`,
+     MY_ACCOUNT: '/my-account',
      KEEP_SERVICES: `/keep-services`,
 -    COMPUTE_NODES: `/nodes`
++    COMPUTE_NODES: `/nodes`,
 +    USERS: '/users'
  };
  
  export const getResourceUrl = (uuid: string) => {
@@@ -94,5 -98,5 +99,8 @@@ export const matchMyAccountRoute = (rou
  export const matchKeepServicesRoute = (route: string) =>
      matchPath(route, { path: Routes.KEEP_SERVICES });
  
 +export const matchUsersRoute = (route: string) =>
 +    matchPath(route, { path: Routes.USERS });
++
+ export const matchComputeNodesRoute = (route: string) =>
 -    matchPath(route, { path: Routes.COMPUTE_NODES });
++    matchPath(route, { path: Routes.COMPUTE_NODES });
diff --cc src/store/advanced-tab/advanced-tab.ts
index 67d1394,6b20f8b..4da4d7e
--- a/src/store/advanced-tab/advanced-tab.ts
+++ b/src/store/advanced-tab/advanced-tab.ts
@@@ -73,7 -74,7 +74,8 @@@ enum ResourcePrefix 
      AUTORIZED_KEYS = 'authorized_keys',
      VIRTUAL_MACHINES = 'virtual_machines',
      KEEP_SERVICES = 'keep_services',
-     USERS = 'users'
++    USERS = 'users',
+     COMPUTE_NODES = 'nodes'
  }
  
  enum KeepServiceData {
@@@ -81,14 -82,14 +83,19 @@@
      CREATED_AT = 'created_at'
  }
  
 +enum UserData {
 +    USER = 'user',
 +    USERNAME = 'username'
 +}
 +
- type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData | UserData;
+ enum ComputeNodeData {
+     COMPUTE_NODE = 'node',
+     PROPERTIES = 'properties'
+ }
+ 
 -type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData | ComputeNodeData;
++type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData | ComputeNodeData | UserData;
  type AdvanceResourcePrefix = GroupContentsResourcePrefix | ResourcePrefix;
- type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | UserResource | undefined;
 -type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | NodeResource | undefined;
++type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | NodeResource | UserResource | undefined;
  
  export const openAdvancedTabDialog = (uuid: string) =>
      async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
@@@ -199,27 -200,21 +206,42 @@@
                  });
                  dispatch<any>(initAdvancedTabDialog(advanceDataKeepService));
                  break;
 +            case ResourceKind.USER:
 +                const { resources } = getState();
 +                const data = getResource<UserResource>(uuid)(resources);
 +                const metadata = await services.linkService.list({
 +                    filters: new FilterBuilder()
 +                        .addEqual('headUuid', uuid)
 +                        .getFilters()
 +                });
 +                const advanceDataUser = advancedTabData({
 +                    uuid,
 +                    metadata,
 +                    user: '',
 +                    apiResponseKind: userApiResponse,
 +                    data,
 +                    resourceKind: UserData.USER,
 +                    resourcePrefix: ResourcePrefix.USERS,
 +                    resourceKindProperty: UserData.USERNAME,
 +                    property: data!.username
 +                });
 +                dispatch<any>(initAdvancedTabDialog(advanceDataUser));
 +                break;
+             case ResourceKind.NODE:
+                 const dataComputeNode = getState().computeNodes.find(node => node.uuid === uuid);
+                 const advanceDataComputeNode = advancedTabData({
+                     uuid,
+                     metadata: '',
+                     user: '',
+                     apiResponseKind: computeNodeApiResponse,
+                     data: dataComputeNode,
+                     resourceKind: ComputeNodeData.COMPUTE_NODE,
+                     resourcePrefix: ResourcePrefix.COMPUTE_NODES,
+                     resourceKindProperty: ComputeNodeData.PROPERTIES,
+                     property: dataComputeNode!.properties
+                 });
+                 dispatch<any>(initAdvancedTabDialog(advanceDataComputeNode));
+                 break;
              default:
                  dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Could not open advanced tab for this resource.", hideDuration: 2000, kind: SnackbarKind.ERROR }));
          }
@@@ -470,26 -465,27 +492,51 @@@ const keepServiceApiResponse = (apiResp
      return response;
  };
  
 +const userApiResponse = (apiResponse: UserResource) => {
 +    const {
 +        uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid,
 +        email, firstName, lastName, identityUrl, isActive, isAdmin, prefs, defaultOwnerUuid, username
 +    } = apiResponse;
 +    const response = `"uuid": "${uuid}",
 +"owner_uuid": "${ownerUuid}",
 +"created_at": "${createdAt}",
 +"modified_by_client_uuid": ${stringify(modifiedByClientUuid)},
 +"modified_by_user_uuid": ${stringify(modifiedByUserUuid)},
 +"modified_at": ${stringify(modifiedAt)},
 +"email": "${email}",
 +"first_name": "${firstName}",
 +"last_name": "${stringify(lastName)}",
 +"identity_url": "${identityUrl}",
 +"is_active": "${isActive},
 +"is_admin": "${isAdmin},
 +"prefs": "${stringifyObject(prefs)},
 +"default_owner_uuid": "${defaultOwnerUuid},
 +"username": "${username}"`;
 +
 +    return response;
++};
++
+ const computeNodeApiResponse = (apiResponse: NodeResource) => {
+     const {
+         uuid, slotNumber, hostname, domain, ipAddress, firstPingAt, lastPingAt, jobUuid,
+         ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid,
+         properties, info
+     } = apiResponse;
+     const response = `"uuid": "${uuid}",
+ "owner_uuid": "${ownerUuid}",
+ "modified_by_client_uuid": ${stringify(modifiedByClientUuid)},
+ "modified_by_user_uuid": ${stringify(modifiedByUserUuid)},
+ "modified_at": ${stringify(modifiedAt)},
+ "created_at": "${createdAt}",
+ "slot_number": "${stringify(slotNumber)}",
+ "hostname": "${stringify(hostname)}",
+ "domain": "${stringify(domain)}",
+ "ip_address": "${stringify(ipAddress)}",
+ "first_ping_at": "${stringify(firstPingAt)}",
+ "last_ping_at": "${stringify(lastPingAt)}",
+ "job_uuid": "${stringify(jobUuid)}",
+ "properties": "${JSON.stringify(properties, null, 4)}",
+ "info": "${JSON.stringify(info, null, 4)}"`;
+ 
+     return response;
  };
diff --cc src/store/navigation/navigation-action.ts
index 4ee2210,a365272..bae1689
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@@ -68,6 -68,8 +68,10 @@@ export const navigateToRepositories = p
  
  export const navigateToSshKeys= push(Routes.SSH_KEYS);
  
+ export const navigateToMyAccount = push(Routes.MY_ACCOUNT);
+ 
  export const navigateToKeepServices = push(Routes.KEEP_SERVICES);
  
- export const navigateToUsers = push(Routes.USERS);
 -export const navigateToComputeNodes = push(Routes.COMPUTE_NODES);
++export const navigateToComputeNodes = push(Routes.COMPUTE_NODES);
++
++export const navigateToUsers = push(Routes.USERS);
diff --cc src/store/store.ts
index d04775f,321a19b..1862d6f
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@@ -46,8 -46,7 +46,9 @@@ import { resourcesDataReducer } from "~
  import { virtualMachinesReducer } from "~/store/virtual-machines/virtual-machines-reducer";
  import { repositoriesReducer } from '~/store/repositories/repositories-reducer';
  import { keepServicesReducer } from '~/store/keep-services/keep-services-reducer';
 +import { UserMiddlewareService } from '~/store/users/user-panel-middleware-service';
 +import { USERS_PANEL_ID } from '~/store/users/users-actions';
+ import { computeNodesReducer } from '~/store/compute-nodes/compute-nodes-reducer';
  
  const composeEnhancers =
      (process.env.NODE_ENV === 'development' &&
diff --cc src/store/workbench/workbench-actions.ts
index e7fbd14,49c50f2..d33bdaf
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@@ -57,8 -58,7 +58,9 @@@ import { searchResultsPanelColumns } fr
  import { loadVirtualMachinesPanel } from '~/store/virtual-machines/virtual-machines-actions';
  import { loadRepositoriesPanel } from '~/store/repositories/repositories-actions';
  import { loadKeepServicesPanel } from '~/store/keep-services/keep-services-actions';
 +import { loadUsersPanel, userBindedActions } from '~/store/users/users-actions';
 +import { userPanelColumns } from '~/views/user-panel/user-panel';
+ import { loadComputeNodesPanel } from '~/store/compute-nodes/compute-nodes-actions';
  
  export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
  
@@@ -130,10 -130,7 +132,10 @@@ export const loadProject = (uuid: strin
              const userUuid = services.authService.getUuid();
              dispatch(setIsProjectPanelTrashed(false));
              if (userUuid) {
-                 if (extractUuidKind(uuid) === ResourceKind.USER && userUuid!==uuid) {
 -                if (userUuid !== uuid) {
++                if (extractUuidKind(uuid) === ResourceKind.USER && userUuid !== uuid) {
 +                    // Load another users home projects
 +                    dispatch(finishLoadingProject(uuid));
 +                } else if (userUuid !== uuid) {
                      const match = await loadGroupContentsResource({ uuid, userUuid, services });
                      match({
                          OWNED: async project => {
@@@ -421,12 -423,11 +428,17 @@@ export const loadKeepServices = handleF
          await dispatch(loadKeepServicesPanel());
      });
  
 +export const loadUsers = handleFirstTimeLoad(
 +    async (dispatch: Dispatch<any>) => {
 +        await dispatch(loadUsersPanel());
 +        dispatch(setBreadcrumbs([{ label: 'Users' }]));
 +    });
 +
+ export const loadComputeNodes = handleFirstTimeLoad(
+     async (dispatch: Dispatch<any>) => {
+         await dispatch(loadComputeNodesPanel());
+     });
+ 
  const finishLoadingProject = (project: GroupContentsResource | string) =>
      async (dispatch: Dispatch<any>) => {
          const uuid = typeof project === 'string' ? project : project.uuid;
diff --cc src/validators/validators.tsx
index 464f190,a3f5df2..30fa36b
--- a/src/validators/validators.tsx
+++ b/src/validators/validators.tsx
@@@ -24,8 -24,7 +24,10 @@@ export const PROCESS_NAME_VALIDATION = 
  
  export const REPOSITORY_NAME_VALIDATION = [require, maxLength(255)];
  
 +export const USER_EMAIL_VALIDATION = [require, maxLength(255)];
 +export const USER_LENGTH_VALIDATION = [maxLength(255)];
 +
  export const SSH_KEY_PUBLIC_VALIDATION = [require, isRsaKey, maxLength(1024)];
  export const SSH_KEY_NAME_VALIDATION = [require, maxLength(255)];
+ 
+ export const MY_ACCOUNT_VALIDATION = [require];
diff --cc src/views-components/context-menu/context-menu.tsx
index 29b8afb,3fa1ab3..68a48ee
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@@ -73,5 -73,5 +73,6 @@@ export enum ContextMenuKind 
      SSH_KEY = "SshKey",
      VIRTUAL_MACHINE = "VirtualMachine",
      KEEP_SERVICE = "KeepService",
-     USER = "User"
++    USER = "User",
+     NODE = "Node"
  }
diff --cc src/views-components/main-app-bar/account-menu.tsx
index 889b51d,ee726f3..412f849
--- a/src/views-components/main-app-bar/account-menu.tsx
+++ b/src/views-components/main-app-bar/account-menu.tsx
@@@ -12,9 -12,8 +12,9 @@@ 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 } from '~/store/navigation/navigation-action';
+ import { navigateToSshKeys, navigateToKeepServices, navigateToComputeNodes, navigateToMyAccount } from '~/store/navigation/navigation-action';
  import { openVirtualMachines } from "~/store/virtual-machines/virtual-machines-actions";
 +import { navigateToUsers } from '~/store/navigation/navigation-action';
  
  interface AccountMenuProps {
      user?: User;
@@@ -38,9 -37,9 +38,10 @@@ export const AccountMenu = connect(mapS
                  <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(navigateToKeepServices)}>Keep Services</MenuItem>}
-                 <MenuItem>My account</MenuItem>
+                 { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToKeepServices)}>Keep Services</MenuItem> }
+                 { user.isAdmin && <MenuItem onClick={() => dispatch(navigateToComputeNodes)}>Compute Nodes</MenuItem> }
+                 <MenuItem onClick={() => dispatch(navigateToMyAccount)}>My account</MenuItem>
                  <MenuItem onClick={() => dispatch(logout())}>Logout</MenuItem>
              </DropdownMenu>
              : null);
diff --cc src/views-components/main-content-bar/main-content-bar.tsx
index fe68145,78b79a8..7022fc5
--- a/src/views-components/main-content-bar/main-content-bar.tsx
+++ b/src/views-components/main-content-bar/main-content-bar.tsx
@@@ -18,9 -18,9 +18,10 @@@ interface MainContentBarProps 
  
  const isButtonVisible = ({ router }: RootState) => {
      const pathname = router.location ? router.location.pathname : '';
-     return !matchWorkflowRoute(pathname) && !matchVirtualMachineRoute(pathname) &&
-         !matchRepositoriesRoute(pathname) && !matchSshKeysRoute(pathname) && !matchKeepServicesRoute(pathname) &&
-         !matchUsersRoute(pathname);
+     return !Routes.matchWorkflowRoute(pathname) && !Routes.matchVirtualMachineRoute(pathname) &&
+         !Routes.matchRepositoriesRoute(pathname) && !Routes.matchSshKeysRoute(pathname) &&
 -        !Routes.matchKeepServicesRoute(pathname) && !Routes.matchComputeNodesRoute(pathname);
++        !Routes.matchKeepServicesRoute(pathname) && !Routes.matchComputeNodesRoute(pathname) && 
++        !Routes.matchUsersRoute(pathname);
  };
  
  export const MainContentBar = connect((state: RootState) => ({
diff --cc src/views/workbench/workbench.tsx
index 5a6ba97,5efffa1..e0ec14f
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -63,10 -68,6 +68,9 @@@ import { AttributesComputeNodeDialog } 
  import { AttributesKeepServiceDialog } from '~/views-components/keep-services-dialog/attributes-dialog';
  import { AttributesSshKeyDialog } from '~/views-components/ssh-keys-dialog/attributes-dialog';
  import { VirtualMachineAttributesDialog } from '~/views-components/virtual-machines-dialog/attributes-dialog';
- import { RemoveVirtualMachineDialog } from '~/views-components/virtual-machines-dialog/remove-dialog';
 +import { UserPanel } from '~/views/user-panel/user-panel';
 +import { UserAttributesDialog } from '~/views-components/user-dialog/attributes-dialog';
 +import { CreateUserDialog } from '~/views-components/dialog-forms/create-user-dialog';
  
  type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
  
@@@ -140,7 -141,8 +144,9 @@@ export const WorkbenchPanel 
                                  <Route path={Routes.REPOSITORIES} component={RepositoriesPanel} />
                                  <Route path={Routes.SSH_KEYS} component={SshKeyPanel} />
                                  <Route path={Routes.KEEP_SERVICES} component={KeepServicePanel} />
 +                                <Route path={Routes.USERS} component={UserPanel} />
+                                 <Route path={Routes.COMPUTE_NODES} component={ComputeNodePanel} />
+                                 <Route path={Routes.MY_ACCOUNT} component={MyAccountPanel} />
                              </Switch>
                          </Grid>
                      </Grid>

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list