modal-for-file-selection
authorPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Mon, 1 Oct 2018 11:27:11 +0000 (13:27 +0200)
committerPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Mon, 1 Oct 2018 11:27:11 +0000 (13:27 +0200)
Feature #14231

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

src/store/collection-panel/collection-panel-files/collection-panel-files-actions.ts
src/store/file-selection/file-selection-actions.ts [new file with mode: 0644]
src/views-components/context-menu/action-sets/project-action-set.ts
src/views-components/dialog-file-selection/dialog-file-selection.tsx [new file with mode: 0644]
src/views-components/dialog-forms/file-selection-dialog.ts [new file with mode: 0644]
src/views-components/dialog-move/dialog-move-to.tsx
src/views-components/workflow-tree-picker/workflow-tree-picker.tsx
src/views/login-panel/login-panel.tsx
src/views/workbench/workbench.tsx

index f214fd2f7b41297677efac451836bf09568eee1a..0460c977972059994e8d8b142bbbd528d388111d 100644 (file)
@@ -11,10 +11,8 @@ 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, stopSubmit, reset } from 'redux-form';
-import { getCommonResourceServiceError, CommonResourceServiceError } from "~/services/common-service/common-resource-service";
+import { startSubmit, stopSubmit, reset } from 'redux-form';
 import { getDialog } from "~/store/dialog/dialog-reducer";
-import { resetPickerProjectTree } from '~/store/project-tree-picker/project-tree-picker-actions';
 
 export const collectionPanelFilesAction = unionize({
     SET_COLLECTION_FILES: ofType<CollectionFilesTree>(),
diff --git a/src/store/file-selection/file-selection-actions.ts b/src/store/file-selection/file-selection-actions.ts
new file mode 100644 (file)
index 0000000..cfdc27b
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { dialogActions } from "~/store/dialog/dialog-actions";
+import { resetPickerProjectTree } from '~/store/project-tree-picker/project-tree-picker-actions';
+
+export const FILE_SELECTION = 'fileSelection';
+
+export const openFileSelectionDialog = () =>
+    (dispatch: Dispatch) => {
+        dispatch<any>(resetPickerProjectTree());
+        dispatch(dialogActions.OPEN_DIALOG({ id: FILE_SELECTION, data: {} }));
+    };
\ No newline at end of file
index e5a1915472c7d39ef3f8d9e67c5160c8d437b1ca..36b8eef0ca9efc2e23e6b82e9c50a63238b9883e 100644 (file)
@@ -12,6 +12,7 @@ import { openProjectCreateDialog } from '~/store/projects/project-create-actions
 import { openProjectUpdateDialog } from '~/store/projects/project-update-actions';
 import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
 import { toggleProjectTrashed } from "~/store/trash/trash-actions";
+import { openFileSelectionDialog } from '../../../store/file-selection/file-selection-actions';
 
 export const projectActionSet: ContextMenuActionSet = [[
     {
@@ -45,7 +46,7 @@ export const projectActionSet: ContextMenuActionSet = [[
     {
         icon: MoveToIcon,
         name: "Move to",
-        execute: (dispatch, resource) => dispatch<any>(openMoveProjectDialog(resource))
+        execute: (dispatch, resource) => dispatch<any>(openFileSelectionDialog())
     },
     {
         icon: CopyIcon,
diff --git a/src/views-components/dialog-file-selection/dialog-file-selection.tsx b/src/views-components/dialog-file-selection/dialog-file-selection.tsx
new file mode 100644 (file)
index 0000000..6521e2b
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import * as React from 'react';
+import { InjectedFormProps, Field } from 'redux-form';
+import { WithDialogProps } from '~/store/dialog/with-dialog';
+import { CollectionCreateFormDialogData } from '~/store/collections/collection-create-actions';
+import { FormDialog } from '~/components/form-dialog/form-dialog';
+import { require } from '~/validators/require';
+import { WorkflowTreePickerField } from '~/views-components/workflow-tree-picker/workflow-tree-picker';
+
+type FileSelectionProps = WithDialogProps<{}> & InjectedFormProps<CollectionCreateFormDialogData>;
+
+export const DialogFileSelection = (props: FileSelectionProps) =>
+    <FormDialog
+        dialogTitle='Choose a file'
+        formFields={FileSelectionFields}
+        submitLabel='Ok'
+        {...props}
+    />;
+
+const FileSelectionFields = () =>
+    <Field
+        name='tree'
+        validate={FILES_FIELD_VALIDATION}
+        component={WorkflowTreePickerField} />;
+
+const FILES_FIELD_VALIDATION = [require];
\ No newline at end of file
diff --git a/src/views-components/dialog-forms/file-selection-dialog.ts b/src/views-components/dialog-forms/file-selection-dialog.ts
new file mode 100644 (file)
index 0000000..7c883cb
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { compose } from "redux";
+import { reduxForm } from 'redux-form';
+import { withDialog } from "~/store/dialog/with-dialog";
+import { FILE_SELECTION } from '~/store/file-selection/file-selection-actions';
+import { DialogFileSelection } from '~/views-components/dialog-file-selection/dialog-file-selection';
+import { dialogActions } from '~/store/dialog/dialog-actions';
+
+export const FileSelectionDialog = compose(
+    withDialog(FILE_SELECTION),
+    reduxForm({
+        form: FILE_SELECTION,
+        onSubmit: (data, dispatch) => {
+            dispatch(dialogActions.CLOSE_DIALOG({ id: FILE_SELECTION }));
+            return data;
+        }
+    })
+)(DialogFileSelection);
\ No newline at end of file
index 6b0ac881003f7b1a4f38c05fef07f301be3a7d43..425b9e462a5439b47f3eb82a26fbe4eefe5481e0 100644 (file)
@@ -6,7 +6,7 @@ import * as React from "react";
 import { InjectedFormProps, Field } from 'redux-form';
 import { WithDialogProps } from '~/store/dialog/with-dialog';
 import { FormDialog } from '~/components/form-dialog/form-dialog';
-import { WorkflowTreePickerField } from '~/views-components/workflow-tree-picker/workflow-tree-picker';
+import { ProjectTreePickerField } from '~/views-components/project-tree-picker/project-tree-picker';
 import { MOVE_TO_VALIDATION } from '~/validators/validators';
 import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog';
 
@@ -21,6 +21,6 @@ export const DialogMoveTo = (props: WithDialogProps<string> & InjectedFormProps<
 const MoveToDialogFields = () =>
     <Field
         name="ownerUuid"
-        component={WorkflowTreePickerField}
+        component={ProjectTreePickerField}
         validate={MOVE_TO_VALIDATION} />;
 
index f9db4eaaca3fc19cafd9999cf8ac5f497a113b15..3f971720f525ef1fcd3a4bc9bd2da5c98594b1c7 100644 (file)
@@ -17,8 +17,9 @@ import { RootState } from "~/store/store";
 import { ServiceRepository } from "~/services/services";
 import { FilterBuilder } from "~/services/api/filter-builder";
 import { WrappedFieldProps } from 'redux-form';
-import { ResourceKind } from '~/models/resource';
+import { ResourceKind, extractUuidKind } from '~/models/resource';
 import { GroupContentsResource } from '~/services/groups-service/groups-service';
+import { loadCollectionFiles } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions';
 
 type WorkflowTreePickerProps = Pick<MainWorkflowTreePickerProps, 'onContextMenu' | 'toggleItemActive' | 'toggleItemOpen'>;
 
@@ -55,7 +56,7 @@ const getNotSelectedTreePickerKind = (pickerId: string) => {
     return [TreePickerId.PROJECTS, TreePickerId.FAVORITES, TreePickerId.SHARED_WITH_ME].filter(nodeId => nodeId !== pickerId);
 };
 
-export enum TreePickerId {
+enum TreePickerId {
     PROJECTS = 'Projects',
     SHARED_WITH_ME = 'Shared with me',
     FAVORITES = 'Favorites'
@@ -75,6 +76,8 @@ export const WorkflowTreePicker = connect(undefined, mapDispatchToProps)((props:
 
 export const loadProjectTreePicker = (nodeId: string) =>
     async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+        console.log(nodeId);
+        console.log(extractUuidKind(nodeId));
         dispatch(workflowTreePickerActions.LOAD_TREE_PICKER_NODE({ nodeId, pickerId: TreePickerId.PROJECTS }));
 
         const ownerUuid = nodeId.length === 0 ? services.authService.getUuid() || '' : nodeId;
@@ -84,9 +87,11 @@ export const loadProjectTreePicker = (nodeId: string) =>
             .addEqual('ownerUuid', ownerUuid)
             .getFilters();
 
-        const { items } = await services.groupsService.contents(ownerUuid, { filters });
+        const { items } = (extractUuidKind(nodeId) === ResourceKind.COLLECTION)
+            ? dispatch<any>(loadCollectionFiles(nodeId))
+            : await services.groupsService.contents(ownerUuid, { filters });
 
-        dispatch<any>(receiveTreePickerData(nodeId, items, TreePickerId.PROJECTS));
+        await dispatch<any>(receiveTreePickerData(nodeId, items, TreePickerId.PROJECTS));
     };
 
 export const loadFavoriteTreePicker = (nodeId: string) =>
@@ -111,7 +116,6 @@ export const loadFavoriteTreePicker = (nodeId: string) =>
     };
 
 const getProjectPickerIcon = (item: TreeItem<ProjectResource>) => {
-    console.log(item);
     switch (item.data.name) {
         case TreePickerId.FAVORITES:
             return FavoriteIcon;
@@ -129,7 +133,7 @@ const getResourceIcon = (item: TreeItem<GroupContentsResource>) => {
         case ResourceKind.COLLECTION:
             return CollectionIcon;
         case ResourceKind.PROJECT:
-            return ProjectsIcon;
+            return ProjectIcon;
         default:
             return ProjectIcon;
     }
@@ -143,7 +147,7 @@ const renderTreeItem = (item: TreeItem<ProjectResource>) =>
         hasMargin={true} />;
 
 
-export const receiveTreePickerData = (nodeId: string, items: GroupContentsResource[], pickerId: string) =>
+export const receiveTreePickerData = (nodeId: string, items: GroupContentsResource[] = [], pickerId: string) =>
     (dispatch: Dispatch) => {
         dispatch(workflowTreePickerActions.LOAD_TREE_PICKER_NODE_SUCCESS({
             nodeId,
index 2928a94ef00265a0dc9c0c3391bb73778be3a4f0..6a9210acad79f58288f2fc9448903af750c79f10 100644 (file)
@@ -55,7 +55,7 @@ export const LoginPanel = withStyles(styles)(connect()(
     <Grid container direction="column" item xs alignItems="center" justify="center" className={classes.root}>
         <Grid item className={classes.container}>
             <Typography variant="title" align="center" className={classes.title}>
-                Welcome to the Arvados Wrokbench
+                Welcome to the Arvados Workbench
             </Typography>
             <Typography variant="body1" className={classes.content}>
                 The "Log in" button below will show you a Google sign-in page.
index 47e22541508dfb7d7650006096c20a4138472d25..ec806d5f5bafd40cc109acdc81ea8677ac8c5aaf 100644 (file)
@@ -41,6 +41,7 @@ import { SharedWithMePanel } from '~/views/shared-with-me-panel/shared-with-me-p
 import { RunProcessPanel } from '~/views/run-process-panel/run-process-panel';
 import SplitterLayout from 'react-splitter-layout';
 import { WorkflowPanel } from '~/views/workflow-panel/workflow-panel';
+import { FileSelectionDialog } from '~/views-components/dialog-forms/file-selection-dialog';
 
 type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content';
 
@@ -114,6 +115,7 @@ export const WorkbenchPanel =
             <CurrentTokenDialog />
             <FileRemoveDialog />
             <FileRemoveDialog />
+            <FileSelectionDialog />
             <FilesUploadCollectionDialog />
             <MoveCollectionDialog />
             <MoveProcessDialog />