diff --git a/packages/component-wizard/README.md b/packages/component-wizard/README.md index 4dad06438dc664791f1fa8d9f6c2f9042d2e4b2f..eb859bbd33ef85a468f3edff2562d906de3377a0 100644 --- a/packages/component-wizard/README.md +++ b/packages/component-wizard/README.md @@ -15,7 +15,7 @@ Configuration file must be under config `journal` (make use of `withJournal`) an | backText | Text to show on Back button - Go back 1 step | false | 'Back' | `string` | | nextText | Text to show on Back button - Go forward 1 step | false | 'Next' | `string` | | cancelText | Text to show on Cancel button - Go to `/` | false | 'Back' | `string` | -| submissionRedirect | Path to redirect user after submitting the form | false | `/` | `string` | +| submissionRedirect | Path to redirect user after submitting the form. Passes as state `project` as project.id and `version` as version.id | false | `/` | `string` | | confirmationModal | If present, component will be rendered as a modal before submitting the form. Accepts `toggleConfirming` to close the modal and must have 2 buttons for submit and close modal (see below) | false | none | `React Component` | | formSectionKeys | Redux form data model. Keys to be saved on the form. | true | [] | `array` | | dispatchFunctions | Functions to be dispatched in case a component needs a dispatched function (f.i. `uploadFile`) | true | none | `array` | diff --git a/packages/component-wizard/src/components/AutosaveIndicator.js b/packages/component-wizard/src/components/AutosaveIndicator.js index 2a134b9baa2d3d5b3a1646e7a18b2ad490e840ff..0521de13d86368684bd8f92fea983a7573523ce6 100644 --- a/packages/component-wizard/src/components/AutosaveIndicator.js +++ b/packages/component-wizard/src/components/AutosaveIndicator.js @@ -1,47 +1,66 @@ import React from 'react' import moment from 'moment' +import { connect } from 'react-redux' import classnames from 'classnames' import { compose, withProps } from 'recompose' import { Icon } from '@pubsweet/ui' +import { getAutosave } from '../redux/autosave' + import classes from './AutosaveIndicator.local.scss' const durationParser = lastUpdate => { const today = moment() const last = moment(lastUpdate) const duration = moment.duration(today.diff(last)) - return `Last saved: ${duration.humanize()} ago.` + return `Progress saved ${duration.humanize()} ago.` } -const Indicator = ({ isVisibile, isFetching, error, lastUpdate }) => +const Indicator = ({ + isVisibile, + autosave: { isFetching, error, lastUpdate }, +}) => isVisibile ? ( <div className={classnames(classes.container)}> {isFetching && ( <div className={classnames(classes['icon-container'])}> <div className={classnames(classes.rotate, classes.icon)}> - <Icon size={16}>refresh-cw</Icon> + <Icon size={16}>loader</Icon> </div> <span>Saving changes...</span> </div> )} - {!isFetching && lastUpdate && <span>{durationParser(lastUpdate)}</span>} + {!isFetching && + lastUpdate && ( + <div className={classnames(classes['icon-container'])}> + <div className={classnames(classes.icon)}> + <Icon size={16}>check-circle</Icon> + </div> + <span>{durationParser(lastUpdate)}</span> + </div> + )} {!isFetching && error && ( <div className={classnames(classes['icon-container'])}> <div className={classnames(classes.icon)}> <Icon color="red" size={16}> - slash + alert-triangle </Icon> </div> - <span className={classnames(classes['error-text'])}>{error}</span> + <span className={classnames(classes['error-text'])} title={error}> + Changes not saved + </span> </div> )} </div> ) : null export default compose( - withProps(({ isFetching, lastUpdate, error }) => ({ + connect(state => ({ + autosave: getAutosave(state), + })), + withProps(({ autosave: { isFetching, error, lastUpdate } }) => ({ isVisibile: Boolean(isFetching || lastUpdate || error), })), )(Indicator) diff --git a/packages/component-wizard/src/components/AutosaveIndicator.local.scss b/packages/component-wizard/src/components/AutosaveIndicator.local.scss index 0b88db1af267bd05d439b592e801d45f9eb7e668..5392f64ad863d4691dbfadbccd3ca401003e8cea 100644 --- a/packages/component-wizard/src/components/AutosaveIndicator.local.scss +++ b/packages/component-wizard/src/components/AutosaveIndicator.local.scss @@ -2,7 +2,6 @@ align-items: center; display: flex; justify-content: flex-end; - margin-bottom: 5px; } @keyframes rotating { @@ -52,12 +51,16 @@ align-items: center; display: flex; justify-content: center; - margin: 0 10px 0 0; + margin: 0 5px 0 0; + } + + span { + font-size: 12px; } } .error-text { color: red; - font-size: 14px; + font-size: 12px; font-weight: 400; } diff --git a/packages/component-wizard/src/components/WizardFormStep.js b/packages/component-wizard/src/components/WizardFormStep.js index 0c372e59226c832a10fb21e0e9051431d4d834cd..b73c90c7f32df09b261eb4bbae8794452eff19e5 100644 --- a/packages/component-wizard/src/components/WizardFormStep.js +++ b/packages/component-wizard/src/components/WizardFormStep.js @@ -6,13 +6,7 @@ import { compose, getContext, withProps } from 'recompose' import { reduxForm, formValueSelector, SubmissionError } from 'redux-form' import WizardStep from './WizardStep' - -import { - getAutosave, - autosaveRequest, - autosaveFailure, - autosaveSuccess, -} from '../redux/autosave' +import { autosaveRequest } from '../redux/autosave' const wizardSelector = formValueSelector('wizard') @@ -34,8 +28,6 @@ const onChange = ( ...newValues, }), ) - .then(({ receivedAt }) => dispatch(autosaveSuccess(receivedAt))) - .catch(() => dispatch(autosaveFailure())) } } @@ -65,7 +57,7 @@ const submitManuscript = ( ), ) .then(() => { - history.push(redirectPath) + history.push(redirectPath, { project: project.id, version: version.id }) }) .catch(error => { if (error.validationErrors) { @@ -124,7 +116,6 @@ export default compose( })), connect((state, { wizard: { formSectionKeys } }) => ({ formValues: wizardSelector(state, ...formSectionKeys), - autosave: getAutosave(state), })), reduxForm({ form: 'wizard', diff --git a/packages/component-wizard/src/components/WizardStep.js b/packages/component-wizard/src/components/WizardStep.js index 4df47c8bb20229c5515f7bb317d25ca9e050c51d..ff5bdc3b9f3ba264388d94a8e9ca4f0054f84017 100644 --- a/packages/component-wizard/src/components/WizardStep.js +++ b/packages/component-wizard/src/components/WizardStep.js @@ -20,7 +20,6 @@ export default ({ formValues, wizard, dispatchFns, - autosave, confirmation, toggleConfirmation, wizard: { confirmationModal: ConfirmationModal }, @@ -84,6 +83,6 @@ export default ({ </div> )} </form> - <AutosaveIndicator {...autosave} /> + <AutosaveIndicator /> </div> ) diff --git a/packages/component-wizard/src/redux/autosave.js b/packages/component-wizard/src/redux/autosave.js index 76f0507654722c8ac2bff395511fec6d3d239190..a9a8bb816c086884dd7031aeb99dcd6a041e8392 100644 --- a/packages/component-wizard/src/redux/autosave.js +++ b/packages/component-wizard/src/redux/autosave.js @@ -34,14 +34,16 @@ export default (state = initialState, action) => { isFetching: true, } case AUTOSAVE_FAILURE: + case 'UPDATE_FRAGMENT_FAILURE': return { ...initialState, error: action.error, } case AUTOSAVE_SUCCESS: + case 'UPDATE_FRAGMENT_SUCCESS': return { ...initialState, - lastUpdate: action.lastUpdate, + lastUpdate: action.receivedAt, } default: return state diff --git a/packages/components-faraday/src/components/UIComponents/ConfirmationPage.js b/packages/components-faraday/src/components/UIComponents/ConfirmationPage.js new file mode 100644 index 0000000000000000000000000000000000000000..35cd479808558baf671252d8fa3227658c906add --- /dev/null +++ b/packages/components-faraday/src/components/UIComponents/ConfirmationPage.js @@ -0,0 +1,63 @@ +import React from 'react' +import classnames from 'classnames' +import { compose } from 'recompose' +import { connect } from 'react-redux' +import { Button } from '@pubsweet/ui' +import { get, isEmpty } from 'lodash' +import { withJournal } from 'xpub-journal' +import { getFragmentAuthors } from 'pubsweet-components-faraday/src/redux/authors' + +import classes from './UIComponents.local.scss' + +const ConfirmationPage = ({ + journal, + authors = [], + location: { state }, + history, +}) => { + const email = get(authors.find(a => a.isCorresponding), 'email') + return ( + <div className={classnames(classes.container)}> + {isEmpty(state) ? ( + <h2>Thank you for you submission</h2> + ) : ( + <div> + <h2>Thank You for Submitting Your Manuscript</h2> + <p> + Your manuscript has been successfully submitted to{' '} + <b>{journal.metadata.nameText}</b> and assigned the manuscript ID{' '} + <b> + {' '} + <a + href={`/projects/${state.project}/versions/${ + state.version + }/manuscript`} + > + {state.project} + </a> + </b>. + </p> + <p> + An acknowledgement email will be sent to {email} when our system has + finished processing the submission. At that point, you will be able + to track the status of your submission. Please note, this may take a + few minutes. + </p> + <p> + {`You can keep track of your submission's progress on your dashboard.`} + </p> + <Button onClick={() => history.push('/')} primary> + Go to Dashboard + </Button> + </div> + )} + </div> + ) +} + +export default compose( + withJournal, + connect((state, { location: { state: locationState } }) => ({ + authors: getFragmentAuthors(state, get(locationState, 'version')), + })), +)(ConfirmationPage) diff --git a/packages/components-faraday/src/components/UIComponents/NotFound.js b/packages/components-faraday/src/components/UIComponents/NotFound.js new file mode 100644 index 0000000000000000000000000000000000000000..f0c04c2e25457aeac3160e029e81d6b83e6b48de --- /dev/null +++ b/packages/components-faraday/src/components/UIComponents/NotFound.js @@ -0,0 +1,23 @@ +import React from 'react' +import { Icon } from '@pubsweet/ui' +import classnames from 'classnames' + +import classes from './UIComponents.local.scss' + +const NotFound = ({ history }) => ( + <div className={classnames(classes.container)}> + <div> + <Icon size={32}>cloud-off</Icon> + </div> + <h2>The page cannot be found</h2> + <h3> + The page you are looking for might have been removed, had its name + changed, or is temporarily unavailable. + </h3> + <a href="#" onClick={history.goBack}> + Back + </a> + </div> +) + +export default NotFound diff --git a/packages/components-faraday/src/components/UIComponents/UIComponents.local.scss b/packages/components-faraday/src/components/UIComponents/UIComponents.local.scss new file mode 100644 index 0000000000000000000000000000000000000000..10255c4b467b541296f7332916e9f95fe0733440 --- /dev/null +++ b/packages/components-faraday/src/components/UIComponents/UIComponents.local.scss @@ -0,0 +1,9 @@ +.container { + margin: 0 auto; + text-align: center; + width: 70vw; + + a { + color: black; + } +} diff --git a/packages/xpub-faraday-server/package.json b/packages/xpub-faraday-server/package.json index ee016b7c364ab25ea0d6ddda538016ddc2a7d811..be17dc271762b45ad8a60361ca7487a252a17fb7 100644 --- a/packages/xpub-faraday-server/package.json +++ b/packages/xpub-faraday-server/package.json @@ -17,7 +17,8 @@ "body-parser": "^1.17.2", "config": "^1.26.1", "moment": "^2.18.1", - "nodemailer": "^4.0.1" + "nodemailer": "^4.0.1", + "uuid": "^3.2.1" }, "peerDependencies": { "@pubsweet/logger": "^0.0.1", diff --git a/packages/xpub-faraday-server/src/AuthorBackend.js b/packages/xpub-faraday-server/src/AuthorBackend.js index e71de40326aa0371cc64ce690a142c77f568e6e1..f17cc851d5783d453c70dc653d1503b016c9cc84 100644 --- a/packages/xpub-faraday-server/src/AuthorBackend.js +++ b/packages/xpub-faraday-server/src/AuthorBackend.js @@ -1,4 +1,5 @@ const bodyParser = require('body-parser') +const uuid = require('uuid') const AuthorBackend = app => { const authBearer = app.locals.passport.authenticate('bearer', { @@ -39,7 +40,32 @@ const AuthorBackend = app => { return } } + req.body.id = uuid.v4() fragment.authors.push(req.body) + const reqUser = await app.locals.models.User.find(req.user) + if (reqUser.admin === true && req.body.isSubmitting === true) { + try { + // check if author has corresponding user + const user = await app.locals.models.User.findByEmail( + req.body.email, + ) + fragment.owners.push(user.id) + } catch (e) { + if (e.name === 'NotFoundError') { + // create a new User account + const userBody = { + username: `${req.body.firstName}${ + req.body.lastName + }${Math.floor(Math.random() * 1000)}`, + email: req.body.email, + password: uuid.v4(), + } + let newUser = new app.locals.models.User(userBody) + newUser = await newUser.save() + fragment.owners.push(newUser.id) + } + } + } fragment = await fragment.save() res.status(200).json(fragment) } catch (e) { diff --git a/packages/xpub-faraday-server/src/AuthorBackend.test.js b/packages/xpub-faraday-server/src/AuthorBackend.test.js index e01f686aa5b2a4312afe8c89c83dab86e5883f3f..c5e73107ac12cd4918a24b6aedd0eb726a1c9e0d 100644 --- a/packages/xpub-faraday-server/src/AuthorBackend.test.js +++ b/packages/xpub-faraday-server/src/AuthorBackend.test.js @@ -8,37 +8,67 @@ const express = require('express') const fixtures = require('./fixtures/fixtures') const passport = require('passport') const BearerStrategy = require('passport-http-bearer').Strategy +const cloneDeep = require('lodash/cloneDeep') -function makeApp(response) { +function makeApp(fragment, standardUser, existingUser) { const app = express() app.use(bodyParser.json()) - // Passport strategies + app.use(passport.initialize()) passport.use( 'bearer', new BearerStrategy((token, done) => - done(null, fixtures.user, { scope: 'all' }), + done(null, fixtures.users.standardUser, { scope: 'all' }), ), ) app.locals.passport = passport - app.locals.models = { Fragment: { find: jest.fn( () => - response instanceof Error - ? Promise.reject(response) - : Promise.resolve(response), + fragment instanceof Error + ? Promise.reject(fragment) + : Promise.resolve(fragment), ), }, + User: {}, + } + function UserMock(properties) { + this.type = 'user' + this.email = properties.email + this.username = properties.username + this.password = properties.password } + UserMock.find = jest.fn( + () => + standardUser instanceof Error + ? Promise.reject(standardUser) + : Promise.resolve(standardUser), + ) + UserMock.findByEmail = jest.fn( + () => + existingUser instanceof Error + ? Promise.reject(existingUser) + : Promise.resolve(existingUser), + ) + + UserMock.prototype.save = jest.fn(() => { + this.id = '111222' + return Promise.resolve(this) + }) + + app.locals.models.User = UserMock + component.backend()(app) return supertest(app) } describe('Author Backend API', () => { + let testFixtures = {} + beforeEach(() => (testFixtures = cloneDeep(fixtures))) + it('should return an error if fragment is not found', () => { const error = new Error() error.name = 'NotFoundError' @@ -46,7 +76,7 @@ describe('Author Backend API', () => { return makeApp(error) .post('/api/fragments/123/authors') .set('Authorization', 'Bearer 123') - .send(fixtures.author) + .send(testFixtures.authors.standardAuthor) .expect(404, '{"error":"Fragment not found"}') }) @@ -59,29 +89,74 @@ describe('Author Backend API', () => { return makeApp(error) .post('/api/fragments/123/authors') .set('Authorization', 'Bearer 123') - .send(fixtures.invalidAuthor) + .send(testFixtures.authors.invalidAuthor) .expect(404, '{"error":"firstName is required"}') }) it('should return an error if an author already exists with the same email', () => - makeApp(fixtures.fragment) + makeApp(testFixtures.fragments.standardFragment) .post('/api/fragments/123-valid-id/authors') .set('Authorization', 'Bearer 123') - .send(fixtures.author) + .send(testFixtures.authors.standardAuthor) .expect(400, '{"error":"Author with the same email already exists"}')) it('should return an error if there already is a submitting author', () => - makeApp(fixtures.fragment) + makeApp(testFixtures.fragments.standardFragment) .post('/api/fragments/123-valid-id/authors') .set('Authorization', 'Bearer 123') - .send(fixtures.newSubmittingAuthor) + .send(testFixtures.authors.newSubmittingAuthor) .expect(400, '{"error":"There can only be one sumbitting author"}')) - it('should return success', () => - makeApp(fixtures.fragment) + it('should return success when saving a new author', () => + makeApp( + testFixtures.fragments.standardFragment, + testFixtures.users.standardUser, + ) + .post('/api/fragments/123-valid-id/authors') + .set('Authorization', 'Bearer 123') + .send(testFixtures.authors.newAuthor) + .expect(200, '') + .then(() => + expect(testFixtures.fragments.standardFragment.save).toHaveBeenCalled(), + )) + + it('should return success when the admin adds a submitting author and the author already has a corresponding user account', () => + makeApp( + testFixtures.fragments.adminFragment, + testFixtures.users.admin, + testFixtures.users.existingUser, + ) .post('/api/fragments/123-valid-id/authors') .set('Authorization', 'Bearer 123') - .send(fixtures.newAuthor) + .send(testFixtures.authors.standardAuthor) .expect(200, '') - .then(() => expect(fixtures.fragment.save).toHaveBeenCalled())) + .then(() => { + expect(testFixtures.fragments.adminFragment.save).toHaveBeenCalled() + expect( + testFixtures.fragments.adminFragment.owners.length, + ).toBeGreaterThan(0) + expect(testFixtures.fragments.adminFragment.owners[0]).toBe('123987') + })) + + it('should return success when the admin adds a submitting author and creates a corresponding user account', () => { + const error = new Error() + error.name = 'NotFoundError' + error.status = 404 + return makeApp( + testFixtures.fragments.adminFragment, + testFixtures.users.admin, + error, + ) + .post('/api/fragments/123-valid-id/authors') + .set('Authorization', 'Bearer 123') + .send(testFixtures.authors.standardAuthor) + .expect(200, '') + .then(() => { + expect(testFixtures.fragments.adminFragment.save).toHaveBeenCalled() + expect( + testFixtures.fragments.adminFragment.owners.length, + ).toBeGreaterThan(0) + expect(testFixtures.fragments.adminFragment.owners[0]).toBe('111222') + }) + }) }) diff --git a/packages/xpub-faraday-server/src/fixtures/authors.js b/packages/xpub-faraday-server/src/fixtures/authors.js new file mode 100644 index 0000000000000000000000000000000000000000..16f8d33738f14ad14e18079c86ebe60318d29f4f --- /dev/null +++ b/packages/xpub-faraday-server/src/fixtures/authors.js @@ -0,0 +1,48 @@ +const authors = { + standardAuthor: { + firstName: 'Andrew', + middleName: '', + lastName: 'Smith', + email: 'email@email.com', + affiliation: 'University', + country: '', + isCorresponding: false, + isSubmitting: true, + id: '123', + }, + newAuthor: { + firstName: 'Robert', + middleName: '', + lastName: 'Smith', + email: 'email_robert@email.com', + affiliation: 'University', + country: '', + isCorresponding: true, + isSubmitting: false, + id: '456', + }, + invalidAuthor: { + firstName: '', + middleName: '', + lastName: 'Jones', + email: 'email2@email.com', + affiliation: 'University', + country: '', + isCorresponding: false, + isSubmitting: false, + id: '768', + }, + newSubmittingAuthor: { + firstName: 'Andrew', + middleName: '', + lastName: 'Smith', + email: 'email3@email.com', + affiliation: 'University', + country: '', + isCorresponding: false, + isSubmitting: true, + id: '879', + }, +} + +module.exports = authors diff --git a/packages/xpub-faraday-server/src/fixtures/fixtures.js b/packages/xpub-faraday-server/src/fixtures/fixtures.js index f570e534a22f13729c04e89d8fcc35846989c8ea..2d96a7abd59a92428a0b7c8e5fb517d0e536f58d 100644 --- a/packages/xpub-faraday-server/src/fixtures/fixtures.js +++ b/packages/xpub-faraday-server/src/fixtures/fixtures.js @@ -1,69 +1,9 @@ -const author = { - firstName: 'Andrew', - middleName: '', - lastName: 'Smith', - email: 'email@email.com', - affiliation: 'University', - country: '', - isCorresponding: false, - isSubmitting: true, -} - -const newAuthor = { - firstName: 'Robert', - middleName: '', - lastName: 'Smith', - email: 'email_robert@email.com', - affiliation: 'University', - country: '', - isCorresponding: true, - isSubmitting: false, -} - -const invalidAuthor = { - firstName: '', - middleName: '', - lastName: 'Jones', - email: 'email2@email.com', - affiliation: 'University', - country: '', - isCorresponding: false, - isSubmitting: false, -} - -const newSubmittingAuthor = { - firstName: 'Andrew', - middleName: '', - lastName: 'Smith', - email: 'email3@email.com', - affiliation: 'University', - country: '', - isCorresponding: false, - isSubmitting: true, -} - -const fragment = { - type: 'fragment', - fragmentType: 'blogpost', - title: 'Just your regular blogpost', - source: '<blog></blog>', - presentation: '<p></p>', - authors: [author], - save: jest.fn(), -} - -const user = { - type: 'user', - username: 'testuser', - email: 'test@example.com', - password: 'test', -} +const authors = require('./authors') +const fragments = require('./fragments') +const users = require('./users') module.exports = { - author, - invalidAuthor, - fragment, - newSubmittingAuthor, - newAuthor, - user, + authors, + users, + fragments, } diff --git a/packages/xpub-faraday-server/src/fixtures/fragments.js b/packages/xpub-faraday-server/src/fixtures/fragments.js new file mode 100644 index 0000000000000000000000000000000000000000..7bf3f31de4a4326bb5c0f11560c44045b0869419 --- /dev/null +++ b/packages/xpub-faraday-server/src/fixtures/fragments.js @@ -0,0 +1,26 @@ +const authors = require('./authors') + +const fragments = { + standardFragment: { + type: 'fragment', + fragmentType: 'blogpost', + title: 'Just your regular blogpost', + source: '<blog></blog>', + presentation: '<p></p>', + authors: [authors.standardAuthor], + save: jest.fn(), + }, + + adminFragment: { + type: 'fragment', + fragmentType: 'blogpost', + title: 'Just your admin blogpost', + source: '<blog></blog>', + presentation: '<p></p>', + authors: [], + save: jest.fn(), + owners: [], + }, +} + +module.exports = fragments diff --git a/packages/xpub-faraday-server/src/fixtures/users.js b/packages/xpub-faraday-server/src/fixtures/users.js new file mode 100644 index 0000000000000000000000000000000000000000..25e63b0790dc2a648775df008b6ec5c98421f811 --- /dev/null +++ b/packages/xpub-faraday-server/src/fixtures/users.js @@ -0,0 +1,24 @@ +const users = { + standardUser: { + type: 'user', + username: 'testuser', + email: 'test@example.com', + password: 'test', + }, + admin: { + type: 'user', + username: 'admin', + email: 'admin@example.com', + password: 'test', + admin: true, + }, + existingUser: { + type: 'user', + username: 'authoruser', + email: 'email@email.com', + password: 'test', + id: '123987', + }, +} + +module.exports = users diff --git a/packages/xpub-faraday/app/config/journal/metadata.js b/packages/xpub-faraday/app/config/journal/metadata.js index 06375b6dc8f4488d5c5323c8bc382305426ce4c3..f099501bf61de0aa128bbd2094665c4dfd1defb2 100644 --- a/packages/xpub-faraday/app/config/journal/metadata.js +++ b/packages/xpub-faraday/app/config/journal/metadata.js @@ -5,4 +5,5 @@ export default { issn: '2474-7394', name: <Logo srcUrl="/assets/hindawi-logo.png" />, logo: '/assets/hindawi-logo.png', + nameText: 'Faraday Journal', } diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js index 0679a1da98fc652db1f106c288c3ef8a15466ea6..36a635a46bcf18cea3dfc0711a2150609808eeaf 100644 --- a/packages/xpub-faraday/app/routes.js +++ b/packages/xpub-faraday/app/routes.js @@ -1,5 +1,5 @@ import React from 'react' -import { Route } from 'react-router-dom' +import { Route, Switch } from 'react-router-dom' import App from 'pubsweet-component-xpub-app/src/components' @@ -12,25 +12,34 @@ import { import DashboardPage from 'pubsweet-component-xpub-dashboard/src/components/DashboardPage' import WizardPage from 'pubsweet-component-wizard/src/components/WizardPage' - -const ConfirmationPage = () => <h1>Confirmation page</h1> +import ManuscriptPage from 'pubsweet-component-xpub-manuscript/src/components/ManuscriptPage' +import ConfirmationPage from 'pubsweet-components-faraday/src/components/UIComponents/ConfirmationPage' +import NotFound from 'pubsweet-components-faraday/src/components/UIComponents/NotFound' const Routes = () => ( <App> - <Route component={LoginPage} exact path="/login" /> - <Route component={SignupPage} exact path="/signup" /> - <PrivateRoute component={DashboardPage} exact path="/" /> - <PrivateRoute - component={ConfirmationPage} - exact - path="/confirmation-page" - /> - <PrivateRoute component={LogoutPage} exact path="/logout" /> - <PrivateRoute - component={WizardPage} - exact - path="/projects/:project/versions/:version/submit" - /> + <Switch> + <Route component={LoginPage} exact path="/login" /> + <Route component={SignupPage} exact path="/signup" /> + <PrivateRoute component={DashboardPage} exact path="/" /> + <PrivateRoute + component={ConfirmationPage} + exact + path="/confirmation-page" + /> + <PrivateRoute component={LogoutPage} exact path="/logout" /> + <PrivateRoute + component={WizardPage} + exact + path="/projects/:project/versions/:version/submit" + /> + <PrivateRoute + component={ManuscriptPage} + exact + path="/projects/:project/versions/:version/manuscript" + /> + <Route component={NotFound} /> + </Switch> </App> ) diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js index 8e82f6e4606256b1c0f2e0d3f60a28879f972057..198a4d45fdf8a28279b7cdd9e5f5e0d0acaee3fd 100644 --- a/packages/xpub-faraday/config/validations.js +++ b/packages/xpub-faraday/config/validations.js @@ -74,6 +74,7 @@ module.exports = { country: Joi.string().allow(''), isSubmitting: Joi.boolean(), isCorresponding: Joi.boolean(), + id: Joi.string().uuid(), }), ), }, diff --git a/yarn.lock b/yarn.lock index 2d4c3805cd1346afc94e5b73d9e673975ce6cf71..653131550f0125810372583c353dda187e41f606 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10997,6 +10997,10 @@ uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +uuid@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"