20031: Navigate to new collections when copying/moving to new collection
[arvados-workbench2.git] / src / store / collections / collection-partial-move-actions.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { Dispatch } from "redux";
6 import { FormErrors, initialize, startSubmit, stopSubmit } from "redux-form";
7 import { CommonResourceServiceError, getCommonResourceServiceError } from "services/common-service/common-resource-service";
8 import { ServiceRepository } from "services/services";
9 import { filterCollectionFilesBySelection } from "store/collection-panel/collection-panel-files/collection-panel-files-state";
10 import { dialogActions } from "store/dialog/dialog-actions";
11 import { navigateTo } from "store/navigation/navigation-action";
12 import { progressIndicatorActions } from "store/progress-indicator/progress-indicator-actions";
13 import { resetPickerProjectTree } from "store/project-tree-picker/project-tree-picker-actions";
14 import { updateResources } from "store/resources/resources-actions";
15 import { SnackbarKind, snackbarActions } from "store/snackbar/snackbar-actions";
16 import { RootState } from "store/store";
17 import { initProjectsTreePicker } from "store/tree-picker/tree-picker-actions";
18
19 export const COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION = 'COLLECTION_PARTIAL_MOVE_TO_NEW_DIALOG';
20 export const COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION = 'COLLECTION_PARTIAL_MOVE_TO_SELECTED_DIALOG';
21
22 export interface CollectionPartialMoveToNewCollectionFormData {
23     name: string;
24     description: string;
25     projectUuid: string;
26 }
27
28 export interface CollectionPartialMoveToExistingCollectionFormData {
29     destination: {uuid: string, path?: string};
30 }
31
32 export const openCollectionPartialMoveToNewCollectionDialog = () =>
33     (dispatch: Dispatch, getState: () => RootState) => {
34         const currentCollection = getState().collectionPanel.item;
35         if (currentCollection) {
36             const initialData = {
37                 name: `Files moved from: ${currentCollection.name}`,
38                 description: currentCollection.description,
39                 projectUuid: undefined
40             };
41             dispatch(initialize(COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION, initialData));
42             dispatch<any>(resetPickerProjectTree());
43             dispatch<any>(initProjectsTreePicker(COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION));
44             dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION, data: {} }));
45         }
46     };
47
48 export const moveCollectionPartialToNewCollection = ({ name, description, projectUuid }: CollectionPartialMoveToNewCollectionFormData) =>
49     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
50         const state = getState();
51         // Get current collection
52         const sourceCollection = state.collectionPanel.item;
53
54         if (sourceCollection) {
55             try {
56                 dispatch(startSubmit(COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION));
57                 dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION));
58
59                 // Get selected files
60                 const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, true)
61                     .map(file => file.id.replace(new RegExp(`(^${sourceCollection.uuid})`), ''));
62
63                 // Move files
64                 const updatedCollection = await services.collectionService.moveFiles(
65                     sourceCollection.uuid,
66                     sourceCollection.portableDataHash,
67                     paths,
68                     {
69                         name,
70                         description,
71                         ownerUuid: projectUuid,
72                         uuid: undefined,
73                     },
74                     '/',
75                     false
76                 );
77                 dispatch(updateResources([updatedCollection]));
78                 dispatch<any>(navigateTo(updatedCollection.uuid))
79
80                 dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION }));
81                 dispatch(snackbarActions.OPEN_SNACKBAR({
82                     message: 'Files have been moved to selected collection.',
83                     hideDuration: 2000,
84                     kind: SnackbarKind.SUCCESS
85                 }));
86                 dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION));
87             } catch (e) {
88                 const error = getCommonResourceServiceError(e);
89                 if (error === CommonResourceServiceError.UNKNOWN) {
90                     dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION }));
91                     dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not move files to selected collection', hideDuration: 2000, kind: SnackbarKind.ERROR }));
92                 }
93                 dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_MOVE_TO_NEW_COLLECTION));
94             }
95         }
96     };
97
98 export const openCollectionPartialMoveToExistingCollectionDialog = () =>
99     (dispatch: Dispatch, getState: () => RootState) => {
100         const currentCollection = getState().collectionPanel.item;
101         if (currentCollection) {
102             const initialData = {
103                 destination: {uuid: '', path: ''}
104             };
105             dispatch(initialize(COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION, initialData));
106             dispatch<any>(resetPickerProjectTree());
107             dispatch<any>(initProjectsTreePicker(COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION));
108             dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION, data: {} }));
109         }
110     };
111
112 export const moveCollectionPartialToExistingCollection = ({ destination }: CollectionPartialMoveToExistingCollectionFormData) =>
113     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
114         const state = getState();
115         // Get current collection
116         const sourceCollection = state.collectionPanel.item;
117
118         if (sourceCollection && destination.uuid) {
119             try {
120                 dispatch(startSubmit(COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION));
121                 dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION));
122                 // Get selected files
123                 const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, true)
124                     .map(file => file.id.replace(new RegExp(`(^${sourceCollection.uuid})`), ''));
125
126                 // Move files
127                 const updatedCollection = await services.collectionService.moveFiles(sourceCollection.uuid, sourceCollection.portableDataHash, paths, {uuid: destination.uuid}, destination.path || '/', false);
128                 dispatch(updateResources([updatedCollection]));
129
130                 dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION }));
131                 dispatch(snackbarActions.OPEN_SNACKBAR({
132                     message: 'Files have been moved to selected collection.',
133                     hideDuration: 2000,
134                     kind: SnackbarKind.SUCCESS
135                 }));
136                 dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION));
137             } catch (e) {
138                 const error = getCommonResourceServiceError(e);
139                 if (error === CommonResourceServiceError.UNKNOWN) {
140                     dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION }));
141                     dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Could not copy this files to selected collection', hideDuration: 2000, kind: SnackbarKind.ERROR }));
142                 }
143                 dispatch(progressIndicatorActions.STOP_WORKING(COLLECTION_PARTIAL_MOVE_TO_SELECTED_COLLECTION));
144             }
145         }
146     };