From f1a67f84271759751064fd1f304330813ee3cf8d Mon Sep 17 00:00:00 2001
From: Bogdan Cochior <bogdan.cochior@thinslices.com>
Date: Wed, 9 May 2018 13:56:23 +0300
Subject: [PATCH] refactor(review-form): wip: refactor

---
 .../src/components/ReviewerReportForm.js      | 90 ++++++++++---------
 .../src/components/ReviewsAndReports.js       | 27 +++++-
 packages/components-faraday/src/index.js      |  1 +
 .../src/redux/recommendations.js              | 63 ++++++++++++-
 4 files changed, 135 insertions(+), 46 deletions(-)

diff --git a/packages/component-manuscript/src/components/ReviewerReportForm.js b/packages/component-manuscript/src/components/ReviewerReportForm.js
index 2e91779f1..a82a853ef 100644
--- a/packages/component-manuscript/src/components/ReviewerReportForm.js
+++ b/packages/component-manuscript/src/components/ReviewerReportForm.js
@@ -1,9 +1,10 @@
 import React, { Fragment } from 'react'
+import { debounce, isEqual } from 'lodash'
 import { connect } from 'react-redux'
 import { required } from 'xpub-validators'
 import styled, { css } from 'styled-components'
-import { compose, withHandlers, withProps } from 'recompose'
 import { th, Menu, ValidatedField, Icon, Button } from '@pubsweet/ui'
+import { compose, withHandlers, withProps } from 'recompose'
 import {
   reduxForm,
   isSubmitting,
@@ -20,8 +21,11 @@ import {
   withModal2,
 } from 'pubsweet-component-modal/src/components'
 import {
-  selectFetching,
   selectError,
+  selectFetching,
+  createRecommendation,
+  updateRecommendation,
+  getFragmentRecommendations,
 } from 'pubsweet-components-faraday/src/redux/recommendations'
 
 import { parseReviewResponseToForm, parseReviewRequest } from './utils'
@@ -47,23 +51,21 @@ const options = [
   },
 ]
 
