export const COLLECTION_PARTIAL_COPY_FORM_NAME = 'COLLECTION_PARTIAL_COPY_DIALOG';
export const COLLECTION_PARTIAL_COPY_TO_SELECTED_COLLECTION = 'COLLECTION_PARTIAL_COPY_TO_SELECTED_DIALOG';
+export const COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS = 'COLLECTION_PARTIAL_COPY_TO_SEPARATE_DIALOG';
export interface CollectionPartialCopyToNewCollectionFormData {
name: string;
destination: {uuid: string, path?: string};
}
+export interface CollectionPartialCopyToSeparateCollectionsFormData {
+ name: string;
+ projectUuid: string;
+}
+
export const openCollectionPartialCopyToNewCollectionDialog = () =>
(dispatch: Dispatch, getState: () => RootState) => {
const currentCollection = getState().collectionPanel.item;
}
}
};
+
+export const openCollectionPartialCopyToSeparateCollectionsDialog = () =>
+ (dispatch: Dispatch, getState: () => RootState) => {
+ const currentCollection = getState().collectionPanel.item;
+ if (currentCollection) {
+ const initialData = {
+ name: currentCollection.name,
+ projectUuid: undefined
+ };
+ dispatch(initialize(COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS, initialData));
+ dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS));
+ dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS, data: {} }));
+ }
+ };
+
+export const copyCollectionPartialToSeparateCollections = ({ name, projectUuid }: CollectionPartialCopyToSeparateCollectionsFormData) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ const state = getState();
+ // Get current collection
+ const sourceCollection = state.collectionPanel.item;
+
+ if (sourceCollection) {
+ try {
+ dispatch(startSubmit(COLLECTION_PARTIAL_COPY_FORM_NAME));
+ dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PARTIAL_COPY_FORM_NAME));
+
+ // Get selected files
+ const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, true)
+ .map(file => file.id.replace(new RegExp(`(^${sourceCollection.uuid})`), ''));
+
+ // Copy files
+ const collections = await Promise.all(paths.map((path) =>
+ services.collectionService.copyFiles(
+ sourceCollection.portableDataHash,
+ [path],
+ {
+ name: `File split from collection ${name}${path}`,
+ ownerUuid: projectUuid,
+ uuid: undefined,
+ },
+ '/',
+ false
+ )
+ ));
+ dispatch(updateResources(collections));
+
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({
+ message: 'New collections created.',
+ hideDuration: 2000,
+ kind: SnackbarKind.SUCCESS
+ }));
+ dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_COPY_FORM_NAME));
+ } catch (e) {
+ const error = getCommonResourceServiceError(e);
+ console.log(e, error);
+ if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Collection from one or more files already exists', hideDuration: 2000, kind: SnackbarKind.ERROR }));
+ } else if (error === CommonResourceServiceError.UNKNOWN) {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not create a copy of collection', hideDuration: 2000, kind: SnackbarKind.ERROR }));
+ } else {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_FORM_NAME }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Collection has been copied but may contain incorrect files.', hideDuration: 2000, kind: SnackbarKind.ERROR }));
+ }
+ dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_COPY_FORM_NAME));
+ }
+ }
+ };
export const COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION = 'COLLECTION_PARTIAL_MOVE_TO_NEW_DIALOG';
export const COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION = 'COLLECTION_PARTIAL_MOVE_TO_SELECTED_DIALOG';
+export const COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS = 'COLLECTION_PARTIAL_MOVE_TO_SEPARATE_DIALOG';
export interface CollectionPartialMoveToNewCollectionFormData {
name: string;
destination: {uuid: string, path?: string};
}
+export interface CollectionPartialMoveToSeparateCollectionsFormData {
+ name: string;
+ projectUuid: string;
+}
+
export const openCollectionPartialMoveToNewCollectionDialog = () =>
(dispatch: Dispatch, getState: () => RootState) => {
const currentCollection = getState().collectionPanel.item;
}
}
};
+
+export const openCollectionPartialMoveToSeparateCollectionsDialog = () =>
+ (dispatch: Dispatch, getState: () => RootState) => {
+ const currentCollection = getState().collectionPanel.item;
+ if (currentCollection) {
+ const initialData = {
+ name: currentCollection.name,
+ projectUuid: undefined
+ };
+ dispatch(initialize(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS, initialData));
+ dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS));
+ dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS, data: {} }));
+ }
+ };
+
+export const moveCollectionPartialToSeparateCollections = ({ name, projectUuid }: CollectionPartialMoveToSeparateCollectionsFormData) =>
+ async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ const state = getState();
+ // Get current collection
+ const sourceCollection = state.collectionPanel.item;
+
+ if (sourceCollection) {
+ try {
+ dispatch(startSubmit(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS));
+ dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS));
+
+ // Get selected files
+ const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, true)
+ .map(file => file.id.replace(new RegExp(`(^${sourceCollection.uuid})`), ''));
+
+ // Move files
+ const collections = await Promise.all(paths.map((path) =>
+ services.collectionService.moveFiles(
+ sourceCollection.uuid,
+ sourceCollection.portableDataHash,
+ [path],
+ {
+ name: `File split from collection ${name}${path}`,
+ ownerUuid: projectUuid,
+ uuid: undefined,
+ },
+ '/',
+ false
+ )
+ ));
+ dispatch(updateResources(collections));
+
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({
+ message: 'New collections created.',
+ hideDuration: 2000,
+ kind: SnackbarKind.SUCCESS
+ }));
+ dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS));
+ } catch (e) {
+ const error = getCommonResourceServiceError(e);
+ if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Collection from one or more files already exists', hideDuration: 2000, kind: SnackbarKind.ERROR }));
+ } else if (error === CommonResourceServiceError.UNKNOWN) {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not create a copy of collection', hideDuration: 2000, kind: SnackbarKind.ERROR }));
+ } else {
+ dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS }));
+ dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Collection has been copied but may contain incorrect files.', hideDuration: 2000, kind: SnackbarKind.ERROR }));
+ }
+ dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS));
+ }
+ }
+ };
import { collectionPanelFilesAction, openMultipleFilesRemoveDialog } from "store/collection-panel/collection-panel-files/collection-panel-files-actions";
import {
openCollectionPartialCopyToNewCollectionDialog,
- openCollectionPartialCopyToExistingCollectionDialog
+ openCollectionPartialCopyToExistingCollectionDialog,
+ openCollectionPartialCopyToSeparateCollectionsDialog
} from 'store/collections/collection-partial-copy-actions';
-import { openCollectionPartialMoveToExistingCollectionDialog, openCollectionPartialMoveToNewCollectionDialog } from "store/collections/collection-partial-move-actions";
+import { openCollectionPartialMoveToExistingCollectionDialog, openCollectionPartialMoveToNewCollectionDialog, openCollectionPartialMoveToSeparateCollectionsDialog } from "store/collections/collection-partial-move-actions";
// These action sets are used on the multi-select actions button.
export const readOnlyCollectionFilesActionSet: ContextMenuActionSet = [[
execute: dispatch => {
dispatch<any>(openCollectionPartialCopyToExistingCollectionDialog());
}
+ },
+ {
+ name: "Copy selected into separate collections",
+ execute: dispatch => {
+ dispatch<any>(openCollectionPartialCopyToSeparateCollectionsDialog());
+ }
}
]];
execute: dispatch => {
dispatch<any>(openCollectionPartialMoveToExistingCollectionDialog());
}
+ },
+ {
+ name: "Move selected into separate collections",
+ execute: dispatch => {
+ dispatch<any>(openCollectionPartialMoveToSeparateCollectionsDialog());
+ }
}
]]);
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import React from "react";
+import { memoize } from "lodash/fp";
+import { FormDialog } from 'components/form-dialog/form-dialog';
+import { CollectionProjectPickerField } from 'views-components/form-fields/collection-form-fields';
+import { WithDialogProps } from 'store/dialog/with-dialog';
+import { InjectedFormProps } from 'redux-form';
+import { CollectionPartialCopyToSeparateCollectionsFormData } from 'store/collections/collection-partial-copy-actions';
+import { PickerIdProp } from "store/tree-picker/picker-id";
+
+type DialogCollectionPartialCopyProps = WithDialogProps<string> & InjectedFormProps<CollectionPartialCopyToSeparateCollectionsFormData>;
+
+export const DialogCollectionPartialCopyToSeparateCollection = (props: DialogCollectionPartialCopyProps & PickerIdProp) =>
+ <FormDialog
+ dialogTitle='Copy to separate collections'
+ formFields={CollectionPartialCopyFields(props.pickerId)}
+ submitLabel='Create collections'
+ {...props}
+ />;
+
+const CollectionPartialCopyFields = memoize(
+ (pickerId: string) =>
+ () =>
+ <>
+ <CollectionProjectPickerField {...{ pickerId }} />
+ </>);
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { compose } from "redux";
+import { reduxForm } from 'redux-form';
+import { withDialog, } from 'store/dialog/with-dialog';
+import { COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS, CollectionPartialCopyToSeparateCollectionsFormData, copyCollectionPartialToSeparateCollections } from 'store/collections/collection-partial-copy-actions';
+import { DialogCollectionPartialCopyToSeparateCollection } from "views-components/dialog-copy/dialog-collection-partial-copy-to-separate-collections";
+import { pickerId } from "store/tree-picker/picker-id";
+
+export const PartialCopyToSeparateCollectionsDialog = compose(
+ withDialog(COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS),
+ reduxForm<CollectionPartialCopyToSeparateCollectionsFormData>({
+ form: COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS,
+ onSubmit: (data, dispatch) => {
+ dispatch(copyCollectionPartialToSeparateCollections(data));
+ }
+ }),
+ pickerId(COLLECTION_PARTIAL_COPY_TO_SEPARATE_COLLECTIONS),
+)(DialogCollectionPartialCopyToSeparateCollection);
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { compose } from "redux";
+import { reduxForm } from 'redux-form';
+import { withDialog, } from 'store/dialog/with-dialog';
+import { COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS, CollectionPartialMoveToSeparateCollectionsFormData, moveCollectionPartialToSeparateCollections } from "store/collections/collection-partial-move-actions";
+import { DialogCollectionPartialMoveToSeparateCollections } from "views-components/dialog-move/dialog-collection-partial-move-to-separate-collections";
+import { pickerId } from "store/tree-picker/picker-id";
+
+export const PartialMoveToSeparateCollectionsDialog = compose(
+ withDialog(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS),
+ reduxForm<CollectionPartialMoveToSeparateCollectionsFormData>({
+ form: COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS,
+ onSubmit: (data, dispatch) => {
+ dispatch(moveCollectionPartialToSeparateCollections(data));
+ }
+ }),
+ pickerId(COLLECTION_PARTIAL_MOVE_TO_SEPARATE_COLLECTIONS),
+)(DialogCollectionPartialMoveToSeparateCollections);
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import React from "react";
+import { memoize } from "lodash/fp";
+import { FormDialog } from 'components/form-dialog/form-dialog';
+import { CollectionProjectPickerField } from 'views-components/form-fields/collection-form-fields';
+import { WithDialogProps } from 'store/dialog/with-dialog';
+import { InjectedFormProps } from 'redux-form';
+import { CollectionPartialMoveToSeparateCollectionsFormData } from "store/collections/collection-partial-move-actions";
+import { PickerIdProp } from "store/tree-picker/picker-id";
+
+type DialogCollectionPartialMoveProps = WithDialogProps<string> & InjectedFormProps<CollectionPartialMoveToSeparateCollectionsFormData>;
+
+export const DialogCollectionPartialMoveToSeparateCollections = (props: DialogCollectionPartialMoveProps & PickerIdProp) =>
+ <FormDialog
+ dialogTitle='Move to separate collections'
+ formFields={CollectionPartialMoveFields(props.pickerId)}
+ submitLabel='Create collections'
+ {...props}
+ />;
+
+const CollectionPartialMoveFields = memoize(
+ (pickerId: string) =>
+ () =>
+ <>
+ <CollectionProjectPickerField {...{ pickerId }} />
+ </>);
import { FilesUploadCollectionDialog } from 'views-components/dialog-forms/files-upload-collection-dialog';
import { PartialCopyToNewCollectionDialog } from 'views-components/dialog-forms/partial-copy-to-new-collection-dialog';
import { PartialCopyToExistingCollectionDialog } from 'views-components/dialog-forms/partial-copy-to-existing-collection-dialog';
+import { PartialCopyToSeparateCollectionsDialog } from 'views-components/dialog-forms/partial-copy-to-separate-collections-dialog';
import { PartialMoveToNewCollectionDialog } from 'views-components/dialog-forms/partial-move-to-new-collection-dialog';
import { PartialMoveToExistingCollectionDialog } from 'views-components/dialog-forms/partial-move-to-existing-collection-dialog';
+import { PartialMoveToSeparateCollectionsDialog } from 'views-components/dialog-forms/partial-move-to-separate-collections-dialog';
import { RemoveProcessDialog } from 'views-components/process-remove-dialog/process-remove-dialog';
import { MainContentBar } from 'views-components/main-content-bar/main-content-bar';
import { Grid } from '@material-ui/core';
<PublicKeyDialog />
<PartialCopyToNewCollectionDialog />
<PartialCopyToExistingCollectionDialog />
+ <PartialCopyToSeparateCollectionsDialog />
<PartialMoveToNewCollectionDialog />
<PartialMoveToExistingCollectionDialog />
+ <PartialMoveToSeparateCollectionsDialog />
<ProcessInputDialog />
<RestoreCollectionVersionDialog />
<RemoveApiClientAuthorizationDialog />