[arvados-workbench2] updated: 2.6.0-85-g2bd3f83d
git repository hosting
git at public.arvados.org
Wed Sep 6 21:08:30 UTC 2023
Summary of changes:
.../collection-panel-files.tsx | 1 -
src/components/data-explorer/data-explorer.tsx | 3 ++
src/components/data-table/data-table.tsx | 3 +-
.../multiselect-toolbar/MultiselectToolbar.tsx | 2 +-
src/store/collections/collection-copy-actions.ts | 56 ++++++++++++----------
src/store/copy-dialog/copy-dialog.ts | 3 +-
src/store/workbench/workbench-actions.ts | 51 +++++++++++++-------
.../action-sets/collection-action-set.ts | 2 +-
.../data-explorer/data-explorer.tsx | 33 ++++++-------
src/views-components/dialog-copy/dialog-copy.tsx | 55 +++++++++++----------
.../dialog-forms/copy-collection-dialog.ts | 16 +++----
11 files changed, 126 insertions(+), 99 deletions(-)
via 2bd3f83db9934198b658b7035a7be65017b754d9 (commit)
from 23575ae95aab42c4c4d9c2b5ee0236fab004dccb (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 2bd3f83db9934198b658b7035a7be65017b754d9
Author: Lisa Knox <lisaknox83 at gmail.com>
Date: Wed Sep 6 17:08:25 2023 -0400
15768: collection copy works except dialog Arvados-DCO-1.1-Signed-off-by: Lisa Knox <lisa.knox at curii.com>
diff --git a/src/components/collection-panel-files/collection-panel-files.tsx b/src/components/collection-panel-files/collection-panel-files.tsx
index 95dd4d4c..0fe933f5 100644
--- a/src/components/collection-panel-files/collection-panel-files.tsx
+++ b/src/components/collection-panel-files/collection-panel-files.tsx
@@ -278,7 +278,6 @@ export const CollectionPanelFiles = withStyles(styles)(
}
pathPromise[key] = true;
- console.log(key);
return webdavClient.propfind(`c=${key}`, webDAVRequestConfig);
}
diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx
index f0f30c81..91d7dc77 100644
--- a/src/components/data-explorer/data-explorer.tsx
+++ b/src/components/data-explorer/data-explorer.tsx
@@ -83,6 +83,7 @@ interface DataExplorerDataProps<T> {
currentItemUuid: string;
elementPath?: string;
isMSToolbarVisible: boolean;
+ checkedList: TCheckedList;
}
interface DataExplorerActionProps<T> {
@@ -188,6 +189,7 @@ export const DataExplorer = withStyles(styles)(
elementPath,
toggleMSToolbar,
setCheckedListOnStore,
+ checkedList,
} = this.props;
return (
<Paper
@@ -288,6 +290,7 @@ export const DataExplorer = withStyles(styles)(
currentRoute={paperKey}
toggleMSToolbar={toggleMSToolbar}
setCheckedListOnStore={setCheckedListOnStore}
+ checkedList={checkedList}
/>
</Grid>
<Grid
diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx
index ae68a6bc..c82f2ce3 100644
--- a/src/components/data-table/data-table.tsx
+++ b/src/components/data-table/data-table.tsx
@@ -53,6 +53,7 @@ export interface DataTableDataProps<I> {
currentRoute?: string;
toggleMSToolbar: (isVisible: boolean) => void;
setCheckedListOnStore: (checkedList: TCheckedList) => void;
+ checkedList: TCheckedList;
}
type CssRules =
@@ -141,7 +142,7 @@ export const DataTable = withStyles(styles)(
class Component<T> extends React.Component<DataTableProps<T>> {
state: DataTableState = {
isSelected: false,
- checkedList: {},
+ checkedList: this.props.checkedList,
};
componentDidMount(): void {
diff --git a/src/components/multiselect-toolbar/MultiselectToolbar.tsx b/src/components/multiselect-toolbar/MultiselectToolbar.tsx
index b726cfa0..8c36f60f 100644
--- a/src/components/multiselect-toolbar/MultiselectToolbar.tsx
+++ b/src/components/multiselect-toolbar/MultiselectToolbar.tsx
@@ -176,6 +176,7 @@ function selectActionsByKind(currentResourceKinds: Array<string>, filterSet: TMu
function mapStateToProps(state: RootState) {
const { isVisible, checkedList } = state.multiselect;
+ // console.log("checkedList", checkedList); //here
return {
isVisible: isVisible,
checkedList: checkedList as TCheckedList,
@@ -201,7 +202,6 @@ function mapDispatchToProps(dispatch: Dispatch) {
default:
for (const kind in kindGroups) {
const action = findActionByName(selectedAction.name as string, kindToActionSet[kind]);
- console.log(action, kindGroups[kind]);
if (action) action.execute(dispatch, kindGroups[kind]);
}
break;
diff --git a/src/store/collections/collection-copy-actions.ts b/src/store/collections/collection-copy-actions.ts
index eb9c64fd..fe204aad 100644
--- a/src/store/collections/collection-copy-actions.ts
+++ b/src/store/collections/collection-copy-actions.ts
@@ -4,52 +4,56 @@
import { Dispatch } from "redux";
import { dialogActions } from "store/dialog/dialog-actions";
-import { FormErrors, initialize, startSubmit, stopSubmit } from 'redux-form';
-import { resetPickerProjectTree } from 'store/project-tree-picker/project-tree-picker-actions';
-import { RootState } from 'store/store';
-import { ServiceRepository } from 'services/services';
-import { getCommonResourceServiceError, CommonResourceServiceError } from 'services/common-service/common-resource-service';
-import { CopyFormDialogData } from 'store/copy-dialog/copy-dialog';
+import { FormErrors, initialize, startSubmit, stopSubmit } from "redux-form";
+import { resetPickerProjectTree } from "store/project-tree-picker/project-tree-picker-actions";
+import { RootState } from "store/store";
+import { ServiceRepository } from "services/services";
+import { getCommonResourceServiceError, CommonResourceServiceError } from "services/common-service/common-resource-service";
+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 { 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';
+export const COLLECTION_COPY_FORM_NAME = "collectionCopyFormName";
-export const openCollectionCopyDialog = (resource: { name: string, uuid: string }) =>
- (dispatch: Dispatch) => {
- dispatch<any>(resetPickerProjectTree());
- dispatch<any>(initProjectsTreePicker(COLLECTION_COPY_FORM_NAME));
- const initialData: CopyFormDialogData = { name: `Copy of: ${resource.name}`, ownerUuid: '', uuid: resource.uuid };
- dispatch<any>(initialize(COLLECTION_COPY_FORM_NAME, initialData));
- dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_COPY_FORM_NAME, data: {} }));
- };
+export const openCollectionCopyDialog = (resource: { name: string; uuid: string; isSingle?: boolean }) => (dispatch: Dispatch) => {
+ dispatch<any>(resetPickerProjectTree());
+ dispatch<any>(initProjectsTreePicker(COLLECTION_COPY_FORM_NAME));
+ const initialData: CopyFormDialogData = { name: `Copy of: ${resource.name}`, ownerUuid: "", uuid: resource.uuid, isSingle: resource.isSingle };
+ dispatch<any>(initialize(COLLECTION_COPY_FORM_NAME, initialData));
+ dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_COPY_FORM_NAME, data: {} }));
+};
-export const copyCollection = (resource: CopyFormDialogData) =>
- async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+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 {
if (!collection) {
collection = await services.collectionService.get(resource.uuid);
}
- const collManifestText = await services.collectionService.get(resource.uuid, undefined, ['manifestText']);
+ 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 });
+ 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) {
const error = getCommonResourceServiceError(e);
if (error === CommonResourceServiceError.UNIQUE_NAME_VIOLATION) {
- dispatch(stopSubmit(
- COLLECTION_COPY_FORM_NAME,
- { ownerUuid: 'A collection with the same name already exists in the target project.' } as FormErrors
- ));
+ dispatch(
+ stopSubmit(COLLECTION_COPY_FORM_NAME, {
+ ownerUuid: "A collection with the same name already exists in the target project.",
+ } as FormErrors)
+ );
} else {
dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_COPY_FORM_NAME }));
- throw new Error('Could not copy the collection.');
+ throw new Error("Could not copy the collection.");
}
return;
} finally {
diff --git a/src/store/copy-dialog/copy-dialog.ts b/src/store/copy-dialog/copy-dialog.ts
index 4450cfc6..af4d7ace 100644
--- a/src/store/copy-dialog/copy-dialog.ts
+++ b/src/store/copy-dialog/copy-dialog.ts
@@ -6,4 +6,5 @@ export interface CopyFormDialogData {
name: string;
uuid: string;
ownerUuid: string;
-}
\ No newline at end of file
+ isSingle?: boolean;
+}
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 0de438c5..e79df239 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -281,7 +281,6 @@ export const createProject = (data: projectCreateActions.ProjectCreateFormDialog
export const moveProject =
(data: MoveToFormDialogData, isSecondaryMove = false) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
- console.log(data);
const checkedList = getState().multiselect.checkedList;
const uuidsToMove: string[] = data.isSingle ? [data.uuid] : selectedToArray(checkedList);
@@ -427,28 +426,44 @@ export const createCollection = (data: collectionCreateActions.CollectionCreateF
};
export const copyCollection = (data: CopyFormDialogData) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
- try {
- const copyToProject = getResource(data.ownerUuid)(getState().resources);
- const collection = await dispatch<any>(collectionCopyActions.copyCollection(data));
- if (copyToProject && collection) {
- dispatch<any>(reloadProjectMatchingUuid([copyToProject.uuid]));
+ const checkedList = getState().multiselect.checkedList;
+ const uuidsToCopy: string[] = data.isSingle ? [data.uuid] : selectedToArray(checkedList);
+
+ //if no items in checkedlist && no items passed in, default to normal context menu behavior
+ if (!uuidsToCopy.length) uuidsToCopy.push(data.uuid);
+
+ const collectionsToCopy: Resource[] = uuidsToCopy
+ .map(uuid => getResource(uuid)(getState().resources) as any)
+ .filter(resource => resource.kind === ResourceKind.COLLECTION);
+
+ for (const collection of collectionsToCopy) {
+ await copySingleCollection(collection as Resource & { name: string });
+ }
+
+ async function copySingleCollection(copyToProject: Resource & { name: string }) {
+ const newName = data.isSingle ? data.name : `Copy of: ${copyToProject.name}`;
+ try {
+ const collection = await dispatch<any>(collectionCopyActions.copyCollection({ ...copyToProject, name: newName }));
+ if (copyToProject && collection) {
+ await dispatch<any>(reloadProjectMatchingUuid([copyToProject.uuid]));
+ dispatch(
+ snackbarActions.OPEN_SNACKBAR({
+ message: "Collection has been copied.",
+ hideDuration: 3000,
+ kind: SnackbarKind.SUCCESS,
+ link: collection.ownerUuid,
+ })
+ );
+ }
+ } catch (e) {
dispatch(
snackbarActions.OPEN_SNACKBAR({
- message: "Collection has been copied.",
- hideDuration: 3000,
- kind: SnackbarKind.SUCCESS,
- link: collection.ownerUuid,
+ message: e.message,
+ hideDuration: 2000,
+ kind: SnackbarKind.ERROR,
})
);
}
- } catch (e) {
- dispatch(
- snackbarActions.OPEN_SNACKBAR({
- message: e.message,
- hideDuration: 2000,
- kind: SnackbarKind.ERROR,
- })
- );
}
};
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 f960571e..f1250582 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
@@ -66,7 +66,7 @@ const commonActionSet: ContextMenuActionSet = [
icon: CopyIcon,
name: "Make a copy",
execute: (dispatch, resources) => {
- resources.forEach(resource => dispatch<any>(openCollectionCopyDialog(resource))); //here
+ dispatch<any>(openCollectionCopyDialog(resources[0]));
},
},
{
diff --git a/src/views-components/data-explorer/data-explorer.tsx b/src/views-components/data-explorer/data-explorer.tsx
index 871389d4..d885fd5a 100644
--- a/src/views-components/data-explorer/data-explorer.tsx
+++ b/src/views-components/data-explorer/data-explorer.tsx
@@ -2,17 +2,17 @@
//
// SPDX-License-Identifier: AGPL-3.0
-import { connect } from 'react-redux';
-import { RootState } from 'store/store';
-import { DataExplorer as DataExplorerComponent } from 'components/data-explorer/data-explorer';
-import { getDataExplorer } from 'store/data-explorer/data-explorer-reducer';
-import { Dispatch } from 'redux';
-import { dataExplorerActions } from 'store/data-explorer/data-explorer-action';
-import { DataColumn } from 'components/data-table/data-column';
-import { DataColumns, TCheckedList } from 'components/data-table/data-table';
-import { DataTableFilters } from 'components/data-table-filters/data-table-filters-tree';
-import { LAST_REFRESH_TIMESTAMP } from 'components/refresh-button/refresh-button';
-import { toggleMSToolbar, setCheckedListOnStore } from 'store/multiselect/multiselect-actions';
+import { connect } from "react-redux";
+import { RootState } from "store/store";
+import { DataExplorer as DataExplorerComponent } from "components/data-explorer/data-explorer";
+import { getDataExplorer } from "store/data-explorer/data-explorer-reducer";
+import { Dispatch } from "redux";
+import { dataExplorerActions } from "store/data-explorer/data-explorer-action";
+import { DataColumn } from "components/data-table/data-column";
+import { DataColumns, TCheckedList } from "components/data-table/data-table";
+import { DataTableFilters } from "components/data-table-filters/data-table-filters-tree";
+import { LAST_REFRESH_TIMESTAMP } from "components/refresh-button/refresh-button";
+import { toggleMSToolbar, setCheckedListOnStore } from "store/multiselect/multiselect-actions";
interface Props {
id: string;
@@ -23,11 +23,11 @@ interface Props {
}
const mapStateToProps = (state: RootState, { id }: Props) => {
- const progress = state.progressIndicator.find((p) => p.id === id);
+ const progress = state.progressIndicator.find(p => p.id === id);
const dataExplorerState = getDataExplorer(state.dataExplorer, id);
- const currentRoute = state.router.location ? state.router.location.pathname : '';
- const currentRefresh = localStorage.getItem(LAST_REFRESH_TIMESTAMP) || '';
- const currentItemUuid = currentRoute === '/workflows' ? state.properties.workflowPanelDetailsUuid : state.detailsPanel.resourceUuid;
+ const currentRoute = state.router.location ? state.router.location.pathname : "";
+ const currentRefresh = localStorage.getItem(LAST_REFRESH_TIMESTAMP) || "";
+ const currentItemUuid = currentRoute === "/workflows" ? state.properties.workflowPanelDetailsUuid : state.detailsPanel.resourceUuid;
const isMSToolbarVisible = state.multiselect.isVisible;
return {
...dataExplorerState,
@@ -37,10 +37,11 @@ const mapStateToProps = (state: RootState, { id }: Props) => {
paperKey: currentRoute,
currentItemUuid,
isMSToolbarVisible,
+ checkedList: state.multiselect.checkedList,
};
};
-const mapDispatchToProps = (dispatchFn) => {
+const mapDispatchToProps = dispatchFn => {
return (dispatch: Dispatch, { id, onRowClick, onRowDoubleClick, onContextMenu }: Props) => ({
onSetColumns: (columns: DataColumns<any, any>) => {
dispatch(dataExplorerActions.SET_COLUMNS({ id, columns }));
diff --git a/src/views-components/dialog-copy/dialog-copy.tsx b/src/views-components/dialog-copy/dialog-copy.tsx
index a3e30119..aa6b6784 100644
--- a/src/views-components/dialog-copy/dialog-copy.tsx
+++ b/src/views-components/dialog-copy/dialog-copy.tsx
@@ -3,37 +3,40 @@
// SPDX-License-Identifier: AGPL-3.0
import React from "react";
-import { memoize } from 'lodash/fp';
-import { InjectedFormProps, Field } from 'redux-form';
-import { WithDialogProps } from 'store/dialog/with-dialog';
-import { FormDialog } from 'components/form-dialog/form-dialog';
-import { ProjectTreePickerField } from 'views-components/projects-tree-picker/tree-picker-field';
-import { COPY_NAME_VALIDATION, COPY_FILE_VALIDATION } from 'validators/validators';
+import { memoize } from "lodash/fp";
+import { InjectedFormProps, Field } from "redux-form";
+import { WithDialogProps } from "store/dialog/with-dialog";
+import { FormDialog } from "components/form-dialog/form-dialog";
+import { ProjectTreePickerField } from "views-components/projects-tree-picker/tree-picker-field";
+import { COPY_NAME_VALIDATION, COPY_FILE_VALIDATION } from "validators/validators";
import { TextField } from "components/text-field/text-field";
-import { CopyFormDialogData } from 'store/copy-dialog/copy-dialog';
-import { PickerIdProp } from 'store/tree-picker/picker-id';
+import { CopyFormDialogData } from "store/copy-dialog/copy-dialog";
+import { PickerIdProp } from "store/tree-picker/picker-id";
type CopyFormDialogProps = WithDialogProps<string> & InjectedFormProps<CopyFormDialogData>;
-export const DialogCopy = (props: CopyFormDialogProps & PickerIdProp) =>
+export const DialogCopy = (props: CopyFormDialogProps & PickerIdProp) => (
<FormDialog
- dialogTitle='Make a copy'
+ dialogTitle="Make a copy"
formFields={CopyDialogFields(props.pickerId)}
- submitLabel='Copy'
+ submitLabel="Copy"
{...props}
- />;
+ />
+);
-const CopyDialogFields = memoize((pickerId: string) =>
- () =>
- <>
- <Field
- name='name'
- component={TextField as any}
- validate={COPY_NAME_VALIDATION}
- label="Enter a new name for the copy" />
- <Field
- name="ownerUuid"
- component={ProjectTreePickerField}
- validate={COPY_FILE_VALIDATION}
- pickerId={pickerId}/>
- </>);
+const CopyDialogFields = memoize((pickerId: string) => () => (
+ <>
+ <Field
+ name="name"
+ component={TextField as any}
+ validate={COPY_NAME_VALIDATION}
+ label="Enter a new name for the copy"
+ />
+ <Field
+ name="ownerUuid"
+ component={ProjectTreePickerField}
+ validate={COPY_FILE_VALIDATION}
+ pickerId={pickerId}
+ />
+ </>
+));
diff --git a/src/views-components/dialog-forms/copy-collection-dialog.ts b/src/views-components/dialog-forms/copy-collection-dialog.ts
index a1c822cf..eb1f2615 100644
--- a/src/views-components/dialog-forms/copy-collection-dialog.ts
+++ b/src/views-components/dialog-forms/copy-collection-dialog.ts
@@ -4,12 +4,12 @@
import { compose } from "redux";
import { withDialog } from "store/dialog/with-dialog";
-import { reduxForm } from 'redux-form';
-import { COLLECTION_COPY_FORM_NAME } from 'store/collections/collection-copy-actions';
+import { reduxForm } from "redux-form";
+import { COLLECTION_COPY_FORM_NAME } from "store/collections/collection-copy-actions";
import { DialogCopy } from "views-components/dialog-copy/dialog-copy";
-import { copyCollection } from 'store/workbench/workbench-actions';
-import { CopyFormDialogData } from 'store/copy-dialog/copy-dialog';
-import { pickerId } from 'store/tree-picker/picker-id';
+import { copyCollection } from "store/workbench/workbench-actions";
+import { CopyFormDialogData } from "store/copy-dialog/copy-dialog";
+import { pickerId } from "store/tree-picker/picker-id";
export const CopyCollectionDialog = compose(
withDialog(COLLECTION_COPY_FORM_NAME),
@@ -18,7 +18,7 @@ export const CopyCollectionDialog = compose(
touchOnChange: true,
onSubmit: (data, dispatch) => {
dispatch(copyCollection(data));
- }
+ },
}),
- pickerId(COLLECTION_COPY_FORM_NAME),
-)(DialogCopy);
\ No newline at end of file
+ pickerId(COLLECTION_COPY_FORM_NAME)
+)(DialogCopy);
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list