--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from "react";
+import { Field, InjectedFormProps, WrappedFieldProps } from "redux-form";
+import { Dialog, DialogTitle, DialogContent, DialogActions, Button, CircularProgress } from "@material-ui/core";
+
+import { WithDialogProps } from "../../store/dialog/with-dialog";
+import { ProjectTreePickerWithSidePanel } from "../../views-components/project-tree-picker/project-tree-picker";
+import { MOVE_TO_VALIDATION } from "../../validators/move-to/move-to-validator";
+
+export const MoveTo = (props: WithDialogProps<string> & InjectedFormProps<{ name: string }>) =>
+ <form>
+ <Dialog open={props.open}
+ disableBackdropClick={true}
+ disableEscapeKeyDown={true}>
+ <DialogTitle>Move to</DialogTitle>
+ <DialogContent>
+ <Field
+ name="projectUuid"
+ component={Picker}
+ validate={MOVE_TO_VALIDATION} />
+ </DialogContent>
+ <DialogActions>
+ <Button
+ variant='flat'
+ color='primary'
+ disabled={props.submitting}
+ onClick={props.closeDialog}>
+ Cancel
+ </Button>
+ <Button
+ variant='contained'
+ color='primary'
+ type='submit'
+ onClick={props.handleSubmit}
+ disabled={props.pristine || props.invalid || props.submitting}>
+ {props.submitting
+ ? <CircularProgress size={20} />
+ : 'Move'}
+ </Button>
+ </DialogActions>
+ </Dialog>
+ </form>;
+
+const Picker = (props: WrappedFieldProps) =>
+ <div style={{ width: '400px', height: '144px', display: 'flex', flexDirection: 'column' }}>
+ <ProjectTreePickerWithSidePanel onChange={projectUuid => props.input.onChange(projectUuid)} />
+ </div>;
\ No newline at end of file
import { maxLength } from '../max-length';
export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)];
-export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)];
\ No newline at end of file
+export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)];
+export const COLLECTION_PROJECT_VALIDATION = [require];
\ No newline at end of file
export const PROJECT_NAME_VALIDATION = [require, maxLength(255)];
export const PROJECT_DESCRIPTION_VALIDATION = [maxLength(255)];
-export const COLLECTION_NAME_VALIDATION = [require, maxLength(255)];
-export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)];
-export const COLLECTION_PROJECT_VALIDATION = [require];
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { require } from '../require';
+
+export const MOVE_TO_VALIDATION = [require];
\ No newline at end of file
import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, ProvenanceGraphIcon, AdvancedIcon, RemoveIcon } from "../../../components/icon/icon";
import { openUpdater } from "../../../store/collections/updater/collection-updater-action";
import { favoritePanelActions } from "../../../store/favorite-panel/favorite-panel-action";
+import { openMoveToDialog } from "../../move-to-dialog/move-to-dialog";
export const collectionActionSet: ContextMenuActionSet = [[
{
{
icon: MoveToIcon,
name: "Move to",
- execute: (dispatch, resource) => {
- // add code
+ execute: (dispatch) => {
+ dispatch<any>(openMoveToDialog());
}
},
{
import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, RemoveIcon } from "../../../components/icon/icon";
import { openUpdater } from "../../../store/collections/updater/collection-updater-action";
import { favoritePanelActions } from "../../../store/favorite-panel/favorite-panel-action";
+import { openMoveToDialog } from "../../move-to-dialog/move-to-dialog";
export const collectionResourceActionSet: ContextMenuActionSet = [[
{
{
icon: MoveToIcon,
name: "Move to",
- execute: (dispatch, resource) => {
- // add code
+ execute: (dispatch) => {
+ dispatch<any>(openMoveToDialog());
}
},
{
import { ContextMenuActionSet } from "../context-menu-action-set";
import { projectActions } from "../../../store/project/project-action";
-import { NewProjectIcon } from "../../../components/icon/icon";
+import { NewProjectIcon, MoveToIcon } from "../../../components/icon/icon";
import { ToggleFavoriteAction } from "../actions/favorite-action";
import { toggleFavorite } from "../../../store/favorites/favorites-actions";
import { favoritePanelActions } from "../../../store/favorite-panel/favorite-panel-action";
+import { openMoveToDialog } from "../../move-to-dialog/move-to-dialog";
export const projectActionSet: ContextMenuActionSet = [[{
icon: NewProjectIcon,
dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
});
}
-}]];
+}, {
+ icon: MoveToIcon,
+ name: "Move to",
+ execute: (dispatch) => {
+ dispatch<any>(openMoveToDialog());
+ }
+},]];
import { Dialog, DialogTitle, DialogContent, DialogActions, Button, CircularProgress, FormHelperText } from "@material-ui/core";
import { WithDialogProps } from "../../store/dialog/with-dialog";
import { TextField } from "../../components/text-field/text-field";
-import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION, COLLECTION_PROJECT_VALIDATION } from "../../validators/create-project/create-project-validator";
+import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION, COLLECTION_PROJECT_VALIDATION } from "../../validators/create-collection/create-collection-validator";
import { ProjectTreePicker } from "../project-tree-picker/project-tree-picker";
export const DialogCollectionCreateWithSelected = (props: WithDialogProps<string> & InjectedFormProps<{ name: string }>) =>
--- /dev/null
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { withDialog } from "../../store/dialog/with-dialog";
+import { dialogActions } from "../../store/dialog/dialog-actions";
+import { MoveTo } from "../../components/move-to-dialog/move-to-dialog";
+import { loadProjectTreePickerProjects } from "../project-tree-picker/project-tree-picker";
+import { reduxForm, startSubmit, stopSubmit } from "redux-form";
+
+export const MOVE_TO_DIALOG = 'moveToDialog';
+
+export const openMoveToDialog = () =>
+ (dispatch: Dispatch) => {
+ dispatch<any>(loadProjectTreePickerProjects(''));
+ dispatch(dialogActions.OPEN_DIALOG({ id: MOVE_TO_DIALOG, data: {}}));
+ };
+
+export const [MoveToProjectDialog] = [MoveTo]
+ .map(withDialog(MOVE_TO_DIALOG))
+ .map(reduxForm({
+ form: MOVE_TO_DIALOG,
+ onSubmit: (data, dispatch) => {
+ dispatch(startSubmit(MOVE_TO_DIALOG));
+ setTimeout(() => dispatch(stopSubmit(MOVE_TO_DIALOG, { name: 'Invalid path' })), 2000);
+ }
+ }));
\ No newline at end of file
type ProjectTreePickerProps = Pick<TreeProps<ProjectResource>, 'toggleItemActive' | 'toggleItemOpen'>;
-const mapDispatchToProps = (dispatch: Dispatch, props: {onChange: (projectUuid: string) => void}): ProjectTreePickerProps => ({
+const mapDispatchToProps = (dispatch: Dispatch, props: { onChange: (projectUuid: string) => void }): ProjectTreePickerProps => ({
toggleItemActive: id => {
dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_SELECT({ id }));
props.onChange(id);
});
export const ProjectTreePicker = connect(undefined, mapDispatchToProps)((props: ProjectTreePickerProps) =>
- <div style={{display: 'flex', flexDirection: 'column'}}>
- <Typography variant='caption' style={{flexShrink: 0}}>
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
+ <Typography variant='caption' style={{ flexShrink: 0 }}>
Select a project
</Typography>
- <div style={{flexGrow: 1, overflow: 'auto'}}>
+ <div style={{ flexGrow: 1, overflow: 'auto' }}>
<TreePicker {...props} render={renderTreeItem} />
</div>
</div>);
+export const ProjectTreePickerWithSidePanel = connect(undefined, mapDispatchToProps)((props: ProjectTreePickerProps) =>
+ <div style={{ display: 'flex', flexDirection: 'column' }}>
+ <div style={{ flexGrow: 1, overflow: 'auto' }}>
+ <TreePicker {...props} render={renderTreeItem} />
+ </div>
+ </div>
+);
+
// TODO: move action creator to store directory
export const loadProjectTreePickerProjects = (id: string) =>
async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
import { FileRemoveDialog } from '../../views-components/file-remove-dialog/file-remove-dialog';
import { MultipleFilesRemoveDialog } from '../../views-components/file-remove-dialog/multiple-files-remove-dialog';
import { DialogCollectionCreateWithSelectedFile } from '../../views-components/create-collection-dialog-with-selected/create-collection-dialog-with-selected';
+import { MoveToProjectDialog } from '../../views-components/move-to-dialog/move-to-dialog';
const DRAWER_WITDH = 240;
const APP_BAR_HEIGHT = 100;
<CreateProjectDialog />
<CreateCollectionDialog />
<RenameFileDialog />
+ <MoveToProjectDialog />
<DialogCollectionCreateWithSelectedFile />
<FileRemoveDialog />
<MultipleFilesRemoveDialog />