diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 98e8ef6e541e894353f219b3f249bfcdaf957757..38e63ece935111f7c77f35bebd2ebc3469244151 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,9 +17,10 @@ build: stage: build script: - docker version + - docker build -t $IMAGE_ORG/$IMAGE_NAME:$CI_COMMIT_SHA . + - if [ -z "$DOCKERHUB_USERNAME" ] || [ -z "$DOCKERHUB_PASSWORD" ]; then echo "Not pushing" && exit 0; fi - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD - echo "Ignore warning! Cannot perform an interactive login from a non TTY device" - - docker build -t $IMAGE_ORG/$IMAGE_NAME:$CI_COMMIT_SHA . - docker push $IMAGE_ORG/$IMAGE_NAME:$CI_COMMIT_SHA lint: @@ -40,6 +41,18 @@ test: - cd ${HOME} - npm run test +push:latest: + image: docker:latest + stage: staging + script: + - if [ -z "$DOCKERHUB_USERNAME" ] || [ -z "$DOCKERHUB_PASSWORD" ]; then echo "Not pushing" && exit 0; fi + - docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD + - echo "Ignore warning! Cannot perform an interactive login from a non TTY device" + - docker build -t $IMAGE_ORG/$IMAGE_NAME:latest --label COMMIT_SHA=$CI_COMMIT_SHA . + - docker push $IMAGE_ORG/$IMAGE_NAME:latest + only: + - master + # ----------------------------------------------- # xpub-collabra --------------------------------- # ----------------------------------------------- @@ -50,10 +63,11 @@ review:xpub-collabra: variables: PACKAGE_NAME: xpub-collabra FORCE_FRESH_DB: "yes" + REQUIRES_PROVISIONING: "yes" environment: name: $PACKAGE_NAME/review/$CI_COMMIT_REF_NAME # !! kube-lego will fail if domain > 64 chars - url: "https://${CI_ENVIRONMENT_SLUG}.${BASE_DOMAIN}" + url: "http://${CI_ENVIRONMENT_SLUG}.${BASE_DOMAIN}" on_stop: stop_review:xpub-collabra except: - master @@ -66,6 +80,7 @@ stop_review:xpub-collabra: stage: review variables: PACKAGE_NAME: xpub-collabra + REQUIRES_PROVISIONING: "yes" GIT_STRATEGY: none environment: name: $PACKAGE_NAME/review/$CI_COMMIT_REF_NAME @@ -76,7 +91,7 @@ stop_review:xpub-collabra: script: - source deploy.sh - delete_deployment - + - delete_objects_in_environment pvc staging:xpub-collabra: image: pubsweet/deployer:latest @@ -131,8 +146,8 @@ demo:xpub-collabra: # PACKAGE_NAME: xpub-ui # environment: # name: $PACKAGE_NAME/review/$CI_COMMIT_REF_NAME -# # !! kube-lego will fail if domain > 64 chars -# url: "https://${CI_ENVIRONMENT_SLUG}.${BASE_DOMAIN}" +# # !! kube-lego will fail if domain > 63 chars +# url: "http://${CI_ENVIRONMENT_SLUG}.${BASE_DOMAIN}" # on_stop: stop_review:xpub-ui # except: # - master diff --git a/README.md b/README.md index abe79d39f62c196676dc0ae9e0d320f3f54be493..a99626638452059daec1f4a4ed1f161cf4fda033 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ You can follow more fine-grained lists of things that we're working on ### PubSweet components * `component-app`: a PubSweet component that provides an app container with nav bar and journal provider. -* `component-authentication`: a PubSweet component that provides authentication-related client pages. * `component-dashboard`: a PubSweet component that provides a Dashboard page. * `component-manuscript`: a PubSweet component that provides a Manuscript page. * `component-review`: a PubSweet component that provides a Review page. diff --git a/package.json b/package.json index 085498ae12288afd01e9a02933c028267c2623a4..3079488b9c8e79a98648ee3b8ff63c566d39db2b 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "lerna": "^2.5.1", "lint-staged": "^4.1.3", "prettier": "^1.8.2", + "react-router-redux": "^5.0.0-alpha.9", "stylelint": "^8.2.0", "stylelint-config-pubsweet": "^0.0.3" }, diff --git a/packages/component-app/package.json b/packages/component-app/package.json index 3307ac7ce63e18a4f85d26b47689b9a4a78aca29..176ed10ac605764322a5e71798245e0d90286b5a 100644 --- a/packages/component-app/package.json +++ b/packages/component-app/package.json @@ -19,7 +19,7 @@ "redux": "^3.6.0", "xpub-bootstrap": "^0.0.2", "xpub-journal": "^0.0.2", - "@pubsweet/ui": "^0.1.1" + "@pubsweet/ui": "^0.2.0" }, "peerDependencies": { "prop-types": "^15.5.10", diff --git a/packages/component-app/src/components/App.js b/packages/component-app/src/components/App.js index a40e281afff7d593e6b271605c1281454b8ad567..be2dd011c9c044a6f39a280c2a8c714478d4ad39 100644 --- a/packages/component-app/src/components/App.js +++ b/packages/component-app/src/components/App.js @@ -6,17 +6,16 @@ import { connect } from 'react-redux' import { AppBar } from '@pubsweet/ui' import { withJournal } from 'xpub-journal' import 'xpub-bootstrap' +import actions from 'pubsweet-client/src/actions' import classes from './App.local.scss' -const App = ({ children, currentUser, journal }) => ( +const App = ({ children, currentUser, journal, logoutUser }) => ( <div className={classes.root}> <AppBar - brandLink="/" - brandName={journal.metadata.name} - loginLink="/login" - logoutLink="/logout" - userName={currentUser ? currentUser.username : null} + brand={journal.metadata.name} + onLogoutClick={logoutUser} + user={currentUser} /> <div className={classes.main}>{children}</div> @@ -24,8 +23,11 @@ const App = ({ children, currentUser, journal }) => ( ) export default compose( - connect(state => ({ - currentUser: state.currentUser.user, - })), + connect( + state => ({ + currentUser: state.currentUser.user, + }), + { logoutUser: actions.logoutUser }, + ), withJournal, )(App) diff --git a/packages/component-authentication/README.md b/packages/component-authentication/README.md deleted file mode 100644 index 779ea8cce0b65d325f62b47818c6450a36602eee..0000000000000000000000000000000000000000 --- a/packages/component-authentication/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## pubsweet-component-authentication - -A module containing all the PubSweet components needed for authentication. This module uses UI elements from `pubsweet-ui` and brings in the currentUser reducer from `pubsweet-client` so that all the authentication-related redux code is in the same place. A `PrivateRoute` component is used to ensure that the current user is authenticated and loaded before a page is rendered. - -*Note: -This should be merged with the default authentication components provided by pubsweet.* diff --git a/packages/component-authentication/package.json b/packages/component-authentication/package.json deleted file mode 100644 index b62bb98b25953bc1c8e08c19deaec1515cd5760a..0000000000000000000000000000000000000000 --- a/packages/component-authentication/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "pubsweet-component-xpub-authentication", - "version": "0.0.2", - "main": "src", - "author": "Collaborative Knowledge Foundation", - "license": "MIT", - "files": [ - "src", - "dist" - ], - "dependencies": { - "classnames": "^2.2.5", - "lodash": "^4.17.4", - "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", - "react": "^15.6.1", - "react-dom": "^15.6.1", - "react-redux": "^5.0.2", - "react-router-dom": "^4.2.2", - "recompose": "^0.26.0", - "redux": "^3.6.0", - "redux-form": "^7.0.3", - "@pubsweet/ui": "^0.1.1" - }, - "devDependencies": { - "babel-core": "^6.26.0", - "babel-loader": "^7.1.2", - "babel-preset-env": "^1.6.0", - "babel-preset-react": "^6.24.1", - "babel-preset-stage-2": "^6.24.1", - "css-loader": "^0.28.4", - "faker": "^4.1.0", - "file-loader": "^1.1.5", - "node-sass": "^4.5.3", - "react-styleguidist": "^6.0.8", - "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" - }, - "peerDependencies": { - "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", - "react": "^15.6.1", - "react-dom": "^15.6.1", - "react-redux": "^5.0.2", - "react-router-dom": "^4.2.2" - }, - "scripts": { - "styleguide": "styleguidist server", - "styleguide:build": "styleguidist build" - } -} diff --git a/packages/component-authentication/src/components/Form.local.scss b/packages/component-authentication/src/components/Form.local.scss deleted file mode 100644 index 8332e321e5586ddfd10128cb71f2ab0378c69df8..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/Form.local.scss +++ /dev/null @@ -1,86 +0,0 @@ -.root { - font-family: "Fira Sans Condensed", sans-serif; - margin: 0 auto; - width: 30ch; -} - -.title { - font-size: 2em; - margin-bottom: 1.2em; - text-align: left; -} - -.root input { - border: 0 none; - border-bottom: 1px dashed #aaa; - display: block; - font-family: "Fira Sans", sans-serif; - padding: 0; - width: 100%; - - // &:hover, - // &:focus { - // border-bottom: 1px dashed var(--color-primary); - // border-color: transparent; - // box-shadow: none; - // outline-style: none; - // } -} - -.form { - font-size: 0.8em; - margin-top: 1em; - - label { - cursor: text; - display: block; - font-style: italic; - text-transform: lowercase; - - &:hover { - color: var(--color-primary); - } - - input { - font-size: 1.3em; - line-height: 1; - margin-bottom: 3em; - margin-top: 0.6em; - } - } -} - -.root input:hover, -.root input:focus { - border-bottom: 1px dashed var(--color-primary); - border-color: transparent; - box-shadow: none; - outline-style: none; -} - -.button { - display: block; - margin-top: 1em; - padding: 0.4em 2em; -} - -.alternate { - color: #777; - font-size: 0.8em; - margin-top: 1.6em; - text-align: left; - - .message { - margin-right: 1ch; - } - - .link { - border-bottom: 1px solid currentcolor; - color: var(--color-primary); - cursor: pointer; - } -} - -.error { - color: red; -} diff --git a/packages/component-authentication/src/components/Login.js b/packages/component-authentication/src/components/Login.js deleted file mode 100644 index 289d5f7642646b605867500b08f78c61309abf4a..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/Login.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react' -import { Field } from 'redux-form' -import { Link } from 'react-router-dom' -import { Button, TextField } from '@pubsweet/ui' -import classes from './Form.local.scss' - -const UsernameInput = props => <TextField label="Username" {...props.input} /> -const PasswordInput = props => ( - <TextField label="Password" {...props.input} type="password" /> -) - -const Login = ({ errorMessage, handleSubmit }) => ( - <div className={classes.root}> - <div className={classes.title}>Login</div> - - {errorMessage && <div className={classes.error}>{errorMessage}</div>} - - <form className={classes.form} onSubmit={handleSubmit}> - <Field component={UsernameInput} name="username" /> - <Field component={PasswordInput} name="password" /> - <Button className={classes.button} primary type="submit"> - Login - </Button> - </form> - - <div className={classes.alternate}> - <span className={classes.message}>You don't have an account?</span> - <Link className={classes.link} to="/signup"> - Sign up - </Link> - </div> - </div> -) - -export default Login diff --git a/packages/component-authentication/src/components/Login.md b/packages/component-authentication/src/components/Login.md deleted file mode 100644 index a6e46436111060ee42936ea346a7fa806468c838..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/Login.md +++ /dev/null @@ -1,23 +0,0 @@ -A login form. - -```js -const { reduxForm } = require('redux-form'); - -const LoginForm = reduxForm({ form: 'login' })(Login); - -<LoginForm - onSubmit={values => console.log(values)}/> -``` - -An error is displayed at the top of the form. - -```js -const { reduxForm } = require('redux-form'); - -const LoginForm = reduxForm({ form: 'login-error' })(Login); - -<LoginForm - errorMessage="There was an error" - onSubmit={values => console.log(values)}/> -``` - diff --git a/packages/component-authentication/src/components/LoginPage.js b/packages/component-authentication/src/components/LoginPage.js deleted file mode 100644 index 21ec2c0767493c0079f790574037fad84e96de3c..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/LoginPage.js +++ /dev/null @@ -1,31 +0,0 @@ -import { reduxForm, SubmissionError } from 'redux-form' -import { compose } from 'recompose' -import { connect } from 'react-redux' -import { login } from '../redux/login' -import Login from './Login' -import redirectPath from '../redirect' - -const onSubmit = (values, dispatch, { history, location }) => { - dispatch(login(values)) - .then(() => { - history.push(redirectPath({ location })) - }) - .catch(error => { - if (error.validationErrors) { - throw new SubmissionError(error.validationErrors) - } else { - console.error(error) - // TODO: display error - } - }) -} - -export default compose( - reduxForm({ - form: 'login', - onSubmit, - }), - connect(state => ({ - error: state.login.error, - })), -)(Login) diff --git a/packages/component-authentication/src/components/LogoutPage.js b/packages/component-authentication/src/components/LogoutPage.js deleted file mode 100644 index cc3378af337233a55d76c48dcb9c973170d88765..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/LogoutPage.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react' -import { compose } from 'recompose' -import { connect } from 'react-redux' -import { Redirect } from 'react-router-dom' -import { logout } from '../redux/logout' - -class Logout extends React.Component { - componentDidMount() { - const { isAuthenticated, logout } = this.props - - if (isAuthenticated) { - logout() - } - } - - componentWillReceiveProps(nextProps) { - const { isAuthenticated, logout } = nextProps - - if (isAuthenticated) { - logout() - } - } - - render() { - const { isAuthenticated } = this.props - - return isAuthenticated ? <div>Signing out…</div> : <Redirect to="/" /> - } -} - -export default compose( - connect( - state => ({ - isAuthenticated: state.currentUser.isAuthenticated, - }), - { - logout, - }, - ), -)(Logout) diff --git a/packages/component-authentication/src/components/PrivateRoute.js b/packages/component-authentication/src/components/PrivateRoute.js deleted file mode 100644 index 7ef65bd770709795a55d0c704e691ef50280d266..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/PrivateRoute.js +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react' -import { compose } from 'recompose' -import { connect } from 'react-redux' -import { Route, Redirect, withRouter } from 'react-router-dom' -import { getCurrentUser } from '../redux/currentUser' - -const PrivateRoute = ({ - currentUser, - getCurrentUser, - component: Component, - ...rest -}) => ( - <Route - {...rest} - render={props => { - if (!currentUser.isFetched) { - if (!currentUser.isFetching) { - getCurrentUser() - } - - return <div>loading…</div> - } - - if (!currentUser.isAuthenticated) { - return ( - <Redirect - to={{ - pathname: '/login', - state: { from: props.location }, - }} - /> - ) - } - - return <Component {...props} /> - }} - /> -) - -export default compose( - withRouter, - connect( - state => ({ - currentUser: state.currentUser, - }), - { - getCurrentUser, - }, - ), -)(PrivateRoute) diff --git a/packages/component-authentication/src/components/Signup.js b/packages/component-authentication/src/components/Signup.js deleted file mode 100644 index e7497177509b9b81c9cbd324a6092f16a18f2e10..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/Signup.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react' -import { Field } from 'redux-form' -import { Link } from 'react-router-dom' -import { Button, TextField } from '@pubsweet/ui' -import classes from './Form.local.scss' - -const UsernameInput = props => <TextField label="Username" {...props.input} /> -const EmailInput = props => ( - <TextField label="Email" {...props.input} type="email" /> -) -const PasswordInput = props => ( - <TextField label="Password" {...props.input} type="password" /> -) - -const Signup = ({ errorMessage, handleSubmit }) => ( - <div className={classes.root}> - <div className={classes.title}>Sign up</div> - - {errorMessage && <div className={classes.error}>{errorMessage}</div>} - - <form className={classes.form} onSubmit={handleSubmit}> - <Field component={UsernameInput} name="username" /> - <Field component={EmailInput} name="email" /> - <Field component={PasswordInput} name="password" /> - <Button className={classes.button} primary type="submit"> - Sign up - </Button> - </form> - - <div className={classes.alternate}> - <span className={classes.message}>Already have an account?</span> - <Link className={classes.link} to="/login"> - Login - </Link> - </div> - </div> -) - -export default Signup diff --git a/packages/component-authentication/src/components/Signup.md b/packages/component-authentication/src/components/Signup.md deleted file mode 100644 index ca2e125e5f1e91e663b61d1c138422ecc4e1a91b..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/Signup.md +++ /dev/null @@ -1,24 +0,0 @@ -A signup form. - -```js -const { reduxForm } = require('redux-form'); - -const SignupForm = reduxForm({ form: 'signup' })(Signup); - -<SignupForm - onSubmit={values => console.log(values)}/> -``` - -An error is displayed at the top of the form. - -```js - -const { reduxForm } = require('redux-form'); - -const SignupForm = reduxForm({ form: 'signup-error' })(Signup); - -<SignupForm - errorMessage="There was an error" - onSubmit={values => console.log(values)}/> -``` - diff --git a/packages/component-authentication/src/components/SignupPage.js b/packages/component-authentication/src/components/SignupPage.js deleted file mode 100644 index 74443dcb6a4d04ee32f69eb8696cfb79cc3ff77a..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/SignupPage.js +++ /dev/null @@ -1,31 +0,0 @@ -import { connect } from 'react-redux' -import { compose } from 'recompose' -import { reduxForm, SubmissionError } from 'redux-form' -import { signup } from '../redux/signup' -import Signup from './Signup' -import redirectPath from '../redirect' - -const onSubmit = (values, dispatch, { history, location }) => { - dispatch(signup(values)) - .then(() => { - history.push(redirectPath({ location })) - }) - .catch(error => { - if (error.validationErrors) { - throw new SubmissionError(error.validationErrors) - } else { - console.error(error) - // TODO: display error - } - }) -} - -export default compose( - reduxForm({ - form: 'signup', - onSubmit, - }), - connect(state => ({ - error: state.signup.error, - })), -)(Signup) diff --git a/packages/component-authentication/src/components/index.js b/packages/component-authentication/src/components/index.js deleted file mode 100644 index 09e29ab7e68f3f486663c7aea776432680211d4c..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/components/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export { default as PrivateRoute } from './PrivateRoute' -export { default as LoginPage } from './LoginPage' -export { default as LogoutPage } from './LogoutPage' -export { default as SignupPage } from './SignupPage' diff --git a/packages/component-authentication/src/index.js b/packages/component-authentication/src/index.js deleted file mode 100644 index 44c18796cbf37e9b2319ab74efbbcdcff5a1a5a8..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/index.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - frontend: { - components: [() => require('./components')], - reducers: { - currentUser: () => require('./redux/currentUser').default, - login: () => require('./redux/login').default, - signup: () => require('./redux/signup').default, - }, - }, -} diff --git a/packages/component-authentication/src/redirect.js b/packages/component-authentication/src/redirect.js deleted file mode 100644 index fad202d048b96a1692c4c069044c7022c1b20164..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/redirect.js +++ /dev/null @@ -1,10 +0,0 @@ -import { get } from 'lodash' -import config from 'config' - -const allowedRedirect = pathname => - ['/logout', '/login', '/signup'].indexOf(pathname) === -1 - -export default ({ location: { state } }) => - state && state.from && allowedRedirect(state.from.pathname) - ? state.from.pathname - : get(config, ['pubsweet-client', 'login-redirect'], '/') diff --git a/packages/component-authentication/src/redux/currentUser.js b/packages/component-authentication/src/redux/currentUser.js deleted file mode 100644 index 93b4c12a858104bcd8a7db7fce1774f277902cab..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/redux/currentUser.js +++ /dev/null @@ -1,90 +0,0 @@ -import * as api from 'pubsweet-client/src/helpers/api' - -import { LOGOUT_SUCCESS } from './logout' - -/* constants */ - -export const GET_CURRENT_USER_REQUEST = 'GET_CURRENT_USER_REQUEST' -export const GET_CURRENT_USER_SUCCESS = 'GET_CURRENT_USER_SUCCESS' -export const GET_CURRENT_USER_FAILURE = 'GET_CURRENT_USER_FAILURE' - -/* actions */ - -export const getCurrentUserRequest = () => ({ - type: GET_CURRENT_USER_REQUEST, -}) - -export const getCurrentUserSuccess = user => ({ - type: GET_CURRENT_USER_SUCCESS, - user, -}) - -export const getCurrentUserFailure = error => ({ - error, - type: GET_CURRENT_USER_FAILURE, -}) - -export const getCurrentUser = () => dispatch => { - dispatch(getCurrentUserRequest()) - return api.get('/users/authenticate').then( - user => dispatch(getCurrentUserSuccess(user)), - error => { - dispatch(getCurrentUserFailure(error)) - throw error - }, - ) -} - -/* reducer */ - -const initialState = { - error: null, - isAuthenticated: false, - isFetched: false, - isFetching: false, - user: null, -} - -export default (state = initialState, action) => { - switch (action.type) { - case GET_CURRENT_USER_REQUEST: - return { - error: null, - isAuthenticated: false, - isFetched: false, - isFetching: true, - user: null, - } - - case GET_CURRENT_USER_FAILURE: - return { - error: action.error, - isAuthenticated: false, - isFetched: true, - isFetching: false, - user: null, - } - - case GET_CURRENT_USER_SUCCESS: - return { - error: null, - isAuthenticated: true, - isFetched: true, - isFetching: false, - user: action.user, - } - - // clear the current user on logout - case LOGOUT_SUCCESS: - return { - error: null, - isAuthenticated: false, - isFetched: false, - isFetching: false, - user: null, - } - - default: - return state - } -} diff --git a/packages/component-authentication/src/redux/index.js b/packages/component-authentication/src/redux/index.js deleted file mode 100644 index 4434d36dfce249f7b9e605285cbe3322a8107f1e..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/redux/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export * as currentUser from './currentUser' -export * as login from './login' -export * as signup from './signup' diff --git a/packages/component-authentication/src/redux/login.js b/packages/component-authentication/src/redux/login.js deleted file mode 100644 index 706cb02549612e2b681d90706e927acc1416a3b5..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/redux/login.js +++ /dev/null @@ -1,73 +0,0 @@ -import * as api from 'pubsweet-client/src/helpers/api' -import { getCurrentUser } from './currentUser' - -// TODO: This will break when rendered on a server -const localStorage = window.localStorage || undefined - -/* constants */ - -export const LOGIN_REQUEST = 'LOGIN_REQUEST' -export const LOGIN_SUCCESS = 'LOGIN_SUCCESS' -export const LOGIN_FAILURE = 'LOGIN_FAILURE' - -/* actions */ - -export const loginRequest = credentials => ({ - type: LOGIN_REQUEST, -}) - -export const loginSuccess = user => ({ - type: LOGIN_SUCCESS, -}) - -export const loginFailure = error => ({ - error, - type: LOGIN_FAILURE, -}) - -export const login = credentials => dispatch => { - dispatch(loginRequest()) - return api.create('/users/authenticate', credentials).then( - user => { - localStorage.setItem('token', user.token) - dispatch(loginSuccess()) - return dispatch(getCurrentUser()) - }, - error => { - dispatch(loginFailure(error)) - throw error - }, - ) -} - -/* reducer */ - -const initialState = { - error: null, - isFetching: false, -} - -export default (state = initialState, action) => { - switch (action.type) { - case LOGIN_REQUEST: - return { - error: null, - isFetching: true, - } - - case LOGIN_SUCCESS: - return { - error: null, - isFetching: false, - } - - case LOGIN_FAILURE: - return { - error: action.error, - isFetching: false, - } - - default: - return state - } -} diff --git a/packages/component-authentication/src/redux/logout.js b/packages/component-authentication/src/redux/logout.js deleted file mode 100644 index 63871ebb2a48ad1080d2dfee9f3b15772dc6e60e..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/redux/logout.js +++ /dev/null @@ -1,14 +0,0 @@ -/* constants */ - -export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS' - -/* actions */ - -export const logoutSuccess = () => ({ - type: LOGOUT_SUCCESS, -}) - -export const logout = () => dispatch => { - localStorage.removeItem('token') - return dispatch(logoutSuccess()) -} diff --git a/packages/component-authentication/src/redux/signup.js b/packages/component-authentication/src/redux/signup.js deleted file mode 100644 index daa23590f8d875ad7355547dc629f4ba1be515b9..0000000000000000000000000000000000000000 --- a/packages/component-authentication/src/redux/signup.js +++ /dev/null @@ -1,70 +0,0 @@ -import * as api from 'pubsweet-client/src/helpers/api' -import { login } from './login' - -/* constants */ - -export const SIGNUP_REQUEST = 'SIGNUP_REQUEST' -export const SIGNUP_SUCCESS = 'SIGNUP_SUCCESS' -export const SIGNUP_FAILURE = 'SIGNUP_FAILURE' - -/* actions */ - -export const signupRequest = () => ({ - type: SIGNUP_REQUEST, -}) - -export const signupSuccess = user => ({ - type: SIGNUP_SUCCESS, - user, -}) - -export const signupFailure = error => ({ - error, - type: SIGNUP_FAILURE, -}) - -export const signup = credentials => dispatch => { - dispatch(signupRequest()) - return api.create('/users', credentials).then( - user => { - dispatch(signupSuccess(user)) - dispatch(login(credentials)) - }, - error => { - dispatch(signupFailure(error)) - throw error - }, - ) -} - -/* reducer */ - -const initialState = { - error: null, - isFetching: false, -} - -export default (state = initialState, action) => { - switch (action.type) { - case SIGNUP_REQUEST: - return { - error: null, - isFetching: true, - } - - case SIGNUP_SUCCESS: - return { - error: null, - isFetching: false, - } - - case SIGNUP_FAILURE: - return { - error: action.error, - isFetching: false, - } - - default: - return state - } -} diff --git a/packages/component-authentication/styleguide.config.js b/packages/component-authentication/styleguide.config.js deleted file mode 100644 index 2c8697088f1d9f28b22dcae5474b05479c6aa9dd..0000000000000000000000000000000000000000 --- a/packages/component-authentication/styleguide.config.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - title: 'xpub authentication style guide', - styleguideComponents: { - StyleGuideRenderer: require.resolve( - 'xpub-styleguide/src/components/StyleGuideRenderer', - ), - Wrapper: require.resolve('xpub-styleguide/src/components/Wrapper'), - }, - skipComponentsWithoutExample: true, - serverPort: 6061, - theme: { - fontFamily: { - base: '"Fira Sans", sans-serif', - }, - color: { - link: 'cornflowerblue', - }, - }, -} diff --git a/packages/component-authentication/webpack.config.js b/packages/component-authentication/webpack.config.js deleted file mode 100644 index 4aa149ad2cbf750326137fc79ccd7e7685271ad3..0000000000000000000000000000000000000000 --- a/packages/component-authentication/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const webpackConfig = require('xpub-styleguide/src/webpack-config') - -module.exports = webpackConfig(__dirname) diff --git a/packages/component-dashboard/package.json b/packages/component-dashboard/package.json index 4cc09c79703d7e84d7b7bdd49d9c1bd038b98145..fa0ce59c28e4dae0595712578dfd4609c72f8cb2 100644 --- a/packages/component-dashboard/package.json +++ b/packages/component-dashboard/package.json @@ -12,7 +12,7 @@ "classnames": "^2.2.5", "lodash": "^4.17.4", "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "pubsweet-component-ink-frontend": "^0.2.3", "react": "^15.6.1", "react-dom": "^15.6.1", @@ -25,7 +25,7 @@ "xpub-connect": "^0.0.2", "xpub-journal": "^0.0.2", "xpub-selectors": "^0.0.2", - "@pubsweet/ui": "^0.1.1", + "@pubsweet/ui": "^0.2.0", "xpub-upload": "^0.0.2" }, "devDependencies": { diff --git a/packages/component-dashboard/src/components/Dashboard.js b/packages/component-dashboard/src/components/Dashboard.js index 81cdee5e05d8ae10bcaf92172dfd7dcce83fd965..5a155027ce69538af01ff6bbcea2a0a080fa8421 100644 --- a/packages/component-dashboard/src/components/Dashboard.js +++ b/packages/component-dashboard/src/components/Dashboard.js @@ -43,7 +43,7 @@ const Dashboard = ({ {dashboard.owner.map(project => ( <OwnerItemWithVersion deleteProject={() => - // eslint-disable-next-line + // eslint-disable-next-line no-alert window.confirm( 'Are you sure you want to delete this submission?', ) && deleteProject(project) diff --git a/packages/component-dashboard/src/components/Dashboard.local.scss b/packages/component-dashboard/src/components/Dashboard.local.scss index 2612ee6232a5fcf5c0aac0f2b60d2c0de3c991d4..5b9d944a864a1b4f5b4337bf5b2449a85914c791 100644 --- a/packages/component-dashboard/src/components/Dashboard.local.scss +++ b/packages/component-dashboard/src/components/Dashboard.local.scss @@ -16,7 +16,8 @@ color: var(--color-primary); font-family: Vollkorn, serif; font-size: 1.6em; - margin: 4em 0 2em; + // margin: 4em 0 2em; + margin: 1em 0 1em; text-transform: uppercase; } @@ -26,7 +27,7 @@ } .section:not(:last-of-type) { - margin-bottom: 20px; + margin-bottom: 70px; } a { diff --git a/packages/component-dashboard/src/components/DashboardPage.js b/packages/component-dashboard/src/components/DashboardPage.js index e8efaac3c80fbda1ddd7a9bd0a646e89b57f4505..d2e4f0b7b2149c3731d18d05b38ca90b4f742e5d 100644 --- a/packages/component-dashboard/src/components/DashboardPage.js +++ b/packages/component-dashboard/src/components/DashboardPage.js @@ -29,40 +29,46 @@ export default compose( connect( state => { const { collections } = state - const { conversion, teams } = state + // const { conversion, teams } = state + const { conversion } = state const currentUser = selectCurrentUser(state) const sortedCollections = newestFirst(collections) - const unassignedCollections = sortedCollections.filter( - collection => - collection.status === 'submitted' && - !teams.some( - team => - team.object.type === 'collection' && - team.object.id === collection.id && - team.teamType.name === 'handlingEditor', - ), - ) - const myCollections = teams - .filter( - team => - team.group === 'editor' && - team.object.type === 'collection' && - team.members.includes(currentUser.id), - ) - .map(team => - collections.find(collection => collection.id === team.object.id), - ) + // const unassignedCollections = sortedCollections.filter( + // collection => + // collection.status === 'submitted' && + // !teams.some( + // team => + // team.object.type === 'collection' && + // team.object.id === collection.id && + // team.teamType.name === 'handlingEditor', + // ), + // ) + // const myCollections = teams + // .filter( + // team => + // team.group === 'editor' && + // team.object.type === 'collection' && + // team.members.includes(currentUser.id), + // ) + // .map(team => + // collections.find(collection => collection.id === team.object.id), + // ) const dashboard = { - editor: newestFirst( - unassignedCollections - .concat(myCollections) - .filter( - (collection, index, items) => - items.findIndex(item => item.id === collection.id) === index, - ), + // editor: newestFirst( + // unassignedCollections + // .concat(myCollections) + // .filter( + // (collection, index, items) => + // items.findIndex(item => item.id === collection.id) === index, + // ), + // ), + editor: sortedCollections.filter( + collection => + collection.status === 'submitted' || + collection.status === 'revising', ), owner: sortedCollections.filter( collection => diff --git a/packages/component-dashboard/src/components/Reviews.js b/packages/component-dashboard/src/components/Reviews.js index 7ab111cfd159a362136776ca51ec2e3d8c38a233..a671e4f0fc0d4ee45d904c2a903c1b82eb2f76b4 100644 --- a/packages/component-dashboard/src/components/Reviews.js +++ b/packages/component-dashboard/src/components/Reviews.js @@ -1,20 +1,25 @@ import React from 'react' import { compose, withProps } from 'recompose' import { groupBy } from 'lodash' +import { withJournal } from 'xpub-journal' import { Badge } from '@pubsweet/ui' import classes from './Reviews.local.scss' -const Reviews = ({ reviews }) => ( +const Reviews = ({ reviews, journal }) => ( <div className={classes.root}> - {Object.keys(reviews).map(status => ( + {journal.reviewStatus.map(status => ( <span className={classes.badge} key={status}> - <Badge count={reviews[status].length} label={status} /> + <Badge + count={reviews[status] ? reviews[status].length : 0} + label={status} + /> </span> ))} </div> ) export default compose( + withJournal, withProps(props => ({ reviews: groupBy(props.version.reviewers, 'status'), })), diff --git a/packages/component-dashboard/src/components/Status.js b/packages/component-dashboard/src/components/Status.js index cbac37d53e82b41b7dc501e173a0e31c9480d403..928e602f73c00fd68da3d2deb6327988fafb7d27 100644 --- a/packages/component-dashboard/src/components/Status.js +++ b/packages/component-dashboard/src/components/Status.js @@ -8,7 +8,9 @@ const labels = { assignedToEditor: 'Assigned to editor', assigningReviewers: 'Assigning reviewers', new: 'Unsubmitted', + rejected: 'Rejected', submitted: 'Submitted', + revising: 'Under Revision', } const Status = ({ status }) => ( diff --git a/packages/component-dashboard/src/components/metadata/MetadataOwners.js b/packages/component-dashboard/src/components/metadata/MetadataOwners.js index 40bb90e45ccbb5ca2b6e8abc2302c37361ae5aaa..6142add1bd2749fb34b3e85520d1e637886f2316 100644 --- a/packages/component-dashboard/src/components/metadata/MetadataOwners.js +++ b/packages/component-dashboard/src/components/metadata/MetadataOwners.js @@ -4,7 +4,7 @@ const MetadataOwners = ({ owners }) => ( <span> {owners.map((owner, index) => [ index === 0 ? null : <span>, </span>, - <span>{owner.name || 'Anonymous'}</span>, + <span>{owner.username || 'Anonymous'}</span>, ])} </span> ) diff --git a/packages/component-dashboard/src/components/metadata/MetadataReviewType.js b/packages/component-dashboard/src/components/metadata/MetadataReviewType.js index 11522e78d5df54c18c9174e2310687d258277feb..95cec2654b3fb73a8be9b35728125957f06ae268 100644 --- a/packages/component-dashboard/src/components/metadata/MetadataReviewType.js +++ b/packages/component-dashboard/src/components/metadata/MetadataReviewType.js @@ -1,7 +1,7 @@ import React from 'react' -const MetadataReviewType = ({ openReview }) => ( - <span>{openReview ? 'Open review' : 'Closed review'}</span> +const MetadataReviewType = ({ openPeerReview }) => ( + <span>{openPeerReview === 'yes' ? 'Open review' : 'Closed review'}</span> ) export default MetadataReviewType diff --git a/packages/component-dashboard/src/components/sections/EditorItem.js b/packages/component-dashboard/src/components/sections/EditorItem.js index 902cec169cb1fffac36a2694f0311ff41b340d1e..5efbbfc62dd1e234ade700782760ecbfcc27b49c 100644 --- a/packages/component-dashboard/src/components/sections/EditorItem.js +++ b/packages/component-dashboard/src/components/sections/EditorItem.js @@ -11,6 +11,35 @@ import classes from './Item.local.scss' import Reviews from '../Reviews' import VersionTitle from './VersionTitle' +const Actions = ({ project, version }) => ( + <div className={classes.links}> + <div className={classes.link}> + {/* {(!version.decision || + version.decision.status !== 'revising' || + version.decision.status !== 'submitted') && ( + <span> + <ProjectLink page="reviewers" project={project} version={version}> + Assign Reviewers + </ProjectLink> + + <Divider separator="|" /> + </span> + )} */} + + <ProjectLink + id={project.id} + page="decisions" + project={project} + version={version} + > + {version.decision && version.decision.status === 'submitted' + ? `Decision: ${version.decision.recommendation}` + : 'Control Panel'} + </ProjectLink> + </div> + </div> +) + const EditorItem = ({ AssignEditor, project, version, addUserToTeam }) => ( <div className={classes.root}> <div className={classes.header}> @@ -25,38 +54,15 @@ const EditorItem = ({ AssignEditor, project, version, addUserToTeam }) => ( <Divider separator="–" /> <MetadataSections sections={version.metadata.articleSection} /> <Divider separator="–" /> - <MetadataReviewType openReview={version.declarations.openReview} /> + <MetadataReviewType + openPeerReview={version.declarations.openPeerReview} + /> </div> </div> <div className={classes.main}> <VersionTitle className={classes.versionTitle} version={version} /> - - <div className={classes.links}> - <div className={classes.link}> - {(!version.decision || version.decision.status !== 'submitted') && ( - <span> - <ProjectLink page="reviewers" project={project} version={version}> - Assign Reviewers - </ProjectLink> - - <Divider separator="|" /> - </span> - )} - - <ProjectLink - id={project.id} - page="decisions" - project={project} - version={version} - > - {version.decision && version.decision.status === 'submitted' - ? `Decision: ${version.decision.recommendation}` - : 'Make decision'} - </ProjectLink> - </div> - </div> - + <Actions project={project} version={version} /> <div className={classes.actions} /> </div> diff --git a/packages/component-dashboard/src/components/sections/OwnerItem.js b/packages/component-dashboard/src/components/sections/OwnerItem.js index d122fccc2214e4ad47da4c717175febf47c86ee3..6e9fd74500cacea9db295d63852f4d142d2b182d 100644 --- a/packages/component-dashboard/src/components/sections/OwnerItem.js +++ b/packages/component-dashboard/src/components/sections/OwnerItem.js @@ -17,7 +17,7 @@ const OwnerItem = ({ project, version, deleteProject }) => ( <div className={classes.links}> <div className={classes.link}> <ProjectLink page="submit" project={project} version={version}> - Submission + Summary info </ProjectLink> </div> diff --git a/packages/component-dashboard/src/components/sections/ReviewerItem.js b/packages/component-dashboard/src/components/sections/ReviewerItem.js index 8ec3b786910cfb0641f85e48464051725b047224..9b68a4617b75578bebe94ea92a5ed07e552d7cac 100644 --- a/packages/component-dashboard/src/components/sections/ReviewerItem.js +++ b/packages/component-dashboard/src/components/sections/ReviewerItem.js @@ -7,7 +7,7 @@ import Divider from './Divider' import VersionTitle from './VersionTitle' // TODO: only return links if version id is in reviewer.accepted array -// TODO: only return actions if not accepted or declined +// TODO: only return actions if not accepted or rejected // TODO: review id in link const ReviewerItem = ({ project, version, currentUser, reviewerResponse }) => { @@ -19,8 +19,9 @@ const ReviewerItem = ({ project, version, currentUser, reviewerResponse }) => { <VersionTitle className={classes.versionTitle} version={version} /> {reviewer && ( - <div> - {reviewer.status === 'accepted' && ( + <div className={classes.links}> + {(reviewer.status === 'accepted' || + reviewer.status === 'completed') && ( <div className={classes.links}> <div className={classes.link}> <ProjectLink @@ -29,7 +30,7 @@ const ReviewerItem = ({ project, version, currentUser, reviewerResponse }) => { project={project} version={version} > - {reviewer.submitted ? 'Reviewed' : 'Do Review'} + {reviewer.submitted ? 'Completed' : 'Do Review'} </ProjectLink> </div> </div> @@ -52,7 +53,7 @@ const ReviewerItem = ({ project, version, currentUser, reviewerResponse }) => { <div className={classes.action}> <Button onClick={() => - reviewerResponse(project, version, reviewer, 'declined') + reviewerResponse(project, version, reviewer, 'rejected') } > reject @@ -60,8 +61,7 @@ const ReviewerItem = ({ project, version, currentUser, reviewerResponse }) => { </div> </div> )} - - {reviewer.status === 'declined' && <div>declined</div>} + {reviewer.status === 'rejected' && 'rejected'} </div> )} </div> diff --git a/packages/component-manuscript/package.json b/packages/component-manuscript/package.json index f5c91201e2d0761259d92cc1706d9acd74500b11..8f897f54d729617c135ae5ca429b0dd37065e60a 100644 --- a/packages/component-manuscript/package.json +++ b/packages/component-manuscript/package.json @@ -7,13 +7,13 @@ ], "main": "src", "dependencies": { - "wax-editor-react": "^0.0.10", + "wax-editor-react": "^0.1.7", "xpub-connect": "^0.0.2", "xpub-selectors": "^0.0.2" }, "peerDependencies": { "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-redux": "^5.0.2", @@ -38,7 +38,7 @@ "webpack": "^3.8.1", "webpack-node-externals": "^1.6.0", "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-redux": "^5.0.2", diff --git a/packages/component-review/package.json b/packages/component-review/package.json index abc7d527bb05ee8f82501d4446bf1de4e75e2875..7824ddc8a8de19a7775f8668da5db217d9758f09 100644 --- a/packages/component-review/package.json +++ b/packages/component-review/package.json @@ -13,7 +13,7 @@ "lodash": "^4.17.4", "moment": "^2.18.1", "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-moment": "^0.6.1", @@ -25,12 +25,12 @@ "redux-form": "^7.0.3", "striptags": "^3.1.0", "uuid": "^3.1.0", - "wax-editor-react": "^0.0.10", + "wax-editor-react": "^0.1.7", "xpub-connect": "^0.0.2", "xpub-edit": "^0.0.2", "xpub-journal": "^0.0.2", "xpub-selectors": "^0.0.2", - "@pubsweet/ui": "^0.1.1", + "@pubsweet/ui": "^0.2.0", "xpub-upload": "^0.0.2", "xpub-validators": "^0.0.2" }, @@ -53,7 +53,7 @@ }, "peerDependencies": { "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-redux": "^5.0.2", diff --git a/packages/component-review/src/components/DecisionPage.js b/packages/component-review/src/components/DecisionPage.js index 3067b621f2cc90c7f60a5c24843b33191f159a5b..09eac49bce3afdcb7176856faed7f83262750a18 100644 --- a/packages/component-review/src/components/DecisionPage.js +++ b/packages/component-review/src/components/DecisionPage.js @@ -56,7 +56,7 @@ const handleDecision = (project, version) => dispatch => actions.updateCollection({ id: project.id, rev: project.rev, - status: 'revise', + status: 'revising', }), ).then(() => dispatch( diff --git a/packages/component-review/src/components/ReviewPage.js b/packages/component-review/src/components/ReviewPage.js index 3b42c80703c07784bbcb2089be8ce82417fbfef8..337231247252a7e011bc6d5f354b69e98b31b588 100644 --- a/packages/component-review/src/components/ReviewPage.js +++ b/packages/component-review/src/components/ReviewPage.js @@ -23,9 +23,9 @@ const onSubmit = ( { history, project, version, reviewer }, ) => { Object.assign(reviewer, { - status: 'reviewed', - submitted: new Date(), ...values, + status: 'completed', + submitted: new Date(), }) return dispatch( @@ -48,7 +48,7 @@ const onSubmit = ( const onChange = (values, dispatch, { project, version, reviewer }) => { Object.assign(reviewer, { - submitted: new Date(), + // submitted: new Date(), ...values, }) diff --git a/packages/component-review/src/components/decision/DecisionLayout.js b/packages/component-review/src/components/decision/DecisionLayout.js index 295bed8ad929a8878fc3075c6c19a20cbd9660c3..ef571250d18d3dd37ed78a96f3b1150f5748e4f0 100644 --- a/packages/component-review/src/components/decision/DecisionLayout.js +++ b/packages/component-review/src/components/decision/DecisionLayout.js @@ -1,6 +1,7 @@ import React from 'react' import moment from 'moment' // import classnames from 'classnames' +import { Link } from 'react-router-dom' import SimpleEditor from 'wax-editor-react' import classes from './DecisionLayout.local.scss' import DecisionForm from './DecisionForm' @@ -9,13 +10,19 @@ import ReviewMetadata from '../metadata/ReviewMetadata' import Decision from './Decision' import Tabs from '../tabs/Tabs' +// TODO -- is passing arrays of react components as props an ok practice? +/* + TODO -- should we make an editor for each tab, or should we just rerender + the same one with different content? +*/ + const DecisionLayout = ({ - project, - versions, currentVersion, - valid, handleSubmit, + project, uploadFile, + valid, + versions, }) => { const decisionSections = [] const editorSections = [] @@ -43,7 +50,13 @@ const DecisionLayout = ({ editorSections.push({ content: ( - <SimpleEditor content={version.source} layout="bare" readOnly /> + <SimpleEditor + content={version.source} + editing="selection" + key={key} + layout="bare" + readOnly + /> ), key, label, @@ -53,15 +66,21 @@ const DecisionLayout = ({ const { decision } = currentVersion - if (!decision || !decision.submitted) { + if (currentVersion.submitted && (!decision || !decision.submitted)) { const submittedMoment = moment() const key = submittedMoment.format('x') const label = submittedMoment.format('YYYY-MM-DD') - decisionSections.push({ content: ( <div> <ReviewMetadata version={currentVersion} /> + <Link + to={`/projects/${project.id}/versions/${ + currentVersion.id + }/reviewers`} + > + Assign Reviewers + </Link> <DecisionReviews version={currentVersion} /> <DecisionForm decision={decision} @@ -77,7 +96,13 @@ const DecisionLayout = ({ editorSections.push({ content: ( - <SimpleEditor content={currentVersion.source} layout="bare" readOnly /> + <SimpleEditor + content={currentVersion.source} + editing="selection" + key={key} + layout="bare" + readOnly + /> ), key, label, diff --git a/packages/component-review/src/components/decision/DecisionReview.js b/packages/component-review/src/components/decision/DecisionReview.js index 49b5faea12177acd7b8bbcced2c3cb450d63c108..8de518cf54a406dbd82a9a21b54d7300beb04032 100644 --- a/packages/component-review/src/components/decision/DecisionReview.js +++ b/packages/component-review/src/components/decision/DecisionReview.js @@ -4,39 +4,71 @@ import { withJournal } from 'xpub-journal' import Review from '../review/Review' import classes from './DecisionReview.local.scss' -const DecisionReview = ({ review, reviewer, journal, open, toggleOpen }) => ( - <div> - <div className={classes.heading}> - <span - className={classes.indicator} - style={{ - backgroundColor: review.recommendation - ? journal.recommendations.find( - item => item.value === review.recommendation, - ).color - : 'black', - }} - /> +const ToggleReview = ({ open, toggle }) => ( + <button className={classes.toggle} onClick={toggle}> + {open ? 'Hide' : 'Show'} + </button> +) - <span className={classes.ordinal}>Review {reviewer.ordinal}</span> +const Bullet = ({ journal, recommendation }) => { + const recommendationColor = journal.recommendations.find( + item => item.value === recommendation, + ).color - <span className={classes.name}>{reviewer.name || 'Anonymous'}</span> + return ( + <span + className={classes.indicator} + style={{ + backgroundColor: recommendation ? recommendationColor : 'black', + }} + /> + ) +} - <span className={classes.dots} /> +const ReviewHeading = ({ + journal, + name, + open, + ordinal, + recommendation, + toggleOpen, +}) => ( + <div className={classes.heading}> + <Bullet journal={journal} recommendation={recommendation} /> - <button className={classes.toggle} onClick={toggleOpen}> - {open ? 'Hide' : 'Show'} - </button> - </div> + <span className={classes.ordinal}>Review {ordinal}</span> + <span className={classes.name}>{name || 'Anonymous'}</span> - {open && ( - <div className={classes.review}> - <Review review={review} /> - </div> - )} + <span className={classes.dots} /> + + <ToggleReview open toggle={toggleOpen} /> </div> ) +const DecisionReview = ({ review, reviewer, journal, open, toggleOpen }) => { + const { recommendation } = review.Recommendation + const { name, ordinal } = reviewer + + return ( + <div> + <ReviewHeading + journal={journal} + name={name} + open={open} + ordinal={ordinal} + recommendation={recommendation} + toggleOpen={toggleOpen} + /> + + {open && ( + <div className={classes.review}> + <Review review={review} /> + </div> + )} + </div> + ) +} + export default compose( withJournal, withState('open', 'setOpen', ({ open }) => open), diff --git a/packages/component-review/src/components/decision/DecisionReviews.js b/packages/component-review/src/components/decision/DecisionReviews.js index 659014093459125ac571728e33dccc965b8e5a47..66aada888cfc0fce999d08334cc47044820048c3 100644 --- a/packages/component-review/src/components/decision/DecisionReviews.js +++ b/packages/component-review/src/components/decision/DecisionReviews.js @@ -13,6 +13,7 @@ const DecisionReviews = ({ journal, version }) => ( .map((review, index) => ( <div className={classes.review} key={review.id}> <DecisionReview + open review={review} reviewer={{ name: null, diff --git a/packages/component-review/src/components/metadata/ReviewMetadata.js b/packages/component-review/src/components/metadata/ReviewMetadata.js index 8c3912c5e7f68df90dead525c77dd1be7b7c24d3..2d7c8023d1fef2cb90bedc9e5a230141479cdf96 100644 --- a/packages/component-review/src/components/metadata/ReviewMetadata.js +++ b/packages/component-review/src/components/metadata/ReviewMetadata.js @@ -10,7 +10,9 @@ const ReviewMetadata = ({ version, handlingEditors }) => ( <tbody> <tr> <th className={classes.heading}>peer review:</th> - <td>{version.declarations.openReview ? 'open' : 'closed'}</td> + <td> + {version.declarations.openPeerReview === 'yes' ? 'open' : 'closed'} + </td> </tr> {!!handlingEditors && ( diff --git a/packages/component-review/src/components/review/Review.js b/packages/component-review/src/components/review/Review.js index 27bf6e2f115fe840d271b51b4eaa410a3db7ea6d..5c34514c60dc65029224caac225788bbf8fb4938 100644 --- a/packages/component-review/src/components/review/Review.js +++ b/packages/component-review/src/components/review/Review.js @@ -40,7 +40,9 @@ const Review = ({ review }) => ( <div> <div className={classes.heading}>Recommendation</div> - <div className={classes.recommendation}>{review.recommendation}</div> + <div className={classes.recommendation}> + {review.Recommendation.recommendation} + </div> </div> </div> ) diff --git a/packages/component-review/src/components/review/ReviewLayout.js b/packages/component-review/src/components/review/ReviewLayout.js index 2c762bab596f251dcc4888375c47a8132d89c365..1dae14203276643e81565598057fadfb1945ddc2 100644 --- a/packages/component-review/src/components/review/ReviewLayout.js +++ b/packages/component-review/src/components/review/ReviewLayout.js @@ -22,9 +22,12 @@ const ReviewLayout = ({ const editorSections = [] versions.forEach(version => { - const review = version.reviewers.find( - review => review.reviewer === reviewer.id, - ) + let review + if (version.reviewers) { + review = version.reviewers.find( + review => review.reviewer === reviewer._reviewer.id, + ) + } if (review && review.submitted) { const submittedMoment = moment(review.submitted) @@ -48,7 +51,13 @@ const ReviewLayout = ({ // TODO: need to include unreviewed versions? editorSections.push({ content: ( - <SimpleEditor content={version.source} layout="bare" readOnly /> + <SimpleEditor + content={version.source} + editing="selection" + key={key} + layout="bare" + readOnly + /> ), key, label, @@ -57,10 +66,10 @@ const ReviewLayout = ({ }, []) const review = currentVersion.reviewers.find( - review => review.reviewer === reviewer.id, + review => review.id === reviewer.id, ) - if (!review || !review.submitted) { + if (currentVersion.submitted && (!review || !review.submitted)) { const submittedMoment = moment() const key = submittedMoment.format('x') const label = submittedMoment.format('YYYY-MM-DD') @@ -86,7 +95,13 @@ const ReviewLayout = ({ editorSections.push({ content: ( - <SimpleEditor content={currentVersion.source} layout="bare" readOnly /> + <SimpleEditor + content={currentVersion.source} + editing="selection" + key={key} + layout="bare" + readOnly + /> ), key, label, diff --git a/packages/component-review/src/components/tabs/Tabs.js b/packages/component-review/src/components/tabs/Tabs.js index 19493a37b7aa766c7df2955707c0e428af715386..b62de60d59e4fd2f7c388e59d0e7a03b60f454f8 100644 --- a/packages/component-review/src/components/tabs/Tabs.js +++ b/packages/component-review/src/components/tabs/Tabs.js @@ -9,13 +9,12 @@ class Tabs extends React.Component { super(props) this.state = { - activeKey: null, + activeKey: props.activeKey || null, } } componentDidMount() { const { activeKey } = this.props - this.setState({ activeKey }) } diff --git a/packages/component-submit/package.json b/packages/component-submit/package.json index f5a2d81758cd0e1d88e54d9813301f9b777c59fa..b15eea0549450f09197b6f9de8fc965f0ea378a3 100644 --- a/packages/component-submit/package.json +++ b/packages/component-submit/package.json @@ -12,7 +12,7 @@ "classnames": "^2.2.5", "lodash": "^4.17.4", "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-redux": "^5.0.2", @@ -25,7 +25,7 @@ "xpub-edit": "^0.0.2", "xpub-journal": "^0.0.2", "xpub-selectors": "^0.0.2", - "@pubsweet/ui": "^0.1.1", + "@pubsweet/ui": "^0.2.0", "xpub-upload": "^0.0.2", "xpub-validators": "^0.0.2" }, @@ -48,7 +48,7 @@ }, "peerDependencies": { "prop-types": "^15.5.10", - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-redux": "^5.0.2", diff --git a/packages/component-submit/src/components/Declarations.js b/packages/component-submit/src/components/Declarations.js index d7d3e967ff9a1d719fffb1c713941250d53383c1..21b9585a7ed7b1a4105cbc0a648d84a664c2085b 100644 --- a/packages/component-submit/src/components/Declarations.js +++ b/packages/component-submit/src/components/Declarations.js @@ -1,12 +1,14 @@ import React from 'react' import classnames from 'classnames' import { FormSection } from 'redux-form' -import { ValidatedField, YesOrNo } from '@pubsweet/ui' +import { ValidatedField, RadioGroup } from '@pubsweet/ui' import { withJournal } from 'xpub-journal' import { required } from 'xpub-validators' import classes from './Declarations.local.scss' -const DeclarationInput = input => <YesOrNo inline {...input} /> +const DeclarationInput = options => input => ( + <RadioGroup inline options={options} {...input} /> +) const Declarations = ({ journal, readonly }) => ( <FormSection name="declarations"> @@ -22,7 +24,7 @@ const Declarations = ({ journal, readonly }) => ( > <div className={classes.legend}>{question.legend}</div> <ValidatedField - component={DeclarationInput} + component={DeclarationInput(question.options)} name={question.id} readonly={readonly} required diff --git a/packages/component-submit/src/components/Notes.js b/packages/component-submit/src/components/Notes.js index 431aab2667d00156c9f98cff5416b44a878e11ec..5a19bd621074973db9946028fb6b9f0b509a51a1 100644 --- a/packages/component-submit/src/components/Notes.js +++ b/packages/component-submit/src/components/Notes.js @@ -16,7 +16,7 @@ const FundingInput = input => ( const InstructionsInput = input => ( <NoteEditor placeholder="Enter instructions for the editor…" - title="Special instructions (confidential)" + title="Special instructions (confidential, to Editors only)" {...input} /> ) diff --git a/packages/xpub-collabra/app/config/journal/declarations.js b/packages/xpub-collabra/app/config/journal/declarations.js index 012e4d46c2bfe3b20da969a9277a391d61c18094..d870cf6b67b87fba12c170af534ece0bf3793351 100644 --- a/packages/xpub-collabra/app/config/journal/declarations.js +++ b/packages/xpub-collabra/app/config/journal/declarations.js @@ -2,27 +2,87 @@ export default { questions: [ { id: 'openData', - legend: 'Data is open', + legend: 'Data is open ?', + options: [ + { + label: 'Yes', + value: 'yes', + }, + { + label: 'No/Not Applicable', + value: 'no', + }, + ], }, { id: 'previouslySubmitted', - legend: 'Previously submitted', + legend: 'Previously submitted ?', + options: [ + { + label: 'Yes', + value: 'yes', + }, + { + label: 'No', + value: 'no', + }, + ], }, { id: 'openPeerReview', - legend: 'Open peer review', + legend: 'Open peer review ?', + options: [ + { + label: 'Yes', + value: 'yes', + }, + { + label: 'No', + value: 'no', + }, + ], }, { id: 'streamlinedReview', - legend: 'Streamlined review', + legend: 'Streamlined review ?', + options: [ + { + label: 'Yes', + value: 'yes', + }, + { + label: 'No', + value: 'no', + }, + ], }, { id: 'researchNexus', - legend: 'Submitted as part of the research nexus?', + legend: 'Submitted as part of the research nexus ?', + options: [ + { + label: 'Yes', + value: 'yes', + }, + { + label: 'No', + value: 'no', + }, + ], }, { id: 'preregistered', - legend: 'Pre-registered?', + legend: 'Pre-registered ?', + options: [ + { + label: 'Yes', + value: 'yes', + }, + { + label: 'No', + value: 'no', + }, + ], }, ], } diff --git a/packages/xpub-collabra/app/config/journal/index.js b/packages/xpub-collabra/app/config/journal/index.js index 30bc3a405632a2e2ff3972ac0c490a26666ce330..0c6ad26b9490fd2fbfc5c1536954b068c51c1071 100644 --- a/packages/xpub-collabra/app/config/journal/index.js +++ b/packages/xpub-collabra/app/config/journal/index.js @@ -7,3 +7,4 @@ export { default as articleSections } from './article-sections' export { default as articleTypes } from './article-types' export { default as editors } from './editors' export { default as roles } from './roles' +export { default as reviewStatus } from './review-status' diff --git a/packages/xpub-collabra/app/config/journal/review-status.js b/packages/xpub-collabra/app/config/journal/review-status.js new file mode 100644 index 0000000000000000000000000000000000000000..fd8c98ac00f8dadbeaf93e619bc26499ab95c7b6 --- /dev/null +++ b/packages/xpub-collabra/app/config/journal/review-status.js @@ -0,0 +1 @@ +export default ['invited', 'accepted', 'rejected', 'completed'] diff --git a/packages/xpub-collabra/app/routes.js b/packages/xpub-collabra/app/routes.js index d15a0637a088be488d1b25c3f2e9f68325df6073..f4719c134fb076fbd24c63f9011d251f77a0c7b3 100644 --- a/packages/xpub-collabra/app/routes.js +++ b/packages/xpub-collabra/app/routes.js @@ -1,14 +1,11 @@ import React from 'react' +import { withProps } from 'recompose' import { Route } from 'react-router-dom' +import { AuthenticatedComponent } from 'pubsweet-client' import App from 'pubsweet-component-xpub-app/src/components' - -import { - PrivateRoute, - SignupPage, - LoginPage, - LogoutPage, -} from 'pubsweet-component-xpub-authentication/src/components' +import Login from 'pubsweet-component-login/LoginContainer' +import Signup from 'pubsweet-component-signup/SignupContainer' import DashboardPage from 'pubsweet-component-xpub-dashboard/src/components/DashboardPage' import SubmitPage from 'pubsweet-component-xpub-submit/src/components/SubmitPage' @@ -17,6 +14,19 @@ import ReviewersPage from 'pubsweet-component-xpub-review/src/components/Reviewe import ReviewPage from 'pubsweet-component-xpub-review/src/components/ReviewPage' import DecisionPage from 'pubsweet-component-xpub-review/src/components/DecisionPage' +const LoginPage = withProps({ passwordReset: false })(Login) + +const PrivateRoute = ({ component: Component, ...rest }) => ( + <Route + {...rest} + render={props => ( + <AuthenticatedComponent> + <Component {...props} /> + </AuthenticatedComponent> + )} + /> +) + // TODO: use componentDidMount to fetch the current user before rendering? const Routes = () => ( @@ -48,9 +58,7 @@ const Routes = () => ( path="/projects/:project/versions/:version/decisions/:decision" /> - <PrivateRoute component={LogoutPage} exact path="/logout" /> - - <Route component={SignupPage} exact path="/signup" /> + <Route component={Signup} exact path="/signup" /> <Route component={LoginPage} exact path="/login" /> {/* <Redirect from="/" to="/dashboard"/> */} diff --git a/packages/xpub-collabra/config/components.json b/packages/xpub-collabra/config/components.json index 8c447f58070819ee76fa7ef806d94e547b5135ef..f286079017a647031c49ae05c77f37cb41d98d6e 100644 --- a/packages/xpub-collabra/config/components.json +++ b/packages/xpub-collabra/config/components.json @@ -1,9 +1,10 @@ [ "pubsweet-component-xpub-app", - "pubsweet-component-xpub-authentication", "pubsweet-component-xpub-dashboard", "pubsweet-component-xpub-manuscript", "pubsweet-component-xpub-review", "pubsweet-component-xpub-submit", - "pubsweet-component-ink-backend" + "pubsweet-component-ink-backend", + "pubsweet-component-login", + "pubsweet-component-signup" ] diff --git a/packages/xpub-collabra/package.json b/packages/xpub-collabra/package.json index 270bea33cbfb19df9b45dd045da2a13b29fc9349..020cd0bcd7b8fb575044c65800f62320bd2d0d32 100644 --- a/packages/xpub-collabra/package.json +++ b/packages/xpub-collabra/package.json @@ -8,7 +8,7 @@ "url": "https://gitlab.coko.foundation/xpub/xpub" }, "dependencies": { - "@pubsweet/ui": "^0.1.1", + "@pubsweet/ui": "^0.2.0", "babel-core": "^6.26.0", "config": "^1.26.2", "font-awesome": "^4.7.0", @@ -19,11 +19,12 @@ "moment": "^2.18.1", "prop-types": "^15.5.10", "pubsweet": "^1.1.1", - "pubsweet-client": "^1.1.1", + "pubsweet-client": "^1.1.4", "pubsweet-component-ink-backend": "^0.1.1", "pubsweet-component-ink-frontend": "^0.2.3", + "pubsweet-component-login":"^0.6.0", + "pubsweet-component-signup": "^0.5.0", "pubsweet-component-xpub-app": "^0.0.2", - "pubsweet-component-xpub-authentication": "^0.0.2", "pubsweet-component-xpub-dashboard": "^0.0.2", "pubsweet-component-xpub-manuscript": "^0.0.2", "pubsweet-component-xpub-review": "^0.0.2", diff --git a/packages/xpub-collabra/webpack/babel-includes.js b/packages/xpub-collabra/webpack/babel-includes.js index cf4c70690af26d8fec6abcbeb6b3ce54b5be6963..ba73256a5abfd47176e81ab3e739b785ac64457a 100644 --- a/packages/xpub-collabra/webpack/babel-includes.js +++ b/packages/xpub-collabra/webpack/babel-includes.js @@ -4,10 +4,14 @@ const path = require('path') // TODO: compile components to ES5 for distribution module.exports = [ + // include app folder path.join(__dirname, '..', 'app'), - /pubsweet-[^/]+\/src/, + // include pubsweet and xpub packages which are published untranspiled /xpub-[^/]+\/src/, /component-[^/]+\/src/, /wax-[^/]+\/src/, - /@pubsweet\/[^/]+\/src/, + /pubsweet-[^/\\]+\/(?!node_modules)/, + /@pubsweet\/[^/\\]+\/(?!node_modules)/, + // include other packages when this repo is mounted in a workspace + /packages\/[^/\\]+\/(?!node_modules)/, ] diff --git a/packages/xpub-connect/src/components/ConnectPage.js b/packages/xpub-connect/src/components/ConnectPage.js index 8f5aa92910f6917879e95d1c9c6b0a7f059e61c6..9cdafed26da3fd32b540335a9a241df8ac9fb502 100644 --- a/packages/xpub-connect/src/components/ConnectPage.js +++ b/packages/xpub-connect/src/components/ConnectPage.js @@ -17,7 +17,7 @@ const ConnectPage = requirements => WrappedComponent => { } componentWillReceiveProps = nextProps => { - this.fetch(nextProps) + // this.fetch(nextProps) } fetch({ isAuthenticated }) { diff --git a/packages/xpub-upload/package.json b/packages/xpub-upload/package.json index e7d05c8e68ed5008ac0074851f89c3e4792c1c35..9fc35a59f405f7b8fa5a149a75c38a1cd9587ba8 100644 --- a/packages/xpub-upload/package.json +++ b/packages/xpub-upload/package.json @@ -9,7 +9,7 @@ "dist" ], "dependencies": { - "pubsweet-client": "^1.0.0-beta.8", + "pubsweet-client": "^1.1.4", "react": "^15.6.1", "react-dom": "^15.6.1", "react-redux": "^5.0.2", diff --git a/yarn.lock b/yarn.lock index eb9f5d31429e918fb8aecaf690cc3f639c668a03..cd963f86ae65944dda281815be146e1fc038cfc9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -112,9 +112,9 @@ typeface-fira-sans-condensed "^0.0.43" typeface-vollkorn "^0.0.43" -"@pubsweet/ui@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@pubsweet/ui/-/ui-0.1.1.tgz#fdd6aaf85ff79de62ef6933ac90105a2b7cd8863" +"@pubsweet/ui@^0.2.0": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@pubsweet/ui/-/ui-0.2.3.tgz#da93ef5bcb46444798dea9e482f0f70b5114342a" dependencies: babel-jest "^21.2.0" classnames "^2.2.5" @@ -3228,7 +3228,7 @@ eslint-config-airbnb@^16.1.0: dependencies: eslint-config-airbnb-base "^12.1.0" -eslint-config-prettier@^2.6.0, eslint-config-prettier@^2.7.0: +eslint-config-prettier@^2.7.0: version "2.9.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" dependencies: @@ -8093,7 +8093,7 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@^1.7.4, prettier@^1.8.2: +prettier@^1.8.2: version "1.9.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827" @@ -8298,22 +8298,19 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" -pubsweet-client@^1.0.0-beta.8, pubsweet-client@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pubsweet-client/-/pubsweet-client-1.1.1.tgz#5865f87760cc762d6ee077db0ff5ca68592c1fb4" +pubsweet-client@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/pubsweet-client/-/pubsweet-client-1.1.4.tgz#9b4ea16bd25d305d7e3392aa45c0db8865471611" dependencies: authsome "0.0.9" config "^1.21.0" - eslint-config-prettier "^2.6.0" event-source-polyfill "^0.0.10" global "^4.3.1" - husky "^0.14.3" isomorphic-fetch "^2.1.1" lint-staged "^6.0.0" lodash "^4.0.0" - prettier "^1.7.4" prop-types "^15.5.8" - pubsweet-component-login "^0.5.6" + pubsweet-component-login "^0.6.0" react "^15.4.4" react-css-themr "^2.1.2" react-redux "^5.0.2" @@ -8323,6 +8320,7 @@ pubsweet-client@^1.0.0-beta.8, pubsweet-client@^1.1.1: redux-form "^7.0.3" redux-logger "^3.0.1" redux-thunk "^2.2.0" + reselect "^3.0.1" pubsweet-component-ink-backend@^0.1.1: version "0.1.1" @@ -8346,9 +8344,9 @@ pubsweet-component-ink-frontend@^0.2.3: react-redux "^5.0.6" redux "^3.7.2" -pubsweet-component-login@^0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/pubsweet-component-login/-/pubsweet-component-login-0.5.6.tgz#fd637d1287254d2d08c56c51e209180ba4a6e585" +pubsweet-component-login@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pubsweet-component-login/-/pubsweet-component-login-0.6.0.tgz#4f5ee6ca096b8b8651d50c9798957a694e42c6d2" dependencies: prop-types "^15.5.10" react-bootstrap "^0.31.3" @@ -8356,6 +8354,17 @@ pubsweet-component-login@^0.5.6: react-router-dom "^4.2.2" react-router-redux "^4.0.8" redux "^3.7.2" + redux-form "^7.0.3" + +pubsweet-component-signup@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pubsweet-component-signup/-/pubsweet-component-signup-0.5.0.tgz#26fd0720b8ccbe8a35ba97277d9a3ad69cb9b6a9" + dependencies: + prop-types "^15.5.10" + react-bootstrap "^0.31.3" + react-redux "^5.0.6" + react-router "^4.2.0" + redux "^3.7.2" pubsweet-server@^1.0.0-beta.2, pubsweet-server@^1.0.1: version "1.0.1" @@ -8752,7 +8761,7 @@ react-router-redux@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/react-router-redux/-/react-router-redux-4.0.8.tgz#227403596b5151e182377dab835b5d45f0f8054e" -react-router-redux@next: +react-router-redux@^5.0.0-alpha.9, react-router-redux@next: version "5.0.0-alpha.9" resolved "https://registry.yarnpkg.com/react-router-redux/-/react-router-redux-5.0.0-alpha.9.tgz#825431516e0e6f1fd93b8807f6bd595e23ec3d10" dependencies: @@ -9430,6 +9439,10 @@ requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" +reselect@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -11018,23 +11031,23 @@ watchpack@^1.4.0: chokidar "^1.7.0" graceful-fs "^4.1.2" -wax-editor-core@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/wax-editor-core/-/wax-editor-core-0.2.1.tgz#850433da5919eefd66defbb388ba70641ae1f818" +wax-editor-core@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/wax-editor-core/-/wax-editor-core-0.3.7.tgz#37fcdb9f32870b241732d7fa27e80b7674ebe5f4" dependencies: font-awesome "^4.7.0" lodash "^4.17.4" substance "1.0.0-beta.6.5" -wax-editor-react@^0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/wax-editor-react/-/wax-editor-react-0.0.10.tgz#6cb19c05fed918490034d2a7b6ce3891428f6807" +wax-editor-react@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/wax-editor-react/-/wax-editor-react-0.1.7.tgz#222981d68603e2fbd82fecec4d7d4cb1c35c1b08" dependencies: lodash "^4.17.4" react "^15.6.1" react-dom "^15.6.1" react-router-dom "^4.2.2" - wax-editor-core "^0.2.1" + wax-editor-core "^0.3.7" wbuf@^1.1.0, wbuf@^1.7.2: version "1.7.2"