-const review = {
-  id: 'revuewiuuuid',
-  userId: 'uuuuuuid',
-  recommendation: 'publish',
-  recommendationType: 'review',
-  comments: [
-    {
-      content: 'Here is public text',
-      public: true,
-      files: [],
-    },
-    {
-      content: 'Here is PRIVATE text',
-      public: false,
-      files: [],
-    },
-  ],
+const onChange = (
+  values,
+  dispatch,
+  { project, version, createRecommendation, updateRecommendation },
+) => {
+  dispatch(autosaveRequest())
+  if (values.id) {
+    updateRecommendation(parseReviewRequest(values))
+      .then(console.log)
+      .then(dispatch(autosaveSuccess(new Date())))
+  } else {
+    createRecommendation(parseReviewRequest(values))
+      .then(console.log)
+      .then(dispatch(autosaveSuccess(new Date())))
+  }
 }
 
 const ReviewerReportForm = ({
@@ -71,7 +73,6 @@ const ReviewerReportForm = ({
   changeField,
   handleSubmit,
   formValues = {},
-  initialValues,
 }) => (
   <Root>
     <Row>
@@ -163,9 +164,6 @@ const ReviewerReportForm = ({
   </Root>
 )
 
-// To be removed
-const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
-
 const ModalWrapper = compose(
   connect(state => ({
     fetching: selectFetching(state),
@@ -181,10 +179,16 @@ export default compose(
       formValues: getFormValues('reviewerReport')(state),
       isSubmitting: isSubmitting('reviewerReport')(state),
     }),
-    { changeForm, getFormValues },
+    {
+      changeForm,
+      getFormValues,
+      getFragmentRecommendations,
+      createRecommendation,
+      updateRecommendation,
+    },
   ),
-  withProps(() => ({
-    initialValues: parseReviewResponseToForm({}),
+  withProps(({ recommendations = [] }) => ({
+    initialValues: parseReviewResponseToForm(recommendations[0]),
   })),
   withModal2(props => ({
     modalComponent: ModalWrapper,
@@ -196,27 +200,31 @@ export default compose(
   }),
   reduxForm({
     form: 'reviewerReport',
-    enableReinitialize: true,
-    forceUnregisterOnUnmount: true,
-    onChange: (values, dispatch) => {
-      dispatch(autosaveRequest())
-      sleep(1000).then(() => dispatch(autosaveSuccess(new Date())))
-    },
-    onSubmit: (values, dispatch, { isSubmitting, showModal, hideModal }) => {
+    onChange: debounce(onChange, 1000, { maxWait: 5000 }),
+    onSubmit: (
+      values,
+      dispatch,
+      { isSubmitting, showModal, hideModal, project, version },
+    ) => {
       showModal({
         title: 'Ready to Submit your Report?',
         subtitle: 'Once submitted, the report can`t be modified',
         confirmText: 'Submit report',
         onConfirm: () => {
-          sleep(1000)
+          dispatch(autosaveRequest())
+          updateRecommendation(parseReviewRequest(values))
+            .then(console.log)
             .then(hideModal)
-            .then(() => {
-              // TODO: link to backend
-              const review = parseReviewRequest(values)
-              window.alert(
-                `You submitted:\n\n${JSON.stringify(review, null, 2)}`,
-              )
-            })
+            .then(dispatch(autosaveSuccess(new Date())))
+          // sleep(1000)
+          //   .then(hideModal)
+          //   .then(() => {
+          //     // TODO: link to backend
+          //     const review = parseReviewRequest(values)
+          //     window.alert(
+          //       `You submitted:\n\n${JSON.stringify(review, null, 2)}`,
+          //     )
+          //   })
         },
         onCancel: hideModal,
       })
diff --git a/packages/component-manuscript/src/components/ReviewsAndReports.js b/packages/component-manuscript/src/components/ReviewsAndReports.js
index 15fa55f80..dc1ff11fc 100644
--- a/packages/component-manuscript/src/components/ReviewsAndReports.js
+++ b/packages/component-manuscript/src/components/ReviewsAndReports.js
@@ -12,6 +12,10 @@ import {
   getCollectionReviewers,
   currentUserIsReviewer,
 } from 'pubsweet-components-faraday/src/redux/reviewers'
+import {
+  getFragmentRecommendations,
+  selectRecommendations,
+} from 'pubsweet-components-faraday/src/redux/recommendations'
 
 import Tabs from '../molecules/Tabs'
 import Expandable from '../molecules/Expandable'
@@ -33,7 +37,9 @@ const getTabSections = (collectionId, reviewers) => [
 
 const ReviewsAndReports = ({
   project,
+  version,
   reviewers = [],
+  recommendations = [],
   isReviewer,
   currentUserIs,
 }) => (
@@ -57,7 +63,11 @@ const ReviewsAndReports = ({
     {isReviewer && (
       <Root id="review-report">
         <Expandable label="Your Report" startExpanded>
-          <ReviewerReportForm />
+          <ReviewerReportForm
+            project={project}
+            recommendations={recommendations}
+            version={version}
+          />
         </Expandable>
       </Root>
     )}
@@ -68,20 +78,29 @@ export default compose(
   connect(
     (state, { project }) => ({
       reviewers: selectReviewers(state),
+      recommendations: selectRecommendations(state),
       fetchingReviewers: selectFetchingReviewers(state),
       isReviewer: currentUserIsReviewer(state, project.id),
     }),
-    { getCollectionReviewers },
+    { getCollectionReviewers, getFragmentRecommendations },
   ),
   withHandlers({
-    getReviewers: ({ project, setReviewers, getCollectionReviewers }) => () => {
+    getReviewers: ({ project, getCollectionReviewers }) => () => {
       getCollectionReviewers(project.id)
     },
+    getRecommendations: ({
+      project,
+      version,
+      getFragmentRecommendations,
+    }) => () => {
+      getFragmentRecommendations(project.id, version.id)
+    },
   }),
   lifecycle({
     componentDidMount() {
-      const { getReviewers } = this.props
+      const { getReviewers, getRecommendations } = this.props
       getReviewers()
+      getRecommendations()
     },
   }),
 )(ReviewsAndReports)
diff --git a/packages/components-faraday/src/index.js b/packages/components-faraday/src/index.js
index a73434f5e..d21969e7b 100644
--- a/packages/components-faraday/src/index.js
+++ b/packages/components-faraday/src/index.js
@@ -6,6 +6,7 @@ module.exports = {
       files: () => require('./redux/files').default,
       editors: () => require('./redux/editors').default,
       reviewers: () => require('./redux/reviewers').default,
+      recommendations: () => require('./redux/recommendations').default,
     },
   },
 }
diff --git a/packages/components-faraday/src/redux/recommendations.js b/packages/components-faraday/src/redux/recommendations.js
index b59d6abf4..2754da667 100644
--- a/packages/components-faraday/src/redux/recommendations.js
+++ b/packages/components-faraday/src/redux/recommendations.js
@@ -11,6 +11,7 @@ const ERROR = 'recommendations/ERROR'
 
 const GET_RECOMMENDATIONS_SUCCESS = 'recommendations/GET_SUCCESS'
 const GET_RECOMMENDATION_SUCCESS = 'recommendations/GET_ITEM_SUCCESS'
+const CREATE_RECOMMENDATION_SUCCESS = 'recommendations/CREATE_SUCCESS'
 const UPDATE_RECOMMENDATION_SUCCESS = 'recommendations/UPDATE_SUCCESS'
 
 export const recommendationsRequest = () => ({
@@ -32,6 +33,11 @@ export const getRecommendationSuccess = recommendation => ({
   payload: { recommendation },
 })
 
+export const createRecommendationSuccess = recommendation => ({
+  type: CREATE_RECOMMENDATION_SUCCESS,
+  payload: { recommendation },
+})
+
 export const updateRecommendationSuccess = recommendation => ({
   type: UPDATE_RECOMMENDATION_SUCCESS,
   payload: { recommendation },
@@ -40,10 +46,63 @@ export const updateRecommendationSuccess = recommendation => ({
 // Selectors
 export const selectFetching = state =>
   get(state, 'recommendations.fetching') || false
-
 export const selectError = state => get(state, 'recommendations.error')
+export const selectRecommendations = state =>
+  get(state, 'recommendations.recommendations') || []
+
+const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
 
 // Actions
+export const getFragmentRecommendations = (
+  collectionId,
+  fragmentId,
+) => dispatch => {
+  dispatch(recommendationsRequest())
+  const review = {
+    id: 'revuewiuuuid',
+    userId: 'uuuuuuid',
+    recommendation: 'publish',
+    recommendationType: 'review',
+    comments: [
+      {
+        content: 'Here is public text',
+        public: true,
+        files: [],
+      },
+      {
+        content: 'Here is PRIVATE text',
+        public: false,
+        files: [],
+      },
+    ],
+  }
+  return sleep(1000).then(() => {
+    dispatch(getRecommendationsSuccess([review]))
+    return [review]
+  })
+  // return apiGet(
+  //   `/collections/${collectionId}/fragments/${fragmentId}/recommendations`,
+  // ).then(
+  //   r => dispatch(getRecommendationsSuccess(r)),
+  //   err => dispatch(recommendationsError(err)),
+  // )
+}
+
+export const updateRecommendation = recommendation => dispatch => {
+  dispatch(recommendationsRequest())
+  return sleep(1000).then(() => {
+    dispatch(updateRecommendationSuccess(recommendation))
+    return recommendation
+  })
+}
+
+export const createRecommendation = recommendation => dispatch => {
+  dispatch(recommendationsRequest())
+  return sleep(1000).then(() => {
+    dispatch(updateRecommendationSuccess(recommendation))
+    return recommendation
+  })
+}
 
 // State
 const initialState = {
@@ -83,10 +142,12 @@ export default (state = initialState, action = {}) => {
         recommendation: action.payload.recommendation,
       }
     case UPDATE_RECOMMENDATION_SUCCESS:
+    case CREATE_RECOMMENDATION_SUCCESS:
       return {
         ...state,
         fetching: false,
         error: null,
+        recommendations: [action.payload.recommendation],
         recommendation: action.payload.recommendation,
       }
     default:
-- 
GitLab