From 42f46bf682cf6590b1d87424d616c5c9b9c9154d Mon Sep 17 00:00:00 2001 From: Michal Klobukowski Date: Sat, 18 Aug 2018 11:22:46 +0200 Subject: [PATCH] Implement file renaming Feature #14015 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- .../collection-panel-files-actions.ts | 33 ++++++++++++++++++- .../collection-files-item-action-set.ts | 7 ++-- .../rename-file-dialog/rename-file-dialog.tsx | 24 ++++---------- 3 files changed, 42 insertions(+), 22 deletions(-) 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 f2dc551b..818197db 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 @@ -11,9 +11,10 @@ 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 { startSubmit, initialize, SubmissionError, stopSubmit, reset } from 'redux-form'; import { loadProjectTreePickerProjects } from '../../../views-components/project-tree-picker/project-tree-picker'; import { getCommonResourceServiceError, CommonResourceServiceError } from "~/common/api/common-resource-service"; +import { getDialog } from "~/store/dialog/dialog-reducer"; export const collectionPanelFilesAction = unionize({ SET_COLLECTION_FILES: ofType(), @@ -136,3 +137,33 @@ export const doCollectionPartialCopy = ({ name, description, projectUuid }: Coll } }; +export const RENAME_FILE_DIALOG = 'renameFileDialog'; +export interface RenameFileDialogData { + name: string; + id: string; +} + +export const openRenameFileDialog = (data: RenameFileDialogData) => + (dispatch: Dispatch) => { + dispatch(reset(RENAME_FILE_DIALOG)); + dispatch(dialogActions.OPEN_DIALOG({ id: RENAME_FILE_DIALOG, data })); + }; + +export const renameFile = (newName: string) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const dialog = getDialog(getState().dialog, RENAME_FILE_DIALOG); + const currentCollection = getState().collectionPanel.item; + if (dialog && currentCollection) { + dispatch(startSubmit(RENAME_FILE_DIALOG)); + const oldPath = dialog.data.id; + const newPath = dialog.data.id.replace(dialog.data.name, newName); + try { + await services.collectionService.moveFile(currentCollection.uuid, oldPath, newPath); + dispatch(loadCollectionFiles(currentCollection.uuid)); + dispatch(dialogActions.CLOSE_DIALOG({ id: RENAME_FILE_DIALOG })); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'File name changed.', hideDuration: 2000 })); + } catch (e) { + dispatch(stopSubmit(RENAME_FILE_DIALOG, { name: 'Could not rename the file' })); + } + } + }; diff --git a/src/views-components/context-menu/action-sets/collection-files-item-action-set.ts b/src/views-components/context-menu/action-sets/collection-files-item-action-set.ts index a3bfa0b9..0bc693cc 100644 --- a/src/views-components/context-menu/action-sets/collection-files-item-action-set.ts +++ b/src/views-components/context-menu/action-sets/collection-files-item-action-set.ts @@ -3,17 +3,16 @@ // SPDX-License-Identifier: AGPL-3.0 import { ContextMenuActionSet } from "../context-menu-action-set"; -import { RenameIcon, DownloadIcon, RemoveIcon } from "~/components/icon/icon"; -import { openRenameFileDialog } from "../../rename-file-dialog/rename-file-dialog"; +import { RenameIcon, RemoveIcon } from "~/components/icon/icon"; import { DownloadCollectionFileAction } from "../actions/download-collection-file-action"; -import { openFileRemoveDialog } from "../../../store/collection-panel/collection-panel-files/collection-panel-files-actions"; +import { openFileRemoveDialog, openRenameFileDialog } from '../../../store/collection-panel/collection-panel-files/collection-panel-files-actions'; export const collectionFilesItemActionSet: ContextMenuActionSet = [[{ name: "Rename", icon: RenameIcon, execute: (dispatch, resource) => { - dispatch(openRenameFileDialog(resource.name)); + dispatch(openRenameFileDialog({ name: resource.name, id: resource.uuid })); } }, { component: DownloadCollectionFileAction, diff --git a/src/views-components/rename-file-dialog/rename-file-dialog.tsx b/src/views-components/rename-file-dialog/rename-file-dialog.tsx index f23d4c06..20116fcd 100644 --- a/src/views-components/rename-file-dialog/rename-file-dialog.tsx +++ b/src/views-components/rename-file-dialog/rename-file-dialog.tsx @@ -3,33 +3,23 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { Dispatch, compose } from 'redux'; +import { compose } from 'redux'; import { reduxForm, reset, startSubmit, stopSubmit, InjectedFormProps, Field } from 'redux-form'; import { withDialog, WithDialogProps } from '~/store/dialog/with-dialog'; -import { dialogActions } from "~/store/dialog/dialog-actions"; import { FormDialog } from '~/components/form-dialog/form-dialog'; import { DialogContentText } from '@material-ui/core'; import { TextField } from '~/components/text-field/text-field'; - -export const RENAME_FILE_DIALOG = 'renameFileDialog'; - -export const openRenameFileDialog = (originalName: string) => - (dispatch: Dispatch) => { - dispatch(reset(RENAME_FILE_DIALOG)); - dispatch(dialogActions.OPEN_DIALOG({ id: RENAME_FILE_DIALOG, data: originalName })); - }; +import { RENAME_FILE_DIALOG, RenameFileDialogData, renameFile } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions'; export const RenameFileDialog = compose( withDialog(RENAME_FILE_DIALOG), reduxForm({ form: RENAME_FILE_DIALOG, - onSubmit: (data, dispatch) => { - dispatch(startSubmit(RENAME_FILE_DIALOG)); - // TODO: call collection file renaming action here - setTimeout(() => dispatch(stopSubmit(RENAME_FILE_DIALOG, { name: 'Invalid name' })), 2000); + onSubmit: (data: { name: string }, dispatch) => { + dispatch(renameFile(data.name)); } }) -)((props: WithDialogProps & InjectedFormProps<{ name: string }>) => +)((props: WithDialogProps & InjectedFormProps<{ name: string }>) => ); -const RenameDialogFormFields = (props: WithDialogProps) => <> +const RenameDialogFormFields = (props: WithDialogProps) => <> - {`Please, enter a new name for ${props.data}`} + {`Please, enter a new name for ${props.data.name}`}