diff --git a/packages/component-manuscript/src/components/SubmitRevision.js b/packages/component-manuscript/src/components/SubmitRevision.js index 0baa62663023112b0a07bfd5177593ae420dc40d..3ec785de80cd9af7eb6471637fbec8d2af7d514a 100644 --- a/packages/component-manuscript/src/components/SubmitRevision.js +++ b/packages/component-manuscript/src/components/SubmitRevision.js @@ -1,20 +1,21 @@ import React from 'react' -import { get, omit, debounce } from 'lodash' import PropTypes from 'prop-types' import { connect } from 'react-redux' import { th } from '@pubsweet/ui-toolkit' import { actions } from 'pubsweet-client' +import { required } from 'xpub-validators' import { DragDropContext } from 'react-dnd' +import { get, omit, debounce } from 'lodash' +import styled, { css } from 'styled-components' +import HTML5Backend from 'react-dnd-html5-backend' +import { ValidatedField, Button } from '@pubsweet/ui' +import { AbstractEditor, TitleEditor } from 'xpub-edit' import { - Field, reduxForm, + getFormSyncErrors, getFormValues, change as changeForm, } from 'redux-form' -import styled, { css } from 'styled-components' -import HTML5Backend from 'react-dnd-html5-backend' -import { ValidatedField, Button } from '@pubsweet/ui' -import { AbstractEditor, TitleEditor } from 'xpub-edit' import { AuthorList, Files } from 'pubsweet-components-faraday/src/components' import { submitRevision } from 'pubsweet-component-wizard/src/redux/conversion' import AutosaveIndicator from 'pubsweet-component-wizard/src/components/AutosaveIndicator' @@ -37,11 +38,27 @@ import { import { Expandable } from '../molecules/' +const parseEmptyHtml = value => { + if (value && value.replace('<p></p>', '').replace('<h1></h1>', '')) { + return undefined + } + return 'Required' +} + +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 +} + const TextAreaField = input => <Textarea {...input} height={70} rows={6} /> const SubmitRevision = ({ addFile, project, version, + formError, removeFile, handleSubmit, responseFiles, @@ -53,27 +70,35 @@ const SubmitRevision = ({ <ValidatedField component={input => <TitleEditor {...input} />} name="metadata.title" + validate={[parseEmptyHtml]} /> <Title>ABSTRACT*</Title> <ValidatedField component={input => <AbstractEditor {...input} />} name="metadata.abstract" + validate={[parseEmptyHtml]} /> <Title>AUTHORS DETAILS*</Title> - <Field - component={() => ( - <AuthorList authorPath="revision.authors" parentForm="revision" /> - )} - name="authors" - /> + <CustomValidatedField> + <ValidatedField + component={() => ( + <AuthorList authorPath="revision.authors" parentForm="revision" /> + )} + name="authors" + validate={[required]} + /> + </CustomValidatedField> </Expandable> <Expandable label="FILES"> - <Field - component={() => ( - <Files filePath="revision.files" parentForm="revision" /> - )} - name="files" - /> + <CustomValidatedField> + <ValidatedField + component={() => ( + <Files filePath="revision.files" parentForm="revision" /> + )} + name="files" + validate={[requiredFiles]} + /> + </CustomValidatedField> </Expandable> <Expandable label="RESPONSE TO REVIEWER COMMENTS" startExpanded> <Title>Reply text*</Title> @@ -82,6 +107,7 @@ const SubmitRevision = ({ <ValidatedField component={TextAreaField} name="commentsToReviewers" + validate={[required]} /> </FullWidth> </Row> @@ -104,6 +130,7 @@ const SubmitRevision = ({ </FilePicker> </Expandable> <SubmitContainer> + {formError && <Error>There are some errors above.</Error>} <AutosaveIndicator formName="revision" /> <Button onClick={handleSubmit} primary> SUBMIT REVISION @@ -138,6 +165,7 @@ export default compose( state => ({ fileFetching: getRequestStatus(state), formValues: getFormValues('revision')(state), + formError: getFormSyncErrors('revision')(state), }), { changeForm, @@ -207,6 +235,20 @@ const defaultText = css` font-size: ${th('fontSizeBaseSmall')}; ` +const Error = styled.span` + color: ${th('colorError')}; + font-size: ${th('fontSizeBaseSmall')}; + margin-right: ${th('subGridUnit')}; +` + +const CustomValidatedField = styled.div` + div { + div:last-child { + margin-top: 0; + } + } +` + const Textarea = styled.textarea` border-color: ${({ hasError }) => hasError ? th('colorError') : th('colorPrimary')}; @@ -264,7 +306,7 @@ const SubmitContainer = styled.div` align-items: center; display: flex; flex-direction: row; - justify-content: flex-end; + justify-content: space-between; margin-top: calc(${th('subGridUnit')} * 2); ` // #endregion