[ARVADOS-WORKBENCH2] created: 2.2.1-36-g73122efb

Git user git at public.arvados.org
Fri Jul 30 05:41:45 UTC 2021


        at  73122efb6429184611d17b3278ecbe9c2e26a6c2 (commit)


commit 73122efb6429184611d17b3278ecbe9c2e26a6c2
Author: Stephen Smith <stephen at curii.com>
Date:   Fri Jul 30 01:40:17 2021 -0400

    17951: Remove compute node ui and associated code
    
    Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>

diff --git a/src/index.tsx b/src/index.tsx
index b1eca99e..2d62194b 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -51,7 +51,6 @@ import { keepServiceActionSet } from 'views-components/context-menu/action-sets/
 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';
 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';
@@ -92,7 +91,6 @@ 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);
diff --git a/src/models/resource.ts b/src/models/resource.ts
index 371278e5..c94c4b25 100644
--- a/src/models/resource.ts
+++ b/src/models/resource.ts
@@ -32,7 +32,6 @@ export enum ResourceKind {
     GROUP = "arvados#group",
     LINK = "arvados#link",
     LOG = "arvados#log",
-    NODE = "arvados#node",
     PROCESS = "arvados#containerRequest",
     PROJECT = "arvados#group",
     REPOSITORY = "arvados#repository",
@@ -57,8 +56,7 @@ export enum ResourceObjectType {
     VIRTUAL_MACHINE = '2x53u',
     WORKFLOW = '7fd4e',
     SSH_KEY = 'fngyi',
-    KEEP_SERVICE = 'bi6l4',
-    NODE = '7ekkf'
+    KEEP_SERVICE = 'bi6l4'
 }
 
 export const RESOURCE_UUID_PATTERN = '[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}';
@@ -101,8 +99,6 @@ export const extractUuidKind = (uuid: string = '') => {
             return ResourceKind.SSH_KEY;
         case ResourceObjectType.KEEP_SERVICE:
             return ResourceKind.KEEP_SERVICE;
-        case ResourceObjectType.NODE:
-            return ResourceKind.NODE;
         case ResourceObjectType.API_CLIENT_AUTHORIZATION:
             return ResourceKind.API_CLIENT_AUTHORIZATION;
         case ResourceObjectType.LINK:
diff --git a/src/routes/route-change-handlers.ts b/src/routes/route-change-handlers.ts
index 6d171e04..70f65cb4 100644
--- a/src/routes/route-change-handlers.ts
+++ b/src/routes/route-change-handlers.ts
@@ -39,7 +39,6 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
     const sshKeysAdminMatch = Routes.matchSshKeysAdminRoute(pathname);
     const siteManagerMatch = Routes.matchSiteManagerRoute(pathname);
     const keepServicesMatch = Routes.matchKeepServicesRoute(pathname);
-    const computeNodesMatch = Routes.matchComputeNodesRoute(pathname);
     const apiClientAuthorizationsMatch = Routes.matchApiClientAuthorizationsRoute(pathname);
     const myAccountMatch = Routes.matchMyAccountRoute(pathname);
     const linkAccountMatch = Routes.matchLinkAccountRoute(pathname);
@@ -98,8 +97,6 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
         store.dispatch(WorkbenchActions.loadSiteManager);
     } else if (keepServicesMatch) {
         store.dispatch(WorkbenchActions.loadKeepServices);
-    } else if (computeNodesMatch) {
-        store.dispatch(WorkbenchActions.loadComputeNodes);
     } else if (apiClientAuthorizationsMatch) {
         store.dispatch(WorkbenchActions.loadApiClientAuthorizations);
     } else if (myAccountMatch) {
diff --git a/src/routes/routes.ts b/src/routes/routes.ts
index d9da0234..528a0376 100644
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@ -39,7 +39,6 @@ export const Routes = {
     MY_ACCOUNT: '/my-account',
     LINK_ACCOUNT: '/link_account',
     KEEP_SERVICES: `/keep-services`,
-    COMPUTE_NODES: `/nodes`,
     USERS: '/users',
     API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
     GROUPS: '/groups',
@@ -176,9 +175,6 @@ export const matchFedTokenRoute = (route: string) =>
 export const matchUsersRoute = (route: string) =>
     matchPath(route, { path: Routes.USERS });
 
-export const matchComputeNodesRoute = (route: string) =>
-    matchPath(route, { path: Routes.COMPUTE_NODES });
-
 export const matchApiClientAuthorizationsRoute = (route: string) =>
     matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
 
diff --git a/src/services/node-service/node-service.ts b/src/services/node-service/node-service.ts
deleted file mode 100644
index 0cf1a83b..00000000
--- a/src/services/node-service/node-service.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { AxiosInstance } from "axios";
-import { CommonResourceService } from "services/common-service/common-resource-service";
-import { NodeResource } from 'models/node';
-import { ApiActions } from 'services/api/api-actions';
-
-export class NodeService extends CommonResourceService<NodeResource> {
-    constructor(serverApi: AxiosInstance, actions: ApiActions) {
-        super(serverApi, "nodes", actions);
-    }
-} 
\ No newline at end of file
diff --git a/src/services/services.ts b/src/services/services.ts
index b9118981..2afb843f 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -29,7 +29,6 @@ import { VirtualMachinesService } from "services/virtual-machines-service/virtua
 import { RepositoriesService } from 'services/repositories-service/repositories-service';
 import { AuthorizedKeysService } from 'services/authorized-keys-service/authorized-keys-service';
 import { VocabularyService } from 'services/vocabulary-service/vocabulary-service';
-import { NodeService } from 'services/node-service/node-service';
 import { FileViewersConfigService } from 'services/file-viewers-config-service/file-viewers-config-service';
 import { LinkAccountService } from "./link-account-service/link-account-service";
 import parse from "parse-duration";
@@ -69,7 +68,6 @@ export const createServices = (config: Config, actions: ApiActions, useApiClient
     const keepService = new KeepService(apiClient, actions);
     const linkService = new LinkService(apiClient, actions);
     const logService = new LogService(apiClient, actions);
-    const nodeService = new NodeService(apiClient, actions);
     const permissionService = new PermissionService(apiClient, actions);
     const projectService = new ProjectService(apiClient, actions);
     const repositoriesService = new RepositoriesService(apiClient, actions);
@@ -106,7 +104,6 @@ export const createServices = (config: Config, actions: ApiActions, useApiClient
         keepService,
         linkService,
         logService,
-        nodeService,
         permissionService,
         projectService,
         repositoriesService,
diff --git a/src/store/advanced-tab/advanced-tab.tsx b/src/store/advanced-tab/advanced-tab.tsx
index cf30669d..0f8bf3cb 100644
--- a/src/store/advanced-tab/advanced-tab.tsx
+++ b/src/store/advanced-tab/advanced-tab.tsx
@@ -21,7 +21,6 @@ import { VirtualMachinesResource } from 'models/virtual-machines';
 import { UserResource } from 'models/user';
 import { LinkResource } from 'models/link';
 import { KeepServiceResource } from 'models/keep-services';
-import { NodeResource } from 'models/node';
 import { ApiClientAuthorization } from 'models/api-client-authorization';
 import React from 'react';
 
@@ -76,7 +75,6 @@ enum ResourcePrefix {
     AUTORIZED_KEYS = 'authorized_keys',
     VIRTUAL_MACHINES = 'virtual_machines',
     KEEP_SERVICES = 'keep_services',
-    COMPUTE_NODES = 'nodes',
     USERS = 'users',
     API_CLIENT_AUTHORIZATIONS = 'api_client_authorizations',
     LINKS = 'links'
@@ -92,11 +90,6 @@ enum UserData {
     USERNAME = 'username'
 }
 
-enum ComputeNodeData {
-    COMPUTE_NODE = 'node',
-    PROPERTIES = 'properties'
-}
-
 enum ApiClientAuthorizationsData {
     API_CLIENT_AUTHORIZATION = 'api_client_authorization',
     DEFAULT_OWNER_UUID = 'default_owner_uuid'
@@ -107,9 +100,9 @@ enum LinkData {
     PROPERTIES = 'properties'
 }
 
-type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData | ComputeNodeData | ApiClientAuthorizationsData | UserData | LinkData;
+type AdvanceResourceKind = CollectionData | ProcessData | ProjectData | RepositoryData | SshKeyData | VirtualMachineData | KeepServiceData | ApiClientAuthorizationsData | UserData | LinkData;
 type AdvanceResourcePrefix = GroupContentsResourcePrefix | ResourcePrefix;
-type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | NodeResource | ApiClientAuthorization | UserResource | LinkResource | undefined;
+type AdvanceResponseData = ContainerRequestResource | ProjectResource | CollectionResource | RepositoryResource | SshKeyResource | VirtualMachinesResource | KeepServiceResource | ApiClientAuthorization | UserResource | LinkResource | undefined;
 
 export const openAdvancedTabDialog = (uuid: string) =>
     async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
@@ -241,22 +234,6 @@ export const openAdvancedTabDialog = (uuid: string) =>
                 });
                 dispatch<any>(initAdvancedTabDialog(advanceDataUser));
                 break;
-            case ResourceKind.NODE:
-                const computeNodeResources = getState().resources;
-                const dataComputeNode = getResource<NodeResource>(uuid)(computeNodeResources);
-                const advanceDataComputeNode = advancedTabData({
-                    uuid,
-                    metadata: '',
-                    user: '',
-                    apiResponseKind: computeNodeApiResponse,
-                    data: dataComputeNode,
-                    resourceKind: ComputeNodeData.COMPUTE_NODE,
-                    resourcePrefix: ResourcePrefix.COMPUTE_NODES,
-                    resourceKindProperty: ComputeNodeData.PROPERTIES,
-                    property: dataComputeNode ? dataComputeNode.properties : {}
-                });
-                dispatch<any>(initAdvancedTabDialog(advanceDataComputeNode));
-                break;
             case ResourceKind.API_CLIENT_AUTHORIZATION:
                 const apiClientAuthorizationResources = getState().resources;
                 const dataApiClientAuthorization = getResource<ApiClientAuthorization>(uuid)(apiClientAuthorizationResources);
@@ -578,32 +555,6 @@ const userApiResponse = (apiResponse: UserResource) => {
     return <span style={{ marginLeft: '-15px' }}>{'{'} {response} {'\n'} <span style={{ marginLeft: '-15px' }}>{'}'}</span></span>;
 };
 
-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, 2)}",
-"info": "${JSON.stringify(info, null, 2)}"`;
-
-    return <span style={{ marginLeft: '-15px' }}>{'{'} {response} {'\n'} <span style={{ marginLeft: '-15px' }}>{'}'}</span></span>;
-};
-
 const apiClientAuthorizationApiResponse = (apiResponse: ApiClientAuthorization) => {
     const {
         uuid, ownerUuid, apiToken, apiClientId, userId, createdByIpAddress, lastUsedByIpAddress,
diff --git a/src/store/compute-nodes/compute-nodes-actions.ts b/src/store/compute-nodes/compute-nodes-actions.ts
deleted file mode 100644
index 25d3bad3..00000000
--- a/src/store/compute-nodes/compute-nodes-actions.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { Dispatch } from "redux";
-import { RootState } from 'store/store';
-import { setBreadcrumbs } from 'store/breadcrumbs/breadcrumbs-actions';
-import { dialogActions } from 'store/dialog/dialog-actions';
-import {snackbarActions, SnackbarKind} from 'store/snackbar/snackbar-actions';
-import { navigateToRootProject } from 'store/navigation/navigation-action';
-import { bindDataExplorerActions } from 'store/data-explorer/data-explorer-action';
-import { getResource } from 'store/resources/resources';
-import { ServiceRepository } from "services/services";
-import { NodeResource } from 'models/node';
-
-export const COMPUTE_NODE_PANEL_ID = "computeNodeId";
-export const computeNodesActions = bindDataExplorerActions(COMPUTE_NODE_PANEL_ID);
-
-export const COMPUTE_NODE_REMOVE_DIALOG = 'computeNodeRemoveDialog';
-export const COMPUTE_NODE_ATTRIBUTES_DIALOG = 'computeNodeAttributesDialog';
-
-export const loadComputeNodesPanel = () =>
-    async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
-        const user = getState().auth.user;
-        if (user && user.isAdmin) {
-            try {
-                dispatch(setBreadcrumbs([{ label: 'Compute Nodes' }]));
-                dispatch(computeNodesActions.REQUEST_ITEMS());
-            } catch (e) {
-                return;
-            }
-        } else {
-            dispatch(navigateToRootProject);
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: "You don't have permissions to view this page", hideDuration: 2000, kind: SnackbarKind.ERROR }));
-        }
-    };
-
-export const openComputeNodeAttributesDialog = (uuid: string) =>
-    (dispatch: Dispatch, getState: () => RootState) => {
-        const { resources } = getState();
-        const computeNode = getResource<NodeResource>(uuid)(resources);
-        dispatch(dialogActions.OPEN_DIALOG({ id: COMPUTE_NODE_ATTRIBUTES_DIALOG, data: { computeNode } }));
-    };
-
-export const openComputeNodeRemoveDialog = (uuid: string) =>
-    (dispatch: Dispatch, getState: () => RootState) => {
-        dispatch(dialogActions.OPEN_DIALOG({
-            id: COMPUTE_NODE_REMOVE_DIALOG,
-            data: {
-                title: 'Remove compute node',
-                text: 'Are you sure you want to remove this compute node?',
-                confirmButtonLabel: 'Remove',
-                uuid
-            }
-        }));
-    };
-
-export const removeComputeNode = (uuid: string) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removing ...', kind: SnackbarKind.INFO }));
-        try {
-            await services.nodeService.delete(uuid);
-            dispatch(computeNodesActions.REQUEST_ITEMS());
-            dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Compute node has been successfully removed.', hideDuration: 2000, kind: SnackbarKind.SUCCESS }));
-        } catch (e) {
-            return;
-        }
-    };
\ No newline at end of file
diff --git a/src/store/compute-nodes/compute-nodes-middleware-service.ts b/src/store/compute-nodes/compute-nodes-middleware-service.ts
deleted file mode 100644
index bdd728aa..00000000
--- a/src/store/compute-nodes/compute-nodes-middleware-service.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { ServiceRepository } from 'services/services';
-import { MiddlewareAPI, Dispatch } from 'redux';
-import { DataExplorerMiddlewareService, dataExplorerToListParams, listResultsToDataExplorerItemsMeta } from 'store/data-explorer/data-explorer-middleware-service';
-import { RootState } from 'store/store';
-import { snackbarActions, SnackbarKind } from 'store/snackbar/snackbar-actions';
-import { DataExplorer, getDataExplorer } from 'store/data-explorer/data-explorer-reducer';
-import { updateResources } from 'store/resources/resources-actions';
-import { getSortColumn } from "store/data-explorer/data-explorer-reducer";
-import { computeNodesActions } from 'store/compute-nodes/compute-nodes-actions';
-import { OrderDirection, OrderBuilder } from 'services/api/order-builder';
-import { ListResults } from 'services/common-service/common-service';
-import { NodeResource } from 'models/node';
-import { SortDirection } from 'components/data-table/data-column';
-import { ComputeNodePanelColumnNames } from 'views/compute-node-panel/compute-node-panel-root';
-
-export class ComputeNodeMiddlewareService extends DataExplorerMiddlewareService {
-    constructor(private services: ServiceRepository, id: string) {
-        super(id);
-    }
-
-    async requestItems(api: MiddlewareAPI<Dispatch, RootState>) {
-        const state = api.getState();
-        const dataExplorer = getDataExplorer(state.dataExplorer, this.getId());
-        try {
-            const response = await this.services.nodeService.list(getParams(dataExplorer));
-            api.dispatch(updateResources(response.items));
-            api.dispatch(setItems(response));
-        } catch {
-            api.dispatch(couldNotFetchLinks());
-        }
-    }
-}
-
-export const getParams = (dataExplorer: DataExplorer) => ({
-    ...dataExplorerToListParams(dataExplorer),
-    order: getOrder(dataExplorer)
-});
-
-const getOrder = (dataExplorer: DataExplorer) => {
-    const sortColumn = getSortColumn(dataExplorer);
-    const order = new OrderBuilder<NodeResource>();
-    if (sortColumn) {
-        const sortDirection = sortColumn && sortColumn.sortDirection === SortDirection.ASC
-            ? OrderDirection.ASC
-            : OrderDirection.DESC;
-
-        const columnName = sortColumn && sortColumn.name === ComputeNodePanelColumnNames.UUID ? "uuid" : "modifiedAt";
-        return order
-            .addOrder(sortDirection, columnName)
-            .getOrder();
-    } else {
-        return order.getOrder();
-    }
-};
-
-export const setItems = (listResults: ListResults<NodeResource>) =>
-    computeNodesActions.SET_ITEMS({
-        ...listResultsToDataExplorerItemsMeta(listResults),
-        items: listResults.items.map(resource => resource.uuid),
-    });
-
-const couldNotFetchLinks = () =>
-    snackbarActions.OPEN_SNACKBAR({
-        message: 'Could not fetch compute nodes.',
-        kind: SnackbarKind.ERROR
-    });
diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts
index 556d83b4..59a6813b 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -120,17 +120,6 @@ export const openKeepServiceContextMenu = (event: React.MouseEvent<HTMLElement>,
         }));
     };
 
-export const openComputeNodeContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) =>
-    (dispatch: Dispatch) => {
-        dispatch<any>(openContextMenu(event, {
-            name: '',
-            uuid: resourceUuid,
-            ownerUuid: '',
-            kind: ResourceKind.NODE,
-            menuKind: ContextMenuKind.NODE
-        }));
-    };
-
 export const openApiClientAuthorizationContextMenu =
     (event: React.MouseEvent<HTMLElement>, resourceUuid: string) =>
         (dispatch: Dispatch) => {
diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts
index 21a26a3a..97082e5a 100644
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@ -136,8 +136,6 @@ export const navigateToLinkAccount = push(Routes.LINK_ACCOUNT);
 
 export const navigateToKeepServices = push(Routes.KEEP_SERVICES);
 
-export const navigateToComputeNodes = push(Routes.COMPUTE_NODES);
-
 export const navigateToUsers = push(Routes.USERS);
 
 export const navigateToApiClientAuthorizations = push(Routes.API_CLIENT_AUTHORIZATIONS);
diff --git a/src/store/store.ts b/src/store/store.ts
index d0f1af87..59a0cb12 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -55,8 +55,6 @@ import { GroupDetailsPanelMiddlewareService } from 'store/group-details-panel/gr
 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';
-import { COMPUTE_NODE_PANEL_ID } from 'store/compute-nodes/compute-nodes-actions';
-import { ComputeNodeMiddlewareService } from 'store/compute-nodes/compute-nodes-middleware-service';
 import { API_CLIENT_AUTHORIZATION_PANEL_ID } from 'store/api-client-authorizations/api-client-authorizations-actions';
 import { ApiClientAuthorizationMiddlewareService } from 'store/api-client-authorizations/api-client-authorizations-middleware-service';
 import { PublicFavoritesMiddlewareService } from 'store/public-favorites-panel/public-favorites-middleware-service';
@@ -124,9 +122,6 @@ export function configureStore(history: History, services: ServiceRepository, co
     const linkPanelMiddleware = dataExplorerMiddleware(
         new LinkMiddlewareService(services, LINK_PANEL_ID)
     );
-    const computeNodeMiddleware = dataExplorerMiddleware(
-        new ComputeNodeMiddlewareService(services, COMPUTE_NODE_PANEL_ID)
-    );
     const apiClientAuthorizationMiddlewareService = dataExplorerMiddleware(
         new ApiClientAuthorizationMiddlewareService(services, API_CLIENT_AUTHORIZATION_PANEL_ID)
     );
@@ -164,7 +159,6 @@ export function configureStore(history: History, services: ServiceRepository, co
         groupsPanelMiddleware,
         groupDetailsPanelMiddleware,
         linkPanelMiddleware,
-        computeNodeMiddleware,
         apiClientAuthorizationMiddlewareService,
         publicFavoritesMiddleware,
         collectionsContentAddress,
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 3aa59802..6ea30855 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -81,10 +81,8 @@ 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 { linkPanelActions, loadLinkPanel } from 'store/link-panel/link-panel-actions';
-import { computeNodesActions, loadComputeNodesPanel } from 'store/compute-nodes/compute-nodes-actions';
 import { linkPanelColumns } from 'views/link-panel/link-panel-root';
 import { userPanelColumns } from 'views/user-panel/user-panel';
-import { computeNodePanelColumns } from 'views/compute-node-panel/compute-node-panel-root';
 import { loadApiClientAuthorizationsPanel, apiClientAuthorizationsActions } from 'store/api-client-authorizations/api-client-authorizations-actions';
 import { apiClientAuthorizationPanelColumns } from 'views/api-client-authorization-panel/api-client-authorization-panel-root';
 import * as groupPanelActions from 'store/groups-panel/groups-panel-actions';
@@ -140,7 +138,6 @@ export const loadWorkbench = () =>
             dispatch(groupPanelActions.GroupsPanelActions.SET_COLUMNS({ columns: groupsPanelColumns }));
             dispatch(groupDetailsPanelActions.GroupDetailsPanelActions.SET_COLUMNS({ columns: groupDetailsPanelColumns }));
             dispatch(linkPanelActions.SET_COLUMNS({ columns: linkPanelColumns }));
-            dispatch(computeNodesActions.SET_COLUMNS({ columns: computeNodePanelColumns }));
             dispatch(apiClientAuthorizationsActions.SET_COLUMNS({ columns: apiClientAuthorizationPanelColumns }));
             dispatch(collectionsContentAddressActions.SET_COLUMNS({ columns: collectionContentAddressPanelColumns }));
             dispatch(subprocessPanelActions.SET_COLUMNS({ columns: subprocessPanelColumns }));
@@ -517,11 +514,6 @@ export const loadUsers = handleFirstTimeLoad(
         dispatch(setBreadcrumbs([{ label: 'Users' }]));
     });
 
-export const loadComputeNodes = handleFirstTimeLoad(
-    async (dispatch: Dispatch<any>) => {
-        await dispatch(loadComputeNodesPanel());
-    });
-
 export const loadApiClientAuthorizations = handleFirstTimeLoad(
     async (dispatch: Dispatch<any>) => {
         await dispatch(loadApiClientAuthorizationsPanel());
diff --git a/src/views-components/compute-nodes-dialog/attributes-dialog.tsx b/src/views-components/compute-nodes-dialog/attributes-dialog.tsx
deleted file mode 100644
index 0c937b19..00000000
--- a/src/views-components/compute-nodes-dialog/attributes-dialog.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import React from "react";
-import { compose } from 'redux';
-import {
-    withStyles, Dialog, DialogTitle, DialogContent, DialogActions,
-    Button, StyleRulesCallback, WithStyles, Grid
-} from '@material-ui/core';
-import { WithDialogProps, withDialog } from "store/dialog/with-dialog";
-import { COMPUTE_NODE_ATTRIBUTES_DIALOG } from 'store/compute-nodes/compute-nodes-actions';
-import { ArvadosTheme } from 'common/custom-theme';
-import { NodeResource, NodeProperties, NodeInfo } from 'models/node';
-import classnames from "classnames";
-
-type CssRules = 'root' | 'grid';
-
-const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
-    root: {
-        fontSize: '0.875rem',
-        '& div:nth-child(odd):not(.nestedRoot)': {
-            textAlign: 'right',
-            color: theme.palette.grey["500"]
-        },
-        '& div:nth-child(even)': {
-            overflowWrap: 'break-word'
-        }
-    },
-    grid: {
-        padding: '8px 0 0 0'
-    }
-});
-
-interface AttributesComputeNodeDialogDataProps {
-    computeNode: NodeResource;
-}
-
-export const AttributesComputeNodeDialog = compose(
-    withDialog(COMPUTE_NODE_ATTRIBUTES_DIALOG),
-    withStyles(styles))(
-        ({ open, closeDialog, data, classes }: WithDialogProps<AttributesComputeNodeDialogDataProps> & WithStyles<CssRules>) =>
-            <Dialog open={open} onClose={closeDialog} fullWidth maxWidth='sm'>
-                <DialogTitle>Attributes</DialogTitle>
-                <DialogContent>
-                    {data.computeNode && <div>
-                        {renderPrimaryInfo(data.computeNode, classes)}
-                        {renderInfo(data.computeNode.info, classes)}
-                        {renderProperties(data.computeNode.properties, classes)}
-                    </div>}
-                </DialogContent>
-                <DialogActions>
-                    <Button
-                        variant='text'
-                        color='primary'
-                        onClick={closeDialog}>
-                        Close
-                    </Button>
-                </DialogActions>
-            </Dialog>
-    );
-
-const renderPrimaryInfo = (computeNode: NodeResource, classes: any) => {
-    const { uuid, ownerUuid, createdAt, modifiedAt, modifiedByClientUuid, modifiedByUserUuid } = computeNode;
-    return (
-        <Grid container direction="row" spacing={16} className={classes.root}>
-            <Grid item xs={5}>UUID</Grid>
-            <Grid item xs={7}>{uuid}</Grid>
-            <Grid item xs={5}>Owner uuid</Grid>
-            <Grid item xs={7}>{ownerUuid}</Grid>
-            <Grid item xs={5}>Created at</Grid>
-            <Grid item xs={7}>{createdAt}</Grid>
-            <Grid item xs={5}>Modified at</Grid>
-            <Grid item xs={7}>{modifiedAt}</Grid>
-            <Grid item xs={5}>Modified by user uuid</Grid>
-            <Grid item xs={7}>{modifiedByUserUuid}</Grid>
-            <Grid item xs={5}>Modified by client uuid</Grid>
-            <Grid item xs={7}>{modifiedByClientUuid || '(none)'}</Grid>
-        </Grid>
-    );
-};
-
-const renderInfo = (info: NodeInfo, classes: any) => {
-    const { last_action, ping_secret, ec2_instance_id, slurm_state } = info;
-    return (
-        <Grid container direction="row" spacing={16} className={classnames([classes.root, classes.grid])}>
-            <Grid item xs={5}>Info - Last action</Grid>
-            <Grid item xs={7}>{last_action || '(none)'}</Grid>
-            <Grid item xs={5}>Info - Ping secret</Grid>
-            <Grid item xs={7}>{ping_secret || '(none)'}</Grid>
-            <Grid item xs={5}>Info - ec2 instance id</Grid>
-            <Grid item xs={7}>{ec2_instance_id || '(none)'}</Grid>
-            <Grid item xs={5}>Info - Slurm state</Grid>
-            <Grid item xs={7}>{slurm_state || '(none)'}</Grid>
-        </Grid>
-    );
-};
-
-const renderProperties = (properties: NodeProperties, classes: any) => {
-    const { total_ram_mb, total_cpu_cores, total_scratch_mb, cloud_node } = properties;
-    return (
-        <Grid container direction="row" spacing={16} className={classnames([classes.root, classes.grid])}>
-            <Grid item xs={5}>Properties - Total ram mb</Grid>
-            <Grid item xs={7}>{total_ram_mb || '(none)'}</Grid>
-            <Grid item xs={5}>Properties - Total scratch mb</Grid>
-            <Grid item xs={7}>{total_scratch_mb || '(none)'}</Grid>
-            <Grid item xs={5}>Properties - Total cpu cores</Grid>
-            <Grid item xs={7}>{total_cpu_cores || '(none)'}</Grid>
-            <Grid item xs={5}>Properties - Cloud node size </Grid>
-            <Grid item xs={7}>{cloud_node ? cloud_node.size : '(none)'}</Grid>
-            <Grid item xs={5}>Properties - Cloud node price</Grid>
-            <Grid item xs={7}>{cloud_node ? cloud_node.price : '(none)'}</Grid>
-        </Grid>
-    );
-};
\ No newline at end of file
diff --git a/src/views-components/compute-nodes-dialog/remove-dialog.tsx b/src/views-components/compute-nodes-dialog/remove-dialog.tsx
deleted file mode 100644
index 60ca0f92..00000000
--- a/src/views-components/compute-nodes-dialog/remove-dialog.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { Dispatch, compose } from 'redux';
-import { connect } from "react-redux";
-import { ConfirmationDialog } from "components/confirmation-dialog/confirmation-dialog";
-import { withDialog, WithDialogProps } from "store/dialog/with-dialog";
-import { COMPUTE_NODE_REMOVE_DIALOG, removeComputeNode } from 'store/compute-nodes/compute-nodes-actions';
-
-const mapDispatchToProps = (dispatch: Dispatch, props: WithDialogProps<any>) => ({
-    onConfirm: () => {
-        props.closeDialog();
-        dispatch<any>(removeComputeNode(props.data.uuid));
-    }
-});
-
-export const  RemoveComputeNodeDialog = compose(
-    withDialog(COMPUTE_NODE_REMOVE_DIALOG),
-    connect(null, mapDispatchToProps)
-)(ConfirmationDialog);
\ No newline at end of file
diff --git a/src/views-components/context-menu/action-sets/compute-node-action-set.ts b/src/views-components/context-menu/action-sets/compute-node-action-set.ts
deleted file mode 100644
index e09ec9e0..00000000
--- a/src/views-components/context-menu/action-sets/compute-node-action-set.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { openComputeNodeRemoveDialog, openComputeNodeAttributesDialog } from 'store/compute-nodes/compute-nodes-actions';
-import { openAdvancedTabDialog } from 'store/advanced-tab/advanced-tab';
-import { ContextMenuActionSet } from "views-components/context-menu/context-menu-action-set";
-import { AdvancedIcon, RemoveIcon, AttributesIcon } from "components/icon/icon";
-
-export const computeNodeActionSet: ContextMenuActionSet = [[{
-    name: "Attributes",
-    icon: AttributesIcon,
-    execute: (dispatch, { uuid }) => {
-        dispatch<any>(openComputeNodeAttributesDialog(uuid));
-    }
-}, {
-    name: "Advanced",
-    icon: AdvancedIcon,
-    execute: (dispatch, { uuid }) => {
-        dispatch<any>(openAdvancedTabDialog(uuid));
-    }
-}, {
-    name: "Remove",
-    icon: RemoveIcon,
-    execute: (dispatch, { uuid }) => {
-        dispatch<any>(openComputeNodeRemoveDialog(uuid));
-    }
-}]];
diff --git a/src/views-components/context-menu/context-menu.tsx b/src/views-components/context-menu/context-menu.tsx
index 7fd66c2c..603ee90b 100644
--- a/src/views-components/context-menu/context-menu.tsx
+++ b/src/views-components/context-menu/context-menu.tsx
@@ -96,7 +96,6 @@ export enum ContextMenuKind {
     VIRTUAL_MACHINE = "VirtualMachine",
     KEEP_SERVICE = "KeepService",
     USER = "User",
-    NODE = "Node",
     GROUPS = "Group",
     GROUP_MEMBER = "GroupMember",
     LINK = "Link",
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index dccd2786..314390e2 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -232,11 +232,6 @@ export const TokenScopes = withResourceData('scopes', renderCommonData);
 
 export const TokenUserId = withResourceData('userId', renderCommonData);
 
-// Compute Node Resources
-const renderNodeInfo = (data: string) => {
-    return <Typography>{JSON.stringify(data, null, 4)}</Typography>;
-};
-
 const clusterColors = [
     ['#f44336', '#fff'],
     ['#2196f3', '#fff'],
@@ -262,20 +257,6 @@ export const ResourceCluster = (props: { uuid: string }) => {
     }}>{clusterId}</span>;
 };
 
-export const ComputeNodeInfo = withResourceData('info', renderNodeInfo);
-
-export const ComputeNodeDomain = withResourceData('domain', renderCommonData);
-
-export const ComputeNodeFirstPingAt = withResourceData('firstPingAt', renderCommonDate);
-
-export const ComputeNodeHostname = withResourceData('hostname', renderCommonData);
-
-export const ComputeNodeIpAddress = withResourceData('ipAddress', renderCommonData);
-
-export const ComputeNodeJobUuid = withResourceData('jobUuid', renderCommonData);
-
-export const ComputeNodeLastPingAt = withResourceData('lastPingAt', renderCommonDate);
-
 // Links Resources
 const renderLinkName = (item: { name: string }) =>
     <Typography noWrap>{item.name || '(none)'}</Typography>;
diff --git a/src/views-components/main-app-bar/admin-menu.tsx b/src/views-components/main-app-bar/admin-menu.tsx
index ab5c2ead..198306b5 100644
--- a/src/views-components/main-app-bar/admin-menu.tsx
+++ b/src/views-components/main-app-bar/admin-menu.tsx
@@ -38,7 +38,6 @@ export const AdminMenu = connect(mapStateToProps)(
                 <MenuItem onClick={() => dispatch(NavigationAction.navigateToApiClientAuthorizations)}>Api Tokens</MenuItem>
                 <MenuItem onClick={() => dispatch(openUserPanel())}>Users</MenuItem>
                 <MenuItem onClick={() => dispatch(NavigationAction.navigateToGroups)}>Groups</MenuItem>
-                <MenuItem onClick={() => dispatch(NavigationAction.navigateToComputeNodes)}>Compute Nodes</MenuItem>
                 <MenuItem onClick={() => dispatch(NavigationAction.navigateToKeepServices)}>Keep Services</MenuItem>
                 <MenuItem onClick={() => dispatch(NavigationAction.navigateToLinks)}>Links</MenuItem>
             </DropdownMenu>
diff --git a/src/views/compute-node-panel/compute-node-panel-root.tsx b/src/views/compute-node-panel/compute-node-panel-root.tsx
deleted file mode 100644
index 1060197a..00000000
--- a/src/views/compute-node-panel/compute-node-panel-root.tsx
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import React from 'react';
-import { ShareMeIcon } from 'components/icon/icon';
-import { DataExplorer } from 'views-components/data-explorer/data-explorer';
-import { DataTableDefaultView } from 'components/data-table-default-view/data-table-default-view';
-import { COMPUTE_NODE_PANEL_ID } from 'store/compute-nodes/compute-nodes-actions';
-import { DataColumns } from 'components/data-table/data-table';
-import { SortDirection } from 'components/data-table/data-column';
-import { createTree } from 'models/tree';
-import {
-    ComputeNodeInfo, ComputeNodeDomain, ComputeNodeHostname, ComputeNodeJobUuid,
-    ComputeNodeFirstPingAt, ComputeNodeLastPingAt, ComputeNodeIpAddress, CommonUuid
-} from 'views-components/data-explorer/renderers';
-import { ResourcesState } from 'store/resources/resources';
-
-export enum ComputeNodePanelColumnNames {
-    INFO = 'Info',
-    UUID = 'UUID',
-    DOMAIN = 'Domain',
-    FIRST_PING_AT = 'First ping at',
-    HOSTNAME = 'Hostname',
-    IP_ADDRESS = 'IP Address',
-    JOB = 'Job',
-    LAST_PING_AT = 'Last ping at'
-}
-
-export const computeNodePanelColumns: DataColumns<string> = [
-    {
-        name: ComputeNodePanelColumnNames.INFO,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeInfo uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.UUID,
-        selected: true,
-        configurable: true,
-        sortDirection: SortDirection.NONE,
-        filters: createTree(),
-        render: uuid => <CommonUuid uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.DOMAIN,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeDomain uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.FIRST_PING_AT,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeFirstPingAt uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.HOSTNAME,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeHostname uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.IP_ADDRESS,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeIpAddress uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.JOB,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeJobUuid uuid={uuid} />
-    },
-    {
-        name: ComputeNodePanelColumnNames.LAST_PING_AT,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ComputeNodeLastPingAt uuid={uuid} />
-    }
-];
-
-const DEFAULT_MESSAGE = 'Your compute node list is empty.';
-
-export interface ComputeNodePanelRootActionProps {
-    onItemClick: (item: string) => void;
-    onContextMenu: (event: React.MouseEvent<HTMLElement>, item: string) => void;
-    onItemDoubleClick: (item: string) => void;
-}
-
-export interface ComputeNodePanelRootDataProps {
-    resources: ResourcesState;
-}
-
-type ComputeNodePanelRootProps = ComputeNodePanelRootActionProps & ComputeNodePanelRootDataProps;
-
-export const ComputeNodePanelRoot = (props: ComputeNodePanelRootProps) => {
-    return <DataExplorer
-        id={COMPUTE_NODE_PANEL_ID}
-        onRowClick={props.onItemClick}
-        onRowDoubleClick={props.onItemDoubleClick}
-        onContextMenu={props.onContextMenu}
-        contextMenuColumn={true}
-        hideColumnSelector
-        hideSearchInput
-        dataTableDefaultView={
-            <DataTableDefaultView
-                icon={ShareMeIcon}
-                messages={[DEFAULT_MESSAGE]} />
-        } />;
-};
diff --git a/src/views/compute-node-panel/compute-node-panel.tsx b/src/views/compute-node-panel/compute-node-panel.tsx
deleted file mode 100644
index 308be4d6..00000000
--- a/src/views/compute-node-panel/compute-node-panel.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { RootState } from 'store/store';
-import { Dispatch } from 'redux';
-import { connect } from 'react-redux';
-import {
-    ComputeNodePanelRoot,
-    ComputeNodePanelRootDataProps,
-    ComputeNodePanelRootActionProps
-} from 'views/compute-node-panel/compute-node-panel-root';
-import { openComputeNodeContextMenu } from 'store/context-menu/context-menu-actions';
-
-const mapStateToProps = (state: RootState): ComputeNodePanelRootDataProps => {
-    return {
-        resources: state.resources
-    };
-};
-
-const mapDispatchToProps = (dispatch: Dispatch): ComputeNodePanelRootActionProps => ({
-    onContextMenu: (event, resourceUuid) => {
-        dispatch<any>(openComputeNodeContextMenu(event, resourceUuid));
-    },
-    onItemClick: (resourceUuid: string) => { return; },
-    onItemDoubleClick: uuid => { return; }
-});
-
-export const ComputeNodePanel = connect(mapStateToProps, mapDispatchToProps)(ComputeNodePanelRoot);
\ No newline at end of file
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index e680e271..b708355c 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -56,7 +56,6 @@ import { VirtualMachineAdminPanel } from 'views/virtual-machine-panel/virtual-ma
 import { ProjectPropertiesDialog } from 'views-components/project-properties-dialog/project-properties-dialog';
 import { RepositoriesPanel } from 'views/repositories-panel/repositories-panel';
 import { KeepServicePanel } from 'views/keep-service-panel/keep-service-panel';
-import { ComputeNodePanel } from 'views/compute-node-panel/compute-node-panel';
 import { ApiClientAuthorizationPanel } from 'views/api-client-authorization-panel/api-client-authorization-panel';
 import { LinkPanel } from 'views/link-panel/link-panel';
 import { RepositoriesSampleGitDialog } from 'views-components/repositories-sample-git-dialog/repositories-sample-git-dialog';
@@ -66,13 +65,11 @@ import { RemoveRepositoryDialog } from 'views-components/repository-remove-dialo
 import { CreateSshKeyDialog } from 'views-components/dialog-forms/create-ssh-key-dialog';
 import { PublicKeyDialog } from 'views-components/ssh-keys-dialog/public-key-dialog';
 import { RemoveApiClientAuthorizationDialog } from 'views-components/api-client-authorizations-dialog/remove-dialog';
-import { RemoveComputeNodeDialog } from 'views-components/compute-nodes-dialog/remove-dialog';
 import { RemoveKeepServiceDialog } from 'views-components/keep-services-dialog/remove-dialog';
 import { RemoveLinkDialog } from 'views-components/links-dialog/remove-dialog';
 import { RemoveSshKeyDialog } from 'views-components/ssh-keys-dialog/remove-dialog';
 import { RemoveVirtualMachineDialog } from 'views-components/virtual-machines-dialog/remove-dialog';
 import { AttributesApiClientAuthorizationDialog } from 'views-components/api-client-authorizations-dialog/attributes-dialog';
-import { AttributesComputeNodeDialog } from 'views-components/compute-nodes-dialog/attributes-dialog';
 import { AttributesKeepServiceDialog } from 'views-components/keep-services-dialog/attributes-dialog';
 import { AttributesLinkDialog } from 'views-components/links-dialog/attributes-dialog';
 import { AttributesSshKeyDialog } from 'views-components/ssh-keys-dialog/attributes-dialog';
@@ -171,7 +168,6 @@ let routes = <>
     <Route path={Routes.SITE_MANAGER} component={SiteManagerPanel} />
     <Route path={Routes.KEEP_SERVICES} component={KeepServicePanel} />
     <Route path={Routes.USERS} component={UserPanel} />
-    <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} />
@@ -218,7 +214,6 @@ export const WorkbenchPanel =
             <AddGroupMembersDialog />
             <AdvancedTabDialog />
             <AttributesApiClientAuthorizationDialog />
-            <AttributesComputeNodeDialog />
             <AttributesKeepServiceDialog />
             <AttributesLinkDialog />
             <AttributesSshKeyDialog />
@@ -250,7 +245,6 @@ export const WorkbenchPanel =
             <ProjectPropertiesDialog />
             <RestoreCollectionVersionDialog />
             <RemoveApiClientAuthorizationDialog />
-            <RemoveComputeNodeDialog />
             <RemoveGroupDialog />
             <RemoveGroupMemberDialog />
             <RemoveKeepServiceDialog />

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


hooks/post-receive
-- 




More information about the arvados-commits mailing list