[ARVADOS-WORKBENCH2] updated: 2.2.1-57-g0f7f4ab0
Git user
git at public.arvados.org
Thu Aug 26 19:44:19 UTC 2021
Summary of changes:
cypress/integration/collection.spec.js | 104 ++++--------------
src/common/config.ts | 25 +----
src/components/checkbox-field/checkbox-field.tsx | 64 +----------
src/store/collections/collection-create-actions.ts | 1 -
src/store/collections/collection-update-actions.ts | 2 -
src/store/context-menu/context-menu-actions.ts | 1 -
.../actions/collection-file-viewer-action.test.tsx | 117 +++++++++++++++++++++
.../actions/collection-file-viewer-action.tsx | 9 +-
.../context-menu/actions/helpers.ts | 9 +-
.../details-panel/collection-details.tsx | 6 +-
.../details-panel/details-data.tsx | 7 +-
.../details-panel/details-panel.tsx | 20 +++-
.../details-panel/file-details.tsx | 4 +-
.../dialog-create/dialog-collection-create.tsx | 7 +-
.../dialog-forms/create-collection-dialog.ts | 2 +-
.../dialog-forms/update-collection-dialog.ts | 12 +--
.../dialog-update/dialog-collection-update.tsx | 7 +-
.../form-fields/collection-form-fields.tsx | 24 -----
.../collection-content-address-panel.tsx | 28 ++---
src/views/collection-panel/collection-panel.tsx | 7 +-
src/views/favorite-panel/favorite-panel.tsx | 4 +-
src/views/project-panel/project-panel.tsx | 2 -
.../public-favorites-panel.tsx | 2 -
tools/arvados_config.yml | 16 +--
24 files changed, 202 insertions(+), 278 deletions(-)
create mode 100644 src/views-components/context-menu/actions/collection-file-viewer-action.test.tsx
discards 2e83c4e79939937cb88c5fe9c02ce91459fc2655 (commit)
discards 6d6ea46757e93939c12d026faf9fd3c4d7b83122 (commit)
discards dc63b1fd2a8cbf8c15c5521c27ff72bb5f94e9c7 (commit)
discards 266f22d37cf94f56f857dbbb3e1e5fd2e9934175 (commit)
discards e31bd3f0af6e0b3d4166af144ef8aed5d110b5af (commit)
discards 4da9314a82505cd016803f806f96e5714cc59f0a (commit)
discards 81e046c27b73760acc5bffd51019516a2bbad94c (commit)
discards 4541e7e78a5fbbad1e34cf215fa7f2fa4d40e88d (commit)
discards 1f1c5dbbad160ef2cc7dc0a2cd736fefd5025d1e (commit)
discards ce576a6053b03f3222b30a129d77aa7f54fb1904 (commit)
discards 76f6fc151e007fcce23c89a7414cfbd7b116897b (commit)
discards c2ca3c3f0e34c6226ae8f96b3f68f099e0a2f65f (commit)
discards f1568d57ebf1cbe4c8e649b80633459bea4ad327 (commit)
discards 9deadbed533951f400aa2f626af04ccac21fe865 (commit)
discards 7bdf07a2661affc4f1496d73e27d16f6470e4e4a (commit)
discards ec862c8c86eab36e998186f3138dd396d4ec13f6 (commit)
discards fd49462a5a09e107b7bb5c0ef8635db328b399b8 (commit)
discards 4c35a8d1ba4aeda92e6be16dd389ee6189e32ad8 (commit)
discards ac8fd68834fc706b76fa32df82346d4a3df9026e (commit)
discards 02370859e71ada20e2247df02958a9c532fe614b (commit)
discards b6a0a363d77d17455aab16e09eeb67b9f8067843 (commit)
discards 77c5d854b58b46395c5db5531268494d40f27786 (commit)
discards 2bf65b0d575c9c1e67270b66a7b32b0acd5aff56 (commit)
discards 73122efb6429184611d17b3278ecbe9c2e26a6c2 (commit)
discards 41a579060898b29e6d50000e6f95c93d97a7a433 (commit)
discards e07a6c34953c6546de1c3d13a0bacf031981c356 (commit)
discards 64c1e51d2d973cb0ef0f982afbb80efdb2700ea0 (commit)
discards 463581836f4fa5f1a6a54358998de32aa1dbd8e3 (commit)
discards c025baa77d3d077bc79283cce71e91c3aef06e4b (commit)
discards 9df0dc3888f9d63ae0844e7425cd02b21af9da68 (commit)
discards 8e3a9d4984273a913d472c4af63024c839d22ec6 (commit)
discards 87fff7ceda76e813646e3fe1c2c41bb8ad567143 (commit)
discards 83fd81b2e9518ac54f57e5463b6511da6257b2f7 (commit)
discards a15202e53207acc1878f02c00224d1df9540da8c (commit)
discards 20063f6f7bb9ad7c6a9a0b49b3c5ba4b0abc532e (commit)
discards 6ddbc50bc04b9bedce3f54cf69660fc819fce67a (commit)
discards 8df73e82d637d7b2e81952fdc96a12a1011be99e (commit)
discards e5dc88dd1a6c54610d92854d527e5048543d93ec (commit)
discards ad956f33b83e55aadca7189d5352940aaeadd659 (commit)
discards 40f03448780c8b22cba93d4eff9ca976cea45abf (commit)
discards 3556e5483957f8479c5747e36c626e91a655cc21 (commit)
via 0f7f4ab0fc5027f0de921eafa42046712c5a392c (commit)
via 9e7204697d09dc040bc79832b9bc56cc16b0adfa (commit)
via c11e86550ab3732a9245589b741f14a80fdb92eb (commit)
via a798c09d9460952c7395838950fe7ffbfb23d1f5 (commit)
via f43c86f02dd7eff91d125945a2860e1151ac5262 (commit)
via de2ecc267f382654b48e7cd64f3365655af097be (commit)
via 57056db59366e9af536d9796c3a9ca0e709e8231 (commit)
via 13c8e3af81d583cce6bf1618b14e3174bc8ddfd4 (commit)
via 91c0a082699fa9924c5e85826a107893d6de4ac8 (commit)
via c0bd8013a0941d5a8b0ce0478da025bb8f6bb6c5 (commit)
via 49f9e629a1fb1806baecd4eb04b46917c13aa928 (commit)
via 8650023dd84a06bb3353b6f0c94e111c0bd192cf (commit)
via 41d10c5792a7a866cc5a8f2d49f6b22f1bed24e1 (commit)
via c154977f29cdd067f7f9316b472cc08c086d29c9 (commit)
via 626b653fb1e9c8fffc8873d8e59f6e87f5a1cf83 (commit)
via 57f62c90bb7b7a89ad8ac040812989f140fb637f (commit)
via eb9f55920f1a8ed73e0d931add118501c713d274 (commit)
via e16c61adea5e8eccd1236d8608a750cd7cb565df (commit)
via 2352fda90d2bf2e7d3b09c3f50014b21a8a65ebb (commit)
via 7edfda6a34df2bdd6cb21f22a952f3070de58866 (commit)
via fffe0e4cf71da4c8d2cdca2db958fa6403d0e5ec (commit)
via 7ffd14cca42d5e2c75722f916f5362b32d9a07be (commit)
via 8d954ff99ea4dfda2588c17314dd64f378871ee0 (commit)
via 2953ffd61e451f6bb75bf51489ceeb983e774626 (commit)
via acf4d6c3197384510ab18f4aa776b283480458ea (commit)
via a8e2b7c927f403b8c6b497bbefd3106e3b6db7ef (commit)
via 8451c622fdc4321f7c19c1c09975263a19a7023c (commit)
via f4cb3271191ef9a4978556caec65c146f0d21160 (commit)
via efbe3df438e43ac3f620a37da60ebc18ce3f495c (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (2e83c4e79939937cb88c5fe9c02ce91459fc2655)
\
N -- N -- N (0f7f4ab0fc5027f0de921eafa42046712c5a392c)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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 0f7f4ab0fc5027f0de921eafa42046712c5a392c
Author: Stephen Smith <stephen at curii.com>
Date: Wed Aug 25 01:28:36 2021 -0400
15159: Add unit tests for collection-file-viewer-action and TrustAllContent / secure URLs
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/context-menu/actions/collection-file-viewer-action.test.tsx b/src/views-components/context-menu/actions/collection-file-viewer-action.test.tsx
new file mode 100644
index 00000000..8b90f588
--- /dev/null
+++ b/src/views-components/context-menu/actions/collection-file-viewer-action.test.tsx
@@ -0,0 +1,117 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import React from 'react';
+import { mount, configure } from 'enzyme';
+import Adapter from 'enzyme-adapter-react-16';
+import configureMockStore from 'redux-mock-store'
+import { Provider } from 'react-redux';
+import { CollectionFileViewerAction } from './collection-file-viewer-action';
+import { ContextMenuKind } from 'views-components/context-menu/context-menu';
+import { createTree, initTreeNode, setNode, getNodeValue } from "models/tree";
+import { getInlineFileUrl, sanitizeToken } from "./helpers";
+
+const middlewares = [];
+const mockStore = configureMockStore(middlewares);
+
+configure({ adapter: new Adapter() });
+
+describe('CollectionFileViewerAction', () => {
+ let defaultStore;
+ const fileUrl = "https://download.host:12345/c=abcde-4zz18-abcdefghijklmno/t=v2/token2/token3/cat.jpg";
+ const insecureKeepInlineUrl = "https://download.host:12345/";
+ const secureKeepInlineUrl = "https://*.collections.host:12345/";
+
+ beforeEach(() => {
+ let filesTree = createTree();
+ let data = {id: "000", value: {"url": fileUrl}};
+ filesTree = setNode(initTreeNode(data))(filesTree);
+
+ defaultStore = {
+ auth: {
+ config: {
+ keepWebServiceUrl: "https://download.host:12345/",
+ keepWebInlineServiceUrl: insecureKeepInlineUrl,
+ clusterConfig: {
+ Collections: {
+ TrustAllContent: false
+ }
+ }
+ }
+ },
+ contextMenu: {
+ resource: {
+ uuid: "000",
+ menuKind: ContextMenuKind.COLLECTION_FILE_ITEM,
+ }
+ },
+ collectionPanel: {
+ item: {
+ uuid: ""
+ }
+ },
+ collectionPanelFiles: filesTree
+ };
+ });
+
+ it('should hide open in new tab when unsafe', () => {
+ // given
+ const store = mockStore(defaultStore);
+
+ // when
+ const wrapper = mount(<Provider store={store}>
+ <CollectionFileViewerAction />
+ </Provider>);
+
+ // then
+ expect(wrapper).not.toBeUndefined();
+
+ // and
+ expect(wrapper.find("a")).toHaveLength(0);
+ });
+
+ it('should show open in new tab when TrustAllContent=true', () => {
+ // given
+ let initialState = defaultStore;
+ initialState.auth.config.clusterConfig.Collections.TrustAllContent = true;
+ const store = mockStore(initialState);
+
+ // when
+ const wrapper = mount(<Provider store={store}>
+ <CollectionFileViewerAction />
+ </Provider>);
+
+ // then
+ expect(wrapper).not.toBeUndefined();
+
+ // and
+ expect(wrapper.find("a").prop("href"))
+ .toEqual(sanitizeToken(getInlineFileUrl(fileUrl,
+ initialState.auth.config.keepWebServiceUrl,
+ initialState.auth.config.keepWebInlineServiceUrl))
+ );
+ });
+
+ it('should show open in new tab when inline url is secure', () => {
+ // given
+ let initialState = defaultStore;
+ initialState.auth.config.keepWebInlineServiceUrl = secureKeepInlineUrl;
+ const store = mockStore(initialState);
+
+ // when
+ const wrapper = mount(<Provider store={store}>
+ <CollectionFileViewerAction />
+ </Provider>);
+
+ // then
+ expect(wrapper).not.toBeUndefined();
+
+ // and
+ expect(wrapper.find("a").prop("href"))
+ .toEqual(sanitizeToken(getInlineFileUrl(fileUrl,
+ initialState.auth.config.keepWebServiceUrl,
+ initialState.auth.config.keepWebInlineServiceUrl))
+ );
+ });
+});
commit 9e7204697d09dc040bc79832b9bc56cc16b0adfa
Author: Stephen Smith <stephen at curii.com>
Date: Tue Aug 24 14:57:33 2021 -0400
15159: Update cypress tests to check clusterConfig and inlineUrl for hiding open in new tab
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index 1b9c0849..4690374d 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -122,12 +122,22 @@ describe('Collection panel tests', function () {
}).as('sharedGroup').then(function () {
// Creates the collection using the admin token so we can set up
// a bogus manifest text without block signatures.
- cy.createCollection(adminUser.token, {
- name: 'Test collection',
- owner_uuid: this.sharedGroup.uuid,
- properties: { someKey: 'someValue' },
- manifest_text: `. 37b51d194a7513e45b56f6524f2d51f2+3 0:3:${fileName}\n./${subDirName} 37b51d194a7513e45b56f6524f2d51f2+3 0:3:${fileName}\n`
- })
+ cy.doRequest('GET', '/arvados/v1/config', null, null)
+ .its('body').should((clusterConfig) => {
+ expect(clusterConfig.Collections, "clusterConfig").to.have.property("TrustAllContent", false);
+ expect(clusterConfig.Services, "clusterConfig").to.have.property("WebDAV").have.property("ExternalURL");
+ expect(clusterConfig.Services, "clusterConfig").to.have.property("WebDAVDownload").have.property("ExternalURL");
+ const inlineUrl = clusterConfig.Services.WebDAV.ExternalURL !== ""
+ ? clusterConfig.Services.WebDAV.ExternalURL
+ : clusterConfig.Services.WebDAVDownload.ExternalURL;
+ expect(inlineUrl).to.not.contain("*");
+ })
+ .createCollection(adminUser.token, {
+ name: 'Test collection',
+ owner_uuid: this.sharedGroup.uuid,
+ properties: { someKey: 'someValue' },
+ manifest_text: `. 37b51d194a7513e45b56f6524f2d51f2+3 0:3:${fileName}\n./${subDirName} 37b51d194a7513e45b56f6524f2d51f2+3 0:3:${fileName}\n`
+ })
.as('testCollection').then(function () {
// Share the group with active user.
cy.createLink(adminUser.token, {
@@ -189,6 +199,7 @@ describe('Collection panel tests', function () {
.contains(fileName).rightclick({ force: true });
cy.get('[data-cy=context-menu]')
.should('contain', 'Download')
+ .and('not.contain', 'Open in new tab')
.and('contain', 'Copy to clipboard')
.and(`${isWritable ? '' : 'not.'}contain`, 'Rename')
.and(`${isWritable ? '' : 'not.'}contain`, 'Remove');
@@ -197,6 +208,7 @@ describe('Collection panel tests', function () {
.contains(subDirName).rightclick({ force: true });
cy.get('[data-cy=context-menu]')
.should('not.contain', 'Download')
+ .and('not.contain', 'Open in new tab')
.and('contain', 'Copy to clipboard')
.and(`${isWritable ? '' : 'not.'}contain`, 'Rename')
.and(`${isWritable ? '' : 'not.'}contain`, 'Remove');
commit c11e86550ab3732a9245589b741f14a80fdb92eb
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 23 09:31:21 2021 -0400
15159: Hide file preview when not secure and trustallcontent is false
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 7136c850..c449a2be 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -42,8 +42,8 @@ export class CollectionDetails extends DetailsData<CollectionResource> {
return ['Details', 'Versions'];
}
- getDetails(tabNumber: number) {
- switch (tabNumber) {
+ getDetails({tabNr}) {
+ switch (tabNr) {
case 0:
return this.getCollectionInfo();
case 1:
diff --git a/src/views-components/details-panel/details-data.tsx b/src/views-components/details-panel/details-data.tsx
index 0fae2ac4..bcca325c 100644
--- a/src/views-components/details-panel/details-data.tsx
+++ b/src/views-components/details-panel/details-data.tsx
@@ -5,6 +5,11 @@
import React from 'react';
import { DetailsResource } from "models/details";
+interface GetDetailsParams {
+ tabNr?: number
+ showPreview?: boolean
+}
+
export abstract class DetailsData<T extends DetailsResource = DetailsResource> {
constructor(protected item: T) { }
@@ -17,5 +22,5 @@ export abstract class DetailsData<T extends DetailsResource = DetailsResource> {
}
abstract getIcon(className?: string): React.ReactElement<any>;
- abstract getDetails(tabNr?: number): React.ReactElement<any>;
+ abstract getDetails({tabNr, showPreview}: GetDetailsParams): React.ReactElement<any>;
}
diff --git a/src/views-components/details-panel/details-panel.tsx b/src/views-components/details-panel/details-panel.tsx
index 38ac163e..058db81b 100644
--- a/src/views-components/details-panel/details-panel.tsx
+++ b/src/views-components/details-panel/details-panel.tsx
@@ -20,6 +20,8 @@ import { ProcessDetails } from "./process-details";
import { EmptyDetails } from "./empty-details";
import { DetailsData } from "./details-data";
import { DetailsResource } from "models/details";
+import { Config } from 'common/config';
+import { isInlineFileUrlSafe } from "../context-menu/actions/helpers";
import { getResource } from 'store/resources/resources';
import { toggleDetailsPanel, SLIDE_TIMEOUT, openDetailsPanel } from 'store/details-panel/details-panel-action';
import { FileDetails } from 'views-components/details-panel/file-details';
@@ -77,12 +79,13 @@ const getItem = (res: DetailsResource): DetailsData => {
}
};
-const mapStateToProps = ({ detailsPanel, resources, collectionPanelFiles }: RootState) => {
+const mapStateToProps = ({ auth, detailsPanel, resources, collectionPanelFiles }: RootState) => {
const resource = getResource(detailsPanel.resourceUuid)(resources) as DetailsResource | undefined;
const file = resource
? undefined
: getNode(detailsPanel.resourceUuid)(collectionPanelFiles);
return {
+ authConfig: auth.config,
isOpened: detailsPanel.isOpened,
tabNr: detailsPanel.tabNr,
res: resource || (file && file.value) || EMPTY_RESOURCE,
@@ -101,6 +104,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
export interface DetailsPanelDataProps {
onCloseDrawer: () => void;
setActiveTab: (tabNr: number) => void;
+ authConfig: Config;
isOpened: boolean;
tabNr: number;
res: DetailsResource;
@@ -143,7 +147,17 @@ export const DetailsPanel = withStyles(styles)(
}
renderContent() {
- const { classes, onCloseDrawer, res, tabNr } = this.props;
+ const { classes, onCloseDrawer, res, tabNr, authConfig } = this.props;
+
+ let shouldShowInlinePreview = false;
+ if (!('kind' in res)) {
+ shouldShowInlinePreview = isInlineFileUrlSafe(
+ res ? res.url : "",
+ authConfig.keepWebServiceUrl,
+ authConfig.keepWebInlineServiceUrl
+ ) || authConfig.clusterConfig.Collections.TrustAllContent;
+ }
+
const item = getItem(res);
return <Grid
container
@@ -183,7 +197,7 @@ export const DetailsPanel = withStyles(styles)(
</Tabs>
</Grid>
<Grid item xs className={this.props.classes.tabContainer} >
- {item.getDetails(tabNr)}
+ {item.getDetails({tabNr, showPreview: shouldShowInlinePreview})}
</Grid>
</Grid >;
}
diff --git a/src/views-components/details-panel/file-details.tsx b/src/views-components/details-panel/file-details.tsx
index 7c11eb8b..7b128c2c 100644
--- a/src/views-components/details-panel/file-details.tsx
+++ b/src/views-components/details-panel/file-details.tsx
@@ -18,13 +18,13 @@ export class FileDetails extends DetailsData<CollectionFile | CollectionDirector
return <Icon className={className} />;
}
- getDetails() {
+ getDetails({showPreview}) {
const { item } = this;
return item.type === CollectionFileType.FILE
? <>
<DetailsAttribute label='Size' value={formatFileSize(item.size)} />
{
- isImage(item.url) && <>
+ isImage(item.url) && showPreview && <>
<DetailsAttribute label='Preview' />
<FileThumbnail file={item} />
</>
commit a798c09d9460952c7395838950fe7ffbfb23d1f5
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 16 16:00:08 2021 -0400
15159: Update cypress tests to not expect open file in new tab
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index 3b370b60..1b9c0849 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -189,7 +189,6 @@ describe('Collection panel tests', function () {
.contains(fileName).rightclick({ force: true });
cy.get('[data-cy=context-menu]')
.should('contain', 'Download')
- .and('contain', 'Open in new tab')
.and('contain', 'Copy to clipboard')
.and(`${isWritable ? '' : 'not.'}contain`, 'Rename')
.and(`${isWritable ? '' : 'not.'}contain`, 'Remove');
@@ -198,7 +197,6 @@ describe('Collection panel tests', function () {
.contains(subDirName).rightclick({ force: true });
cy.get('[data-cy=context-menu]')
.should('not.contain', 'Download')
- .and('contain', 'Open in new tab')
.and('contain', 'Copy to clipboard')
.and(`${isWritable ? '' : 'not.'}contain`, 'Rename')
.and(`${isWritable ? '' : 'not.'}contain`, 'Remove');
commit f43c86f02dd7eff91d125945a2860e1151ac5262
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 16 15:17:28 2021 -0400
15159: Hide "open in new tab" if unsafe and TrustAllContent is false
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/common/config.ts b/src/common/config.ts
index f3d06840..d2ddb947 100644
--- a/src/common/config.ts
+++ b/src/common/config.ts
@@ -89,7 +89,8 @@ export interface ClusterConfigJSON {
Value: string,
Protected?: boolean,
}
- }
+ },
+ TrustAllContent: boolean
};
}
@@ -251,6 +252,7 @@ export const mockClusterConfigJSON = (config: Partial<ClusterConfigJSON>): Clust
},
Collections: {
ForwardSlashNameSubstitution: "",
+ TrustAllContent: false,
},
...config
});
diff --git a/src/views-components/context-menu/actions/collection-file-viewer-action.tsx b/src/views-components/context-menu/actions/collection-file-viewer-action.tsx
index 27a65018..f736f0bf 100644
--- a/src/views-components/context-menu/actions/collection-file-viewer-action.tsx
+++ b/src/views-components/context-menu/actions/collection-file-viewer-action.tsx
@@ -7,7 +7,7 @@ import { RootState } from "../../../store/store";
import { FileViewerAction } from 'views-components/context-menu/actions/file-viewer-action';
import { getNodeValue } from "models/tree";
import { ContextMenuKind } from 'views-components/context-menu/context-menu';
-import { getInlineFileUrl, sanitizeToken } from "./helpers";
+import { getInlineFileUrl, sanitizeToken, isInlineFileUrlSafe } from "./helpers";
const mapStateToProps = (state: RootState) => {
const { resource } = state.contextMenu;
@@ -18,7 +18,12 @@ const mapStateToProps = (state: RootState) => {
ContextMenuKind.COLLECTION_DIRECTORY_ITEM,
ContextMenuKind.READONLY_COLLECTION_DIRECTORY_ITEM ].indexOf(resource.menuKind as ContextMenuKind) > -1) {
const file = getNodeValue(resource.uuid)(state.collectionPanelFiles);
- if (file) {
+ const shouldShowInlineUrl = isInlineFileUrlSafe(
+ file ? file.url : "",
+ state.auth.config.keepWebServiceUrl,
+ state.auth.config.keepWebInlineServiceUrl
+ ) || state.auth.config.clusterConfig.Collections.TrustAllContent;
+ if (file && shouldShowInlineUrl) {
const fileUrl = sanitizeToken(getInlineFileUrl(
file.url,
state.auth.config.keepWebServiceUrl,
diff --git a/src/views-components/context-menu/actions/helpers.ts b/src/views-components/context-menu/actions/helpers.ts
index dfa8d04f..159b1c18 100644
--- a/src/views-components/context-menu/actions/helpers.ts
+++ b/src/views-components/context-menu/actions/helpers.ts
@@ -43,4 +43,11 @@ export const getInlineFileUrl = (url: string, keepWebSvcUrl: string, keepWebInli
inlineUrl = inlineUrl.replace(`/c=${collMatch[1]}`, '');
}
return inlineUrl;
-};
\ No newline at end of file
+};
+
+export const isInlineFileUrlSafe = (url: string, keepWebSvcUrl: string, keepWebInlineSvcUrl: string): boolean => {
+ let inlineUrl = keepWebInlineSvcUrl !== ""
+ ? url.replace(keepWebSvcUrl, keepWebInlineSvcUrl)
+ : url;
+ return inlineUrl.indexOf('*.') > -1;
+}
diff --git a/tools/arvados_config.yml b/tools/arvados_config.yml
index a287fed4..9b82948c 100644
--- a/tools/arvados_config.yml
+++ b/tools/arvados_config.yml
@@ -10,7 +10,7 @@ Clusters:
CollectionVersioning: true
PreserveVersionIfIdle: -1s
BlobSigningKey: zfhgfenhffzltr9dixws36j1yhksjoll2grmku38mi7yxd66h5j4q9w4jzanezacp8s6q0ro3hxakfye02152hncy6zml2ed0uc
- TrustAllContent: true
+ TrustAllContent: false
ForwardSlashNameSubstitution: /
ManagedProperties:
original_owner_uuid: {Function: original_owner, Protected: true}
commit de2ecc267f382654b48e7cd64f3365655af097be
Author: Stephen Smith <stephen at curii.com>
Date: Thu Aug 12 13:59:51 2021 -0400
17532: Add cypress test for collection history username
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index f1e337de..3b370b60 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -469,10 +469,14 @@ describe('Collection panel tests', function () {
.within(() => {
// Version 1: 6 bytes in size
cy.get('[data-cy=collection-version-browser-select-1]')
- .should('contain', '1').and('contain', '6 B');
+ .should('contain', '1')
+ .and('contain', '6 B')
+ .and('contain', adminUser.user.uuid);
// Version 2: 3 bytes in size (one file removed)
cy.get('[data-cy=collection-version-browser-select-2]')
- .should('contain', '2').and('contain', '3 B');
+ .should('contain', '2')
+ .and('contain', '3 B')
+ .and('contain', activeUser.user.full_name);
cy.get('[data-cy=collection-version-browser-select-3]')
.should('not.exist');
cy.get('[data-cy=collection-version-browser-select-1]')
commit 57056db59366e9af536d9796c3a9ca0e709e8231
Author: Stephen Smith <stephen at curii.com>
Date: Thu Aug 12 11:10:17 2021 -0400
17532: Move collection details history modified by to its own row
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index f28f8aa0..3965e69d 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -465,9 +465,9 @@ export const UserNameFromID =
if (userFullname === '') {
dispatch<any>(loadResource(uuid, false));
}
- return <Typography inline>
+ return <span>
{userFullname ? userFullname : uuid}
- </Typography>;
+ </span>;
});
export const ResponsiblePerson =
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 3c89a154..7136c850 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -17,7 +17,7 @@ import { Dispatch } from 'redux';
import { navigateTo } from 'store/navigation/navigation-action';
import { openContextMenu, resourceUuidToContextMenuKind } from 'store/context-menu/context-menu-actions';
-export type CssRules = 'versionBrowserHeader' | 'versionBrowserItem';
+export type CssRules = 'versionBrowserHeader' | 'versionBrowserItem' | 'versionBrowserField';
const styles: StyleRulesCallback<CssRules> = theme => ({
versionBrowserHeader: {
@@ -25,6 +25,9 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
fontWeight: 'bold',
},
versionBrowserItem: {
+ flexWrap: 'wrap',
+ },
+ versionBrowserField: {
textAlign: 'center',
}
});
@@ -107,17 +110,12 @@ const CollectionVersionBrowser = withStyles(styles)(
Nr
</Typography>
</Grid>
- <Grid item xs={2}>
+ <Grid item xs={4}>
<Typography variant="caption" className={classes.versionBrowserHeader}>
Size
</Typography>
</Grid>
- <Grid item xs={3}>
- <Typography variant="caption" className={classes.versionBrowserHeader}>
- User
- </Typography>
- </Grid>
- <Grid item xs={5}>
+ <Grid item xs={6}>
<Typography variant="caption" className={classes.versionBrowserHeader}>
Date
</Typography>
@@ -130,25 +128,26 @@ const CollectionVersionBrowser = withStyles(styles)(
key={item.version}
onClick={e => showVersion(item)}
onContextMenu={event => handleContextMenu(event, item)}
- selected={isSelectedVersion}>
+ selected={isSelectedVersion}
+ className={classes.versionBrowserItem}>
<Grid item xs={2}>
- <Typography variant="caption" className={classes.versionBrowserItem}>
+ <Typography variant="caption" className={classes.versionBrowserField}>
{item.version}
</Typography>
</Grid>
- <Grid item xs={2}>
- <Typography variant="caption" className={classes.versionBrowserItem}>
+ <Grid item xs={4}>
+ <Typography variant="caption" className={classes.versionBrowserField}>
{formatFileSize(item.fileSizeTotal)}
</Typography>
</Grid>
- <Grid item xs={3}>
- <Typography variant="caption" className={classes.versionBrowserItem}>
- <UserNameFromID uuid={item.modifiedByUserUuid} />
+ <Grid item xs={6}>
+ <Typography variant="caption" className={classes.versionBrowserField}>
+ {formatDate(item.modifiedAt)}
</Typography>
</Grid>
- <Grid item xs={5}>
- <Typography variant="caption" className={classes.versionBrowserItem}>
- {formatDate(item.modifiedAt)}
+ <Grid item xs={12}>
+ <Typography variant="caption" className={classes.versionBrowserField}>
+ Modified by: <UserNameFromID uuid={item.modifiedByUserUuid} />
</Typography>
</Grid>
</ListItem>
commit 13c8e3af81d583cce6bf1618b14e3174bc8ddfd4
Author: Stephen Smith <stephen at curii.com>
Date: Tue Aug 10 10:45:09 2021 -0400
17532: Remove unused code in renderers
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index 4a56b142..f28f8aa0 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -458,10 +458,8 @@ export const ResourceOwnerWithName =
});
export const UserNameFromID =
- compose(
- userFromID,
- withStyles({}, { withTheme: true }))
- ((props: { uuid: string, userFullname: string, dispatch: Dispatch }) => {
+ compose(userFromID)(
+ (props: { uuid: string, userFullname: string, dispatch: Dispatch }) => {
const { uuid, userFullname, dispatch } = props;
if (userFullname === '') {
commit 91c0a082699fa9924c5e85826a107893d6de4ac8
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 9 21:26:41 2021 -0400
17532: Add modifiedByUser to collection details version history table
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx
index 314390e2..4a56b142 100644
--- a/src/views-components/data-explorer/renderers.tsx
+++ b/src/views-components/data-explorer/renderers.tsx
@@ -425,24 +425,27 @@ export const ResourceOwnerName = connect(
return { owner: ownerName ? ownerName!.name : resource!.ownerUuid };
})((props: { owner: string }) => renderOwner(props.owner));
-export const ResourceOwnerWithName =
- compose(
- connect(
- (state: RootState, props: { uuid: string }) => {
- let ownerName = '';
- const resource = getResource<GroupContentsResource & UserResource>(props.uuid)(state.resources);
+const userFromID =
+ connect(
+ (state: RootState, props: { uuid: string }) => {
+ let userFullname = '';
+ const resource = getResource<GroupContentsResource & UserResource>(props.uuid)(state.resources);
+
+ if (resource) {
+ userFullname = getUserFullname(resource as User) || (resource as GroupContentsResource).name;
+ }
- if (resource) {
- ownerName = getUserFullname(resource as User) || (resource as GroupContentsResource).name;
- }
+ return { uuid: props.uuid, userFullname };
+ });
- return { uuid: props.uuid, ownerName };
- }),
+export const ResourceOwnerWithName =
+ compose(
+ userFromID,
withStyles({}, { withTheme: true }))
- ((props: { uuid: string, ownerName: string, dispatch: Dispatch, theme: ArvadosTheme }) => {
- const { uuid, ownerName, dispatch, theme } = props;
+ ((props: { uuid: string, userFullname: string, dispatch: Dispatch, theme: ArvadosTheme }) => {
+ const { uuid, userFullname, dispatch, theme } = props;
- if (ownerName === '') {
+ if (userFullname === '') {
dispatch<any>(loadResource(uuid, false));
return <Typography style={{ color: theme.palette.primary.main }} inline noWrap>
{uuid}
@@ -450,7 +453,22 @@ export const ResourceOwnerWithName =
}
return <Typography style={{ color: theme.palette.primary.main }} inline noWrap>
- {ownerName} ({uuid})
+ {userFullname} ({uuid})
+ </Typography>;
+ });
+
+export const UserNameFromID =
+ compose(
+ userFromID,
+ withStyles({}, { withTheme: true }))
+ ((props: { uuid: string, userFullname: string, dispatch: Dispatch }) => {
+ const { uuid, userFullname, dispatch } = props;
+
+ if (userFullname === '') {
+ dispatch<any>(loadResource(uuid, false));
+ }
+ return <Typography inline>
+ {userFullname ? userFullname : uuid}
</Typography>;
});
diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx
index 0e747fed..3c89a154 100644
--- a/src/views-components/details-panel/collection-details.tsx
+++ b/src/views-components/details-panel/collection-details.tsx
@@ -12,6 +12,7 @@ import { filterResources, getResource } from 'store/resources/resources';
import { connect } from 'react-redux';
import { Grid, ListItem, StyleRulesCallback, Typography, withStyles, WithStyles } from '@material-ui/core';
import { formatDate, formatFileSize } from 'common/formatters';
+import { UserNameFromID } from '../data-explorer/renderers';
import { Dispatch } from 'redux';
import { navigateTo } from 'store/navigation/navigation-action';
import { openContextMenu, resourceUuidToContextMenuKind } from 'store/context-menu/context-menu-actions';
@@ -106,12 +107,17 @@ const CollectionVersionBrowser = withStyles(styles)(
Nr
</Typography>
</Grid>
- <Grid item xs={4}>
+ <Grid item xs={2}>
<Typography variant="caption" className={classes.versionBrowserHeader}>
Size
</Typography>
</Grid>
- <Grid item xs={6}>
+ <Grid item xs={3}>
+ <Typography variant="caption" className={classes.versionBrowserHeader}>
+ User
+ </Typography>
+ </Grid>
+ <Grid item xs={5}>
<Typography variant="caption" className={classes.versionBrowserHeader}>
Date
</Typography>
@@ -130,12 +136,17 @@ const CollectionVersionBrowser = withStyles(styles)(
{item.version}
</Typography>
</Grid>
- <Grid item xs={4}>
+ <Grid item xs={2}>
<Typography variant="caption" className={classes.versionBrowserItem}>
{formatFileSize(item.fileSizeTotal)}
</Typography>
</Grid>
- <Grid item xs={6}>
+ <Grid item xs={3}>
+ <Typography variant="caption" className={classes.versionBrowserItem}>
+ <UserNameFromID uuid={item.modifiedByUserUuid} />
+ </Typography>
+ </Grid>
+ <Grid item xs={5}>
<Typography variant="caption" className={classes.versionBrowserItem}>
{formatDate(item.modifiedAt)}
</Typography>
@@ -145,4 +156,4 @@ const CollectionVersionBrowser = withStyles(styles)(
})}
</Grid>
</div>;
- }));
\ No newline at end of file
+ }));
commit c0bd8013a0941d5a8b0ce0478da025bb8f6bb6c5
Author: Stephen Smith <stephen at curii.com>
Date: Tue Aug 10 15:19:13 2021 -0400
17982: Trigger loading saved/recent queries when clicking empty search bar
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/search-bar/search-bar-view.tsx b/src/views-components/search-bar/search-bar-view.tsx
index 7f5c1566..28408347 100644
--- a/src/views-components/search-bar/search-bar-view.tsx
+++ b/src/views-components/search-bar/search-bar-view.tsx
@@ -128,10 +128,10 @@ const handleKeyDown = (e: React.KeyboardEvent, props: SearchBarViewProps) => {
const handleInputClick = (e: React.MouseEvent, props: SearchBarViewProps) => {
if (props.searchValue) {
props.onSetView(SearchView.AUTOCOMPLETE);
- props.openSearchView();
} else {
props.onSetView(SearchView.BASIC);
}
+ props.openSearchView();
};
const handleDropdownClick = (e: React.MouseEvent, props: SearchBarViewProps) => {
commit 49f9e629a1fb1806baecd4eb04b46917c13aa928
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Tue Aug 10 14:27:05 2021 -0300
17982: Updates integration test cluster's config file to make tests work again.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/src/views/ssh-key-panel/ssh-key-panel.tsx b/src/views/ssh-key-panel/ssh-key-panel.tsx
index 672b1bf3..24ca3468 100644
--- a/src/views/ssh-key-panel/ssh-key-panel.tsx
+++ b/src/views/ssh-key-panel/ssh-key-panel.tsx
@@ -11,7 +11,7 @@ import { SshKeyPanelRoot, SshKeyPanelRootDataProps, SshKeyPanelRootActionProps }
const mapStateToProps = (state: RootState): SshKeyPanelRootDataProps => {
const sshKeys = state.auth.sshKeys.filter((key) => {
- return key.authorizedUserUuid == (state.auth.user ? state.auth.user.uuid : null);
+ return key.authorizedUserUuid === (state.auth.user ? state.auth.user.uuid : null);
});
return {
commit 8650023dd84a06bb3353b6f0c94e111c0bd192cf
Author: Stephen Smith <stephen at curii.com>
Date: Sun Aug 8 22:45:17 2021 -0400
17982: Open basic searchview on click if searchValue is empty
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/search-bar/search-bar-view.tsx b/src/views-components/search-bar/search-bar-view.tsx
index cab53403..7f5c1566 100644
--- a/src/views-components/search-bar/search-bar-view.tsx
+++ b/src/views-components/search-bar/search-bar-view.tsx
@@ -130,7 +130,7 @@ const handleInputClick = (e: React.MouseEvent, props: SearchBarViewProps) => {
props.onSetView(SearchView.AUTOCOMPLETE);
props.openSearchView();
} else {
- props.closeView();
+ props.onSetView(SearchView.BASIC);
}
};
commit 41d10c5792a7a866cc5a8f2d49f6b22f1bed24e1
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 2 16:45:55 2021 -0400
17690: Add guard against undefined user in ssh key page
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views/ssh-key-panel/ssh-key-panel.tsx b/src/views/ssh-key-panel/ssh-key-panel.tsx
index 0c86b364..672b1bf3 100644
--- a/src/views/ssh-key-panel/ssh-key-panel.tsx
+++ b/src/views/ssh-key-panel/ssh-key-panel.tsx
@@ -11,7 +11,7 @@ import { SshKeyPanelRoot, SshKeyPanelRootDataProps, SshKeyPanelRootActionProps }
const mapStateToProps = (state: RootState): SshKeyPanelRootDataProps => {
const sshKeys = state.auth.sshKeys.filter((key) => {
- return key.authorizedUserUuid == state.auth.user.uuid;
+ return key.authorizedUserUuid == (state.auth.user ? state.auth.user.uuid : null);
});
return {
commit c154977f29cdd067f7f9316b472cc08c086d29c9
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 2 15:26:05 2021 -0400
17690: Fix stray accidental copy+paste
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views/ssh-key-panel/ssh-key-panel.tsx b/src/views/ssh-key-panel/ssh-key-panel.tsx
index f2b7dd3c..0c86b364 100644
--- a/src/views/ssh-key-panel/ssh-key-panel.tsx
+++ b/src/views/ssh-key-panel/ssh-key-panel.tsx
@@ -10,7 +10,7 @@ import { openSshKeyContextMenu } from 'store/context-menu/context-menu-actions';
import { SshKeyPanelRoot, SshKeyPanelRootDataProps, SshKeyPanelRootActionProps } from 'views/ssh-key-panel/ssh-key-panel-root';
const mapStateToProps = (state: RootState): SshKeyPanelRootDataProps => {
- const sshKeys = state.auth.sshKeys = state.auth.sshKeys.filter((key) => {
+ const sshKeys = state.auth.sshKeys.filter((key) => {
return key.authorizedUserUuid == state.auth.user.uuid;
});
commit 626b653fb1e9c8fffc8873d8e59f6e87f5a1cf83
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 2 15:16:03 2021 -0400
17690: Filter ssh keys shown in user keys to only current user
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views/ssh-key-panel/ssh-key-panel.tsx b/src/views/ssh-key-panel/ssh-key-admin-panel.tsx
similarity index 92%
copy from src/views/ssh-key-panel/ssh-key-panel.tsx
copy to src/views/ssh-key-panel/ssh-key-admin-panel.tsx
index 4d896f3d..72a8c4cb 100644
--- a/src/views/ssh-key-panel/ssh-key-panel.tsx
+++ b/src/views/ssh-key-panel/ssh-key-admin-panel.tsx
@@ -28,4 +28,4 @@ const mapDispatchToProps = (dispatch: Dispatch): SshKeyPanelRootActionProps => (
}
});
-export const SshKeyPanel = connect(mapStateToProps, mapDispatchToProps)(SshKeyPanelRoot);
+export const SshKeyAdminPanel = connect(mapStateToProps, mapDispatchToProps)(SshKeyPanelRoot);
diff --git a/src/views/ssh-key-panel/ssh-key-panel.tsx b/src/views/ssh-key-panel/ssh-key-panel.tsx
index 4d896f3d..f2b7dd3c 100644
--- a/src/views/ssh-key-panel/ssh-key-panel.tsx
+++ b/src/views/ssh-key-panel/ssh-key-panel.tsx
@@ -10,9 +10,13 @@ import { openSshKeyContextMenu } from 'store/context-menu/context-menu-actions';
import { SshKeyPanelRoot, SshKeyPanelRootDataProps, SshKeyPanelRootActionProps } from 'views/ssh-key-panel/ssh-key-panel-root';
const mapStateToProps = (state: RootState): SshKeyPanelRootDataProps => {
+ const sshKeys = state.auth.sshKeys = state.auth.sshKeys.filter((key) => {
+ return key.authorizedUserUuid == state.auth.user.uuid;
+ });
+
return {
- sshKeys: state.auth.sshKeys,
- hasKeys: state.auth.sshKeys!.length > 0
+ sshKeys: sshKeys,
+ hasKeys: sshKeys!.length > 0
};
};
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index b708355c..9ce93bf2 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -45,6 +45,7 @@ import SplitterLayout from 'react-splitter-layout';
import { WorkflowPanel } from 'views/workflow-panel/workflow-panel';
import { SearchResultsPanel } from 'views/search-results-panel/search-results-panel';
import { SshKeyPanel } from 'views/ssh-key-panel/ssh-key-panel';
+import { SshKeyAdminPanel } from 'views/ssh-key-panel/ssh-key-admin-panel';
import { SiteManagerPanel } from "views/site-manager-panel/site-manager-panel";
import { MyAccountPanel } from 'views/my-account-panel/my-account-panel';
import { SharingDialog } from 'views-components/sharing-dialog/sharing-dialog';
@@ -164,7 +165,7 @@ let routes = <>
<Route path={Routes.VIRTUAL_MACHINES_ADMIN} component={VirtualMachineAdminPanel} />
<Route path={Routes.REPOSITORIES} component={RepositoriesPanel} />
<Route path={Routes.SSH_KEYS_USER} component={SshKeyPanel} />
- <Route path={Routes.SSH_KEYS_ADMIN} component={SshKeyPanel} />
+ <Route path={Routes.SSH_KEYS_ADMIN} component={SshKeyAdminPanel} />
<Route path={Routes.SITE_MANAGER} component={SiteManagerPanel} />
<Route path={Routes.KEEP_SERVICES} component={KeepServicePanel} />
<Route path={Routes.USERS} component={UserPanel} />
commit 57f62c90bb7b7a89ad8ac040812989f140fb637f
Author: Stephen Smith <stephen at curii.com>
Date: Tue Aug 3 16:29:00 2021 -0400
17564: Change file size unit base from 1000 to 1024
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/common/formatters.ts b/src/common/formatters.ts
index eeab703d..779809f1 100644
--- a/src/common/formatters.ts
+++ b/src/common/formatters.ts
@@ -66,19 +66,19 @@ export function formatUploadSpeed(prevLoaded: number, loaded: number, prevTime:
const FILE_SIZES = [
{
- base: 1000000000000,
+ base: 1099511627776,
unit: "TB"
},
{
- base: 1000000000,
+ base: 1073741824,
unit: "GB"
},
{
- base: 1000000,
+ base: 1048576,
unit: "MB"
},
{
- base: 1000,
+ base: 1024,
unit: "KB"
},
{
commit eb9f55920f1a8ed73e0d931add118501c713d274
Author: Ward Vandewege <ward at curii.com>
Date: Wed Aug 4 12:58:10 2021 -0400
Update the package distribution target list: add debian11, remove
debian8, ubuntu1404, ubuntu1604.
No issue #
Arvados-DCO-1.1-Signed-off-by: Ward Vandewege <ward at curii.com>
diff --git a/Makefile b/Makefile
index 3df3c78c..aaf2271c 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ VERSION?=$(shell ./version-at-commit.sh HEAD)
# changes in the package. (i.e. example config files externally added
ITERATION?=1
-TARGETS?=centos7 debian8 debian10 ubuntu1404 ubuntu1604 ubuntu1804 ubuntu2004
+TARGETS?=centos7 debian10 debian11 ubuntu1804 ubuntu2004
ARVADOS_DIRECTORY?=unset
commit e16c61adea5e8eccd1236d8608a750cd7cb565df
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 2 14:25:10 2021 -0400
17691: Add unit tests for isRsaKey
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/validators/is-rsa-key.test.tsx b/src/validators/is-rsa-key.test.tsx
new file mode 100644
index 00000000..067d7744
--- /dev/null
+++ b/src/validators/is-rsa-key.test.tsx
@@ -0,0 +1,39 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { isRsaKey } from './is-rsa-key';
+
+describe('rsa-key-validator', () => {
+ const rsaKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPpavAS1wUq2+j7PgwkDS+9lm43AkdGxZo+T8qm6ZcB009EUEXya3lQolA52gg/i5aGZg4LT3t1OKxbsaClMd7sNZXYrMW9vd/utvGgAlNEbE/yXsEl2kpxt8lz7RI1XLnoWcV+aKyrsiKdrMKnZyG8CBxKdtzxHzWRl4N1BGrFJf/RnUWJv2VvM/h4/O+KXIjFokPkJ1F8yQChp5OKGkBKGXQ1vV4LjXqEXGVlgiQFM4U2NvCA8hXQR8mYm1vOsTYJzoSsnb+ewbXlVH5d7XsR5S2ULOr88vuYN/P4DF/Q3pEBi7BOyee61P3eHvhCNtb+jQMt59Vj/96y5C/reTMRo2R3B4bmX+Zxr3+DCC5tO1y+U5V39fu7cweimKXc78QDGGAVN0kz4P6P137b5WkCYIozeiBvWRsbGIlHjlGu9+0WuotdluD+OrTguuZ2zr8f32ijddO6y0J+aIdmTxQPxtmcQuRtpRfquoJGLhWAJH6mNZKbWkqqVfd5BA0TYs=';
+ const badKey = 'ssh-rsa bad'
+
+ const ERROR_MESSAGE = 'Public key is invalid';
+
+ describe('rsaKeyValidation', () => {
+ it('should accept keys with comment', () => {
+ // then
+ expect(isRsaKey(rsaKey + " firstlast at example.com")).toBeUndefined();
+ });
+
+ it('should accept keys without comment', () => {
+ // then
+ expect(isRsaKey(rsaKey)).toBeUndefined();
+ });
+
+ it('should reject keys with trailing whitespace', () => {
+ // then
+ expect(isRsaKey(rsaKey + " ")).toBe(ERROR_MESSAGE);
+ expect(isRsaKey(rsaKey + "\n")).toBe(ERROR_MESSAGE);
+ expect(isRsaKey(rsaKey + "\r\n")).toBe(ERROR_MESSAGE);
+ expect(isRsaKey(rsaKey + "\t")).toBe(ERROR_MESSAGE);
+ });
+
+ it('should reject invalid keys', () => {
+ // then
+ expect(isRsaKey(badKey)).toBe(ERROR_MESSAGE);
+ });
+
+ });
+
+});
commit 2352fda90d2bf2e7d3b09c3f50014b21a8a65ebb
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 2 09:35:17 2021 -0400
17691: Relax ssh key frontend validation to accept keys without comment
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/validators/is-rsa-key.tsx b/src/validators/is-rsa-key.tsx
index 7620a801..d41b0929 100644
--- a/src/validators/is-rsa-key.tsx
+++ b/src/validators/is-rsa-key.tsx
@@ -6,5 +6,5 @@
const ERROR_MESSAGE = 'Public key is invalid';
export const isRsaKey = (value: any) => {
- return value.match(/ssh-rsa AAAA[0-9A-Za-z+/]+[=]{0,3} ([^@]+@[^@]+)/i) ? undefined : ERROR_MESSAGE;
+ return value.match(/ssh-rsa AAAA[0-9A-Za-z+/]+[=]{0,3}(( [^@]+@[^@]+)|$)/i) ? undefined : ERROR_MESSAGE;
};
commit 7edfda6a34df2bdd6cb21f22a952f3070de58866
Author: Stephen Smith <stephen at curii.com>
Date: Mon Aug 2 12:38:59 2021 -0400
17526: Remove filename placeholder from webdav dialog curl command
Also add a note to add filenames at the end of the curl URL
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 49283813..8e9edac1 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -148,7 +148,7 @@ export const WebDavS3InfoDialog = compose(
}
const wgetCommand = `wget --http-user=${props.data.username} --http-passwd=${props.data.token} --mirror --no-parent --no-host --cut-dirs=0 ${winDav.toString()}`;
- const curlCommand = `curl -O -u ${props.data.username}:${props.data.token} ${winDav.toString()}<FILENAME>`;
+ const curlCommand = `curl -O -u ${props.data.username}:${props.data.token} ${winDav.toString()}`;
return <Dialog
open={props.open}
@@ -228,7 +228,7 @@ export const WebDavS3InfoDialog = compose(
Download Cyber/Mountain Duck bookmark
</Button>
- <h3>Gnome</h3>
+ <h3>GNOME</h3>
<ol>
<li>Open Files</li>
<li>Select +Other Locations</li>
@@ -278,6 +278,11 @@ export const WebDavS3InfoDialog = compose(
lines={[curlCommand]} />
</DetailsAttribute>
+ <p>
+ Note: This curl command downloads single files.
+ Append the desired filename to the end of the URL.
+ </p>
+
</TabPanel>
</div>
commit fffe0e4cf71da4c8d2cdca2db958fa6403d0e5ec
Author: Stephen Smith <stephen at curii.com>
Date: Thu Jul 29 11:07:14 2021 -0400
17526: Remove redundant user/pass from webdav wget tab and add curl command
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 7255e756..49283813 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -148,6 +148,7 @@ export const WebDavS3InfoDialog = compose(
}
const wgetCommand = `wget --http-user=${props.data.username} --http-passwd=${props.data.token} --mirror --no-parent --no-host --cut-dirs=0 ${winDav.toString()}`;
+ const curlCommand = `curl -O -u ${props.data.username}:${props.data.token} ${winDav.toString()}<FILENAME>`;
return <Dialog
open={props.open}
@@ -270,14 +271,12 @@ export const WebDavS3InfoDialog = compose(
</DetailsAttribute>
<DetailsAttribute
- label='Username'
- value={props.data.username}
- copyValue={props.data.username} />
-
- <DetailsAttribute
- label='Password'
- value={props.data.token}
- copyValue={props.data.token} />
+ label='Curl command'
+ copyValue={curlCommand}
+ classValue={props.classes.detailsAttrValWithCode}>
+ <DefaultCodeSnippet
+ lines={[curlCommand]} />
+ </DetailsAttribute>
</TabPanel>
commit 7ffd14cca42d5e2c75722f916f5362b32d9a07be
Author: Stephen Smith <stephen at curii.com>
Date: Thu Jul 29 10:50:49 2021 -0400
17526: Use codesnippet component on webdav dialog wget command for monospace
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 73c89621..7255e756 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -10,8 +10,9 @@ import { WithDialogProps } from 'store/dialog/with-dialog';
import { compose } from 'redux';
import { DetailsAttribute } from "components/details-attribute/details-attribute";
import { DownloadIcon } from "components/icon/icon";
+import { DefaultCodeSnippet } from "components/default-code-snippet/default-code-snippet";
-export type CssRules = 'details' | 'downloadButton';
+export type CssRules = 'details' | 'downloadButton' | 'detailsAttrValWithCode';
const styles: StyleRulesCallback<CssRules> = theme => ({
details: {
@@ -20,6 +21,10 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
},
downloadButton: {
marginTop: theme.spacing.unit * 2,
+ },
+ detailsAttrValWithCode: {
+ display: "flex",
+ alignItems: "center",
}
});
@@ -258,8 +263,11 @@ export const WebDavS3InfoDialog = compose(
<DetailsAttribute
label='Wget command'
- value={wgetCommand}
- copyValue={wgetCommand} />
+ copyValue={wgetCommand}
+ classValue={props.classes.detailsAttrValWithCode}>
+ <DefaultCodeSnippet
+ lines={[wgetCommand]} />
+ </DetailsAttribute>
<DetailsAttribute
label='Username'
commit 8d954ff99ea4dfda2588c17314dd64f378871ee0
Author: Stephen Smith <stephen at curii.com>
Date: Wed Jul 28 16:55:01 2021 -0400
17526: Fix webdav dialog > wget tab command copy button only copying url
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 50d50944..73c89621 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -142,6 +142,8 @@ export const WebDavS3InfoDialog = compose(
activeTab = 2;
}
+ const wgetCommand = `wget --http-user=${props.data.username} --http-passwd=${props.data.token} --mirror --no-parent --no-host --cut-dirs=0 ${winDav.toString()}`;
+
return <Dialog
open={props.open}
maxWidth="md"
@@ -256,8 +258,8 @@ export const WebDavS3InfoDialog = compose(
<DetailsAttribute
label='Wget command'
- value={`wget --http-user=${props.data.username} --http-passwd=${props.data.token} --mirror --no-parent --no-host --cut-dirs=0 ${winDav.toString()}`}
- copyValue={winDav.toString()} />
+ value={wgetCommand}
+ copyValue={wgetCommand} />
<DetailsAttribute
label='Username'
commit 2953ffd61e451f6bb75bf51489ceeb983e774626
Author: Stephen Smith <stephen at curii.com>
Date: Wed Jul 28 16:45:17 2021 -0400
17526: Rename supportsWebdav to isCollection
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 16fe2526..50d50944 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -135,10 +135,10 @@ export const WebDavS3InfoDialog = compose(
tokenSecret = tokenUuid;
}
- const supportsWebdav = (props.data.uuid.indexOf("-4zz18-") === 5);
+ const isCollection = (props.data.uuid.indexOf("-4zz18-") === 5);
let activeTab = props.data.activeTab;
- if (!supportsWebdav) {
+ if (!isCollection) {
activeTab = 2;
}
@@ -151,10 +151,10 @@ export const WebDavS3InfoDialog = compose(
title={`Open with 3rd party client`} />
<div className={props.classes.details} >
<Tabs value={activeTab} onChange={props.data.setActiveTab}>
- {supportsWebdav && <Tab value={0} key="cyberduck" label="WebDAV" />}
- {supportsWebdav && <Tab value={1} key="windows" label="Windows or MacOS" />}
+ {isCollection && <Tab value={0} key="cyberduck" label="WebDAV" />}
+ {isCollection && <Tab value={1} key="windows" label="Windows or MacOS" />}
<Tab value={2} key="s3" label="S3 bucket" />
- {supportsWebdav && <Tab value={3} key="cli" label="wget / curl" />}
+ {isCollection && <Tab value={3} key="cli" label="wget / curl" />}
</Tabs>
<TabPanel index={1} value={activeTab}>
commit acf4d6c3197384510ab18f4aa776b283480458ea
Author: Stephen Smith <stephen at curii.com>
Date: Wed Jul 28 16:43:05 2021 -0400
17526: Change webdav dialog title to "Open" to preserve ordering
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index 49a79d1c..f1e337de 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -43,7 +43,7 @@ describe('Collection panel tests', function () {
cy.goToPath(`/collections/${testCollection.uuid}`);
cy.get('[data-cy=collection-panel-options-btn]').click();
- cy.get('[data-cy=context-menu]').contains('Access with 3rd party client').click();
+ cy.get('[data-cy=context-menu]').contains('Open with 3rd party client').click();
cy.get('[data-cy=download-button').click();
const filename = path.join(downloadsFolder, `${testCollection.name}.duck`);
diff --git a/src/store/collections/collection-info-actions.ts b/src/store/collections/collection-info-actions.ts
index 4838481e..6107c409 100644
--- a/src/store/collections/collection-info-actions.ts
+++ b/src/store/collections/collection-info-actions.ts
@@ -29,7 +29,7 @@ export const openWebDavS3InfoDialog = (uuid: string, activeTab?: number) =>
dispatch(dialogActions.OPEN_DIALOG({
id: COLLECTION_WEBDAV_S3_DIALOG_NAME,
data: {
- title: 'Access with 3rd party client',
+ title: 'Open with 3rd party client',
token: getState().auth.extraApiToken || getState().auth.apiToken,
downloadUrl: getState().auth.config.keepWebServiceUrl,
collectionsUrl: getState().auth.config.keepWebInlineServiceUrl,
diff --git a/src/views-components/context-menu/action-sets/collection-action-set.ts b/src/views-components/context-menu/action-sets/collection-action-set.ts
index c4c8788f..9b0efac0 100644
--- a/src/views-components/context-menu/action-sets/collection-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-action-set.ts
@@ -90,7 +90,7 @@ export const readOnlyCollectionActionSet: ContextMenuActionSet = [[
toggleFavoriteAction,
{
icon: FolderSharedIcon,
- name: "Access with 3rd party client",
+ name: "Open with 3rd party client",
execute: (dispatch, resource) => {
dispatch<any>(openWebDavS3InfoDialog(resource.uuid));
}
diff --git a/src/views-components/context-menu/action-sets/project-action-set.ts b/src/views-components/context-menu/action-sets/project-action-set.ts
index 02a6731e..a079bf4f 100644
--- a/src/views-components/context-menu/action-sets/project-action-set.ts
+++ b/src/views-components/context-menu/action-sets/project-action-set.ts
@@ -59,7 +59,7 @@ export const readOnlyProjectActionSet: ContextMenuActionSet = [[
},
{
icon: FolderSharedIcon,
- name: "Access with 3rd party client",
+ name: "Open with 3rd party client",
execute: (dispatch, resource) => {
dispatch<any>(openWebDavS3InfoDialog(resource.uuid));
}
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index d6055852..16fe2526 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -148,7 +148,7 @@ export const WebDavS3InfoDialog = compose(
onClose={props.closeDialog}
style={{ alignSelf: 'stretch' }}>
<CardHeader
- title={`Access with 3rd party client`} />
+ title={`Open with 3rd party client`} />
<div className={props.classes.details} >
<Tabs value={activeTab} onChange={props.data.setActiveTab}>
{supportsWebdav && <Tab value={0} key="cyberduck" label="WebDAV" />}
commit a8e2b7c927f403b8c6b497bbefd3106e3b6db7ef
Author: Stephen Smith <stephen at curii.com>
Date: Wed Jul 28 10:17:38 2021 -0400
17526: Add wget/curl tab to webdav dialog
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 267d4412..d6055852 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -154,6 +154,7 @@ export const WebDavS3InfoDialog = compose(
{supportsWebdav && <Tab value={0} key="cyberduck" label="WebDAV" />}
{supportsWebdav && <Tab value={1} key="windows" label="Windows or MacOS" />}
<Tab value={2} key="s3" label="S3 bucket" />
+ {supportsWebdav && <Tab value={3} key="cli" label="wget / curl" />}
</Tabs>
<TabPanel index={1} value={activeTab}>
@@ -251,6 +252,25 @@ export const WebDavS3InfoDialog = compose(
</TabPanel>
+ <TabPanel index={3} value={activeTab}>
+
+ <DetailsAttribute
+ label='Wget command'
+ value={`wget --http-user=${props.data.username} --http-passwd=${props.data.token} --mirror --no-parent --no-host --cut-dirs=0 ${winDav.toString()}`}
+ copyValue={winDav.toString()} />
+
+ <DetailsAttribute
+ label='Username'
+ value={props.data.username}
+ copyValue={props.data.username} />
+
+ <DetailsAttribute
+ label='Password'
+ value={props.data.token}
+ copyValue={props.data.token} />
+
+ </TabPanel>
+
</div>
<DialogActions>
<Button
commit 8451c622fdc4321f7c19c1c09975263a19a7023c
Author: Stephen Smith <stephen at curii.com>
Date: Wed Jul 28 09:56:57 2021 -0400
17526: Rename cyberduck tab to webdav, mention credentials in mac/win tab
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 8e82619c..267d4412 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -151,7 +151,7 @@ export const WebDavS3InfoDialog = compose(
title={`Access with 3rd party client`} />
<div className={props.classes.details} >
<Tabs value={activeTab} onChange={props.data.setActiveTab}>
- {supportsWebdav && <Tab value={0} key="cyberduck" label="Cyberduck/Mountain Duck or Gnome Files" />}
+ {supportsWebdav && <Tab value={0} key="cyberduck" label="WebDAV" />}
{supportsWebdav && <Tab value={1} key="windows" label="Windows or MacOS" />}
<Tab value={2} key="s3" label="S3 bucket" />
</Tabs>
@@ -179,12 +179,14 @@ export const WebDavS3InfoDialog = compose(
<li>Open File Explorer</li>
<li>Click on "This PC", then go to Computer → Add a Network Location</li>
<li>Click Next, then choose "Add a custom network location", then click Next</li>
+ <li>Use the "internet address" and credentials listed under Settings, above</li>
</ol>
<h3>MacOS</h3>
<ol>
<li>Open Finder</li>
<li>Click Go → Connect to server</li>
+ <li>Use the "internet address" and credentials listed under Settings, above</li>
</ol>
</TabPanel>
@@ -204,6 +206,8 @@ export const WebDavS3InfoDialog = compose(
value={props.data.token}
copyValue={props.data.token} />
+ <h3>Cyberduck/Mountain Duck</h3>
+
<Button
data-cy='download-button'
className={props.classes.downloadButton}
commit f4cb3271191ef9a4978556caec65c146f0d21160
Author: Stephen Smith <stephen at curii.com>
Date: Wed Jul 28 09:55:45 2021 -0400
17526: Rename webdav dialong to Access with 3rd party client
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen at curii.com>
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index f3b63218..49a79d1c 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -43,7 +43,7 @@ describe('Collection panel tests', function () {
cy.goToPath(`/collections/${testCollection.uuid}`);
cy.get('[data-cy=collection-panel-options-btn]').click();
- cy.get('[data-cy=context-menu]').contains('Open as network folder or S3 bucket').click();
+ cy.get('[data-cy=context-menu]').contains('Access with 3rd party client').click();
cy.get('[data-cy=download-button').click();
const filename = path.join(downloadsFolder, `${testCollection.name}.duck`);
diff --git a/src/store/collections/collection-info-actions.ts b/src/store/collections/collection-info-actions.ts
index 9f82975f..4838481e 100644
--- a/src/store/collections/collection-info-actions.ts
+++ b/src/store/collections/collection-info-actions.ts
@@ -29,7 +29,7 @@ export const openWebDavS3InfoDialog = (uuid: string, activeTab?: number) =>
dispatch(dialogActions.OPEN_DIALOG({
id: COLLECTION_WEBDAV_S3_DIALOG_NAME,
data: {
- title: 'Access Collection using WebDAV or S3',
+ title: 'Access with 3rd party client',
token: getState().auth.extraApiToken || getState().auth.apiToken,
downloadUrl: getState().auth.config.keepWebServiceUrl,
collectionsUrl: getState().auth.config.keepWebInlineServiceUrl,
diff --git a/src/views-components/context-menu/action-sets/collection-action-set.ts b/src/views-components/context-menu/action-sets/collection-action-set.ts
index 5c66f128..c4c8788f 100644
--- a/src/views-components/context-menu/action-sets/collection-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-action-set.ts
@@ -90,7 +90,7 @@ export const readOnlyCollectionActionSet: ContextMenuActionSet = [[
toggleFavoriteAction,
{
icon: FolderSharedIcon,
- name: "Open as network folder or S3 bucket",
+ name: "Access with 3rd party client",
execute: (dispatch, resource) => {
dispatch<any>(openWebDavS3InfoDialog(resource.uuid));
}
diff --git a/src/views-components/context-menu/action-sets/project-action-set.ts b/src/views-components/context-menu/action-sets/project-action-set.ts
index c8471138..02a6731e 100644
--- a/src/views-components/context-menu/action-sets/project-action-set.ts
+++ b/src/views-components/context-menu/action-sets/project-action-set.ts
@@ -59,7 +59,7 @@ export const readOnlyProjectActionSet: ContextMenuActionSet = [[
},
{
icon: FolderSharedIcon,
- name: "Open as network folder or S3 bucket",
+ name: "Access with 3rd party client",
execute: (dispatch, resource) => {
dispatch<any>(openWebDavS3InfoDialog(resource.uuid));
}
diff --git a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
index 39c1068e..8e82619c 100644
--- a/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
+++ b/src/views-components/webdav-s3-dialog/webdav-s3-dialog.tsx
@@ -148,7 +148,7 @@ export const WebDavS3InfoDialog = compose(
onClose={props.closeDialog}
style={{ alignSelf: 'stretch' }}>
<CardHeader
- title={`Open as Network Folder or S3 Bucket`} />
+ title={`Access with 3rd party client`} />
<div className={props.classes.details} >
<Tabs value={activeTab} onChange={props.data.setActiveTab}>
{supportsWebdav && <Tab value={0} key="cyberduck" label="Cyberduck/Mountain Duck or Gnome Files" />}
commit efbe3df438e43ac3f620a37da60ebc18ce3f495c
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 038b31e2..874e840c 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -119,17 +119,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