From 75ba64019560021921fa3f03a957f550a557fc0a Mon Sep 17 00:00:00 2001 From: Alexandru Munteanu <alexandru.munt@gmail.com> Date: Thu, 19 Jul 2018 14:07:12 +0300 Subject: [PATCH] new wizard --- .../src/components/NewStepOne.js | 8 + .../src/components/NewWizard.js | 306 ++++++++++++++++++ .../component-wizard/src/components/index.js | 3 + .../src/components/AuthorList/AuthorList.js | 3 - .../src/components/Dashboard/DashboardCard.js | 4 +- .../src/components/UIComponents/FormItems.js | 39 ++- .../src/components/index.js | 1 + packages/xpub-faraday/app/routes.js | 7 +- 8 files changed, 363 insertions(+), 8 deletions(-) create mode 100644 packages/component-wizard/src/components/NewStepOne.js create mode 100644 packages/component-wizard/src/components/NewWizard.js diff --git a/packages/component-wizard/src/components/NewStepOne.js b/packages/component-wizard/src/components/NewStepOne.js new file mode 100644 index 000000000..26cf57dfb --- /dev/null +++ b/packages/component-wizard/src/components/NewStepOne.js @@ -0,0 +1,8 @@ +import React, { Fragment } from 'react' + +const NewStepOne = () => <Fragment>new step one here</Fragment> + +export default NewStepOne + +// #region styled-components +// #endregion diff --git a/packages/component-wizard/src/components/NewWizard.js b/packages/component-wizard/src/components/NewWizard.js new file mode 100644 index 000000000..eef588df0 --- /dev/null +++ b/packages/component-wizard/src/components/NewWizard.js @@ -0,0 +1,306 @@ +import React, { Fragment } from 'react' +import { connect } from 'react-redux' +import { reduxForm } from 'redux-form' +import { th } from '@pubsweet/ui-toolkit' +import { actions } from 'pubsweet-client' +import { withJournal } from 'xpub-journal' +import { ConnectPage } from 'xpub-connect' +import { required } from 'xpub-validators' +import { DragDropContext } from 'react-dnd' +import { get, debounce, omit } from 'lodash' +import styled, { css } from 'styled-components' +import HTML5Backend from 'react-dnd-html5-backend' +import { selectCollection, selectFragment } from 'xpub-selectors' +import { Icon, Checkbox, ValidatedField, Menu, Button } from '@pubsweet/ui' +import { withStateHandlers, compose, toClass, withProps } from 'recompose' +import { + Steps, + FormItems, + AuthorList, +} from 'pubsweet-components-faraday/src/components' + +import { autosaveRequest } from '../redux/autosave' + +const { + Row, + Label, + Title, + RowItem, + Subtitle, + TextField, + TextAreaField, +} = FormItems + +// #region StepOne +const NewStepOne = () => ( + <Fragment> + <Title>1. Pre-Submission Checklist</Title> + <Subtitle> + Before moving forward make sure you have all the required files prepared + and the items on the list below reviewed. + </Subtitle> + <Row justify="flex-start"> + <Text> + I have the email addresses of all the co-authors of the manuscript. + </Text> + </Row> + <Row justify="flex-start"> + <Text> + I have the manuscript file in Microsoft Word or Adobe PDF format with + the tables and figures integrated in the manuscript body. + </Text> + </Row> + <Row justify="flex-start"> + <Text> + I have the electronic files of any supplementary materials (e.g., + datasest, images, audio, video) that I want to submit with the + manuscript. + </Text> + </Row> + <Row justify="flex-start"> + <Text> + I am aware that accepted manuscripts are subject to{' '} + <a + href="https://www.google.com" + rel="noopener noreferrer" + target="_blank" + > + Article Processing Charges + </a>. + </Text> + </Row> + <Row justify="flex-start"> + <Text> + I am aware that an ORCID ID is required for the corresponding author + before the article can be published (if accepted). The ORCID ID should + be added via your user account. + </Text> + </Row> + <Row justify="flex-start"> + <Text> + I am aware that if my submission is covered by an institutional + membership, Hindawi will share details of the manuscript with the + administrator of the membership. + </Text> + </Row> + <Row justify="flex-start"> + <Text> + I am aware of the Hindawi article processing charges tax of $1000. + </Text> + </Row> + <Row justify="flex-start"> + <ValidatedField + component={input => ( + <Checkbox + checked={input.value} + {...input} + label={`I've reviewed and understood all the above items.`} + /> + )} + name="agree" + validate={[required]} + /> + </Row> + </Fragment> +) +// #endregion + +// #region StepTwo +const NewStepTwo = ({ version, project, manuscriptTypes }) => ( + <Fragment> + <Title>2. Manuscript & Authors Details</Title> + <Subtitle> + Please provide the details of all the authors of this manuscript, in the + order that they appear on the manuscript. Your details are already + prefiled since, in order to submit a manuscript you must be one of the + authors. + </Subtitle> + <Row className="row"> + <RowItem flex={3} vertical withRightMargin> + <Label>MANUSCRIPT TITLE*</Label> + <ValidatedField + component={input => <TextField {...input} />} + name="metadata.title" + validate={[required]} + /> + </RowItem> + <RowItem vertical> + <Label>MANUSCRIPT TYPE*</Label> + <ValidatedField + component={input => <Menu options={manuscriptTypes} {...input} />} + name="metadata.type" + validate={[required]} + /> + </RowItem> + </Row> + <Row className="row"> + <RowItem vertical> + <Label>ABSTRACT*</Label> + <ValidatedField + component={TextAreaField} + name="metadata.abstract" + validate={[required]} + /> + </RowItem> + </Row> + <Row className="row"> + <RowItem vertical> + <Label>AUTHORS DETAILS*</Label> + <AuthorList + parentForm="submission" + project={project} + version={version} + /> + </RowItem> + </Row> + </Fragment> +) +// #endregion + +const NewWizard = ({ + step, + version, + project, + nextStep, + prevStep, + handleSubmit, + journal: { manuscriptTypes = [] }, +}) => ( + <Fragment> + <Steps currentStep={step} margin="0 20px 60px 0"> + <Steps.Step key="step-one" title="Pre-submission Checklist" /> + <Steps.Step key="step-two" title="Manuscript & Author Details" /> + <Steps.Step key="step-three" title="Files Upload" /> + </Steps> + + <StepRoot className="wizard-root"> + <IconButton> + <Icon primary size={4}> + x + </Icon> + </IconButton> + {step === 0 && <NewStepOne />} + {step === 1 && ( + <NewStepTwo + manuscriptTypes={manuscriptTypes} + project={project} + version={version} + /> + )} + <Row centered> + <ButtonContainer> + <Button onClick={prevStep}>{`< BACK`}</Button> + <Button onClick={handleSubmit} primary> + {`NEXT STEP >`} + </Button> + </ButtonContainer> + </Row> + </StepRoot> + </Fragment> +) + +const onChange = (values, dispatch, { project, version }) => { + const newValues = omit(values, ['agree', 'authorForm']) + dispatch(autosaveRequest()) + dispatch( + actions.updateFragment(project, { + ...version, + ...newValues, + }), + ) +} + +// #region export +export default compose( + ConnectPage(({ match }) => [ + actions.getCollection({ id: match.params.project }), + actions.getFragment( + { id: match.params.project }, + { id: match.params.version }, + ), + ]), + withJournal, + connect((state, { match }) => ({ + version: selectFragment(state, get(match, 'params.version')), + project: selectCollection(state, get(match, 'params.project')), + })), + withStateHandlers( + { step: 1 }, + { + nextStep: ({ step }) => () => ({ step: step + 1 }), + prevStep: ({ step }) => () => ({ step: step - 1 }), + }, + ), + withProps(({ version }) => ({ + initialValues: { + metadata: get(version, 'metadata', {}), + }, + })), + reduxForm({ + form: 'submission', + onChange: debounce(onChange, 1000, { maxWait: 5000 }), + onSubmit: (values, dispatch, { step, nextStep }) => { + if (step < 2) { + nextStep() + } + }, + }), + DragDropContext(HTML5Backend), + toClass, +)(NewWizard) +// #endregion + +// #region styled-components +const defaultText = css` + color: ${th('colorPrimary')}; + font-size: ${th('fontSizeBase')}; + font-family: ${th('fontReading')}; +` +const Text = styled.span` + ${defaultText}; +` + +const StepRoot = styled.div` + align-items: flex-start; + background-color: ${th('colorBackground')}; + border: ${th('borderDefault')}; + display: flex; + flex-direction: column; + padding: 30px; + position: relative; +` + +const IconButton = styled.button` + align-items: center; + background-color: ${th('colorBackground')}; + border: none; + color: ${th('colorPrimary')}; + cursor: ${({ hide }) => (hide ? 'auto' : 'pointer')}; + display: flex; + font-family: ${th('fontInterface')}; + font-size: ${th('fontSizeBaseSmall')}; + opacity: ${({ hide }) => (hide ? 0 : 1)}; + text-align: left; + + position: absolute; + top: 10px; + right: 10px; + + &:active, + &:focus { + outline: none; + } + &:hover { + opacity: 0.7; + } +` + +const ButtonContainer = styled.div` + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; + + width: calc(${th('gridUnit')} * 14); +` +// #endregion diff --git a/packages/component-wizard/src/components/index.js b/packages/component-wizard/src/components/index.js index b24d781c5..ac086570d 100644 --- a/packages/component-wizard/src/components/index.js +++ b/packages/component-wizard/src/components/index.js @@ -1 +1,4 @@ export { default as Wizard } from './WizardPage' +export { default as NewWizard } from './NewWizard' + +export { default as NewStepOne } from './NewStepOne' diff --git a/packages/components-faraday/src/components/AuthorList/AuthorList.js b/packages/components-faraday/src/components/AuthorList/AuthorList.js index 2f070954f..84af49a62 100644 --- a/packages/components-faraday/src/components/AuthorList/AuthorList.js +++ b/packages/components-faraday/src/components/AuthorList/AuthorList.js @@ -1,7 +1,6 @@ import React from 'react' import { get, isBoolean, isNumber } from 'lodash' import { th } from '@pubsweet/ui' -import PropTypes from 'prop-types' import { connect } from 'react-redux' import styled from 'styled-components' import { withRouter } from 'react-router-dom' @@ -10,7 +9,6 @@ import { compose, withState, withProps, - getContext, withHandlers, setDisplayName, } from 'recompose' @@ -82,7 +80,6 @@ const Authors = ({ export default compose( withRouter, - getContext({ version: PropTypes.object, project: PropTypes.object }), connect( (state, { project, parentForm = 'wizard' }) => ({ error: getAuthorError(state), diff --git a/packages/components-faraday/src/components/Dashboard/DashboardCard.js b/packages/components-faraday/src/components/Dashboard/DashboardCard.js index b3e877877..8b91784b6 100644 --- a/packages/components-faraday/src/components/Dashboard/DashboardCard.js +++ b/packages/components-faraday/src/components/Dashboard/DashboardCard.js @@ -92,7 +92,9 @@ const DashboardCard = ({ data-test="button-resume-submission" onClick={() => history.push( - `/projects/${project.id}/versions/${version.id}/submit`, + `/new-wizard/projects/${project.id}/versions/${ + version.id + }/submit`, ) } > diff --git a/packages/components-faraday/src/components/UIComponents/FormItems.js b/packages/components-faraday/src/components/UIComponents/FormItems.js index 5f9a14cd9..da5e726be 100644 --- a/packages/components-faraday/src/components/UIComponents/FormItems.js +++ b/packages/components-faraday/src/components/UIComponents/FormItems.js @@ -2,6 +2,13 @@ import React from 'react' import { th } from '@pubsweet/ui' import styled, { css } from 'styled-components' +const borderColor = ({ theme, validationStatus = 'default' }) => + ({ + error: theme.colorError, + success: theme.colorSuccess, + default: theme.colorBorder, + }[validationStatus]) + const defaultText = css` color: ${th('colorText')}; font-family: ${th('fontReading')}; @@ -65,6 +72,7 @@ export const Row = styled.div` justify-content: ${({ justify }) => justify || 'space-evenly'}; margin: ${({ noMargin }) => noMargin ? 0 : css`calc(${th('subGridUnit')} * 2) 0`}; + width: 100%; label + div[role='alert'] { margin-top: 0; @@ -82,6 +90,10 @@ export const RowItem = styled.div` & > div { flex: 1; } + + div[role='alert'] { + margin-top: 0; + } ` export const Label = styled.div` @@ -115,7 +127,7 @@ export const Textarea = styled.textarea` outline: none; transition: all 300ms linear; - width: ${({ width }) => `${width || 500}px`}; + width: ${({ width }) => `${width || '500px'}`}; height: ${({ height }) => `${height || 150}px`}; &:active, @@ -149,13 +161,34 @@ export const PrivatePolicy = styled.div` text-align: justify; ` -export const TextAreaField = input => <Textarea {...input} height={70} /> +export const TextAreaField = input => ( + <Textarea {...input} height={70} width="100%" /> +) export const LabelHeader = styled.div` color: ${th('colorPrimary')}; font-family: ${th('fontHeading')}; font-size: ${th('fontSizeBaseSmall')}; margin: ${th('subGridUnit')} 0; - text-transform: uppercase; font-weight: bold; + text-transform: uppercase; +` + +export const TextField = styled.input` + border: ${th('borderWidth')} ${th('borderStyle')} ${borderColor}; + + border-radius: ${th('borderRadius')}; + + font-family: inherit; + font-size: inherit; + + height: calc(${th('gridUnit')} * 2); + padding: 0 calc(${th('gridUnit')} / 2); + width: 100%; + + &::placeholder { + color: ${th('colorTextPlaceholder')}; + } + + ${th('cssOverrides.TextField.Input')}; ` diff --git a/packages/components-faraday/src/components/index.js b/packages/components-faraday/src/components/index.js index ddc29a62c..bc0fbc83d 100644 --- a/packages/components-faraday/src/components/index.js +++ b/packages/components-faraday/src/components/index.js @@ -2,6 +2,7 @@ import { Decision } from './MakeDecision' import * as Components from './UIComponents' import { Recommendation } from './MakeRecommendation' +export { FormItems } from './UIComponents' export { default as Steps } from './Steps/Steps' export { default as Files } from './Files/Files' export { default as AppBar } from './AppBar/AppBar' diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js index e06874ce6..b6d663162 100644 --- a/packages/xpub-faraday/app/routes.js +++ b/packages/xpub-faraday/app/routes.js @@ -2,7 +2,7 @@ import React from 'react' import { Route, Switch } from 'react-router-dom' import { AuthenticatedComponent } from 'pubsweet-client' -import { Wizard } from 'pubsweet-component-wizard/src/components' +import { Wizard, NewWizard } from 'pubsweet-component-wizard/src/components' import { UserProfilePage, ChangePasswordPage, @@ -121,6 +121,11 @@ const Routes = () => ( <Route component={ErrorPage} exact path="/error-page" /> <Route component={InfoPage} exact path="/info-page" /> + <PrivateRoute + component={NewWizard} + exact + path="/new-wizard/projects/:project/versions/:version/submit" + /> <Route component={NotFound} /> </Switch> </FaradayApp> -- GitLab