From 75c5890fea971d109ea0c445230e7d235ac885ac Mon Sep 17 00:00:00 2001
From: Alf Eaton <eaton.alf@gmail.com>
Date: Thu, 31 Aug 2017 14:07:43 +0100
Subject: [PATCH] Handle supplemental file uploads

---
 .../src/components/SubmitPage.js              | 61 ++++++++++++++++---
 .../src/components/SupplementaryFiles.js      |  4 +-
 packages/xpub-collabra/.gitignore             |  1 +
 packages/xpub-collabra/config/validations.js  |  8 +++
 packages/xpub-ui/src/atoms/File.js            |  6 +-
 packages/xpub-ui/src/molecules/Files.js       |  1 +
 packages/xpub-ui/src/molecules/Upload.js      |  2 -
 7 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/packages/component-submit/src/components/SubmitPage.js b/packages/component-submit/src/components/SubmitPage.js
index c6df0a2e8..20109a9bb 100644
--- a/packages/component-submit/src/components/SubmitPage.js
+++ b/packages/component-submit/src/components/SubmitPage.js
@@ -1,7 +1,10 @@
-import { compose } from 'recompose'
+/* global CONFIG */
+
+import { compose, withHandlers } from 'recompose'
 import { connect } from 'react-redux'
 import { reduxForm } from 'redux-form'
 import actions from 'pubsweet-client/src/actions'
+import token from 'pubsweet-client/src/helpers/token'
 import { withJournal, ConnectPage } from 'pubsweet-component-xpub-app/src/components'
 import { selectCollection, selectFragment } from 'xpub-selectors'
 import Submit from './Submit'
@@ -16,6 +19,44 @@ const onChange = (values, dispatch) => {
   console.log('change', values)
 }
 
+const uploadFile = (file, project, version) => dispatch => {
+  // TODO: import the endpoint URL from a client module
+  const API_ENDPOINT = CONFIG['pubsweet-server'].API_ENDPOINT
+
+  const data = new FormData()
+  data.append('file', file)
+
+  const request = new XMLHttpRequest()
+  request.open('POST', API_ENDPOINT + '/upload')
+  request.setRequestHeader('Authorization', 'Bearer ' + token())
+  request.setRequestHeader('Accept', 'text/plain') // the response is a URL
+  request.send(data)
+
+  request.addEventListener('load', event => {
+    if (request.status === 200) { // TODO: 201?
+      const url = request.responseText
+
+      // TODO: create this before uploading, to get an upload token?
+      // if (!version.files) {
+        version.files = {}
+      // }
+
+      if (!version.files.supplementary) {
+        version.files.supplementary = []
+      }
+
+      version.files.supplementary.push({
+        name: file.name,
+        url
+      })
+
+      dispatch(actions.updateFragment(project, version))
+    }
+  })
+
+  return request
+}
+
 export default compose(
   reduxForm({
     form: 'submit',
@@ -31,16 +72,16 @@ export default compose(
       const project = selectCollection(state, ownProps.params.project)
       const version = selectFragment(state, ownProps.params.version)
 
-      const initialValues = {
-        declarations: version.declarations,
-        metadata: version.metadata,
-        notes: version.notes,
-        suggestions: version.suggestions,
-        files: version.files
-      }
-
-      return { project, version, initialValues }
+      return { project, version, initialValues: version }
+    },
+    {
+      uploadFile
     }
   ),
+  withHandlers({
+    uploadFile: ({ dispatch, project, version }) => file => {
+      return dispatch(uploadFile(file, project, version))
+    }
+  }),
   withJournal
 )(Submit)
diff --git a/packages/component-submit/src/components/SupplementaryFiles.js b/packages/component-submit/src/components/SupplementaryFiles.js
index 4cfdefe1e..96e57109a 100644
--- a/packages/component-submit/src/components/SupplementaryFiles.js
+++ b/packages/component-submit/src/components/SupplementaryFiles.js
@@ -14,7 +14,9 @@ const SupplementaryFiles = ({ uploadFile }) => (
         name="supplementary"
         id="supplementary"
         component={props =>
-          <Files uploadFile={uploadFile} {...props.input}/>
+          <Files
+            uploadFile={uploadFile}
+            {...props.input}/>
         }/>
     </div>
   </FormSection>
diff --git a/packages/xpub-collabra/.gitignore b/packages/xpub-collabra/.gitignore
index 146856988..072e77a27 100644
--- a/packages/xpub-collabra/.gitignore
+++ b/packages/xpub-collabra/.gitignore
@@ -2,5 +2,6 @@ _build/
 api/
 logs/
 node_modules/
+uploads/
 .env.*
 .env
diff --git a/packages/xpub-collabra/config/validations.js b/packages/xpub-collabra/config/validations.js
index 3c5ad022d..632d37235 100644
--- a/packages/xpub-collabra/config/validations.js
+++ b/packages/xpub-collabra/config/validations.js
@@ -13,6 +13,14 @@ module.exports = {
       authors: Joi.string(),
     }),
     declarations: Joi.object().unknown(),
+    files: Joi.object({
+      supplementary: Joi.array().items(Joi.object({
+        name: Joi.string().required(),
+        type: Joi.string(),
+        size: Joi.number(),
+        url: Joi.string()
+      }))
+    })
   },
   user: {
     name: Joi.string(), // TODO: add "name" to the login form
diff --git a/packages/xpub-ui/src/atoms/File.js b/packages/xpub-ui/src/atoms/File.js
index 50f453aa3..810a5561e 100644
--- a/packages/xpub-ui/src/atoms/File.js
+++ b/packages/xpub-ui/src/atoms/File.js
@@ -11,7 +11,11 @@ const File = ({ value, file, error, progress }) => (
       </div>
     </div>
 
-    <div className={classes.name}>{value.name}</div>
+    <div className={classes.name}>
+      <a href={value.url}>
+        {value.name}
+      </a>
+    </div>
   </div>
 )
 
diff --git a/packages/xpub-ui/src/molecules/Files.js b/packages/xpub-ui/src/molecules/Files.js
index e24229ef4..c2590eb7f 100644
--- a/packages/xpub-ui/src/molecules/Files.js
+++ b/packages/xpub-ui/src/molecules/Files.js
@@ -57,6 +57,7 @@ class Files extends React.Component {
         <div className={classes.files}>
           {uploads && uploads.map(upload => (
             <Upload
+              key={upload.file.name}
               file={upload.file}
               request={upload.request}/>
           ))}
diff --git a/packages/xpub-ui/src/molecules/Upload.js b/packages/xpub-ui/src/molecules/Upload.js
index 333e995d8..a5c0d08ec 100644
--- a/packages/xpub-ui/src/molecules/Upload.js
+++ b/packages/xpub-ui/src/molecules/Upload.js
@@ -31,8 +31,6 @@ class Upload extends React.Component {
       this.setState({
         progress: 1
       })
-
-      this.props.onComplete() // TODO: pass info?
     } else {
       this.setState({
         error: 'There was an error'
-- 
GitLab