[ARVADOS-WORKBENCH2] updated: 2.3.2-1-g6b368635
Git user
git at public.arvados.org
Thu Dec 16 13:49:53 UTC 2021
Summary of changes:
cypress/integration/collection.spec.js | 80 ++++++++++++++++++++++
cypress/integration/favorites.spec.js | 3 +-
src/store/collections/collection-copy-actions.ts | 12 +++-
src/store/collections/collection-move-actions.ts | 8 ++-
.../collections/collection-partial-copy-actions.ts | 8 +--
.../action-sets/collection-files-action-set.ts | 13 ++--
.../projects-tree-picker/projects-tree-picker.tsx | 14 ++--
src/views-components/snackbar/snackbar.tsx | 6 +-
src/views/project-panel/project-panel.tsx | 2 +-
9 files changed, 124 insertions(+), 22 deletions(-)
via 6b368635bf1a768e89237c011de76a4230dc9d6d (commit)
from d0df6414bef82439ff46836f059632250d2de3c2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 6b368635bf1a768e89237c011de76a4230dc9d6d
Author: Lucas Di Pentima <lucas.dipentima at curii.com>
Date: Wed Dec 15 19:32:01 2021 -0300
Merge branch '18584-collection-copy-fix'. Closes #18584.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima at curii.com>
diff --git a/cypress/integration/collection.spec.js b/cypress/integration/collection.spec.js
index eb06a06c..bd211b1a 100644
--- a/cypress/integration/collection.spec.js
+++ b/cypress/integration/collection.spec.js
@@ -595,6 +595,86 @@ describe('Collection panel tests', function () {
})
});
+ it('moves a collection to a different project', function () {
+ const collName = `Test Collection ${Math.floor(Math.random() * 999999)}`;
+ const projName = `Test Project ${Math.floor(Math.random() * 999999)}`;
+ const fileName = `Test_File_${Math.floor(Math.random() * 999999)}`;
+
+ cy.createCollection(adminUser.token, {
+ name: collName,
+ owner_uuid: activeUser.user.uuid,
+ manifest_text: `. 37b51d194a7513e45b56f6524f2d51f2+3 0:3:${fileName}\n`,
+ }).as('testCollection');
+ cy.createGroup(adminUser.token, {
+ name: projName,
+ group_class: 'project',
+ owner_uuid: activeUser.user.uuid,
+ }).as('testProject');
+
+ cy.getAll('@testCollection', '@testProject')
+ .then(function ([testCollection, testProject]) {
+ cy.loginAs(activeUser);
+ cy.goToPath(`/collections/${testCollection.uuid}`);
+ cy.get('[data-cy=collection-files-panel]').should('contain', fileName);
+ cy.get('[data-cy=collection-info-panel]')
+ .should('not.contain', projName)
+ .and('not.contain', testProject.uuid);
+ cy.get('[data-cy=collection-panel-options-btn]').click();
+ cy.get('[data-cy=context-menu]').contains('Move to').click();
+ cy.get('[data-cy=form-dialog]')
+ .should('contain', 'Move to')
+ .within(() => {
+ cy.get('[data-cy=projects-tree-home-tree-picker]')
+ .find('i')
+ .click();
+ cy.get('[data-cy=projects-tree-home-tree-picker]')
+ .contains(projName)
+ .click();
+ });
+ cy.get('[data-cy=form-submit-btn]').click();
+ cy.get('[data-cy=snackbar]')
+ .contains('Collection has been moved')
+ cy.get('[data-cy=collection-info-panel]')
+ .contains(projName).and('contain', testProject.uuid);
+ // Double check that the collection is in the project
+ cy.goToPath(`/projects/${testProject.uuid}`);
+ cy.get('[data-cy=project-panel]').should('contain', collName);
+ });
+ });
+
+ it('makes a copy of an existing collection', function() {
+ const collName = `Test Collection ${Math.floor(Math.random() * 999999)}`;
+ const copyName = `Copy of: ${collName}`;
+
+ cy.createCollection(adminUser.token, {
+ name: collName,
+ owner_uuid: activeUser.user.uuid,
+ manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:some-file\n",
+ }).as('collection').then(function () {
+ cy.loginAs(activeUser)
+ cy.goToPath(`/collections/${this.collection.uuid}`);
+ cy.get('[data-cy=collection-files-panel]')
+ .should('contain', 'some-file');
+ cy.get('[data-cy=collection-panel-options-btn]').click();
+ cy.get('[data-cy=context-menu]').contains('Make a copy').click();
+ cy.get('[data-cy=form-dialog]')
+ .should('contain', 'Make a copy')
+ .within(() => {
+ cy.get('[data-cy=projects-tree-home-tree-picker]')
+ .contains('Projects')
+ .click();
+ cy.get('[data-cy=form-submit-btn]').click();
+ });
+ cy.get('[data-cy=snackbar]')
+ .contains('Collection has been copied.')
+ cy.get('[data-cy=snackbar-goto-action]').click();
+ cy.get('[data-cy=project-panel]')
+ .contains(copyName).click();
+ cy.get('[data-cy=collection-files-panel]')
+ .should('contain', 'some-file');
+ });
+ });
+
it('uses the collection version browser to view a previous version', function () {
const colName = `Test Collection ${Math.floor(Math.random() * 999999)}`;
diff --git a/cypress/integration/favorites.spec.js b/cypress/integration/favorites.spec.js
index 13a2c467..9bc90ebd 100644
--- a/cypress/integration/favorites.spec.js
+++ b/cypress/integration/favorites.spec.js
@@ -44,7 +44,8 @@ describe('Favorites tests', function () {
});
});
- it('can copy selected into the collection', () => {
+ // Disabled while addressing #18587
+ it.skip('can copy selected into the collection', () => {
cy.createCollection(adminUser.token, {
name: `Test source collection ${Math.floor(Math.random() * 999999)}`,
manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"
diff --git a/src/store/collections/collection-copy-actions.ts b/src/store/collections/collection-copy-actions.ts
index 9d812783..eb9c64fd 100644
--- a/src/store/collections/collection-copy-actions.ts
+++ b/src/store/collections/collection-copy-actions.ts
@@ -12,6 +12,8 @@ import { getCommonResourceServiceError, CommonResourceServiceError } from 'servi
import { CopyFormDialogData } from 'store/copy-dialog/copy-dialog';
import { progressIndicatorActions } from "store/progress-indicator/progress-indicator-actions";
import { initProjectsTreePicker } from 'store/tree-picker/tree-picker-actions';
+import { getResource } from "store/resources/resources";
+import { CollectionResource } from "models/collection";
export const COLLECTION_COPY_FORM_NAME = 'collectionCopyFormName';
@@ -27,9 +29,15 @@ export const openCollectionCopyDialog = (resource: { name: string, uuid: string
export const copyCollection = (resource: CopyFormDialogData) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(startSubmit(COLLECTION_COPY_FORM_NAME));
+ let collection = getResource<CollectionResource>(resource.uuid)(getState().resources);
try {
- const collection = await services.collectionService.get(resource.uuid);
- const newCollection = await services.collectionService.create({ ...collection, ownerUuid: resource.ownerUuid, name: resource.name });
+ if (!collection) {
+ collection = await services.collectionService.get(resource.uuid);
+ }
+ const collManifestText = await services.collectionService.get(resource.uuid, undefined, ['manifestText']);
+ collection.manifestText = collManifestText.manifestText;
+ const {href, ...collectionRecord} = collection;
+ const newCollection = await services.collectionService.create({ ...collectionRecord, ownerUuid: resource.ownerUuid, name: resource.name });
dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_COPY_FORM_NAME }));
return newCollection;
} catch (e) {
diff --git a/src/store/collections/collection-move-actions.ts b/src/store/collections/collection-move-actions.ts
index d056b6e5..929f1612 100644
--- a/src/store/collections/collection-move-actions.ts
+++ b/src/store/collections/collection-move-actions.ts
@@ -14,6 +14,8 @@ import { MoveToFormDialogData } from 'store/move-to-dialog/move-to-dialog';
import { resetPickerProjectTree } from 'store/project-tree-picker/project-tree-picker-actions';
import { progressIndicatorActions } from "store/progress-indicator/progress-indicator-actions";
import { initProjectsTreePicker } from 'store/tree-picker/tree-picker-actions';
+import { getResource } from "store/resources/resources";
+import { CollectionResource } from "models/collection";
export const COLLECTION_MOVE_FORM_NAME = 'collectionMoveFormName';
@@ -28,13 +30,17 @@ export const openMoveCollectionDialog = (resource: { name: string, uuid: string
export const moveCollection = (resource: MoveToFormDialogData) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch(startSubmit(COLLECTION_MOVE_FORM_NAME));
+ let cachedCollection = getResource<CollectionResource>(resource.uuid)(getState().resources);
try {
dispatch(progressIndicatorActions.START_WORKING(COLLECTION_MOVE_FORM_NAME));
+ if (!cachedCollection) {
+ cachedCollection = await services.collectionService.get(resource.uuid);
+ }
const collection = await services.collectionService.update(resource.uuid, { ownerUuid: resource.ownerUuid });
dispatch(projectPanelActions.REQUEST_ITEMS());
dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_MOVE_FORM_NAME }));
dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_MOVE_FORM_NAME));
- return collection;
+ return {...cachedCollection, ...collection};
} catch (e) {
const error = getCommonResourceServiceError(e);
if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
diff --git a/src/store/collections/collection-partial-copy-actions.ts b/src/store/collections/collection-partial-copy-actions.ts
index d898c500..9f478d74 100644
--- a/src/store/collections/collection-partial-copy-actions.ts
+++ b/src/store/collections/collection-partial-copy-actions.ts
@@ -52,13 +52,13 @@ export const copyCollectionPartial = ({ name, description, projectUuid }: Collec
if (currentCollection) {
try {
dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PARTIAL_COPY_FORM_NAME));
- const collection = await services.collectionService.get(currentCollection.uuid);
+ const collectionManifestText = await services.collectionService.get(currentCollection.uuid, undefined, ['manifestText']);
const collectionCopy = {
name,
description,
ownerUuid: projectUuid,
uuid: undefined,
- manifestText: collection.manifestText,
+ manifestText: collectionManifestText.manifestText,
};
const newCollection = await services.collectionService.create(collectionCopy);
const copiedFiles = await services.collectionService.files(newCollection.uuid);
@@ -67,7 +67,7 @@ export const copyCollectionPartial = ({ name, description, projectUuid }: Collec
return !paths.find(path => path.indexOf(file.replace(newCollection.uuid, '')) > -1);
});
await services.collectionService.deleteFiles(
- '',
+ newCollection.uuid,
filesToDelete
);
dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
@@ -135,7 +135,7 @@ export const copyCollectionPartialToSelectedCollection = ({ collectionUuid }: Co
});
const diffPathToRemove = difference(paths, pathsToRemove);
await services.collectionService.deleteFiles(selectedCollection.uuid, pathsToRemove.map(path => path.replace(currentCollection.uuid, collectionUuid)));
- const collectionWithDeletedFiles = await services.collectionService.get(collectionUuid);
+ const collectionWithDeletedFiles = await services.collectionService.get(collectionUuid, undefined, ['uuid', 'manifestText']);
await services.collectionService.update(collectionUuid, { manifestText: `${collectionWithDeletedFiles.manifestText}${(currentCollection.manifestText ? currentCollection.manifestText : currentCollection.unsignedManifestText) || ''}` });
await services.collectionService.deleteFiles(collectionWithDeletedFiles.uuid, diffPathToRemove.map(path => path.replace(currentCollection.uuid, collectionUuid)));
dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_TO_SELECTED_COLLECTION }));
diff --git a/src/views-components/context-menu/action-sets/collection-files-action-set.ts b/src/views-components/context-menu/action-sets/collection-files-action-set.ts
index 3aeec4c0..59a5f368 100644
--- a/src/views-components/context-menu/action-sets/collection-files-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-files-action-set.ts
@@ -26,12 +26,13 @@ export const readOnlyCollectionFilesActionSet: ContextMenuActionSet = [[
dispatch<any>(openCollectionPartialCopyDialog());
}
},
- {
- name: "Copy selected into the collection",
- execute: dispatch => {
- dispatch<any>(openCollectionPartialCopyToSelectedCollectionDialog());
- }
- }
+ // Disabled while addressing #18587
+ // {
+ // name: "Copy selected into the collection",
+ // execute: dispatch => {
+ // dispatch<any>(openCollectionPartialCopyToSelectedCollectionDialog());
+ // }
+ // }
]];
export const collectionFilesActionSet: ContextMenuActionSet = readOnlyCollectionFilesActionSet.concat([[
diff --git a/src/views-components/projects-tree-picker/projects-tree-picker.tsx b/src/views-components/projects-tree-picker/projects-tree-picker.tsx
index 2f3ea611..ee8ce1d5 100644
--- a/src/views-components/projects-tree-picker/projects-tree-picker.tsx
+++ b/src/views-components/projects-tree-picker/projects-tree-picker.tsx
@@ -31,11 +31,17 @@ export const ProjectsTreePicker = ({ pickerId, ...props }: ProjectsTreePickerPro
disableActivation
};
return <div>
- <HomeTreePicker pickerId={home} {...p} />
- <SharedTreePicker pickerId={shared} {...p} />
- <PublicFavoritesTreePicker pickerId={publicFavorites} {...p} />
+ <div data-cy="projects-tree-home-tree-picker">
+ <HomeTreePicker pickerId={home} {...p} />
+ </div>
+ <div data-cy="projects-tree-shared-tree-picker">
+ <SharedTreePicker pickerId={shared} {...p} />
+ </div>
+ <div data-cy="projects-tree-public-favourites-tree-picker">
+ <PublicFavoritesTreePicker pickerId={publicFavorites} {...p} />
+ </div>
<div data-cy="projects-tree-favourites-tree-picker">
- <FavoritesTreePicker pickerId={favorites} {...p} />
+ <FavoritesTreePicker pickerId={favorites} {...p} />
</div>
</div>;
};
diff --git a/src/views-components/snackbar/snackbar.tsx b/src/views-components/snackbar/snackbar.tsx
index 2a63a31a..a33b6968 100644
--- a/src/views-components/snackbar/snackbar.tsx
+++ b/src/views-components/snackbar/snackbar.tsx
@@ -116,7 +116,7 @@ export const Snackbar = withStyles(styles)(connect(mapStateToProps, mapDispatchT
onExited={props.onExited}
anchorOrigin={props.anchorOrigin}
autoHideDuration={props.autoHideDuration}>
- <SnackbarContent
+ <div data-cy="snackbar"><SnackbarContent
className={classNames(cssClass)}
aria-describedby="client-snackbar"
message={
@@ -126,7 +126,7 @@ export const Snackbar = withStyles(styles)(connect(mapStateToProps, mapDispatchT
</span>
}
action={actions(props)}
- />
+ /></div>
</MaterialSnackbar>
);
}
@@ -151,7 +151,7 @@ const actions = (props: SnackbarProps) => {
color="inherit"
className={classes.linkButton}
onClick={() => onClick(link)}>
- Go To
+ <span data-cy='snackbar-goto-action'>Go To</span>
</Button>
);
}
diff --git a/src/views/project-panel/project-panel.tsx b/src/views/project-panel/project-panel.tsx
index 67264511..eaf48d14 100644
--- a/src/views/project-panel/project-panel.tsx
+++ b/src/views/project-panel/project-panel.tsx
@@ -147,7 +147,7 @@ export const ProjectPanel = withStyles(styles)(
class extends React.Component<ProjectPanelProps> {
render() {
const { classes } = this.props;
- return <div className={classes.root}>
+ return <div data-cy='project-panel' className={classes.root}>
<DataExplorer
id={PROJECT_PANEL_ID}
onRowClick={this.handleRowClick}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list