From 0e6d36f21126ea98db29ea2764d365eaea0c04fe Mon Sep 17 00:00:00 2001
From: Mihail Hagiu <mihail.hagiu@thinslices.com>
Date: Tue, 23 Oct 2018 15:22:53 +0300
Subject: [PATCH] refactor(InviteHandlingEditor): Custom decorator for invite
 handling editor actions

---
 .../src/components/ManuscriptLayout.js        | 12 ++-
 .../src/components/ManuscriptPage.js          | 63 +---------------
 .../src/inviteHandlingEditor/inviteHE.api.js  | 31 ++++++++
 .../withInviteHandlingEditor.js               | 75 +++++++++++++++++++
 4 files changed, 113 insertions(+), 68 deletions(-)
 create mode 100644 packages/component-manuscript/src/inviteHandlingEditor/inviteHE.api.js
 create mode 100644 packages/component-manuscript/src/inviteHandlingEditor/withInviteHandlingEditor.js

diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js
index 619331cf1..f78aac588 100644
--- a/packages/component-manuscript/src/components/ManuscriptLayout.js
+++ b/packages/component-manuscript/src/components/ManuscriptLayout.js
@@ -29,8 +29,6 @@ const cannotViewReviewersDetails = ['revisionRequested', 'pendingApproval']
 
 const ManuscriptLayout = ({
   history,
-  assignHE,
-  revokeHE,
   currentUser,
   getSignedUrl,
   editorInChief,
@@ -45,7 +43,6 @@ const ManuscriptLayout = ({
   fetchingError,
   formValues,
   heExpanded,
-  onHEResponse,
   toggleAssignHE,
   toggleHEResponse,
   heResponseExpanded,
@@ -67,6 +64,7 @@ const ManuscriptLayout = ({
   toggleEditorialComments,
   submitRevision,
   inviteReviewer,
+  inviteHandlingEditor,
 }) => (
   <Root pb={30}>
     {!isEmpty(collection) && !isEmpty(fragment) ? (
@@ -87,8 +85,8 @@ const ManuscriptLayout = ({
           inviteHE={toggleAssignHE}
           isFetching={isFetching.editorsFetching}
           journal={journal}
-          resendInvitation={assignHE}
-          revokeInvitation={revokeHE}
+          resendInvitation={inviteHandlingEditor.assignHE}
+          revokeInvitation={inviteHandlingEditor.revokeHE}
         />
 
         <ManuscriptMetadata
@@ -140,7 +138,7 @@ const ManuscriptLayout = ({
             expanded={heResponseExpanded}
             formValues={formValues.responseToInvitation}
             label="Do you agree to be the handling editor for this manuscript?"
-            onResponse={onHEResponse}
+            onResponse={inviteHandlingEditor.onHEResponse}
             title="Respond to Editorial Invitation"
             toggle={toggleHEResponse}
           />
@@ -157,7 +155,7 @@ const ManuscriptLayout = ({
         )}
 
         <ManuscriptAssignHE
-          assignHE={assignHE}
+          assignHE={inviteHandlingEditor.assignHE}
           currentUser={currentUser}
           expanded={heExpanded}
           handlingEditors={handlingEditors}
diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js
index 8e67c6d7e..b3f9d69f3 100644
--- a/packages/component-manuscript/src/components/ManuscriptPage.js
+++ b/packages/component-manuscript/src/components/ManuscriptPage.js
@@ -65,6 +65,7 @@ import {
 import ManuscriptLayout from './ManuscriptLayout'
 import withInviteReviewer from '../inviteReviewer/withInviteReviewer'
 import withSubmitRevision from '../submitRevision/withSubmitRevision'
+import withInviteHandlingEditor from '../inviteHandlingEditor/withInviteHandlingEditor'
 import {
   parseEicDecision,
   parseSearchParams,
@@ -75,10 +76,7 @@ import {
   canAssignHE,
   selectFetching,
   getHandlingEditors,
-  assignHandlingEditor,
-  revokeHandlingEditor,
   selectHandlingEditors,
-  handlingEditorDecision,
 } from '../redux/editors'
 
 export default compose(
@@ -129,8 +127,6 @@ export default compose(
     {
       changeForm,
       clearCustomError,
-      assignHandlingEditor,
-      revokeHandlingEditor,
       getUsers: actions.getUsers,
       getFragment: actions.getFragment,
       getCollection: actions.getCollection,
@@ -257,34 +253,6 @@ export default compose(
         setEiC(`${firstName} ${lastName}`)
       }
     },
-    assignHE: ({
-      assignHandlingEditor,
-      fetchUpdatedCollection,
-      collection: { id: collectionId },
-    }) => (email, modalProps) =>
-      assignHandlingEditor({
-        email,
-        collectionId,
-      })
-        .then(() => {
-          fetchUpdatedCollection()
-          modalProps.hideModal()
-        })
-        .catch(handleError(modalProps.setModalError)),
-    revokeHE: ({
-      getCollection,
-      revokeHandlingEditor,
-      collection: { id: collectionId },
-    }) => (invitationId, modalProps) =>
-      revokeHandlingEditor({
-        invitationId,
-        collectionId,
-      })
-        .then(() => {
-          getCollection({ id: collectionId })
-          modalProps.hideModal()
-        })
-        .catch(handleError(modalProps.setModalError)),
     createRecommendation: ({
       fragment,
       collection,
@@ -307,34 +275,6 @@ export default compose(
           handleError(modalProps.setModalError)(err)
         })
     },
-    onHEResponse: ({
-      history,
-      collection,
-      pendingHEInvitation,
-      fetchUpdatedCollection,
-    }) => (values, { hideModal, setModalError, setFetching }) => {
-      const isAccepted = get(values, 'decision', 'decline') === 'accept'
-      setFetching(true)
-      return handlingEditorDecision({
-        isAccepted,
-        collectionId: collection.id,
-        reason: get(values, 'reason', ''),
-        invitationId: pendingHEInvitation.id,
-      })
-        .then(() => {
-          setFetching(false)
-          hideModal()
-          if (isAccepted) {
-            fetchUpdatedCollection()
-          } else {
-            history.replace('/')
-          }
-        })
-        .catch(err => {
-          setFetching(false)
-          handleError(setModalError)(err)
-        })
-    },
     onEditorialRecommendation: ({
       fragment,
       collection,
@@ -387,6 +327,7 @@ export default compose(
       get(currentUser, 'isReviewer', false) &&
       isUndefined(submittedOwnRecommendation),
   })),
+  withInviteHandlingEditor,
   withInviteReviewer,
   withSubmitRevision,
   lifecycle({
diff --git a/packages/component-manuscript/src/inviteHandlingEditor/inviteHE.api.js b/packages/component-manuscript/src/inviteHandlingEditor/inviteHE.api.js
new file mode 100644
index 000000000..ff05375a8
--- /dev/null
+++ b/packages/component-manuscript/src/inviteHandlingEditor/inviteHE.api.js
@@ -0,0 +1,31 @@
+import { create, update, remove } from 'pubsweet-client/src/helpers/api'
+
+export const handlingEditorDecision = ({
+  reason,
+  isAccepted,
+  collectionId,
+  invitationId,
+}) =>
+  update(`/collections/${collectionId}/invitations/${invitationId}`, {
+    isAccepted,
+    reason,
+  })
+
+export const assignHandlingEditor = ({ email, collectionId }) =>
+  create(`/collections/${collectionId}/invitations`, {
+    email,
+    role: 'handlingEditor',
+  }).then(
+    res => res,
+    err => {
+      throw err
+    },
+  )
+
+export const revokeHandlingEditor = ({ invitationId, collectionId }) =>
+  remove(`/collections/${collectionId}/invitations/${invitationId}`).then(
+    res => res,
+    err => {
+      throw err
+    },
+  )
diff --git a/packages/component-manuscript/src/inviteHandlingEditor/withInviteHandlingEditor.js b/packages/component-manuscript/src/inviteHandlingEditor/withInviteHandlingEditor.js
new file mode 100644
index 000000000..693de566d
--- /dev/null
+++ b/packages/component-manuscript/src/inviteHandlingEditor/withInviteHandlingEditor.js
@@ -0,0 +1,75 @@
+import { compose, withHandlers, withProps } from 'recompose'
+import { get, pick } from 'lodash'
+import { withRouter } from 'react-router-dom'
+import { handleError, withFetching } from 'pubsweet-component-faraday-ui'
+import {
+  handlingEditorDecision,
+  assignHandlingEditor,
+  revokeHandlingEditor,
+} from './inviteHE.api'
+
+export default compose(
+  withFetching,
+  withRouter,
+  withHandlers({
+    assignHE: ({
+      fetchUpdatedCollection,
+      collection: { id: collectionId },
+    }) => (email, modalProps) =>
+      assignHandlingEditor({
+        email,
+        collectionId,
+      })
+        .then(() => {
+          fetchUpdatedCollection()
+          modalProps.hideModal()
+        })
+        .catch(handleError(modalProps.setModalError)),
+    revokeHE: ({ getCollection, collection: { id: collectionId } }) => (
+      invitationId,
+      modalProps,
+    ) =>
+      revokeHandlingEditor({
+        invitationId,
+        collectionId,
+      })
+        .then(() => {
+          getCollection({ id: collectionId })
+          modalProps.hideModal()
+        })
+        .catch(handleError(modalProps.setModalError)),
+    onHEResponse: ({
+      history,
+      collection,
+      pendingHEInvitation,
+      fetchUpdatedCollection,
+    }) => (values, { hideModal, setModalError, setFetching }) => {
+      const isAccepted = get(values, 'decision', 'decline') === 'accept'
+      setFetching(true)
+      return handlingEditorDecision({
+        isAccepted,
+        collectionId: collection.id,
+        reason: get(values, 'reason', ''),
+        invitationId: pendingHEInvitation.id,
+      })
+        .then(() => {
+          setFetching(false)
+          hideModal()
+          if (isAccepted) {
+            fetchUpdatedCollection()
+          } else {
+            history.replace('/')
+          }
+        })
+        .catch(err => {
+          setFetching(false)
+          handleError(setModalError)(err)
+        })
+    },
+  }),
+  withProps(props => ({
+    inviteHandlingEditor: {
+      ...pick(props, ['assignHE', 'revokeHE', 'onHEResponse']),
+    },
+  })),
+)
-- 
GitLab