Skip to content
Snippets Groups Projects
DecisionForm.js 4.53 KiB
Newer Older
import React from 'react'
import { get } from 'lodash'
import { connect } from 'react-redux'
import { actions } from 'pubsweet-client'
import { required } from 'xpub-validators'
import styled, { css } from 'styled-components'
import { reduxForm, formValueSelector } from 'redux-form'
import { compose, setDisplayName, withProps } from 'recompose'
import {
  th,
  Icon,
  Button,
  Spinner,
  RadioGroup,
  ValidatedField,
} from '@pubsweet/ui'

import { FormItems } from '../UIComponents'
import {
  selectError,
  selectFetching,
  createRecommendation,
} from '../../redux/recommendations'
import { subtitleParser, decisions, parseFormValues } from './utils'
  Row,
  Title,
  Label,
  RowItem,
  Textarea,
  Subtitle,
  RootContainer,
  FormContainer,
} = FormItems
const Form = RootContainer.withComponent(FormContainer)

const DecisionForm = ({
  decision,
  hideModal,
  heRecommendation: { reason, message = '' },
}) => (
  <Form onSubmit={handleSubmit}>
    <IconButton onClick={hideModal}>
      <Icon primary>x</Icon>
    </IconButton>
    <Title>Make decision</Title>
    {!!reason && (
      <CustomSubtitle>
        Recommended to<BoldSubtitle>{reason}</BoldSubtitle>
      </CustomSubtitle>
    )}
    {!!message && (
      <Row>
        <RowItem vertical>
          <Label>Message from Handling Editor</Label>
          <span>{message}</span>
        </RowItem>
      </Row>
    )}
    <Row>
      <RowItem vertical>
        <Label>Your Decision</Label>
        <ValidatedField
          component={input => (
            <CustomRadioGroup
              justify={reason ? 'space-between' : 'space-around'}
            >
              <RadioGroup
                name="decision"
                options={reason ? decisions : decisions.slice(0, 2)}
                {...input}
              />
            </CustomRadioGroup>
          )}
          name="decision"
        />
      </RowItem>
    </Row>
    {decision === 'return-to-handling-editor' && (
      <Row>
        <RowItem vertical>
          <Label>Comments for Handling Editor</Label>
          <ValidatedField
            component={input => <Textarea {...input} height={70} />}
            name="messageToHE"
    {recommendationError && (
      <Row>
        <RowItem centered>
          <Err>{recommendationError}</Err>
        </RowItem>
      </Row>
    )}
    <Row>
      <RowItem centered>
        <Button onClick={hideModal}>Cancel</Button>
      </RowItem>
      <RowItem centered>
        {isFetching ? (
          <Spinner size={3} />
        ) : (
          <Button primary type="submit">
            Submit
          </Button>
        )}
      </RowItem>
    </Row>
  </Form>
)

const selector = formValueSelector('eicDecision')
export default compose(
  setDisplayName('DecisionForm'),
      isFetching: selectFetching(state),
      decision: selector(state, 'decision'),
      recommendationError: selectError(state),
    }),
    { createRecommendation, getCollections: actions.getCollections },
  ),
  withProps(({ heRecommendation: { recommendation = '', comments = [] } }) => ({
    heRecommendation: {
      reason: subtitleParser(recommendation),
      message: get(comments.find(c => c.public), 'content'),
    },
  })),
  reduxForm({
    form: 'eicDecision',
      dispatch,
      {
        showModal,
        fragmentId,
        collectionId,
        getCollections,
        createRecommendation,
      },
    ) => {
      const recommendation = parseFormValues(values)
      createRecommendation(collectionId, fragmentId, recommendation).then(r => {
        getCollections()
        showModal({
          title: 'Decision submitted',
          cancelText: 'OK',
        })
      })
    },
  }),
)(DecisionForm)

// #region styled-components
const defaultText = css`
  color: ${th('colorText')};
  font-family: ${th('fontReading')};
  font-size: ${th('fontSizeBaseSmall')};
`

const IconButton = styled.div`
  align-self: flex-end;
  cursor: pointer;
`

const CustomSubtitle = Subtitle.extend`
  align-items: center;
  display: flex;
  flex-direction: row;
  justify-content: center;
`

const BoldSubtitle = Subtitle.extend`
  font-weight: bold;
  margin-left: 5px;
`

const CustomRadioGroup = styled.div`
  div {
    flex-direction: row;
    justify-content: ${({ justify }) => justify || 'space-between'};
    label {
      span:last-child {
        font-style: normal;
        ${defaultText};
      }
    }
  }
`
// #endregion