X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/dd89200ad6fdbfa337fdbab5f54def8712c6746c..9cbd6231837df8564953330fc63ce0fb9b9454cc:/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts diff --git a/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts b/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts index 09821083ee..f2dc551b10 100644 --- a/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts +++ b/src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts @@ -3,7 +3,17 @@ // SPDX-License-Identifier: AGPL-3.0 import { default as unionize, ofType, UnionOf } from "unionize"; -import { CollectionFilesTree } from "~/models/collection-file"; +import { Dispatch } from "redux"; +import { CollectionFilesTree, CollectionFileType } from "~/models/collection-file"; +import { ServiceRepository } from "~/services/services"; +import { RootState } from "../../store"; +import { snackbarActions } from "../../snackbar/snackbar-actions"; +import { dialogActions } from '../../dialog/dialog-actions'; +import { getNodeValue } from "~/models/tree"; +import { filterCollectionFilesBySelection } from './collection-panel-files-state'; +import { startSubmit, initialize, SubmissionError, stopSubmit } from 'redux-form'; +import { loadProjectTreePickerProjects } from '../../../views-components/project-tree-picker/project-tree-picker'; +import { getCommonResourceServiceError, CommonResourceServiceError } from "~/common/api/common-resource-service"; export const collectionPanelFilesAction = unionize({ SET_COLLECTION_FILES: ofType(), @@ -14,3 +24,115 @@ export const collectionPanelFilesAction = unionize({ }, { tag: 'type', value: 'payload' }); export type CollectionPanelFilesAction = UnionOf; + +export const loadCollectionFiles = (uuid: string) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const files = await services.collectionService.files(uuid); + dispatch(collectionPanelFilesAction.SET_COLLECTION_FILES(files)); + }; + +export const removeCollectionFiles = (filePaths: string[]) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const currentCollection = getState().collectionPanel.item; + if (currentCollection) { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removing ...' })); + await services.collectionService.deleteFiles(currentCollection.uuid, filePaths); + dispatch(loadCollectionFiles(currentCollection.uuid)); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removed.', hideDuration: 2000 })); + } + }; + +export const removeCollectionsSelectedFiles = () => + (dispatch: Dispatch, getState: () => RootState) => { + const paths = filterCollectionFilesBySelection(getState().collectionPanelFiles, true).map(file => file.id); + dispatch(removeCollectionFiles(paths)); + }; + +export const FILE_REMOVE_DIALOG = 'fileRemoveDialog'; + +export const openFileRemoveDialog = (filePath: string) => + (dispatch: Dispatch, getState: () => RootState) => { + const file = getNodeValue(filePath)(getState().collectionPanelFiles); + if (file) { + const title = file.type === CollectionFileType.DIRECTORY + ? 'Removing directory' + : 'Removing file'; + const text = file.type === CollectionFileType.DIRECTORY + ? 'Are you sure you want to remove this directory?' + : 'Are you sure you want to remove this file?'; + + dispatch(dialogActions.OPEN_DIALOG({ + id: FILE_REMOVE_DIALOG, + data: { + title, + text, + confirmButtonLabel: 'Remove', + filePath + } + })); + } + }; + +export const MULTIPLE_FILES_REMOVE_DIALOG = 'multipleFilesRemoveDialog'; + +export const openMultipleFilesRemoveDialog = () => + dialogActions.OPEN_DIALOG({ + id: MULTIPLE_FILES_REMOVE_DIALOG, + data: { + title: 'Removing files', + text: 'Are you sure you want to remove selected files?', + confirmButtonLabel: 'Remove' + } + }); + +export const COLLECTION_PARTIAL_COPY = 'COLLECTION_PARTIAL_COPY'; + +export interface CollectionPartialCopyFormData { + name: string; + description: string; + projectUuid: string; +} + +export const openCollectionPartialCopyDialog = () => + (dispatch: Dispatch, getState: () => RootState) => { + const currentCollection = getState().collectionPanel.item; + if (currentCollection) { + const initialData = { + name: currentCollection.name, + description: currentCollection.description, + projectUuid: '' + }; + dispatch(initialize(COLLECTION_PARTIAL_COPY, initialData)); + dispatch(loadProjectTreePickerProjects('')); + dispatch(dialogActions.OPEN_DIALOG({ id: COLLECTION_PARTIAL_COPY, data: {} })); + } + }; + +export const doCollectionPartialCopy = ({ name, description, projectUuid }: CollectionPartialCopyFormData) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(startSubmit(COLLECTION_PARTIAL_COPY)); + const state = getState(); + const currentCollection = state.collectionPanel.item; + if (currentCollection) { + try { + const collection = await services.collectionService.get(currentCollection.uuid); + const collectionCopy = { + ...collection, + name, + description, + ownerUuid: projectUuid, + uuid: undefined + }; + const newCollection = await services.collectionService.create(collectionCopy); + const paths = filterCollectionFilesBySelection(state.collectionPanelFiles, false).map(file => file.id); + await services.collectionService.deleteFiles(newCollection.uuid, paths); + dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY })); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'New collection created.', hideDuration: 2000 })); + } catch (e) { + if (getCommonResourceServiceError(e) === CommonResourceServiceError.UNIQUE_VIOLATION) { + dispatch(stopSubmit(COLLECTION_PARTIAL_COPY, { name: 'Collection with this name already exists.' })); + } + } + } + }; +