Commit 931a53e6 authored by Tamlyn Rhodes's avatar Tamlyn Rhodes

feat(component-submit): convert to styled-components

BREAKING CHANGE: requires theme variables to be loaded in the app
Fix sample declaration metadata in styleguide
parent 83949262
Pipeline #4689 passed with stages
in 3 minutes and 28 seconds
......@@ -10,7 +10,6 @@
],
"dependencies": {
"@pubsweet/ui": "^2.0.0",
"classnames": "^2.2.5",
"lodash": "^4.17.4",
"prop-types": "^15.5.10",
"pubsweet-client": "^2.1.0",
......@@ -22,6 +21,7 @@
"redux": "^3.6.0",
"redux-form": "^7.0.3",
"striptags": "^3.1.0",
"styled-components": "^3.1.6",
"xpub-connect": "^0.0.2",
"xpub-edit": "^0.0.2",
"xpub-journal": "^0.0.2",
......@@ -38,10 +38,7 @@
"css-loader": "^0.28.4",
"faker": "^4.1.0",
"file-loader": "^1.1.5",
"node-sass": "^4.5.3",
"react-styleguidist": "^6.2.5",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"webpack-node-externals": "^1.6.0",
"xpub-styleguide": "^0.0.2"
......
import React from 'react'
import styled from 'styled-components'
import { Button, PlainButton } from '@pubsweet/ui'
import classes from './Confirm.local.scss'
import { Heading1 } from '../styles'
const Wrapper = styled.div`
background: var(--color-background);
color: var(--color-text);
line-height: var(--font-line-height);
max-height: 100%;
max-width: 60em;
overflow-y: auto;
padding: calc(var(--grid-unit) * 2);
`
const Paragraph = styled.p`
font-size: var(--font-size-base);
margin-bottom: var(--grid-unit);
width: 55ch;
`
const Divider = styled.span`
margin: 0 calc(var(--grid-unit) / 2);
`
const Confirm = ({ toggleConfirming }) => (
<div className={classes.root}>
<Wrapper>
<article>
<h1 className={classes.heading}>
<Heading1>
By submitting the manuscript, you agree to the following statements.
</h1>
</Heading1>
<p>
<Paragraph>
The corresponding author confirms that all co-authors are included, and
that everyone listed as a co-author agrees to that role and all the
following requirements and acknowledgements.
</p>
</Paragraph>
<p>
<Paragraph>
The submission represents original work and that sources are given
proper attribution. (The journal employs{' '}
<a
......@@ -29,31 +50,31 @@ const Confirm = ({ toggleConfirming }) => (
scholarly content. If in the judgment of a senior editor a submission is
genuinely suspected of plagiarism, it will be returned to the author(s)
with a request for explanation.)
</p>
</Paragraph>
<p>The research was conducted in accordance with ethical principles.</p>
<Paragraph>
The research was conducted in accordance with ethical principles.
</Paragraph>
<p>
<Paragraph>
There is a Data Accessibility Statement, containing information about
the location of open data and materials, in the manuscript.
</p>
</Paragraph>
<p>
<Paragraph>
A conflict of interest statement is present in the manuscript, even if
to state no conflicts of interest.
</p>
<div className={classes.actions}>
<Button primary type="submit">
Submit your manuscript
</Button>
<span className={classes.actionDivider}> or </span>
<PlainButton onClick={toggleConfirming}>
get back to your submission
</PlainButton>
</div>
</Paragraph>
<Button primary type="submit">
Submit your manuscript
</Button>
<Divider> or </Divider>
<PlainButton onClick={toggleConfirming}>
get back to your submission
</PlainButton>
</article>
</div>
</Wrapper>
)
export default Confirm
.root {
background: white;
color: #404040;
line-height: 1.55;
max-height: 100%;
max-width: 60em;
overflow-y: auto;
padding: 4rem;
}
.root p {
font-size: 1em;
margin-bottom: 1.6em;
width: 55ch;
}
.heading {
font-size: 1.3em;
}
.actionDivider {
margin: 0 1em;
}
.cancelLink {
text-decoration: underline;
text-decoration-color: blue;
}
.root button {
margin-top: 2em;
}
.back {
background: white;
margin-top: 0;
padding: 0;
text-transform: none;
}
import React from 'react'
import classnames from 'classnames'
import { css } from 'styled-components'
import { FormSection } from 'redux-form'
import { ValidatedField, RadioGroup } from '@pubsweet/ui'
import { withJournal } from 'xpub-journal'
import { required } from 'xpub-validators'
import classes from './Declarations.local.scss'
import { Section, Legend } from '../styles'
const DeclarationInput = options => input => (
<RadioGroup inline options={options} {...input} />
)
const hoverStyles = css`
background-image: linear-gradient(to right, #666 50%, white 0%);
background-position: 0 90%;
background-repeat: repeat-x;
background-size: 6px 1px;
position: relative;
`
const DeclarationSection = Section.extend`
margin: calc(var(--grid-unit) * 2) 0;
display: flex;
justify-content: space-between;
&:hover {
${props => !props.readonly && hoverStyles};
}
`
const Declarations = ({ journal, readonly }) => (
<FormSection name="declarations">
{journal.declarations.questions.map(question => (
<div
className={classnames(
classes.section,
classes.spread,
!readonly && classes.spreadEnabled,
)}
id={`declarations.${question.id}`}
key={question.id}
>
<div className={classes.legend}>{question.legend}</div>
<DeclarationSection id={`declarations.${question.id}`} key={question.id}>
<Legend>{question.legend}</Legend>
<ValidatedField
component={DeclarationInput(question.options)}
component={props => (
<RadioGroup inline options={question.options} {...props} />
)}
name={question.id}
readonly={readonly}
required
validate={[required]}
/>
</div>
</DeclarationSection>
))}
</FormSection>
)
......
.section {
margin: 4em 0;
}
.spread {
display: flex;
justify-content: space-between;
}
.legend {
font-size: 1em;
font-weight: 600;
}
.spreadEnabled:hover {
background-image: linear-gradient(to right, #666 50%, white 0%);
background-position: 0 90%;
background-repeat: repeat-x;
background-size: 6px 1px;
position: relative;
}
A list of questions that must be answered before submission.
A list of questions that must be answered before submission. The questions are
configured via the journal config on the context.
```js
const { reduxForm } = require('redux-form');
const { reduxForm } = require('redux-form')
const DeclarationsForm = reduxForm({ form: 'declarations' })(Declarations)
const version = {
declarations: {
openData: 'yes'
}
};
const DeclarationsForm = reduxForm({ form: 'declarations' })(Declarations);
<DeclarationsForm
initialValues={version}
onChange={values => console.log(values)}/>
;<DeclarationsForm onChange={values => console.log(values)} />
```
......@@ -11,8 +11,7 @@ import {
minSize,
split,
} from 'xpub-validators'
import classes from './Metadata.local.scss'
import { Section, Legend } from '../styles'
const minSize1 = minSize(1)
const minChars20 = minChars(20)
......@@ -50,7 +49,7 @@ const ArticleSectionInput = journal => input => (
const Metadata = ({ journal, readonly }) => (
<FormSection name="metadata">
<div className={classes.section} id="metadata.title">
<Section id="metadata.title">
<ValidatedField
component={TitleInput}
name="title"
......@@ -58,9 +57,9 @@ const Metadata = ({ journal, readonly }) => (
required
validate={[minChars20, maxChars500]}
/>
</div>
</Section>
<div className={classes.section} id="metadata.abstract">
<Section id="metadata.abstract">
<ValidatedField
component={AbstractInput}
name="abstract"
......@@ -68,10 +67,10 @@ const Metadata = ({ journal, readonly }) => (
required
validate={[minChars100, maxChars5000]}
/>
</div>
</Section>
<div className={classes.section} id="metadata.authors">
<div className={classes.label}>Authors</div>
<Section id="metadata.authors">
<Legend space>Authors</Legend>
<ValidatedField
component={AuthorsInput}
......@@ -82,10 +81,10 @@ const Metadata = ({ journal, readonly }) => (
required
validate={[minSize1]}
/>
</div>
</Section>
<div className={classes.section} id="metadata.keywords">
<div className={classes.label}>Keywords</div>
<Section id="metadata.keywords">
<Legend space>Keywords</Legend>
<ValidatedField
component={KeywordsInput}
......@@ -96,10 +95,10 @@ const Metadata = ({ journal, readonly }) => (
required
validate={[minSize1]}
/>
</div>
</Section>
<div className={classes.section} id="metadata.articleType">
<div className={classes.label}>Type of article</div>
<Section id="metadata.articleType">
<Legend space>Type of article</Legend>
<ValidatedField
component={ArticleTypeInput(journal)}
......@@ -108,10 +107,10 @@ const Metadata = ({ journal, readonly }) => (
required
validate={[required]}
/>
</div>
</Section>
<div className={classes.section} id="metadata.articleSection">
<div className={classes.label}>Section</div>
<Section id="metadata.articleSection">
<Legend space>Section</Legend>
<ValidatedField
component={ArticleSectionInput(journal)}
......@@ -120,7 +119,7 @@ const Metadata = ({ journal, readonly }) => (
required
validate={[required]}
/>
</div>
</Section>
</FormSection>
)
......
.section {
margin: 5em 0;
}
.inline {
display: flex;
}
.label {
font-size: 1em;
font-weight: 600;
// display: block;
margin-bottom: 0.8em;
}
.heading {
color: red;
}
......@@ -3,7 +3,7 @@ import { FormSection } from 'redux-form'
import { NoteEditor } from 'xpub-edit'
import { ValidatedField } from '@pubsweet/ui'
import { required } from 'xpub-validators'
import classes from './Metadata.local.scss'
import { Section } from '../styles'
const FundingInput = input => (
<NoteEditor
......@@ -23,22 +23,22 @@ const InstructionsInput = input => (
const Notes = ({ readonly }) => (
<FormSection name="notes">
<div className={classes.section} id="notes.fundingAcknowledgement">
<Section id="notes.fundingAcknowledgement">
<ValidatedField
component={FundingInput}
name="fundingAcknowledgement"
readonly={readonly}
validate={[required]}
/>
</div>
</Section>
<div className={classes.section} id="notes.specialInstructions">
<Section id="notes.specialInstructions">
<ValidatedField
component={InstructionsInput}
name="specialInstructions"
readonly={readonly}
/>
</div>
</Section>
</FormSection>
)
......
import React from 'react'
import classnames from 'classnames'
import styled from 'styled-components'
import { Link } from 'react-router-dom'
import { Button } from '@pubsweet/ui'
import Metadata from './Metadata'
......@@ -8,8 +8,34 @@ import Suggestions from './Suggestions'
import Notes from './Notes'
import SupplementaryFiles from './SupplementaryFiles'
import Confirm from './Confirm'
import { Heading1 } from '../styles'
// import Validots from './Validots'
import classes from './Submit.local.scss'
const Wrapper = styled.div`
font-family: var(--font-interface);
line-height: 1.3;
margin: auto;
max-width: 60em;
overflow: ${({ confirming }) => confirming && 'hidden'};
`
const Intro = styled.div`
font-style: italic;
line-height: 1.4;
`
const ModalWrapper = styled.div`
align-items: center;
background: rgba(255, 255, 255, 0.95);
bottom: 0;
display: flex;
justify-content: center;
left: 0;
position: fixed;
right: 0;
top: 0;
`
const Submit = ({
project,
......@@ -22,14 +48,10 @@ const Submit = ({
confirming,
toggleConfirming,
}) => (
<div
className={classnames(classes.root, {
[classes.confirming]: confirming,
})}
>
<div className={classes.title}>Submission information</div>
<Wrapper>
<Heading1>Submission information</Heading1>
<div className={classes.intro}>
<Intro>
<div>
We have ingested your manuscript. To access your manuscript in an
editor, please{' '}
......@@ -41,7 +63,7 @@ const Submit = ({
To complete your submission, please answer the following questions.
</div>
<div>The answers will be automatically saved.</div>
</div>
</Intro>
<form onSubmit={handleSubmit}>
<Metadata readonly={readonly} />
......@@ -59,9 +81,9 @@ const Submit = ({
)}
{confirming && (
<div className={classes.confirm}>
<ModalWrapper>
<Confirm toggleConfirming={toggleConfirming} />
</div>
</ModalWrapper>
)}
</form>
......@@ -70,7 +92,7 @@ const Submit = ({
valid={valid}
handleSubmit={handleSubmit}/>
</div> */}
</div>
</Wrapper>
)
export default Submit
.root {
font-family: var(--font-interface);
line-height: 1.3;
margin: auto;
max-width: 60em;
}
.title {
font-size: 2em;
font-weight: bold;
margin-bottom: 0.3em;
}
.intro {
font-style: italic;
line-height: 1.4;
}
a {
color: var(--color-primary);
font-style: italic;
text-decoration: underline;
}
.confirm {
align-items: center;
background: rgba(255, 255, 255, 0.95);
bottom: 0;
display: flex;
justify-content: center;
left: 0;
position: fixed;
right: 0;
top: 0;
}
.confirming {
overflow: hidden;
}
.validots {
position: absolute;
right: 10px;
top: 50px;
}
a:visited {
color: var(--color-primary);
font-style: normal;
}
......@@ -2,7 +2,7 @@ import React from 'react'
import { FormSection } from 'redux-form'
import { TextField, ValidatedField } from '@pubsweet/ui'
import { join, split } from 'xpub-validators'
import classes from './Suggestions.local.scss'
import { Section, Legend } from '../styles'
const joinComma = join(',')
const splitComma = split(',')
......@@ -23,14 +23,19 @@ const OpposedEditorInput = input => (
<TextField placeholder="Add editor names" {...input} />
)
const SubLegend = Legend.extend`
font-weight: normal;
margin-top: var(--grid-unit);
`
const Suggestions = ({ readonly }) => (
<FormSection name="suggestions">
<div className={classes.section} id="suggestions.reviewers">
<Section id="suggestions.reviewers">
<FormSection name="reviewers">
<div className={classes.legend}>Suggested or opposed reviewers</div>
<Legend>Suggested or opposed reviewers</Legend>
<div>
<div className={classes.sublegend}>Suggested reviewers</div>
<SubLegend space>Suggested reviewers</SubLegend>
<ValidatedField
component={SuggestedReviewerInput}
......@@ -42,7 +47,7 @@ const Suggestions = ({ readonly }) => (
</div>
<div>
<div className={classes.sublegend}>Opposed reviewers</div>
<SubLegend space>Opposed reviewers</SubLegend>
<ValidatedField
component={OpposedReviewerInput}
......@@ -53,14 +58,14 @@ const Suggestions = ({ readonly }) => (
/>
</div>
</FormSection>
</div>
</Section>
<div className={classes.section} id="suggestions.editors">
<Section id="suggestions.editors">
<FormSection name="editors">
<div className={classes.legend}>Suggested or opposed editors</div>
<Legend>Suggested or opposed editors</Legend>
<div>
<div className={classes.sublegend}>Suggested editors</div>
<SubLegend space>Suggested editors</SubLegend>
<ValidatedField
component={SuggestedEditorInput}
......@@ -72,7 +77,7 @@ const Suggestions = ({ readonly }) => (
</div>
<div>
<div className={classes.sublegend}>Opposed editors</div>
<SubLegend space>Opposed editors</SubLegend>
<ValidatedField
component={OpposedEditorInput}
......@@ -83,7 +88,7 @@ const Suggestions = ({ readonly }) => (
/>
</div>
</FormSection>
</div>
</Section>
</FormSection>
)
......
.section {
margin-bottom: 3em 3em;
}
.legend {
font-size: 1.1em;
font-weight: 600;
margin-top: 3em;
}
.sublegend {
margin: 2em 0 1em;
}
.root input {
margin-left: 1em;
}
import React from 'react'
import { FormSection } from 'redux-form'
import { Supplementary, ValidatedField } from '@pubsweet/ui'
import classes from './Metadata.local.scss'
import { Section, Legend } from '../styles'
const FileInput = uploadFile => input => (
<Supplementary uploadFile={uploadFile} {...input} />
......@@ -9,17 +9,15 @@ const FileInput = uploadFile => input => (
const SupplementaryFiles = ({ uploadFile, readonly }) => (
<FormSection name="files">
<div className={classes.section} id="files.supplementary">
<div className={classes.label} htmlFor="supplementary">
Upload supplementary materials
</div>
<Section id="files.supplementary">
<Legend htmlFor="supplementary">Upload supplementary materials</Legend>
<ValidatedField
component={FileInput(uploadFile)}
name="supplementary"
readonly={readonly}
/>
</div>
</Section>
</FormSection>
)
......
import React from 'react'
import classnames from 'classnames'
import classes from './Validot.local.scss'
import styled from 'styled-components'
// TODO: use the parent validots node instead of document
// TODO: highlight the scrolled-to element