-
Audrey Hamelers authored88ac8a76
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SelectReviewer.jsx 9.79 KiB
import React from 'react'
import { ApolloConsumer } from 'react-apollo'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { TextField, RadioGroup, ErrorText, H2, H3, Icon } from '@pubsweet/ui'
import { LoadingIcon } from '../ui'
import { GET_USER } from './operations'
const Joi = require('joi')
const ReviewerForm = styled.div`
margin-bottom: calc(${th('gridUnit')} * 6);
`
const Loading = styled.div`
padding: calc(${th('gridUnit')} * 2) 0;
width: 100%;
justify-content: center;
align-items: center;
color: ${th('colorPrimary')};
display: inline-flex;
`
const NewReviewerForm = styled.div`
display: flex;
align-items: flex-start;
flex-wrap: wrap;
& > * {
padding: 0 calc(${th('gridUnit')} * 2);
width: calc(${th('gridUnit')} * 42);
}
`
const Alert = styled.div`
display: flex;
align-items: center;
color: ${th('colorError')};
`
class SelectReviewer extends React.Component {
state = {
newFormDisabled: true,
loading: true,
options: [],
name: '',
surname: '',
email: '',
selected: '',
nameErr: '',
surnameErr: '',
emailErr: '',
}
componentDidMount() {
const {
funding,
submitter,
currentUser,
selectedReviewer: note,
} = this.props
const selectedReviewer = note ? JSON.parse(note.content) : null
const { name: username } = submitter.alias
if (funding && funding.length > 0) {
let options = [
{
value: 'self',
label: `${
submitter.user.id === currentUser.id ? 'Me' : 'Manuscript Submitter'
} (${username.title ? `${username.title} ` : ''}${
username.givenNames
} ${username.surname})`,
},
]
let selected = ''
const emails = []
options = options.concat(
funding.reduce((opts, grant, i) => {
const { pi } = grant
const { email } = pi
if (!emails.some(e => e === email)) {
emails.push(email)
opts.push({
value: `pi-${i}`,
label: `${pi.title ? `${pi.title} ` : ''} ${pi.givenNames} ${
pi.surname
} (PI:${grant.awardId})`,
})
}
if (selectedReviewer && selectedReviewer.email === email) {
selected = `pi-${i}`
}
return opts
}, []),
)
options.push({
value: 'new',
label: 'Other reviewer',
})
let newState = {}
if (selectedReviewer && selected === '') {
if (selectedReviewer.id && currentUser.id === selectedReviewer.id) {
selected = 'self'
} else {
selected = 'new'
newState = {
name: selectedReviewer.name.givenNames,
surname: selectedReviewer.name.surname,
email: selectedReviewer.email,
newFormDisabled: false,
}
}
}
newState.selected = selected
newState.loading = false
newState.options = options
this.setState(newState)
} else {
this.setState({ loading: false })
}
}
setNameRef = nameInput => {
this.nameInput = nameInput
}
render() {
const {
selected,
name,
surname,
email,
newFormDisabled,
options,
loading,
} = this.state
const { selectedReviewer } = this.props
return (
<ApolloConsumer>
{client => {
const updateValues = async () => {
const validEmail = Joi.validate(
email,
Joi.string()
.email({ minDomainAtoms: 2 })
.required(),
)
const validName = Joi.validate(name, Joi.string().required())
const validSurname = Joi.validate(surname, Joi.string().required())
if (!validEmail.error && !validName.error && !validSurname.error) {
const reviewer = {
name: {
givenNames: name,
surname,
},
email,
}
const { data } = await client.query({
query: GET_USER,
variables: { email },
})
if (data.userByEmail) {
reviewer.id = data.userByEmail.id
}
if (selectedReviewer) {
this.props.changeNote({
id: selectedReviewer.id,
notesType: 'selectedReviewer',
content: JSON.stringify(reviewer),
})
} else {
this.props.newNote({
notesType: 'selectedReviewer',
content: JSON.stringify(reviewer),
})
}
}
this.setState({
nameErr: validName.error ? 'Given name is required.' : '',
surnameErr: validSurname.error ? 'Surname is required.' : '',
emailErr: validEmail.error ? 'Valid email is required.' : '',
})
}
const setReviewer = async value => {
if (value === 'new') {
this.setState({ newFormDisabled: false }, () => {
this.nameInput.querySelector('input').focus()
})
} else {
let reviewer = {}
this.setState({ newFormDisabled: true })
if (value === 'self') {
reviewer = {
id: this.props.currentUser.id,
}
} else {
const index = value.substring(3)
const { pi } = this.props.funding[index]
reviewer = {
name: {
title: pi.title,
givenNames: pi.givenNames,
surname: pi.surname,
},
email: pi.email,
}
const { data } = await client.query({
query: GET_USER,
variables: { email: pi.email },
})
if (data.userByEmail) {
reviewer.id = data.userByEmail.id
}
}
if (selectedReviewer) {
this.props.changeNote({
id: selectedReviewer.id,
notesType: 'selectedReviewer',
content: JSON.stringify(reviewer),
})
} else {
this.props.newNote({
notesType: 'selectedReviewer',
content: JSON.stringify(reviewer),
})
}
}
}
return (
<div>
<H2>Reviewer</H2>
<H3>Please designate a reviewer for the submission</H3>
<p>
{`The reviewer will be responsible for approving the web version of this manuscript. The reviewer must be an author of the manuscript.`}
</p>
{loading && (
<Loading>
<LoadingIcon />
</Loading>
)}
{options.length > 0 ? (
<ReviewerForm>
<RadioGroup
name="reviewerGroup"
onChange={setReviewer}
options={options}
value={selected}
/>
{!newFormDisabled && (
<NewReviewerForm>
<div ref={this.setNameRef}>
<TextField
disabled={newFormDisabled}
invalidTest={this.state.nameErr}
label="Given name(s)"
name="name"
onBlur={updateValues}
onChange={e =>
this.setState({ name: e.target.value })
}
value={name}
/>
{this.state.nameErr && (
<ErrorText>{this.state.nameErr}</ErrorText>
)}
</div>
<div>
<TextField
disabled={newFormDisabled}
invalidTest={this.state.nameErr}
label="Surname"
name="surname"
onBlur={updateValues}
onChange={e =>
this.setState({ surname: e.target.value })
}
value={surname}
/>
{this.state.surnameErr && (
<ErrorText>{this.state.surnameErr}</ErrorText>
)}
</div>
<div>
<TextField
disabled={newFormDisabled}
invalidTest={this.state.emailErr}
label="Email address"
name="email"
onBlur={updateValues}
onChange={e =>
this.setState({ email: e.target.value })
}
value={email}
/>
{this.state.emailErr && (
<ErrorText>{this.state.emailErr}</ErrorText>
)}
</div>
</NewReviewerForm>
)}
</ReviewerForm>
) : (
<Alert>
<Icon color="currentColor">alert_circle</Icon>
{`Error: Grants must be entered before a reviewer can be selected.`}
</Alert>
)}
</div>
)
}}
</ApolloConsumer>
)
}
}
export default SelectReviewer