Skip to content
Snippets Groups Projects
Commit d2451e2c authored by Sebastian's avatar Sebastian
Browse files

Merge branch 'refactor-component-invite' of...

Merge branch 'refactor-component-invite' of gitlab.coko.foundation:xpub/xpub-faraday into refactor-component-invite
parents 248546b3 3deee030
No related branches found
No related tags found
1 merge request!5Refactor component invite
const logger = require('@pubsweet/logger') const logger = require('@pubsweet/logger')
const get = require('lodash/get') // const get = require('lodash/get')
const createNewTeam = async (collectionId, role, userId, TeamModel) => { const createNewTeam = async (collectionId, role, userId, TeamModel) => {
let permissions, group, name let permissions, group, name
......
...@@ -13,7 +13,7 @@ export default ({ ...@@ -13,7 +13,7 @@ export default ({
step, step,
project, project,
}) => ( }) => (
<Root data-test={`submission-${project.customId}`}> <Root data-test-submission={project.customId}>
{showProgress && ( {showProgress && (
<Steps currentStep={step} margin="0 20px 60px 0"> <Steps currentStep={step} margin="0 20px 60px 0">
{getSteps().map((step, index) => ( {getSteps().map((step, index) => (
......
...@@ -7,14 +7,11 @@ import { Label } from './FormItems' ...@@ -7,14 +7,11 @@ import { Label } from './FormItems'
export default ({ export default ({
id, id,
firstName, firstName,
middleName,
lastName, lastName,
email, email,
affiliation, affiliation,
country,
dragHandle, dragHandle,
isOver, isOver,
countryParser,
removeAuthor, removeAuthor,
isSubmitting, isSubmitting,
isCorresponding, isCorresponding,
...@@ -46,13 +43,11 @@ export default ({ ...@@ -46,13 +43,11 @@ export default ({
</Header> </Header>
<Row> <Row>
<Label label="First name" value={firstName} /> <Label label="First name" value={firstName} />
<Label label="Middle name" value={middleName} />
<Label label="Last name" value={lastName} /> <Label label="Last name" value={lastName} />
</Row> </Row>
<Row> <Row>
<Label label="Email" value={email} /> <Label label="Email" value={email} />
<Label label="Affiliation" value={affiliation} /> <Label label="Affiliation" value={affiliation} />
<Label label="Country" value={countryParser(country)} />
</Row> </Row>
</AuthorContainer> </AuthorContainer>
</Root> </Root>
......
...@@ -7,10 +7,14 @@ import styled from 'styled-components' ...@@ -7,10 +7,14 @@ import styled from 'styled-components'
import { compose, withProps } from 'recompose' import { compose, withProps } from 'recompose'
import { selectCurrentUser } from 'xpub-selectors' import { selectCurrentUser } from 'xpub-selectors'
import countries from './countries'
import { Spinner } from '../UIComponents/' import { Spinner } from '../UIComponents/'
import { getAuthorFetching } from '../../redux/authors' import {
import { MenuItem, ValidatedTextField } from './FormItems' getAuthorFetching,
getAuthors,
authorSuccess,
authorFailure,
} from '../../redux/authors'
import { ValidatedTextField } from './FormItems'
const emailRegex = new RegExp( const emailRegex = new RegExp(
/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, //eslint-disable-line /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, //eslint-disable-line
...@@ -35,7 +39,6 @@ const AuthorAdder = ({ ...@@ -35,7 +39,6 @@ const AuthorAdder = ({
<Title>{authors.length === 0 ? 'Submitting author' : 'Author'}</Title> <Title>{authors.length === 0 ? 'Submitting author' : 'Author'}</Title>
<Row> <Row>
<ValidatedTextField isRequired label="First name*" name="firstName" /> <ValidatedTextField isRequired label="First name*" name="firstName" />
<ValidatedTextField label="Middle name" name="middleName" />
<ValidatedTextField isRequired label="Last name*" name="lastName" /> <ValidatedTextField isRequired label="Last name*" name="lastName" />
</Row> </Row>
...@@ -51,7 +54,6 @@ const AuthorAdder = ({ ...@@ -51,7 +54,6 @@ const AuthorAdder = ({
label="Affiliation*" label="Affiliation*"
name="affiliation" name="affiliation"
/> />
<MenuItem label="Country*" name="country" options={countries} />
</Row> </Row>
<ButtonsContainer> <ButtonsContainer>
<Button data-test="button-cancel-author" onClick={setEditMode(false)}> <Button data-test="button-cancel-author" onClick={setEditMode(false)}>
...@@ -75,10 +77,16 @@ const AuthorAdder = ({ ...@@ -75,10 +77,16 @@ const AuthorAdder = ({
) )
export default compose( export default compose(
connect(state => ({ connect(
currentUser: selectCurrentUser(state), state => ({
isFetching: getAuthorFetching(state), currentUser: selectCurrentUser(state),
})), isFetching: getAuthorFetching(state),
}),
{
authorSuccess,
authorFailure,
},
),
withProps(({ currentUser: { admin, username, email }, authors }) => { withProps(({ currentUser: { admin, username, email }, authors }) => {
if (!admin && authors.length === 0) { if (!admin && authors.length === 0) {
return { return {
...@@ -106,14 +114,22 @@ export default compose( ...@@ -106,14 +114,22 @@ export default compose(
isCorresponding: isFirstAuthor, isCorresponding: isFirstAuthor,
}, },
collectionId, collectionId,
).then(author => { ).then(
const newAuthors = [...authors, author] () => {
setEditMode(false)() setEditMode(false)()
setTimeout(() => { setTimeout(() => {
setFormAuthors(newAuthors) getAuthors(collectionId).then(
}, 1000) data => {
reset() dispatch(authorSuccess())
}) setFormAuthors(data)
},
err => dispatch(authorFailure(err)),
)
}, 10)
reset()
},
err => dispatch(authorFailure(err)),
)
}, },
}), }),
)(AuthorAdder) )(AuthorAdder)
......
...@@ -6,10 +6,15 @@ import styled, { css } from 'styled-components' ...@@ -6,10 +6,15 @@ import styled, { css } from 'styled-components'
import { compose, withHandlers, withProps } from 'recompose' import { compose, withHandlers, withProps } from 'recompose'
import { reduxForm, Field, change as changeForm } from 'redux-form' import { reduxForm, Field, change as changeForm } from 'redux-form'
import countries from './countries'
import { Spinner } from '../UIComponents' import { Spinner } from '../UIComponents'
import { getAuthorFetching } from '../../redux/authors' import {
import { ValidatedTextField, MenuItem } from './FormItems' getAuthors,
editAuthor,
getAuthorFetching,
authorSuccess,
authorFailure,
} from '../../redux/authors'
import { ValidatedTextField } from './FormItems'
const emailRegex = new RegExp( const emailRegex = new RegExp(
/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, //eslint-disable-line /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i, //eslint-disable-line
...@@ -32,6 +37,7 @@ const AuthorEdit = ({ ...@@ -32,6 +37,7 @@ const AuthorEdit = ({
isCorresponding, isCorresponding,
email, email,
changeCorresponding, changeCorresponding,
...rest
}) => ( }) => (
<Root> <Root>
<Header> <Header>
...@@ -69,7 +75,6 @@ const AuthorEdit = ({ ...@@ -69,7 +75,6 @@ const AuthorEdit = ({
label="First name*" label="First name*"
name="edit.firstName" name="edit.firstName"
/> />
<ValidatedTextField label="Middle name" name="edit.middleName" />
<ValidatedTextField isRequired label="Last name*" name="edit.lastName" /> <ValidatedTextField isRequired label="Last name*" name="edit.lastName" />
</Row> </Row>
...@@ -85,7 +90,6 @@ const AuthorEdit = ({ ...@@ -85,7 +90,6 @@ const AuthorEdit = ({
label="Affiliation*" label="Affiliation*"
name="edit.affiliation" name="edit.affiliation"
/> />
<MenuItem label="Country*" name="edit.country" options={countries} />
</Row> </Row>
</Root> </Root>
) )
...@@ -95,19 +99,18 @@ export default compose( ...@@ -95,19 +99,18 @@ export default compose(
state => ({ state => ({
isFetching: getAuthorFetching(state), isFetching: getAuthorFetching(state),
}), }),
{ changeForm }, { changeForm, authorSuccess, authorFailure },
), ),
withProps(props => ({ withProps(props => ({
initialValues: { initialValues: {
edit: pick(props, [ edit: pick(props, [
'id',
'isCorresponding', 'isCorresponding',
'isSubmitting', 'isSubmitting',
'firstName', 'firstName',
'lastName', 'lastName',
'middleName',
'email', 'email',
'affiliation', 'affiliation',
'country',
]), ]),
}, },
})), })),
...@@ -125,15 +128,22 @@ export default compose( ...@@ -125,15 +128,22 @@ export default compose(
onSubmit: ( onSubmit: (
values, values,
dispatch, dispatch,
{ setAuthorEdit, setAuthors, authors, index, changeForm }, { setAuthorEdit, setAuthors, authors, index, changeForm, project },
) => { ) => {
const newAuthors = [ const newAuthor = values.edit
...authors.slice(0, index), editAuthor(project.id, newAuthor.id, newAuthor).then(
values.edit, () => {
...authors.slice(index + 1), getAuthors(project.id).then(
] data => {
setAuthorEdit(-1)() dispatch(authorSuccess())
setAuthors(newAuthors) setAuthorEdit(-1)()
setAuthors(data)
},
err => dispatch(authorFailure(err)),
)
},
err => dispatch(authorFailure(err)),
)
}, },
}), }),
)(AuthorEdit) )(AuthorEdit)
......
import React from 'react' import React from 'react'
import { get } from 'lodash'
import { th } from '@pubsweet/ui' import { th } from '@pubsweet/ui'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { connect } from 'react-redux' import { connect } from 'react-redux'
...@@ -15,10 +14,17 @@ import { ...@@ -15,10 +14,17 @@ import {
import { change as changeForm } from 'redux-form' import { change as changeForm } from 'redux-form'
import { SortableList } from 'pubsweet-component-sortable-list/src/components' import { SortableList } from 'pubsweet-component-sortable-list/src/components'
import { addAuthor, deleteAuthor, getAuthors } from '../../redux/authors' import {
addAuthor,
deleteAuthor,
getAuthors,
authorFailure,
getAuthorsTeam,
getAuthorError,
updateAuthorsTeam,
} from '../../redux/authors'
import Author from './Author' import Author from './Author'
import countries from './countries'
import StaticList from './StaticList' import StaticList from './StaticList'
import AuthorAdder from './AuthorAdder' import AuthorAdder from './AuthorAdder'
import AuthorEditor from './AuthorEditor' import AuthorEditor from './AuthorEditor'
...@@ -36,6 +42,7 @@ const Authors = ({ ...@@ -36,6 +42,7 @@ const Authors = ({
setEditMode, setEditMode,
editedAuthor, editedAuthor,
setFormAuthors, setFormAuthors,
error,
...rest ...rest
}) => ( }) => (
<Root> <Root>
...@@ -68,6 +75,7 @@ const Authors = ({ ...@@ -68,6 +75,7 @@ const Authors = ({
{...rest} {...rest}
/> />
)} )}
{error && <ErrorMessage>{error}</ErrorMessage>}
</Root> </Root>
) )
...@@ -77,11 +85,13 @@ export default compose( ...@@ -77,11 +85,13 @@ export default compose(
connect( connect(
state => ({ state => ({
currentUser: state.currentUser.user, currentUser: state.currentUser.user,
error: getAuthorError(state),
}), }),
{ {
addAuthor, addAuthor,
changeForm, changeForm,
deleteAuthor, deleteAuthor,
authorFailure,
}, },
), ),
withState('authors', 'setAuthors', []), withState('authors', 'setAuthors', []),
...@@ -104,11 +114,21 @@ export default compose( ...@@ -104,11 +114,21 @@ export default compose(
changeForm('wizard', 'editMode', mode) changeForm('wizard', 'editMode', mode)
setEditMode(v => mode) setEditMode(v => mode)
}, },
dropItem: ({ authors, setFormAuthors }) => () => { dropItem: ({ authors, setFormAuthors, project, authorFailure }) => () => {
setFormAuthors(authors) setFormAuthors(authors)
getAuthorsTeam(project.id)
.then(team => {
const members = authors.map(a => a.id)
updateAuthorsTeam(team.id, { members }).catch(err => {
authorFailure(err)
getAuthors(project.id).then(setFormAuthors)
})
})
.catch(err => {
authorFailure(err)
getAuthors(project.id).then(setFormAuthors)
})
}, },
countryParser: () => countryCode =>
get(countries.find(c => c.value === countryCode), 'label'),
parseAuthorType: () => (isSubmitting, isCorresponding, index) => { parseAuthorType: () => (isSubmitting, isCorresponding, index) => {
if (isSubmitting) return `#${index + 1} Submitting author` if (isSubmitting) return `#${index + 1} Submitting author`
if (isCorresponding) return `#${index + 1} Corresponding author` if (isCorresponding) return `#${index + 1} Corresponding author`
...@@ -121,14 +141,20 @@ export default compose( ...@@ -121,14 +141,20 @@ export default compose(
const newAuthors = SortableList.moveItem(authors, dragIndex, hoverIndex) const newAuthors = SortableList.moveItem(authors, dragIndex, hoverIndex)
setFormAuthors(newAuthors) setFormAuthors(newAuthors)
}, },
removeAuthor: ({ authors, setFormAuthors, deleteAuthor, project }) => ( removeAuthor: ({
id, authors,
authorEmail, setFormAuthors,
) => () => { deleteAuthor,
deleteAuthor(project.id, id).then(() => { authorFailure,
const newAuthors = authors.filter(a => a.id !== id) project,
setFormAuthors(newAuthors) }) => (id, authorEmail) => () => {
}) deleteAuthor(project.id, id).then(
() => {
const newAuthors = authors.filter(a => a.id !== id)
setFormAuthors(newAuthors)
},
err => authorFailure(err),
)
}, },
setAsCorresponding: ({ authors, setFormAuthors }) => authorEmail => () => { setAsCorresponding: ({ authors, setFormAuthors }) => authorEmail => () => {
const newAuthors = authors.map( const newAuthors = authors.map(
...@@ -156,4 +182,7 @@ const Root = styled.div` ...@@ -156,4 +182,7 @@ const Root = styled.div`
border: ${th('borderDefault')}; border: ${th('borderDefault')};
padding: ${th('subGridUnit')}; padding: ${th('subGridUnit')};
` `
const ErrorMessage = styled.div`
color: ${th('colorError')};
`
// #endregion // #endregion
...@@ -7,7 +7,6 @@ export default ({ ...@@ -7,7 +7,6 @@ export default ({
editIndex, editIndex,
setFormAuthors, setFormAuthors,
removeAuthor, removeAuthor,
countryParser,
editComponent, editComponent,
setAuthorEdit, setAuthorEdit,
parseAuthorType, parseAuthorType,
...@@ -27,16 +26,15 @@ export default ({ ...@@ -27,16 +26,15 @@ export default ({
}, },
setAuthors: setFormAuthors, setAuthors: setFormAuthors,
setAuthorEdit, setAuthorEdit,
countryParser,
parseAuthorType, parseAuthorType,
setAsCorresponding, setAsCorresponding,
...author, ...author,
...rest,
}) })
) : ( ) : (
<Author <Author
key={author.firstName} key={author.id}
{...author} {...author}
countryParser={countryParser}
index={index} index={index}
parseAuthorType={parseAuthorType} parseAuthorType={parseAuthorType}
removeAuthor={removeAuthor} removeAuthor={removeAuthor}
......
import { get } from 'lodash' import { get, head } from 'lodash'
import { create, get as apiGet, remove } from 'pubsweet-client/src/helpers/api' import {
create,
get as apiGet,
remove,
update,
} from 'pubsweet-client/src/helpers/api'
// constants // constants
const REQUEST = 'authors/REQUEST' const REQUEST = 'authors/REQUEST'
...@@ -11,7 +16,7 @@ export const authorRequest = () => ({ ...@@ -11,7 +16,7 @@ export const authorRequest = () => ({
type: REQUEST, type: REQUEST,
}) })
export const authorFaiure = error => ({ export const authorFailure = error => ({
type: FAILURE, type: FAILURE,
error, error,
}) })
...@@ -22,19 +27,31 @@ export const authorSuccess = () => ({ ...@@ -22,19 +27,31 @@ export const authorSuccess = () => ({
export const addAuthor = (author, collectionId) => dispatch => { export const addAuthor = (author, collectionId) => dispatch => {
dispatch(authorRequest()) dispatch(authorRequest())
return create(`/users/invite/${collectionId}`, { return create(`/collections/${collectionId}/users`, {
email: author.email, email: author.email,
role: 'author', role: 'author',
...author, ...author,
}) })
} }
export const deleteAuthor = (collectionId, userId) => dispatch => export const deleteAuthor = (collectionId, userId) => dispatch => {
remove(`/collections/${collectionId}/users/${userId}?role=author`) dispatch(authorRequest())
// Promise.resolve(author) return remove(`/collections/${collectionId}/users/${userId}`)
}
export const editAuthor = (collectionId, userId, body) =>
update(`/collections/${collectionId}/users/${userId}`, body)
export const getAuthors = collectionId => export const getAuthors = collectionId =>
apiGet(`/collections/${collectionId}/users?role=author`) apiGet(`/collections/${collectionId}/users`)
export const getAuthorsTeam = collectionId =>
apiGet(`/teams?object.id=${collectionId}&group=author`).then(teams =>
head(teams),
)
export const updateAuthorsTeam = (teamId, body) =>
update(`/teams/${teamId}s`, body)
// selectors // selectors
export const getFragmentAuthors = (state, fragmentId) => export const getFragmentAuthors = (state, fragmentId) =>
...@@ -57,7 +74,7 @@ export default (state = initialState, action) => { ...@@ -57,7 +74,7 @@ export default (state = initialState, action) => {
case FAILURE: case FAILURE:
return { return {
...initialState, ...initialState,
error: action.error, error: get(JSON.parse(get(action.error, 'response') || {}), 'error'),
isFetching: false, isFetching: false,
} }
case 'UPDATE_FRAGMENT_SUCCESS': case 'UPDATE_FRAGMENT_SUCCESS':
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment