[ARVADOS-WORKBENCH2] updated: 1.1.4-535-g6e830f1

Git user git at public.curoverse.com
Mon Aug 6 15:54:52 EDT 2018


Summary of changes:
 src/common/api/common-resource-service.ts          |  6 ++--
 src/common/api/filter-builder.ts                   | 21 +++++++------
 src/components/file-upload/file-upload.tsx         | 24 +++++++++++----
 src/models/collection-file.ts                      |  6 +++-
 src/models/keep.ts                                 | 12 ++++++++
 .../collection-service/collection-service.ts       | 35 ++++++++++++++++++++--
 .../favorite-service/favorite-service.test.ts      |  8 ++---
 src/services/favorite-service/favorite-service.ts  | 10 +++----
 .../keep-service.ts}                               | 26 ++++++++--------
 .../project-service/project-service.test.ts        |  2 +-
 src/services/project-service/project-service.ts    |  2 +-
 src/services/services.ts                           |  6 +++-
 src/store/collections/collections-reducer.ts       | 15 ++++++----
 .../creator/collection-creator-reducer.ts          |  6 ++--
 .../uploader/collection-uploader-actions.ts        | 16 ++++++++++
 .../uploader/collection-uploader-reducer.ts        | 24 +++++++++++++++
 .../favorite-panel-middleware-service.ts           |  2 +-
 .../project-panel-middleware-service.ts            |  8 ++---
 src/store/project/project-action.ts                |  8 ++---
 .../create-collection-dialog.tsx                   | 11 ++++---
 .../dialog-create/dialog-collection-create.tsx     | 18 ++++++++---
 21 files changed, 191 insertions(+), 75 deletions(-)
 create mode 100644 src/models/keep.ts
 copy src/services/{link-service/link-service.ts => keep-service/keep-service.ts} (61%)
 create mode 100644 src/store/collections/uploader/collection-uploader-actions.ts
 create mode 100644 src/store/collections/uploader/collection-uploader-reducer.ts

       via  6e830f14ac2732c6d8661275fff691dd8a6179fa (commit)
      from  b58e3122a2574d81618bca58e27b046f82400f49 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 6e830f14ac2732c6d8661275fff691dd8a6179fa
Author: Daniel Kos <unodgs at gmail.com>
Date:   Mon Aug 6 21:52:22 2018 +0200

    Add adding files to upload zone
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <unodgs at gmail.com>

diff --git a/src/common/api/common-resource-service.ts b/src/common/api/common-resource-service.ts
index 8ad8fe9..a836246 100644
--- a/src/common/api/common-resource-service.ts
+++ b/src/common/api/common-resource-service.ts
@@ -68,10 +68,10 @@ export class CommonResourceService<T extends Resource> {
         this.resourceType = '/' + resourceType + '/';
     }
 
-    create(data: Partial<T>) {
+    create(data?: Partial<T> | any) {
         return CommonResourceService.defaultResponse(
             this.serverApi
-                .post<T>(this.resourceType, CommonResourceService.mapKeys(_.snakeCase)(data)));
+                .post<T>(this.resourceType, data && CommonResourceService.mapKeys(_.snakeCase)(data)));
     }
 
     delete(uuid: string): Promise<T> {
@@ -104,7 +104,7 @@ export class CommonResourceService<T extends Resource> {
         return CommonResourceService.defaultResponse(
             this.serverApi
                 .put<T>(this.resourceType + uuid, data));
-        
+
     }
 }
 
diff --git a/src/common/api/filter-builder.ts b/src/common/api/filter-builder.ts
index 28ad060..e5aab3a 100644
--- a/src/common/api/filter-builder.ts
+++ b/src/common/api/filter-builder.ts
@@ -3,38 +3,37 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as _ from "lodash";
-import { Resource } from "../../models/resource";
 
