diff --git a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptDetailsTop.js b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptDetailsTop.js index a847465a6426d5026e3e90f26918cc30430789fd..372759582c9de528b0560d89e94d432dceda44d9 100644 --- a/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptDetailsTop.js +++ b/packages/component-faraday-ui/src/manuscriptDetails/ManuscriptDetailsTop.js @@ -91,17 +91,18 @@ export default compose( }, ) }, - goToTechnicalCheck: ({ history }) => collection => () => { + goToTechnicalCheck: ({ history, fragment }) => collection => () => { const { - status, id, + status, customId, technicalChecks: { token = '' }, } = collection const stage = status === 'technicalChecks' ? 'eqs' : 'eqa' + const title = get(fragment, 'metadata.title', '') history.push({ pathname: `/${stage}-decision`, - search: `?collectionId=${id}&customId=${customId}&token=${token}`, + search: `?collectionId=${id}&customId=${customId}&token=${token}&title=${title}`, }) }, }), diff --git a/packages/component-faraday-ui/src/modals/MultiAction.js b/packages/component-faraday-ui/src/modals/MultiAction.js index 72ab3e4653341077a912bcc8fed367c182280fbb..696e7935e917e77e61a25d87608e5cbed2fcd762 100644 --- a/packages/component-faraday-ui/src/modals/MultiAction.js +++ b/packages/component-faraday-ui/src/modals/MultiAction.js @@ -55,12 +55,12 @@ export default compose( } props.hideModal() }, - renderContent: ({ content }) => () => { + renderContent: ({ content, ...props }) => () => { if (!content) return null if (typeof content === 'object') { return content } else if (typeof content === 'function') { - return content() + return content(props) } return <Text dangerouslySetInnerHTML={{ __html: content }} mb={1} /> }, diff --git a/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js b/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js index 165361b6ff2853f62f96dbb9082870a66ed87781..398fdf74f3bd2940588bdef847ee0118839da57c 100644 --- a/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js +++ b/packages/components-faraday/src/components/UIComponents/EQSDecisionPage.js @@ -1,9 +1,9 @@ import React from 'react' import { isEmpty } from 'lodash' import { connect } from 'react-redux' -import { Button } from '@pubsweet/ui' -import styled from 'styled-components' -import { th } from '@pubsweet/ui-toolkit' +import { reduxForm } from 'redux-form' +import { required } from 'xpub-validators' +import { Button, H2, TextField, ValidatedField } from '@pubsweet/ui' import { compose, withState, @@ -11,56 +11,113 @@ import { withHandlers, setDisplayName, } from 'recompose' - import { - withModal, - ConfirmationModal, -} from 'pubsweet-component-modal/src/components' + Row, + Text, + Item, + Label, + OpenModal, + ShadowedBox, +} from 'pubsweet-component-faraday-ui' -import { Err, Subtitle } from './FormItems' -import { parseSearchParams } from '../utils' +import { + digitValidator, + parseSearchParams, + manuscriptIdSizeValidator, +} from '../utils' import { technicalDecision, technicalCheckFetching, } from '../../redux/technicalCheck' +const sizeValidator = manuscriptIdSizeValidator(7) + +const Enhanched = () => ( + <Row> + <Item vertical> + <Label required>Manuscript ID</Label> + <ValidatedField + component={TextField} + name="manuscriptId" + validate={[required, digitValidator, sizeValidator]} + /> + </Item> + </Row> +) + +const FormModal = reduxForm({ + form: 'eqs', + onSubmit: (values, dispatch, { acceptManuscript }) => { + acceptManuscript(values) + }, +})(({ isFetching, handleSubmit }) => ( + <OpenModal + content={Enhanched} + isFetching={isFetching} + modalKey="acceptManuscript" + onConfirm={() => handleSubmit()} + title="Accept Manuscript" + > + {showModal => ( + <Button onClick={showModal} primary> + ACCEPT + </Button> + )} + </OpenModal> +)) + const EQSDecisionPage = ({ params, + isFetching, eqsDecision, errorMessage, successMessage, }) => ( - <Root> - <Title> - Take a decision for manuscript <b>{params.customId}</b>. - </Title> - {errorMessage && <Err>{errorMessage}</Err>} - {successMessage && <Subtitle>{successMessage}</Subtitle>} + <ShadowedBox center mt={5}> + <H2>Editorial decision</H2> + <Row mt={2}> + <Text secondary> + Please take a decision for the manuscript titled <b>{params.title}</b>. + </Text> + </Row> + {successMessage && ( + <Row mt={1}> + <Text>{successMessage}</Text> + </Row> + )} + {errorMessage && ( + <Row mt={1}> + <Text error>{errorMessage}</Text> + </Row> + )} {isEmpty(errorMessage) && isEmpty(successMessage) && ( - <ButtonContainer> - <Button onClick={eqsDecision(false)}>REJECT</Button> - <Button onClick={eqsDecision(true)} primary> - ACCEPT - </Button> - </ButtonContainer> + <Row justify="space-around" mt={2}> + <OpenModal + isFetching={isFetching} + modalKey="denyManuscript" + onConfirm={() => {}} + subtitle="Are you sure you want to reject this manuscript?" + title="Reject manuscript" + > + {showModal => <Button onClick={showModal}>REJECT</Button>} + </OpenModal> + <FormModal acceptManuscript={v => {}} isFetching={isFetching} /> + </Row> )} - </Root> + </ShadowedBox> ) export default compose( setDisplayName('EQS Decision page'), connect( - state => ({ + (state, { params }) => ({ isFetching: technicalCheckFetching(state), }), { technicalDecision }, ), - withModal(({ isFetching }) => ({ - isFetching, - modalComponent: ConfirmationModal, - })), withState('params', 'setParams', { + title: '', token: null, customId: null, collectionId: null, @@ -70,10 +127,10 @@ export default compose( lifecycle({ componentDidMount() { const { location, setParams } = this.props - const { customId, collectionId, token } = parseSearchParams( + const { customId, collectionId, token, title } = parseSearchParams( location.search, ) - setParams({ customId, collectionId, token }) + setParams({ customId, collectionId, token, title }) }, }), withHandlers({ @@ -116,33 +173,4 @@ export default compose( )(EQSDecisionPage) // #region styles -const Root = styled.div` - align-items: center; - color: ${th('colorText')}; - display: flex; - flex-direction: column; - justify-content: flex-start; - margin: 0 auto; - text-align: center; - width: 70vw; - - a { - color: ${th('colorText')}; - } -` - -const Title = styled.div` - color: ${th('colorPrimary')}; - font-size: ${th('fontSizeHeading5')}; - font-family: ${th('fontHeading')}; - margin: 10px auto; -` - -const ButtonContainer = styled.div` - align-items: center; - display: flex; - justify-content: space-around; - padding: calc(${th('gridUnit')} / 2); - width: calc(${th('gridUnit')} * 15); -` // #endregion diff --git a/packages/components-faraday/src/components/utils.js b/packages/components-faraday/src/components/utils.js index a31e1eaa6bf6f1b2333552e580a1843243fbadc8..f769c7db68b64ca7a3f8e201a1492cf5803e3b73 100644 --- a/packages/components-faraday/src/components/utils.js +++ b/packages/components-faraday/src/components/utils.js @@ -72,6 +72,7 @@ export const handleFormError = error => { } } +// #region Validators const emailRegex = new RegExp( /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, //eslint-disable-line ) @@ -79,6 +80,14 @@ const emailRegex = new RegExp( export const emailValidator = value => emailRegex.test(value) ? undefined : 'Invalid email' +const digitRegex = new RegExp(/^[0-9]*$/) +export const digitValidator = value => + digitRegex.test(value) ? undefined : 'Only digits are allowed.' + +export const manuscriptIdSizeValidator = size => value => + value.length !== size ? `The ID must be ${size} digits long.` : undefined +// #endregion + export const redirectToError = redirectFn => err => { const errorText = get(JSON.parse(err.response), 'error') redirectFn('/error-page', errorText || 'Oops! Something went wrong.')