ui-move-to-popup-without-side-panel
authorPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Thu, 9 Aug 2018 14:30:33 +0000 (16:30 +0200)
committerPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Thu, 9 Aug 2018 14:30:33 +0000 (16:30 +0200)
Feature #13902

Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>

src/components/move-to-dialog/move-to-dialog.tsx [new file with mode: 0644]
src/validators/create-collection/create-collection-validator.tsx
src/validators/create-project/create-project-validator.tsx
src/validators/move-to/move-to-validator.tsx [new file with mode: 0644]
src/views-components/context-menu/action-sets/collection-action-set.ts
src/views-components/context-menu/action-sets/collection-resource-action-set.ts
src/views-components/context-menu/action-sets/project-action-set.ts
src/views-components/dialog-create/dialog-collection-create-selected.tsx
src/views-components/move-to-dialog/move-to-dialog.tsx [new file with mode: 0644]
src/views-components/project-tree-picker/project-tree-picker.tsx
src/views/workbench/workbench.tsx

diff --git a/src/components/move-to-dialog/move-to-dialog.tsx b/src/components/move-to-dialog/move-to-dialog.tsx
new file mode 100644 (file)
index 0000000..df66c01
--- /dev/null
@@ -0,0 +1,50 @@
+// 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
index 2d8e1f502730059f8eafe19bb93b92db64eedea8..1ada691bc4cd12ca4dd9d9adb40a9eae1b00448d 100644 (file)
@@ -6,4 +6,5 @@ import { require } from '../require';
 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
index ddea8be97055a0c0f5ded7a3e48386c0a4794660..928efdd2205e439c82fbd936e0e476e13f046139 100644 (file)
@@ -7,6 +7,3 @@ import { maxLength } from '../max-length';
 
 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];
diff --git a/src/validators/move-to/move-to-validator.tsx b/src/validators/move-to/move-to-validator.tsx
new file mode 100644 (file)
index 0000000..eb30df3
--- /dev/null
@@ -0,0 +1,7 @@
+// 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
index 10da9ef183448299f8a695f175be28fe1d4c4687..75ffdb3b82d0892bc3164354411feacc11d7a21b 100644 (file)
@@ -8,6 +8,7 @@ import { toggleFavorite } from "../../../store/favorites/favorites-actions";
 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 = [[
     {
@@ -27,8 +28,8 @@ export const collectionActionSet: ContextMenuActionSet = [[
     {
         icon: MoveToIcon,
         name: "Move to",
-        execute: (dispatch, resource) => {
-            // add code
+        execute: (dispatch) => {
+            dispatch<any>(openMoveToDialog());
         }
     },
     {
index e6356bbce093e3493099afaa750581e3f157d52a..f0e7efeb1cd5cfaf70738520af222f2576851c54 100644 (file)
@@ -8,6 +8,7 @@ import { toggleFavorite } from "../../../store/favorites/favorites-actions";
 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 = [[
     {
@@ -27,8 +28,8 @@ export const collectionResourceActionSet: ContextMenuActionSet = [[
     {
         icon: MoveToIcon,
         name: "Move to",
-        execute: (dispatch, resource) => {
-            // add code
+        execute: (dispatch) => {
+            dispatch<any>(openMoveToDialog());
         }
     },
     {
index df298e4b1f8c1c472bae5fdc7c2b8d5ba8f464ad..39359e264fd8eae1649c2b880d5952a729c0437b 100644 (file)
@@ -4,10 +4,11 @@
 
 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,
@@ -22,4 +23,10 @@ export const projectActionSet: ContextMenuActionSet = [[{
             dispatch<any>(favoritePanelActions.REQUEST_ITEMS());
         });
     }
-}]];
+}, {
+    icon: MoveToIcon,
+    name: "Move to",
+    execute: (dispatch) => {
+        dispatch<any>(openMoveToDialog());
+    }
+},]];
index 5069db94b521999953524a3cffbdff1b2c5aacbc..8fb60333e9a888603ece93ab61bb43b3f37502b8 100644 (file)
@@ -7,7 +7,7 @@ import { InjectedFormProps, Field, WrappedFieldProps } from "redux-form";
 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 }>) =>
diff --git a/src/views-components/move-to-dialog/move-to-dialog.tsx b/src/views-components/move-to-dialog/move-to-dialog.tsx
new file mode 100644 (file)
index 0000000..74d5e50
--- /dev/null
@@ -0,0 +1,28 @@
+// 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
index 1c343a2dde1d8a4acf364d95f6f0a451508f5fee..49fb4d455f8db9101334f37721dd60b1ee2d27de 100644 (file)
@@ -19,7 +19,7 @@ import { FilterBuilder } from "../../common/api/filter-builder";
 
 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);
@@ -32,15 +32,23 @@ const mapDispatchToProps = (dispatch: Dispatch, props: {onChange: (projectUuid:
 });
 
 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) => {
index 8377744c1c0a6d0d28f4e9ffaeae24fb41f832d5..090e40eda809486587d198187e96083481372ff9 100644 (file)
@@ -46,6 +46,7 @@ import { RenameFileDialog } from '../../views-components/rename-file-dialog/rena
 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;
@@ -236,6 +237,7 @@ export const Workbench = withStyles(styles)(
                         <CreateProjectDialog />
                         <CreateCollectionDialog />
                         <RenameFileDialog />
+                        <MoveToProjectDialog />
                         <DialogCollectionCreateWithSelectedFile />
                         <FileRemoveDialog />
                         <MultipleFilesRemoveDialog />