Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ManuscriptEicDecision.js 5.30 KiB
import React from 'react'
import { get, initial, chain } from 'lodash'
import { compose, withProps } from 'recompose'
import styled from 'styled-components'
import { reduxForm } from 'redux-form'
import { th } from '@pubsweet/ui-toolkit'
import { required } from 'xpub-validators'
import { Button, Menu, ValidatedField } from '@pubsweet/ui'
import PropTypes from 'prop-types'
import { withModal } from 'pubsweet-component-modal/src/components'

import {
  Row,
  Item,
  Label,
  Textarea,
  MultiAction,
  ContextualBox,
  ItemOverrideAlert,
  withFetching,
} from '../'

const eicDecisions = [
  {
    value: 'return-to-handling-editor',
    label: 'Return to Handling Editor',
    modalTitle: 'Return Manuscript',
    modalSubtitle:
      'A returning manuscript to Handling Editor decision is final',
  },
  {
    value: 'publish',
    label: 'Publish',
    modalTitle: 'Publish Manuscript',
    modalSubtitle: 'A publish decision is final',
  },
  {
    value: 'reject',
    label: 'Reject',
    modalTitle: 'Reject Manuscript',
    modalSubtitle: 'A rejection decision is final',
  },
  {
    value: 'revision',
    label: 'Request Revision',
    modalTitle: 'Request Revision',
  },
]

const filterOptions = (eicDecisions, status) => {
  if (status === 'submitted') return eicDecisions.slice(2)
  if (status === 'pendingApproval') return initial(eicDecisions)
  return eicDecisions.slice(2, 3)
}
const ManuscriptEicDecision = ({
  status,
  options,
  decision,
  formValues,
  collection,
  isFetching,
  handleSubmit,
  messagesLabel,
  submitDecision,
  lastHeRecommendation,
  ...rest
}) => (
  <ContextualBox
    data-test-id="your-editorial-decision-id"
    label="Your Editorial Decision"
    {...rest}
  >
    <Root>
      <Row justify="flex-start" pl={1} pt={1}>
        <ItemOverrideAlert flex={0} vertical>
          <Label required>Decision</Label>
          <ValidatedField
            component={input => <Menu {...input} options={options} />}
            name="decision"
            validate={[required]}
          />
        </ItemOverrideAlert>
      </Row>

      {(decision === 'revision' ||
        decision === 'return-to-handling-editor') && (
        <Row mt={2} pl={1} pr={1}>
          <Item vertical>
            <Label required={decision !== 'reject'}>
              {messagesLabel[get(formValues, 'decision', 'reject')]}
            </Label>
            <ValidatedField
              component={ValidatedTextArea}
              name="message"
              validate={decision !== 'reject' ? [required] : undefined}
            />
          </Item>
        </Row>
      )}
      {decision === 'reject' && (
        <Row mt={2} pl={1} pr={1}>
          <Item vertical>
            <Label required={lastHeRecommendation !== 'reject'}>
              {messagesLabel[get(formValues, 'decision', 'reject')]}
            </Label>
            <ValidatedField
              component={ValidatedTextArea}
              name="message"
              validate={
                lastHeRecommendation !== 'reject' ? [required] : undefined
              }
            />
          </Item>
        </Row>
      )}

      <Row justify="flex-end" mt={1} pr={1}>
        <Button onClick={handleSubmit} primary size="medium">
          SUBMIT DECISION
        </Button>
      </Row>
    </Root>
  </ContextualBox>
)

export default compose(
  withFetching,
  withModal(({ isFetching }) => ({
    isFetching,
    modalKey: 'eic-decision',
    modalComponent: MultiAction,
  })),
  withProps(({ formValues, collection, fragment }) => ({
    modalTitle: eicDecisions.find(
      o => o.value === get(formValues, 'decision', 'publish'),
    ).modalTitle,
    modalSubtitle: eicDecisions.find(
      o => o.value === get(formValues, 'decision', 'publish'),
    ).modalSubtitle,
    decision: get(formValues, 'decision'),
    options: filterOptions(
      eicDecisions,
      get(collection, 'status', 'submitted'),
    ),
    lastHeRecommendation: chain(fragment)
      .get('recommendations', [])
      .last()
      .get('recommendation', '')
      .value(),
  })),
  reduxForm({
    form: 'eic-decision',
    destroyOnUnmount: false,
    onSubmit: (
      values,
      dispatch,
      {
        reset,
        submitDecision,
        showModal,
        setFetching,
        modalTitle,
        confirmMessage,
        modalSubtitle,
      },
    ) => {
      showModal({
        reset,
        title: `${modalTitle}?`,
        confirmText: modalTitle,
        subtitle: modalSubtitle,
        onConfirm: modalProps => {
          submitDecision(values, { ...modalProps, setFetching })
        },
      })
    },
  }),
)(ManuscriptEicDecision)

ManuscriptEicDecision.propTypes = {
  /** Object with details about collection.  */
  collection: PropTypes.object, //eslint-disable-line
  /** Label of the decision of EIC. */
  messagesLabel: PropTypes.object, //eslint-disable-line
  /** Callback function fired when the handling editor submit his decision. */
  submitDecision: PropTypes.func,
  /** Values taken by form. */
  formValues: PropTypes.object, //eslint-disable-line
}
ManuscriptEicDecision.defaultProps = {
  collection: {},
  messagesLabel: {},
  submitDecision: () => {},
  formValues: {},
}

// #region styles
const Root = styled.div`
  display: flex;
  flex-direction: column;
  padding: ${th('gridUnit')};
`

const ValidatedTextArea = styled(Textarea)`
  & + div {
    margin-top: 0;
  }
`
// #endregion