Skip to content
Snippets Groups Projects
utils.js 7.48 KiB
Newer Older
import moment from 'moment'
import { change as changeForm } from 'redux-form'
import { actions } from 'pubsweet-client/src'
import { handleError } from 'pubsweet-component-faraday-ui'

import {
  autosaveRequest,
  autosaveFailure,
} from 'pubsweet-component-wizard/src/redux/autosave'
import {
  createRecommendation,
  updateRecommendation,
} from '../redux/recommendations'

export const parseTitle = version => {
  const title = get(version, 'metadata.title')
  if (title) {
    return title.replace(/<p[^>]*>/g, '').replace(/<\/p>/g, '')
  }
  return 'Untitled'
}

export const parseAuthor = version => {
  const author = find(get(version, 'authors'), a => a.isSubmitting)
  return author ? `${author.firstName} ${author.lastName}` : 'N/A'
}

export const parseType = version => {
  const type = get(version, 'metadata.type')
  return type ? type.replace('-', ' ') : 'N/A'
}

export const parseSubmissionDate = version => {
  const submitted = get(version, 'submitted')
  const submittedDate = moment(submitted)
  const today = moment()
  const daysAgo = moment.duration(today - moment(submitted)).days()
  return submitted
    ? `${submittedDate.format('DD.MM.YYYY')} ${
        daysAgo > 0 ? `(${daysAgo} days)` : ''
      }`
    : 'N/A'
}

export const mapStatusToLabel = ({ visibleStatus, status }) => {
  if (visibleStatus) {
    return visibleStatus
  } else if (status) {
    return capitalize(status)
  }
  return 'Draft'
}

export const parseVersion = version => ({
  type: parseType(version),
  title: parseTitle(version),
  author: parseAuthor(version),
  version: get(version, 'version'),
  submitted: parseSubmissionDate(version),
  abstract: get(version, 'metadata.abstract'),
})

export const parseJournalIssue = (journal, metadata) =>
  journal.issueTypes.find(t => t.value === get(metadata, 'issue'))

export const parseSearchParams = url => {
  const params = new URLSearchParams(url)
  const parsedObject = {}
  for ([key, value] of params) {
    parsedObject[key] = value
  }
export const parseVersionOptions = (fragments = []) =>
  fragments
    .map((f, index) => ({
      value: f,
      label: `Version ${index + 1}`,
    }))
    .reverse()
const alreadyAnswered = `You have already answered this invitation.`
export const redirectToError = redirectFn => err => {
  const errorText = get(JSON.parse(err.response), 'error')
  if (errorText.includes('has already been answered')) {
    redirectFn('/error-page', alreadyAnswered)
  } else {
    redirectFn('/error-page', 'Something went wrong. Please try again.')

export const parseReviewResponseToForm = (review = {}) => {
  if (isEmpty(review)) return {}
  const comments = get(review, 'comments', [])
  const publicComment = comments.find(c => c.public)
  const privateComment = comments.find(c => !c.public)
  return {
    ...review,
    public: get(publicComment, 'content'),
    file: get(publicComment, 'files.0', null),
    confidential: get(privateComment, 'content'),
  }
}

export const parseReviewRequest = (review = {}) => {
  if (isEmpty(review)) return {}
  const comments = [
    {
      public: true,
      files: has(review, 'file') ? [get(review, 'file')] : [],
      content: get(review, 'public'),
  if (get(review, 'confidential', '')) {
    comments.push({
      public: false,
      content: get(review, 'confidential'),
    id: get(review, 'id', null),
    recommendationType: 'review',
    recommendation: get(review, 'recommendation', 'publish'),
export const reviewerReportValidate = values => {
  const errors = {}

  if (!values.public && !values.file) {
    errors.public = 'A file or a public report is required.'
  }

  return errors
}

const onChange = (values, dispatch, { project, version }) => {
  const newValues = parseReviewRequest(values)
  dispatch(autosaveRequest())
  if (newValues.id) {
    updateRecommendation({
      fragmentId: version.id,
      collectionId: project.id,
      recommendation: newValues,
    }).then(
      r => {
        dispatch(autosaveSuccess(Date.now()))
        return r
      },
      err => {
        dispatch(autosaveFailure())
        throw err
      },
    )
    createRecommendation({
      fragmentId: version.id,
      collectionId: project.id,
      recommendation: omit(newValues, 'id'),
    }).then(
      r => {
        dispatch(changeForm('reviewerReport', 'id', r.id))
        dispatch(autosaveSuccess(Date.now()))
        return r
      },
      err => {
        dispatch(autosaveFailure())
        throw err
      },
    )
  }
}

export const onReviewChange = debounce(onChange, 1000, { maxWait: 5000 })

export const onReviewSubmit = (
  values,
  dispatch,
  { project, version, showModal, setFetching, isSubmitting },
) => {
  showModal({
    title: 'Are you done?',
    subtitle: 'Once submitted, the report cannot be modified.',
    confirmText: 'Submit report',
    onConfirm: ({ hideModal, setModalError }) => {
      setFetching(true)
      const newValues = parseReviewRequest(values)
      newValues.submittedOn = Date.now()
      updateRecommendation({
        fragmentId: version.id,
        collectionId: project.id,
        recommendation: newValues,
      })
        .then(() => dispatch(actions.getCollection({ id: project.id })))
          dispatch(actions.getFragments({ id: project.id }))
        .catch(err => {
          setFetching(false)
          handleError(setModalError)(err)
        })
const parseRevision = (values, fragment) => {
  const v = omit(values, 'authorForm')
      metadata: mergeWith(
        {},
        fragment.metadata,
        v.metadata,
        (obj, src) => (src === '' ? obj : src),
      ),
const _onRevisionChange = (values, dispatch, { project, version }) => {
  dispatch(actions.updateFragment(project, parseRevision(values, version)))
}
export const onRevisionChange = debounce(_onRevisionChange, 1000, {
  maxWait: 5000,
})

export const onRevisionSubmit = (
  values,
  dispatch,
  {
    history,
    version,
    project,
    showModal,
    hideModal,
    setModalError,
    submitRevision,
  },
  showModal({
    title: 'Ready to submit your revision?',
    subtitle: `Once submitted, the submission can't be modified.`,
    onConfirm: () => {
      submitRevision(project.id, version.id)
        .then(r => {
          dispatch(actions.getFragments({ id: project.id })).then(() => {
            history.push(`/projects/${r.collectionId}/versions/${r.id}/details`)
            hideModal()
          })
        })
        .catch(e => setModalError('Something went wrong.'))
}
// revision validators
export const requiredHTML = value => {
  if (value && value.replace('<p></p>', '').replace('<h1></h1>', '')) {
    return undefined
  }
  return 'Required'
}

export const requiredFiles = (values, formValues) => {
  const manuscripts = get(formValues, 'files.manuscripts')
  if (!manuscripts || manuscripts.length === 0) {
    return 'At least one main manuscript file is needed.'
  }
  return undefined
}

// new stuff
export const parseEicDecision = ({ decision, message }) => ({
  recommendation: decision,
  recommendationType: 'editorRecommendation',
  comments: [
    {
      public: decision !== 'return-to-handling-editor',
      content: message,
    },
  ],
})