From a19c0cc4a489c17202ed22c6e663dcfa623a3b4d Mon Sep 17 00:00:00 2001
From: Alexandru Munteanu <alexandru.munteanu@thinslices.com>
Date: Wed, 31 Jan 2018 14:41:15 +0200
Subject: [PATCH] Wire upload step to redux form

---
 .../src/components/FileSection.js             |   4 +-
 .../component-wizard/src/components/Files.js  | 115 ++++++------------
 .../src/components/WizardStep.js              |   1 +
 packages/component-wizard/src/redux/files.js  |  46 ++++---
 .../components/SortableList/SortableList.js   |   8 +-
 .../app/config/journal/submit-wizard.js       |   8 +-
 6 files changed, 77 insertions(+), 105 deletions(-)

diff --git a/packages/component-wizard/src/components/FileSection.js b/packages/component-wizard/src/components/FileSection.js
index c1c7c3bb4..45da7de03 100644
--- a/packages/component-wizard/src/components/FileSection.js
+++ b/packages/component-wizard/src/components/FileSection.js
@@ -30,7 +30,6 @@ const FileSection = ({
   isFirst,
   addFile,
   canDrop,
-  dropItems,
   moveItem,
   isFileOver,
   removeFile,
@@ -40,6 +39,7 @@ const FileSection = ({
   isFetching,
   canDropFile,
   disabledFilepicker,
+  dropSortableFile,
 }) =>
   connectFileDrop(
     connectDropTarget(
@@ -82,7 +82,7 @@ const FileSection = ({
         <SortableList
           beginDragProps={['id', 'index', 'name', 'listId']}
           dragHandle={DragHandle}
-          dropItem={dropItems}
+          dropItem={dropSortableFile}
           items={files}
           listId={listId}
           listItem={FileItem}
diff --git a/packages/component-wizard/src/components/Files.js b/packages/component-wizard/src/components/Files.js
index a79666c8c..69f90a37a 100644
--- a/packages/component-wizard/src/components/Files.js
+++ b/packages/component-wizard/src/components/Files.js
@@ -2,7 +2,6 @@ import React from 'react'
 import { get } from 'lodash'
 import PropTypes from 'prop-types'
 import { connect } from 'react-redux'
-import { actions } from 'pubsweet-client'
 import { withRouter } from 'react-router-dom'
 import {
   compose,
@@ -17,10 +16,11 @@ import FileSection from './FileSection'
 
 import {
   uploadFile,
-  setFiles,
   deleteFile,
   getFiles,
   getRequestStatus,
+  setAllFiles,
+  moveFiles,
 } from '../redux/files'
 
 const Files = ({
@@ -29,7 +29,7 @@ const Files = ({
   moveItem,
   removeFile,
   changeList,
-  dropItems,
+  dropSortableFile,
   ...rest
 }) => (
   <div>
@@ -37,7 +37,7 @@ const Files = ({
       addFile={addFile('manuscripts')}
       allowedFileExtensions={['pdf', 'doc', 'docx']}
       changeList={changeList}
-      dropItems={dropItems}
+      dropSortableFile={dropSortableFile}
       files={get(files, 'manuscripts') || []}
       isFirst
       listId="manuscripts"
@@ -49,6 +49,7 @@ const Files = ({
     <FileSection
       addFile={addFile('supplementary')}
       changeList={changeList}
+      dropSortableFile={dropSortableFile}
       files={get(files, 'supplementary') || []}
       listId="supplementary"
       maxFiles={Number.POSITIVE_INFINITY}
@@ -60,6 +61,7 @@ const Files = ({
       addFile={addFile('coverLetter')}
       allowedFileExtensions={['pdf', 'doc', 'docx']}
       changeList={changeList}
+      dropSortableFile={dropSortableFile}
       files={get(files, 'coverLetter') || []}
       isLast
       listId="coverLetter"
@@ -81,102 +83,63 @@ export default compose(
     }),
     {
       uploadFile,
-      updateFragment: actions.updateFragment,
-      setFiles,
       deleteFile,
+      setAllFiles,
+      moveFiles,
     },
   ),
   lifecycle({
     componentDidMount() {
-      const { setFiles, version } = this.props
-      setFiles(version.files.manuscripts, 'manuscripts')
-      setFiles(version.files.supplementary, 'supplementary')
-      setFiles(version.files.coverLetter, 'coverLetter')
+      const { version, setAllFiles } = this.props
+      setAllFiles(version.files)
     },
   }),
   withHandlers({
-    dropItems: ({ files, updateFragment, project, version }) => () => {
-      updateFragment(project, {
-        submitted: new Date(),
-        ...version,
-        files,
-      })
+    dropSortableFile: ({ files, setAllFiles }) => () => {
+      setAllFiles(files)
     },
-    changeList: ({ files, setFiles, updateFragment, project, version }) => (
-      fromListId,
-      toListId,
-      id,
-    ) => {
+    changeList: ({ files, setAllFiles }) => (fromListId, toListId, id) => {
       const swappedFile = files[fromListId].find(f => f.id === id)
 
       const fromFiles = files[fromListId].filter(f => f.id !== id)
       const toFiles = [...files[toListId], swappedFile]
 
-      setFiles(fromFiles, fromListId)
-      setFiles(toFiles, toListId)
-
-      updateFragment(project, {
-        submitted: new Date(),
-        ...version,
-        files: {
-          ...version.files,
-          [fromListId]: fromFiles,
-          [toListId]: toFiles,
-        },
-      })
+      const newFiles = {
+        ...files,
+        [toListId]: toFiles,
+        [fromListId]: fromFiles,
+      }
+      setAllFiles(newFiles)
     },
-    addFile: ({
-      files,
-      setFiles,
-      uploadFile,
-      updateFragment,
-      project,
-      version,
-    }) => type => file => {
-      uploadFile(file, type).then(fileResponse => {
-        setFiles([...files[type], fileResponse], type)
-        updateFragment(project, {
-          submitted: new Date(),
-          ...version,
-          files: {
-            ...version.files,
-            [type]: version.files[type]
-              ? [...version.files[type], fileResponse]
-              : [fileResponse],
-          },
-        })
+    addFile: ({ files, uploadFile, setAllFiles, version }) => type => file => {
+      uploadFile(file, type, version.id).then(fileResponse => {
+        const newFiles = {
+          ...files,
+          [type]: [...files[type], fileResponse],
+        }
+        setAllFiles(newFiles)
       })
     },
-    moveItem: ({
-      setFiles,
-      files,
-      project,
-      version,
-      updateFragment,
-    }) => type => (dragIndex, hoverIndex) => {
-      const newFiles = SortableList.moveItem(files[type], dragIndex, hoverIndex)
-      setFiles(newFiles, type)
+    moveItem: ({ moveFiles, files }) => type => (dragIndex, hoverIndex) => {
+      const newFiles = {
+        ...files,
+        [type]: SortableList.moveItem(files[type], dragIndex, hoverIndex),
+      }
+      moveFiles(newFiles)
     },
     removeFile: ({
-      setFiles,
+      setAllFiles,
       files,
       deleteFile,
-      project,
       version,
-      updateFragment,
     }) => type => id => e => {
       e.preventDefault()
-      deleteFile(id)
-      const newFiles = files[type].filter(f => f.id !== id)
-      setFiles(newFiles, type)
-      updateFragment(project, {
-        submitted: new Date(),
-        ...version,
-        files: {
-          ...version.files,
-          [type]: newFiles,
-        },
-      })
+      deleteFile(id, version.id)
+      const newFiles = {
+        ...files,
+        [type]: files[type].filter(f => f.id !== id),
+      }
+      setAllFiles(newFiles, type)
     },
   }),
   withContext(
diff --git a/packages/component-wizard/src/components/WizardStep.js b/packages/component-wizard/src/components/WizardStep.js
index 52b7609e4..9f0a4b8c5 100644
--- a/packages/component-wizard/src/components/WizardStep.js
+++ b/packages/component-wizard/src/components/WizardStep.js
@@ -66,6 +66,7 @@ export default ({
             )
           },
         )}
+      <Files />
       <div className={classnames(classes.buttons)}>
         <Button onClick={isFirst ? () => history.push('/') : prevStep}>
           {isFirst
diff --git a/packages/component-wizard/src/redux/files.js b/packages/component-wizard/src/redux/files.js
index d10c203ae..3e08bfc6b 100644
--- a/packages/component-wizard/src/redux/files.js
+++ b/packages/component-wizard/src/redux/files.js
@@ -1,4 +1,5 @@
-import request, { remove } from 'pubsweet-client/src/helpers/api'
+import request, { remove, get } from 'pubsweet-client/src/helpers/api'
+import { change as changeForm } from 'redux-form'
 
 const initialState = {
   isFetching: {
@@ -22,15 +23,23 @@ const REMOVE_REQUEST = 'files/REMOVE_REQUEST'
 const REMOVE_FAILURE = 'files/REMOVE_FAILURE'
 const REMOVE_SUCCESS = 'files/REMOVE_SUCCESS'
 
-const SET_FILES = 'files/SET_FILES'
+const SET_ALL_FILES = 'files/SET_ALL_FILES'
 
 // action creators
-export const setFiles = (files, fileType) => ({
-  type: SET_FILES,
+const _setAllFiles = files => ({
+  type: SET_ALL_FILES,
   files,
-  fileType,
 })
 
+export const setAllFiles = files => dispatch => {
+  dispatch(changeForm('wizard', 'files', files))
+  dispatch(_setAllFiles(files))
+}
+
+export const moveFiles = files => dispatch => {
+  dispatch(_setAllFiles(files))
+}
+
 const uploadRequest = type => ({
   type: UPLOAD_REQUEST,
   fileType: type,
@@ -45,9 +54,10 @@ const uploadSuccess = () => ({
   type: UPLOAD_SUCCESS,
 })
 
-const createFileData = (file, type) => {
+const createFileData = (file, type, fragmentId) => {
   const data = new FormData()
   data.append('fileType', type)
+  data.append('framentId', fragmentId)
   data.append('file', file)
 
   return {
@@ -77,9 +87,9 @@ export const getFiles = state => state.files.files
 export const getRequestStatus = state => state.files.isFetching
 
 // thunked actions
-export const uploadFile = (file, type) => dispatch => {
+export const uploadFile = (file, type, fragmentId) => dispatch => {
   dispatch(uploadRequest(type))
-  return request('/aws-upload', createFileData(file, type))
+  return request('/aws-upload', createFileData(file, type, fragmentId))
     .then(r => {
       dispatch(uploadSuccess())
       return r
@@ -87,9 +97,9 @@ export const uploadFile = (file, type) => dispatch => {
     .catch(err => dispatch(uploadFailure(err.message)))
 }
 
-export const deleteFile = fileId => dispatch => {
+export const deleteFile = (fileId, fragmentId) => dispatch => {
   dispatch(removeRequest())
-  return remove(`/aws-delete/${fileId}`)
+  return remove(`/aws-delete/${fragmentId}/${fileId}`)
     .then(r => {
       dispatch(removeSuccess())
       return r
@@ -97,9 +107,17 @@ export const deleteFile = fileId => dispatch => {
     .catch(err => dispatch(removeFailure(err.message)))
 }
 
+export const getSignedUrl = (fileId, fragmentId) =>
+  get(`aws-signed-url/${fragmentId}/${fileId}`)
+
 // reducer
 export default (state = initialState, action) => {
   switch (action.type) {
+    case SET_ALL_FILES:
+      return {
+        ...state,
+        files: action.files,
+      }
     case UPLOAD_REQUEST:
       return {
         ...state,
@@ -109,14 +127,6 @@ export default (state = initialState, action) => {
           [action.fileType]: true,
         },
       }
-    case SET_FILES:
-      return {
-        ...state,
-        files: {
-          ...state.files,
-          [action.fileType]: action.files,
-        },
-      }
     case UPLOAD_FAILURE:
       return {
         ...state,
diff --git a/packages/components-faraday/src/components/SortableList/SortableList.js b/packages/components-faraday/src/components/SortableList/SortableList.js
index 3497cc15c..d5e3a49c4 100644
--- a/packages/components-faraday/src/components/SortableList/SortableList.js
+++ b/packages/components-faraday/src/components/SortableList/SortableList.js
@@ -41,8 +41,12 @@ const itemTarget = {
     }
     monitor.getItem().index = hoverIndex
   },
-  drop({ dropItem, index }) {
-    if (dropItem && typeof dropItem === 'function') dropItem(index)
+  drop({ dropItem, index, listId: toListId, ...rest }, monitor) {
+    const { listId: fromListId } = monitor.getItem()
+    // TODO: fix it for authors too
+    if (fromListId === toListId) {
+      if (dropItem && typeof dropItem === 'function') dropItem(index)
+    }
   },
 }
 
diff --git a/packages/xpub-faraday/app/config/journal/submit-wizard.js b/packages/xpub-faraday/app/config/journal/submit-wizard.js
index df734e05f..2fb9f0428 100644
--- a/packages/xpub-faraday/app/config/journal/submit-wizard.js
+++ b/packages/xpub-faraday/app/config/journal/submit-wizard.js
@@ -1,12 +1,6 @@
 import React from 'react'
 import { AbstractEditor, TitleEditor } from 'xpub-edit'
-import {
-  Menu,
-  CheckboxGroup,
-  YesOrNo,
-  TextField,
-  Supplementary,
-} from '@pubsweet/ui'
+import { Menu, CheckboxGroup, YesOrNo, TextField } from '@pubsweet/ui'
 import uploadFileFn from 'xpub-upload'
 import { required, minChars, minSize } from 'xpub-validators'
 import { Files } from 'pubsweet-component-wizard/src/components/'
-- 
GitLab