From 861e0d2ec703a60a30c635691aed7b2a3b7cbaa7 Mon Sep 17 00:00:00 2001
From: Alexandru Munteanu <alexandru.munt@gmail.com>
Date: Tue, 2 Oct 2018 19:19:30 +0300
Subject: [PATCH] feat(editorial-recommendation): a contextual box for HE to
 submit his/her/xer review

---
 .../EditorialRecommendation.js                | 116 ++++++++++++++++++
 .../EditorialRecommendation.md                |  16 +++
 .../src/contextualBoxes/index.js              |   1 +
 .../src/helpers/withFetching.js               |   6 +-
 .../src/components/ManuscriptLayout.js        |  11 +-
 .../src/components/ManuscriptPage.js          |   3 +
 6 files changed, 149 insertions(+), 4 deletions(-)
 create mode 100644 packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.js
 create mode 100644 packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.md

diff --git a/packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.js b/packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.js
new file mode 100644
index 000000000..679610502
--- /dev/null
+++ b/packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.js
@@ -0,0 +1,116 @@
+import React from 'react'
+import { get } from 'lodash'
+import { reduxForm } from 'redux-form'
+import styled from 'styled-components'
+import { th } from '@pubsweet/ui-toolkit'
+import { required } from 'xpub-validators'
+import { compose, withProps } from 'recompose'
+import { Button, Menu, ValidatedField } from '@pubsweet/ui'
+import { withModal } from 'pubsweet-component-modal/src/components'
+
+import {
+  Row,
+  Text,
+  Label,
+  Textarea,
+  MultiAction,
+  ContextualBox,
+  ItemOverrideAlert,
+  withFetching,
+} from '../'
+
+const options = [
+  { value: 'publish', label: 'Publish' },
+  { value: 'reject', label: 'Reject' },
+  { value: 'minor-revision', label: 'Request Minor Revision' },
+  { value: 'major-revision', label: 'Request Major Revision' },
+]
+
+const EditorialRecommendation = ({ formValues, handleSubmit }) => (
+  <ContextualBox highlight label="Your Editorial Recommendation" startExpanded>
+    <Root>
+      <Row justify="flex-start">
+        <ItemOverrideAlert flex={0} vertical>
+          <Label required>Recommendation</Label>
+          <ValidatedField
+            component={input => <Menu options={options} {...input} />}
+            name="recommendation"
+            validate={[required]}
+          />
+        </ItemOverrideAlert>
+      </Row>
+
+      {get(formValues, 'recommendation') === 'publish' ||
+      get(formValues, 'recommendation') === 'reject' ? (
+        <Row mt={2}>
+          <ItemOverrideAlert vertical>
+            <Label required>Message for Author</Label>
+            <ValidatedField
+              component={Textarea}
+              name="message"
+              validate={[required]}
+            />
+          </ItemOverrideAlert>
+        </Row>
+      ) : (
+        <Row mt={2}>
+          <ItemOverrideAlert mr={1} vertical>
+            <Label>
+              Message for Author <Text secondary>Optional</Text>
+            </Label>
+            <ValidatedField component={Textarea} name="author-message" />
+          </ItemOverrideAlert>
+
+          <ItemOverrideAlert ml={1} vertical>
+            <Label>
+              Message for Editor in Chief <Text secondary>Optional</Text>
+            </Label>
+            <ValidatedField component={Textarea} name="eic-message" />
+          </ItemOverrideAlert>
+        </Row>
+      )}
+
+      <Row justify="flex-end" mt={2}>
+        <Button onClick={handleSubmit} primary size="medium">
+          Submit recommendation
+        </Button>
+      </Row>
+    </Root>
+  </ContextualBox>
+)
+
+export default compose(
+  withFetching,
+  withModal(({ isFetching }) => ({
+    isFetching,
+    modalComponent: MultiAction,
+  })),
+  withProps(({ formValues }) => ({
+    modalTitle: options.find(
+      o => o.value === get(formValues, 'recommendation', 'publish'),
+    ).label,
+  })),
+  reduxForm({
+    form: 'editorialRecommendation',
+    onSubmit: (
+      values,
+      dispatch,
+      { onRecommendationSubmit, showModal, setFetching, modalTitle },
+    ) => {
+      showModal({
+        title: `${modalTitle}?`,
+        onConfirm: props => {
+          onRecommendationSubmit(values, { ...props, setFetching })
+        },
+      })
+    },
+  }),
+)(EditorialRecommendation)
+
+// #region styles
+const Root = styled.div`
+  display: flex;
+  flex-direction: column;
+  padding: ${th('gridUnit')};
+`
+// #endregion
diff --git a/packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.md b/packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.md
new file mode 100644
index 000000000..0102ae846
--- /dev/null
+++ b/packages/component-faraday-ui/src/contextualBoxes/EditorialRecommendation.md
@@ -0,0 +1,16 @@
+HE recommendation.
+
+```js
+const formValues = {
+  recommendation: 'minor-revision',
+}
+
+;<EditorialRecommendation
+  formValues={formValues}
+  modalKey="heRecommendation"
+  onRecommendationSubmit={(values, props) => {
+    console.log('se face surmit la', values)
+    props.setFetching(true)
+  }}
+/>
+```
diff --git a/packages/component-faraday-ui/src/contextualBoxes/index.js b/packages/component-faraday-ui/src/contextualBoxes/index.js
index 54a8bdd97..a9311f90c 100644
--- a/packages/component-faraday-ui/src/contextualBoxes/index.js
+++ b/packages/component-faraday-ui/src/contextualBoxes/index.js
@@ -1,3 +1,4 @@
 export { default as AssignHE } from './AssignHE'
 export { default as ReviewerDetails } from './ReviewerDetails'
 export { default as ReviewerReportForm } from './ReviewerReportForm'