-export class FilterBuilder<T extends Resource = Resource> {
-    static create<T extends Resource = Resource>(resourcePrefix = "") {
-        return new FilterBuilder<T>(resourcePrefix);
+export class FilterBuilder {
+    static create(resourcePrefix = "") {
+        return new FilterBuilder(resourcePrefix);
     }
 
     constructor(
         private resourcePrefix = "",
         private filters = "") { }
 
-    public addEqual(field: keyof T, value?: string) {
+    public addEqual(field: string, value?: string) {
         return this.addCondition(field, "=", value);
     }
 
-    public addLike(field: keyof T, value?: string) {
+    public addLike(field: string, value?: string) {
         return this.addCondition(field, "like", value, "%", "%");
     }
 
-    public addILike(field: keyof T, value?: string) {
+    public addILike(field: string, value?: string) {
         return this.addCondition(field, "ilike", value, "%", "%");
     }
 
-    public addIsA(field: keyof T, value?: string | string[]) {
+    public addIsA(field: string, value?: string | string[]) {
         return this.addCondition(field, "is_a", value);
     }
 
-    public addIn(field: keyof T, value?: string | string[]) {
+    public addIn(field: string, value?: string | string[]) {
         return this.addCondition(field, "in", value);
     }
 
-    public concat<O extends Resource>(filterBuilder: FilterBuilder<O>) {
+    public concat(filterBuilder: FilterBuilder) {
         return new FilterBuilder(this.resourcePrefix, this.filters + (this.filters && filterBuilder.filters ? "," : "") + filterBuilder.getFilters());
     }
 
@@ -46,7 +45,7 @@ export class FilterBuilder<T extends Resource = Resource> {
         return "[" + this.filters + "]";
     }
 
-    private addCondition(field: keyof T, cond: string, value?: string | string[], prefix: string = "", postfix: string = "") {
+    private addCondition(field: string, cond: string, value?: string | string[], prefix: string = "", postfix: string = "") {
         if (value) {
             value = typeof value === "string"
                 ? `"${prefix}${value}${postfix}"`
diff --git a/src/components/file-upload/file-upload.tsx b/src/components/file-upload/file-upload.tsx
index 3a98e27..5fb2842 100644
--- a/src/components/file-upload/file-upload.tsx
+++ b/src/components/file-upload/file-upload.tsx
@@ -3,10 +3,11 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import * as React from 'react';
-import { Grid, StyleRulesCallback, Typography, WithStyles } from '@material-ui/core';
+import { Grid, List, ListItem, ListItemText, StyleRulesCallback, Typography, WithStyles } from '@material-ui/core';
 import { withStyles } from '@material-ui/core';
 import Dropzone from 'react-dropzone';
 import { CloudUploadIcon } from "../icon/icon";
+import { formatFileSize } from "../../common/formatters";
 
 type CssRules = "root" | "dropzone" | "container" | "uploadIcon";
 
@@ -15,7 +16,8 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
     },
     dropzone: {
         width: "100%",
-        height: "100px",
+        height: "200px",
+        overflow: "auto",
         border: "1px dashed black",
         borderRadius: "5px"
     },
@@ -28,21 +30,33 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
 });
 
 interface FileUploadProps {
+    files: File[];
+    onDrop: (files: File[]) => void;
 }
 
 export const FileUpload = withStyles(styles)(
-    ({ classes }: FileUploadProps & WithStyles<CssRules>) =>
+    ({ classes, files, onDrop }: FileUploadProps & WithStyles<CssRules>) =>
     <Grid container direction={"column"}>
         <Typography variant={"subheading"}>
             Upload data
         </Typography>
-        <Dropzone className={classes.dropzone}>
-            <Grid container justify="center" alignItems="center" className={classes.container}>
+        <Dropzone className={classes.dropzone} onDrop={files => onDrop(files)}>
+            <Grid container justify="center" alignItems="center" className={classes.container} direction={"column"}>
                 <Grid item component={"span"}>
                     <Typography variant={"subheading"}>
                         <CloudUploadIcon className={classes.uploadIcon}/> Drag and drop data or <a>browse</a>
                     </Typography>
                 </Grid>
+                <Grid item>
+                    <List>
+                    {files.map((f, idx) =>
+                        <ListItem button key={idx}>
+                            <ListItemText
+                                primary={f.name} primaryTypographyProps={{variant: "body2"}}
+                                secondary={formatFileSize(f.size)}/>
+                        </ListItem>)}
+                    </List>
+                </Grid>
             </Grid>
         </Dropzone>
     </Grid>
diff --git a/src/models/collection-file.ts b/src/models/collection-file.ts
index 7bf6df7..a4b656c 100644
--- a/src/models/collection-file.ts
+++ b/src/models/collection-file.ts
@@ -26,6 +26,10 @@ export interface CollectionFile {
     type: CollectionFileType.FILE;
 }
 
+export interface CollectionUploadFile {
+    name: string;
+}
+
 export const createCollectionDirectory = (data: Partial<CollectionDirectory>): CollectionDirectory => ({
     id: '',
     name: '',
@@ -41,4 +45,4 @@ export const createCollectionFile = (data: Partial<CollectionFile>): CollectionF
     size: 0,
     type: CollectionFileType.FILE,
     ...data
-});
\ No newline at end of file
+});
diff --git a/src/models/keep.ts b/src/models/keep.ts
new file mode 100644
index 0000000..f6b5ef2
--- /dev/null
+++ b/src/models/keep.ts
@@ -0,0 +1,12 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Resource } from "./resource";
+
+export interface KeepResource extends Resource {
+    serviceHost: string;
+    servicePort: number;
+    serviceSslFlag: boolean;
+    serviceType: string;
+}
diff --git a/src/services/collection-service/collection-service.ts b/src/services/collection-service/collection-service.ts
index bb63771..88f3dae 100644
--- a/src/services/collection-service/collection-service.ts
+++ b/src/services/collection-service/collection-service.ts
@@ -4,10 +4,39 @@
 
 import { CommonResourceService } from "../../common/api/common-resource-service";
 import { CollectionResource } from "../../models/collection";
-import { AxiosInstance } from "axios";
+import axios, { AxiosInstance } from "axios";
+import { KeepService } from "../keep-service/keep-service";
+import { FilterBuilder } from "../../common/api/filter-builder";
 
 export class CollectionService extends CommonResourceService<CollectionResource> {
-    constructor(serverApi: AxiosInstance) {
+    constructor(serverApi: AxiosInstance, private keepService: KeepService) {
         super(serverApi, "collections");
     }
-}
\ No newline at end of file
+
+    uploadFiles(files: File[]) {
+        console.log("Uploading files", files);
+
+        const fd = new FormData();
+        fd.append("filters", `[["service_type","=","proxy"]]`);
+        fd.append("_method", "GET");
+
+        const filters = new FilterBuilder();
+        filters.addEqual("service_type", "proxy");
+
+        return this.keepService.list({ filters }).then(data => {
+            console.log(data);
+
+            const serviceHost = (data.items[0].serviceSslFlag ? "https://" : "http://") + data.items[0].serviceHost + ":" + data.items[0].servicePort;
+            console.log("Servicehost", serviceHost);
+
+            const fd = new FormData();
+            files.forEach((f, idx) => fd.append(`file_${idx}`, f));
+
+            axios.post(serviceHost, fd, {
+                onUploadProgress: (e: ProgressEvent) => {
+                    console.log(`${e.loaded} / ${e.total}`);
+                }
+            });
+        });
+    }
+}
diff --git a/src/services/favorite-service/favorite-service.test.ts b/src/services/favorite-service/favorite-service.test.ts
index e3a3bdf..3bc959d 100644
--- a/src/services/favorite-service/favorite-service.test.ts
+++ b/src/services/favorite-service/favorite-service.test.ts
@@ -39,7 +39,7 @@ describe("FavoriteService", () => {
     it("unmarks resource as favorite", async () => {
         const list = jest.fn().mockReturnValue(Promise.resolve({ items: [{ uuid: "linkUuid" }] }));
         const filters = FilterBuilder
-            .create<LinkResource>()
+            .create()
             .addEqual('tailUuid', "userUuid")
             .addEqual('headUuid', "resourceUuid")
             .addEqual('linkClass', LinkClass.STAR);
@@ -57,11 +57,11 @@ describe("FavoriteService", () => {
     it("lists favorite resources", async () => {
         const list = jest.fn().mockReturnValue(Promise.resolve({ items: [{ headUuid: "headUuid" }] }));
         const listFilters = FilterBuilder
-            .create<LinkResource>()
+            .create()
             .addEqual('tailUuid', "userUuid")
             .addEqual('linkClass', LinkClass.STAR);
         const contents = jest.fn().mockReturnValue(Promise.resolve({ items: [{ uuid: "resourceUuid" }] }));
-        const contentFilters = FilterBuilder.create<GroupContentsResource>().addIn('uuid', ["headUuid"]);
+        const contentFilters = FilterBuilder.create().addIn('uuid', ["headUuid"]);
         linkService.list = list;
         groupService.contents = contents;
         const favoriteService = new FavoriteService(linkService, groupService);
@@ -77,7 +77,7 @@ describe("FavoriteService", () => {
     it("checks if resources are present in favorites", async () => {
         const list = jest.fn().mockReturnValue(Promise.resolve({ items: [{ headUuid: "foo" }] }));
         const listFilters = FilterBuilder
-            .create<LinkResource>()
+            .create()
             .addIn("headUuid", ["foo", "oof"])
             .addEqual("tailUuid", "userUuid")
             .addEqual("linkClass", LinkClass.STAR);
diff --git a/src/services/favorite-service/favorite-service.ts b/src/services/favorite-service/favorite-service.ts
index 8da6eec..35dbbaf 100644
--- a/src/services/favorite-service/favorite-service.ts
+++ b/src/services/favorite-service/favorite-service.ts
@@ -13,7 +13,7 @@ import { OrderBuilder } from "../../common/api/order-builder";
 export interface FavoriteListArguments {
     limit?: number;
     offset?: number;
-    filters?: FilterBuilder<LinkResource>;
+    filters?: FilterBuilder;
     order?: FavoriteOrderBuilder;
 }
 
@@ -37,7 +37,7 @@ export class FavoriteService {
         return this.linkService
             .list({
                 filters: FilterBuilder
-                    .create<LinkResource>()
+                    .create()
                     .addEqual('tailUuid', data.userUuid)
                     .addEqual('headUuid', data.resourceUuid)
                     .addEqual('linkClass', LinkClass.STAR)
@@ -48,7 +48,7 @@ export class FavoriteService {
 
     list(userUuid: string, { filters, limit, offset, order }: FavoriteListArguments = {}): Promise<ListResults<GroupContentsResource>> {
         const listFilter = FilterBuilder
-            .create<LinkResource>()
+            .create()
             .addEqual('tailUuid', userUuid)
             .addEqual('linkClass', LinkClass.STAR);
 
@@ -65,7 +65,7 @@ export class FavoriteService {
                     limit,
                     offset,
                     order: order ? order.getContentOrder() : OrderBuilder.create<GroupContentsResource>(),
-                    filters: FilterBuilder.create<GroupContentsResource>().addIn('uuid', uuids),
+                    filters: FilterBuilder.create().addIn('uuid', uuids),
                     recursive: true
                 });
             });
@@ -75,7 +75,7 @@ export class FavoriteService {
         return this.linkService
             .list({
                 filters: FilterBuilder
-                    .create<LinkResource>()
+                    .create()
                     .addIn("headUuid", resourceUuids)
                     .addEqual("tailUuid", userUuid)
                     .addEqual("linkClass", LinkClass.STAR)
diff --git a/src/services/collection-service/collection-service.ts b/src/services/keep-service/keep-service.ts
similarity index 59%
copy from src/services/collection-service/collection-service.ts
copy to src/services/keep-service/keep-service.ts
index bb63771..188e45a 100644
--- a/src/services/collection-service/collection-service.ts
+++ b/src/services/keep-service/keep-service.ts
@@ -1,13 +1,13 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { CommonResourceService } from "../../common/api/common-resource-service";
-import { CollectionResource } from "../../models/collection";
-import { AxiosInstance } from "axios";
-
-export class CollectionService extends CommonResourceService<CollectionResource> {
-    constructor(serverApi: AxiosInstance) {
-        super(serverApi, "collections");
-    }
-}
\ No newline at end of file
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { CommonResourceService } from "../../common/api/common-resource-service";
+import { AxiosInstance } from "axios";
+import { KeepResource } from "../../models/keep";
+
+export class KeepService extends CommonResourceService<KeepResource> {
+    constructor(serverApi: AxiosInstance) {
+        super(serverApi, "keep_services");
+    }
+}
diff --git a/src/services/project-service/project-service.test.ts b/src/services/project-service/project-service.test.ts
index f915c2d..eb7ea74 100644
--- a/src/services/project-service/project-service.test.ts
+++ b/src/services/project-service/project-service.test.ts
@@ -28,7 +28,7 @@ describe("CommonResourceService", () => {
         expect(axiosInstance.get).toHaveBeenCalledWith("/groups/", {
             params: {
                 filters: FilterBuilder
-                    .create<ProjectResource>()
+                    .create()
                     .addEqual("groupClass", "project")
                     .serialize()
             }
diff --git a/src/services/project-service/project-service.ts b/src/services/project-service/project-service.ts
index 31a2ddd..13c60ad 100644
--- a/src/services/project-service/project-service.ts
+++ b/src/services/project-service/project-service.ts
@@ -29,7 +29,7 @@ export class ProjectService extends GroupsService<ProjectResource> {
                 ? filters
                 : FilterBuilder.create())
             .concat(FilterBuilder
-                .create<ProjectResource>()
+                .create()
                 .addEqual("groupClass", GroupClass.PROJECT));
     }
 }
diff --git a/src/services/services.ts b/src/services/services.ts
index 9e1adbf..6e8d0f9 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -11,11 +11,13 @@ import { AxiosInstance } from "axios";
 import { CollectionService } from "./collection-service/collection-service";
 import Axios from "axios";
 import { CollectionFilesService } from "./collection-files-service/collection-files-service";
+import { KeepService } from "./keep-service/keep-service";
 
 export interface ServiceRepository {
     apiClient: AxiosInstance;
 
     authService: AuthService;
+    keepService: KeepService;
     groupsService: GroupsService;
     projectService: ProjectService;
     linkService: LinkService;
@@ -29,16 +31,18 @@ export const createServices = (baseUrl: string): ServiceRepository => {
     apiClient.defaults.baseURL = `${baseUrl}/arvados/v1`;
 
     const authService = new AuthService(apiClient, baseUrl);
+    const keepService = new KeepService(apiClient);
     const groupsService = new GroupsService(apiClient);
     const projectService = new ProjectService(apiClient);
     const linkService = new LinkService(apiClient);
     const favoriteService = new FavoriteService(linkService, groupsService);
-    const collectionService = new CollectionService(apiClient);
+    const collectionService = new CollectionService(apiClient, keepService);
     const collectionFilesService = new CollectionFilesService(collectionService);
 
     return {
         apiClient,
         authService,
+        keepService,
         groupsService,
         projectService,
         linkService,
diff --git a/src/store/collections/collections-reducer.ts b/src/store/collections/collections-reducer.ts
index e1982d2..b2ee455 100644
--- a/src/store/collections/collections-reducer.ts
+++ b/src/store/collections/collections-reducer.ts
@@ -3,15 +3,18 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { combineReducers } from 'redux';
-import * as creator from "./creator/collection-creator-reducer";
-import * as updater from "./updater/collection-updater-reducer";
+import { collectionCreatorReducer, CollectionCreatorState } from "./creator/collection-creator-reducer";
+import { collectionUpdaterReducer, CollectionUpdaterState } from "./updater/collection-updater-reducer";
+import { collectionUploaderReducer, CollectionUploaderState } from "./uploader/collection-uploader-reducer";
 
 export type CollectionsState = {
-    creator: creator.CollectionCreatorState;
-    updater: updater.CollectionUpdaterState;
+    creator: CollectionCreatorState;
+    updater: CollectionUpdaterState;
+    uploader: CollectionUploaderState
 };
 
 export const collectionsReducer = combineReducers({
-    creator: creator.collectionCreatorReducer,
-    updater: updater.collectionUpdaterReducer
+    creator: collectionCreatorReducer,
+    updater: collectionUpdaterReducer,
+    uploader: collectionUploaderReducer
 });
diff --git a/src/store/collections/creator/collection-creator-reducer.ts b/src/store/collections/creator/collection-creator-reducer.ts
index 140cbbe..72c999d 100644
--- a/src/store/collections/creator/collection-creator-reducer.ts
+++ b/src/store/collections/creator/collection-creator-reducer.ts
@@ -4,14 +4,12 @@
 
 import { collectionCreateActions, CollectionCreateAction } from './collection-creator-action';
 
-export type CollectionCreatorState = CollectionCreator;
-
-interface CollectionCreator {
+export interface CollectionCreatorState {
     opened: boolean;
     ownerUuid: string;
 }
 
-const updateCreator = (state: CollectionCreatorState, creator?: Partial<CollectionCreator>) => ({
+const updateCreator = (state: CollectionCreatorState, creator?: Partial<CollectionCreatorState>) => ({
     ...state,
     ...creator
 });
diff --git a/src/store/collections/uploader/collection-uploader-actions.ts b/src/store/collections/uploader/collection-uploader-actions.ts
new file mode 100644
index 0000000..0b9aeb9
--- /dev/null
+++ b/src/store/collections/uploader/collection-uploader-actions.ts
@@ -0,0 +1,16 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { default as unionize, ofType, UnionOf } from "unionize";
+
+export const collectionUploaderActions = unionize({
+    SET_UPLOAD_FILES: ofType<File[]>(),
+    START_UPLOADING: ofType<{}>(),
+    UPDATE_UPLOAD_PROGRESS: ofType<{}>()
+}, {
+    tag: 'type',
+    value: 'payload'
+});
+
+export type CollectionUploaderAction = UnionOf<typeof collectionUploaderActions>;
diff --git a/src/store/collections/uploader/collection-uploader-reducer.ts b/src/store/collections/uploader/collection-uploader-reducer.ts
new file mode 100644
index 0000000..05735d6
--- /dev/null
+++ b/src/store/collections/uploader/collection-uploader-reducer.ts
@@ -0,0 +1,24 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { CollectionUploaderAction, collectionUploaderActions } from "./collection-uploader-actions";
+import { CollectionUploadFile } from "../../../models/collection-file";
+
+export interface CollectionUploaderState {
+    files: File[];
+}
+
+const initialState: CollectionUploaderState = {
+    files: []
+};
+
+export const collectionUploaderReducer = (state: CollectionUploaderState = initialState, action: CollectionUploaderAction) => {
+    return collectionUploaderActions.match(action, {
+        SET_UPLOAD_FILES: (files) => ({
+            ...state,
+            files
+        }),
+        default: () => state
+    });
+};
diff --git a/src/store/favorite-panel/favorite-panel-middleware-service.ts b/src/store/favorite-panel/favorite-panel-middleware-service.ts
index 62d9ae2..be4b645 100644
--- a/src/store/favorite-panel/favorite-panel-middleware-service.ts
+++ b/src/store/favorite-panel/favorite-panel-middleware-service.ts
@@ -40,7 +40,7 @@ export class FavoritePanelMiddlewareService extends DataExplorerMiddlewareServic
                             : order.addAsc("name")
                         : order,
                     filters: FilterBuilder
-                        .create<LinkResource>()
+                        .create()
                         .addIsA("headUuid", typeFilters.map(filter => filter.type))
                         .addILike("name", dataExplorer.searchValue)
                 })
diff --git a/src/store/project-panel/project-panel-middleware-service.ts b/src/store/project-panel/project-panel-middleware-service.ts
index 8d3f06a..fd893a3 100644
--- a/src/store/project-panel/project-panel-middleware-service.ts
+++ b/src/store/project-panel/project-panel-middleware-service.ts
@@ -46,7 +46,7 @@ export class ProjectPanelMiddlewareService extends DataExplorerMiddlewareService
                             .create()
                             .addIsA("uuid", typeFilters.map(f => f.type)))
                         .concat(FilterBuilder
-                            .create<ProcessResource>(GroupContentsResourcePrefix.PROCESS)
+                            .create(GroupContentsResourcePrefix.PROCESS)
                             .addIn("state", statusFilters.map(f => f.type)))
                         .concat(getSearchFilter(dataExplorer.searchValue))
                 })
@@ -88,9 +88,9 @@ const getOrder = (attribute: "name" | "createdAt", direction: SortDirection) =>
 const getSearchFilter = (searchValue: string) =>
     searchValue
         ? [
-            FilterBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.COLLECTION),
-            FilterBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROCESS),
-            FilterBuilder.create<GroupContentsResource>(GroupContentsResourcePrefix.PROJECT)]
+            FilterBuilder.create(GroupContentsResourcePrefix.COLLECTION),
+            FilterBuilder.create(GroupContentsResourcePrefix.PROCESS),
+            FilterBuilder.create(GroupContentsResourcePrefix.PROJECT)]
             .reduce((acc, b) =>
                 acc.concat(b.addILike("name", searchValue)), FilterBuilder.create())
         : FilterBuilder.create();
diff --git a/src/store/project/project-action.ts b/src/store/project/project-action.ts
index 2f9963b..5caf012 100644
--- a/src/store/project/project-action.ts
+++ b/src/store/project/project-action.ts
@@ -22,15 +22,15 @@ export const projectActions = unionize({
     TOGGLE_PROJECT_TREE_ITEM_ACTIVE: ofType<string>(),
     RESET_PROJECT_TREE_ACTIVITY: ofType<string>()
 }, {
-        tag: 'type',
-        value: 'payload'
-    });
+    tag: 'type',
+    value: 'payload'
+});
 
 export const getProjectList = (parentUuid: string = '') => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
     dispatch(projectActions.PROJECTS_REQUEST(parentUuid));
     return services.projectService.list({
         filters: FilterBuilder
-            .create<ProjectResource>()
+            .create()
             .addEqual("ownerUuid", parentUuid)
     }).then(({ items: projects }) => {
         dispatch(projectActions.PROJECTS_SUCCESS({ projects, parentItemId: parentUuid }));
diff --git a/src/views-components/create-collection-dialog/create-collection-dialog.tsx b/src/views-components/create-collection-dialog/create-collection-dialog.tsx
index 0ba2b22..281bd54 100644
--- a/src/views-components/create-collection-dialog/create-collection-dialog.tsx
+++ b/src/views-components/create-collection-dialog/create-collection-dialog.tsx
@@ -12,6 +12,7 @@ import { collectionCreateActions, createCollection } from "../../store/collectio
 import { dataExplorerActions } from "../../store/data-explorer/data-explorer-action";
 import { PROJECT_PANEL_ID } from "../../views/project-panel/project-panel";
 import { snackbarActions } from "../../store/snackbar/snackbar-actions";
+import { ServiceRepository } from "../../services/services";
 
 const mapStateToProps = (state: RootState) => ({
     open: state.collections.creator.opened
@@ -21,7 +22,7 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
     handleClose: () => {
         dispatch(collectionCreateActions.CLOSE_COLLECTION_CREATOR());
     },
-    onSubmit: (data: { name: string, description: string }) => {
+    onSubmit: (data: { name: string, description: string, files: File[] }) => {
         return dispatch<any>(addCollection(data))
             .catch((e: any) => {
                 throw new SubmissionError({ name: e.errors.join("").includes("UniqueViolation") ? "Collection with this name already exists." : "" });
@@ -29,14 +30,16 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
     }
 });
 
-const addCollection = (data: { name: string, description: string }) =>
-    (dispatch: Dispatch) => {
+const addCollection = (data: { name: string, description: string, files: File[] }) =>
+    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         return dispatch<any>(createCollection(data)).then(() => {
             dispatch(snackbarActions.OPEN_SNACKBAR({
                 message: "Collection has been successfully created.",
                 hideDuration: 2000
             }));
-            dispatch(dataExplorerActions.REQUEST_ITEMS({ id: PROJECT_PANEL_ID }));
+            services.collectionService.uploadFiles(data.files).then(() => {
+                dispatch(dataExplorerActions.REQUEST_ITEMS({ id: PROJECT_PANEL_ID }));
+            });
         });
     };
 
diff --git a/src/views-components/dialog-create/dialog-collection-create.tsx b/src/views-components/dialog-create/dialog-collection-create.tsx
index f59728b..a0cbcba 100644
--- a/src/views-components/dialog-create/dialog-collection-create.tsx
+++ b/src/views-components/dialog-create/dialog-collection-create.tsx
@@ -14,6 +14,9 @@ import { Button, StyleRulesCallback, WithStyles, withStyles, CircularProgress }
 
 import { COLLECTION_NAME_VALIDATION, COLLECTION_DESCRIPTION_VALIDATION } from '../../validators/create-project/create-project-validator';
 import { FileUpload } from "../../components/file-upload/file-upload";
+import { connect, DispatchProp } from "react-redux";
+import { RootState } from "../../store/store";
+import { collectionUploaderActions } from "../../store/collections/uploader/collection-uploader-actions";
 
 type CssRules = "button" | "lastButton" | "formContainer" | "textField" | "createProgress" | "dialogActions";
 
@@ -41,14 +44,16 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
         marginBottom: theme.spacing.unit * 3
     }
 });
+
 interface DialogCollectionCreateProps {
     open: boolean;
     handleClose: () => void;
-    onSubmit: (data: { name: string, description: string }) => void;
+    onSubmit: (data: { name: string, description: string, files: File[] }) => void;
     handleSubmit: any;
     submitting: boolean;
     invalid: boolean;
     pristine: boolean;
+    files: File[];
 }
 
 interface TextFieldProps {
@@ -60,9 +65,12 @@ interface TextFieldProps {
 }
 
 export const DialogCollectionCreate = compose(
+    connect((state: RootState) => ({
+        files: state.collections.uploader.files
+    })),
     reduxForm({ form: 'collectionCreateDialog' }),
     withStyles(styles))(
-    class DialogCollectionCreate extends React.Component<DialogCollectionCreateProps & WithStyles<CssRules>> {
+    class DialogCollectionCreate extends React.Component<DialogCollectionCreateProps & DispatchProp & WithStyles<CssRules>> {
         render() {
             const { classes, open, handleClose, handleSubmit, onSubmit, submitting, invalid, pristine } = this.props;
 
@@ -74,7 +82,7 @@ export const DialogCollectionCreate = compose(
                     maxWidth='sm'
                     disableBackdropClick={true}
                     disableEscapeKeyDown={true}>
-                    <form onSubmit={handleSubmit((data: any) => onSubmit(data))}>
+                    <form onSubmit={handleSubmit((data: any) => onSubmit({ ...data, files: this.props.files }))}>
                         <DialogTitle id="form-dialog-title">Create a collection</DialogTitle>
                         <DialogContent className={classes.formContainer}>
                             <Field name="name"
@@ -91,7 +99,9 @@ export const DialogCollectionCreate = compose(
                                     validate={COLLECTION_DESCRIPTION_VALIDATION}
                                     className={classes.textField}
                                     label="Description - optional"/>
-                            <FileUpload/>
+                            <FileUpload
+                                files={this.props.files}
+                                onDrop={files => this.props.dispatch(collectionUploaderActions.SET_UPLOAD_FILES(files))}/>
                         </DialogContent>
                         <DialogActions className={classes.dialogActions}>
                             <Button onClick={handleClose} className={classes.button} color="primary"

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list