[ARVADOS-WORKBENCH2] created: 2.2.2
Git user
git at public.arvados.org
Fri Jan 7 19:47:27 UTC 2022
at 0f7f4ab0fc5027f0de921eafa42046712c5a392c (commit)
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