+export { default as EditorialRecommendation } from './EditorialRecommendation'
diff --git a/packages/component-faraday-ui/src/helpers/withFetching.js b/packages/component-faraday-ui/src/helpers/withFetching.js
index 717a5f95b..753c265e6 100644
--- a/packages/component-faraday-ui/src/helpers/withFetching.js
+++ b/packages/component-faraday-ui/src/helpers/withFetching.js
@@ -2,12 +2,12 @@ import { withStateHandlers } from 'recompose'
 
 export default withStateHandlers(
   {
-    isFetchingg: false,
+    isFetching: false,
     fetchingError: '',
   },
   {
-    setFetching: ({ isFetchingg }) => value => ({
-      isFetchingg: value,
+    setFetching: ({ isFetching }) => value => ({
+      isFetching: value,
     }),
     toggleFetching: ({ isFetching }) => () => ({
       isFetching: !isFetching,
diff --git a/packages/component-manuscript/src/components/ManuscriptLayout.js b/packages/component-manuscript/src/components/ManuscriptLayout.js
index a13df8c34..4e2471f1d 100644
--- a/packages/component-manuscript/src/components/ManuscriptLayout.js
+++ b/packages/component-manuscript/src/components/ManuscriptLayout.js
@@ -8,8 +8,9 @@ import {
   ManuscriptAssignHE,
   ManuscriptMetadata,
   ManuscriptDetailsTop,
-  ManuscriptEicDecision,
   ResponseToInvitation,
+  ManuscriptEicDecision,
+  EditorialRecommendation,
   paddingHelper,
 } from 'pubsweet-component-faraday-ui'
 
@@ -87,6 +88,14 @@ const ManuscriptLayout = ({
           revokeInvitation={revokeHE}
         />
 
+        <EditorialRecommendation
+          formValues={get(formValues, 'editorialRecommendation', {})}
+          modalKey="heRecommendation"
+          onRecommendationSubmit={(values, props) => {
+            props.setFetching(true)
+          }}
+        />
+
         <ManuscriptMetadata
           currentUser={currentUser}
           fragment={fragment}
diff --git a/packages/component-manuscript/src/components/ManuscriptPage.js b/packages/component-manuscript/src/components/ManuscriptPage.js
index 7c2839e59..ce588ddfe 100644
--- a/packages/component-manuscript/src/components/ManuscriptPage.js
+++ b/packages/component-manuscript/src/components/ManuscriptPage.js
@@ -160,6 +160,9 @@ export default compose(
         eicDecision: getFormValues('eic-decision')(state),
         reviewerReport: getFormValues('reviewerReport')(state),
         responseToInvitation: getFormValues('answer-invitation')(state),
+        editorialRecommendation: getFormValues('editorialRecommendation')(
+          state,
+        ),
       },
       invitationsWithReviewers: getInvitationsWithReviewersForFragment(
         state,
-- 
GitLab