From: Daniel Kos Date: Mon, 6 Aug 2018 19:52:22 +0000 (+0200) Subject: Add adding files to upload zone X-Git-Tag: 1.2.0~12^2~4 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/6e830f14ac2732c6d8661275fff691dd8a6179fa Add adding files to upload zone Arvados-DCO-1.1-Signed-off-by: Daniel Kos --- diff --git a/src/common/api/common-resource-service.ts b/src/common/api/common-resource-service.ts index 8ad8fe91..a836246b 100644 --- a/src/common/api/common-resource-service.ts +++ b/src/common/api/common-resource-service.ts @@ -68,10 +68,10 @@ export class CommonResourceService { this.resourceType = '/' + resourceType + '/'; } - create(data: Partial) { + create(data?: Partial | any) { return CommonResourceService.defaultResponse( this.serverApi - .post(this.resourceType, CommonResourceService.mapKeys(_.snakeCase)(data))); + .post(this.resourceType, data && CommonResourceService.mapKeys(_.snakeCase)(data))); } delete(uuid: string): Promise { @@ -104,7 +104,7 @@ export class CommonResourceService { return CommonResourceService.defaultResponse( this.serverApi .put(this.resourceType + uuid, data)); - + } } diff --git a/src/common/api/filter-builder.ts b/src/common/api/filter-builder.ts index 28ad060f..e5aab3ac 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 { - static create(resourcePrefix = "") { - return new FilterBuilder(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(filterBuilder: FilterBuilder) { + public concat(filterBuilder: FilterBuilder) { return new FilterBuilder(this.resourcePrefix, this.filters + (this.filters && filterBuilder.filters ? "," : "") + filterBuilder.getFilters()); } @@ -46,7 +45,7 @@ export class FilterBuilder { 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 3a98e27a..5fb28428 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 = theme => ({ }, dropzone: { width: "100%", - height: "100px", + height: "200px", + overflow: "auto", border: "1px dashed black", borderRadius: "5px" }, @@ -28,21 +30,33 @@ const styles: StyleRulesCallback = theme => ({ }); interface FileUploadProps { + files: File[]; + onDrop: (files: File[]) => void; } export const FileUpload = withStyles(styles)( - ({ classes }: FileUploadProps & WithStyles) => + ({ classes, files, onDrop }: FileUploadProps & WithStyles) => Upload data - - + onDrop(files)}> + Drag and drop data or browse + + + {files.map((f, idx) => + + + )} + + diff --git a/src/models/collection-file.ts b/src/models/collection-file.ts index 7bf6df74..a4b656c5 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 => ({ id: '', name: '', @@ -41,4 +45,4 @@ export const createCollectionFile = (data: Partial): 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 00000000..f6b5ef2a --- /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 bb63771d..88f3daef 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 { - 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 e3a3bdfd..3bc959df 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() + .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() + .create() .addEqual('tailUuid', "userUuid") .addEqual('linkClass', LinkClass.STAR); const contents = jest.fn().mockReturnValue(Promise.resolve({ items: [{ uuid: "resourceUuid" }] })); - const contentFilters = FilterBuilder.create().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() + .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 8da6eec3..35dbbaf7 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; + filters?: FilterBuilder; order?: FavoriteOrderBuilder; } @@ -37,7 +37,7 @@ export class FavoriteService { return this.linkService .list({ filters: FilterBuilder - .create() + .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> { const listFilter = FilterBuilder - .create() + .create() .addEqual('tailUuid', userUuid) .addEqual('linkClass', LinkClass.STAR); @@ -65,7 +65,7 @@ export class FavoriteService { limit, offset, order: order ? order.getContentOrder() : OrderBuilder.create(), - filters: FilterBuilder.create().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() + .create() .addIn("headUuid", resourceUuids) .addEqual("tailUuid", userUuid) .addEqual("linkClass", LinkClass.STAR) diff --git a/src/services/keep-service/keep-service.ts b/src/services/keep-service/keep-service.ts new file mode 100644 index 00000000..188e45af --- /dev/null +++ b/src/services/keep-service/keep-service.ts @@ -0,0 +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 { AxiosInstance } from "axios"; +import { KeepResource } from "../../models/keep"; + +export class KeepService extends CommonResourceService { + 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 f915c2df..eb7ea743 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() + .create() .addEqual("groupClass", "project") .serialize() } diff --git a/src/services/project-service/project-service.ts b/src/services/project-service/project-service.ts index 31a2ddd2..13c60ad3 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 { ? filters : FilterBuilder.create()) .concat(FilterBuilder - .create() + .create() .addEqual("groupClass", GroupClass.PROJECT)); } } diff --git a/src/services/services.ts b/src/services/services.ts index 9e1adbf6..6e8d0f94 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 e1982d28..b2ee4550 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 140cbbea..72c999d0 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) => ({ +const updateCreator = (state: CollectionCreatorState, creator?: Partial) => ({ ...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 00000000..0b9aeb99 --- /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(), + START_UPLOADING: ofType<{}>(), + UPDATE_UPLOAD_PROGRESS: ofType<{}>() +}, { + tag: 'type', + value: 'payload' +}); + +export type CollectionUploaderAction = UnionOf; 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 00000000..05735d65 --- /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 62d9ae2a..be4b645c 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() + .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 8d3f06a5..fd893a3c 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(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(GroupContentsResourcePrefix.COLLECTION), - FilterBuilder.create(GroupContentsResourcePrefix.PROCESS), - FilterBuilder.create(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 2f9963bf..5caf0121 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(), RESET_PROJECT_TREE_ACTIVITY: ofType() }, { - 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() + .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 0ba2b22a..281bd54e 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(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(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 f59728b6..a0cbcba5 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 = 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> { + class DialogCollectionCreate extends React.Component> { 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}> -
onSubmit(data))}> + onSubmit({ ...data, files: this.props.files }))}> Create a collection - + this.props.dispatch(collectionUploaderActions.SET_UPLOAD_FILES(files))}/>