import React from 'react' import { omit } from 'lodash' import styled, { withTheme } from 'styled-components' import { th } from '@pubsweet/ui-toolkit' import { Button, Action, H1, H2, H3, Icon } from '@pubsweet/ui' import { Page, B, Buttons, Close, CloseButton, Modal, PreviewPage, PreviewPanel, EditPanel, PanelHeader, PanelContent, SectionContent as Content, SectionHeader as Header, } from '../ui' import UploadFiles, { SubmissionTypes } from '../upload-files' import PubMedSearch from '../citation-search' import { FileThumbnails } from '../preview-files' import ManuscriptPreview from '../ManuscriptPreview' import { NoteMutations } from '../SubmissionMutations' import GrantSearch from '../GrantSearch' import Citation from './Citation' import ResolveDuplicates from './ResolveDuplicates' import SelectReviewer from './SelectReviewer' import SubmitForm from './SubmitForm' import SubmitHighlights from './SubmitHighlights' const Alert = withTheme(({ children, theme }) => ( <Icon color={theme.colorError} size={3}> {children} </Icon> )) const ErrorReport = styled.p` white-space: pre-wrap; font-style: italic; margin-top: 0; color: ${th('colorError')}; ` const ErrorMessage = styled.p` color: ${th('colorError')}; font-size: ${th('fontSizeBaseSmall')}; display: flex; align-items: flex-start; margin-left: calc(-${th('gridUnit')} / 2); ` const ReviewerWithMutations = NoteMutations(SelectReviewer) const PubMedWithMutations = NoteMutations(PubMedSearch) class Submit extends React.Component { constructor(props) { super(props) this.state = { editing: null, highlights: '', error: '', prune: false, } } componentDidMount() { if ( this.props.currentUser.admin && this.props.manuscript.status === 'submitted' // && // this.props.currentVersion.source ) { const fake = document.createElement('div') // fake.innerHTML = this.props.currentVersion.source this.setState({ highlights: fake.textContent }) } } changeCitation = citation => { this.props.changeCitation(citation) this.setState({ editing: null }) } formatName = name => `${name.title ? `${name.title} ` : ''}${name.givenNames} ${name.surname}` render() { const { currentUser, manuscript, duplicates } = this.props const { id: mId, meta, journal, files: allfiles, status, teams, formState, } = manuscript if (teams && allfiles) { const { editing, highlights, prune } = this.state const { fundingGroup: grants, releaseDelay = '', unmatchedJournal, notes, } = meta const fundingGroup = grants ? grants.map(g => { const n = omit(g, '__typename') n.pi = omit(g.pi, '__typename') return n }) : [] const files = allfiles ? allfiles.filter( file => !file.type || file.type === 'manuscript' || SubmissionTypes.some(t => t.value === file.type), ) : [] const reviewerNote = notes ? notes.find(n => n.notesType === 'selectedReviewer') : null let reviewer = null if (teams && teams.find(team => team.role === 'reviewer')) { const rev = teams.find(team => team.role === 'reviewer').teamMembers[0] reviewer = { id: rev.user.id, name: rev.alias.name, } } const selectedReviewer = reviewerNote ? JSON.parse(reviewerNote.content) : reviewer const submitter = teams && teams.find(team => team.role === 'submitter') ? teams.find(team => team.role === 'submitter').teamMembers[0] : null const citationInformation = { title: 'Citation', content: <Citation journal={journal} metadata={meta} />, edit: ( <div data-citation> <H3>Citation</H3> <PubMedWithMutations citationData={this.changeCitation} manuscript={manuscript} /> </div> ), error: (currentUser.admin && status === 'submitted' && unmatchedJournal) || duplicates ? ( <React.Fragment> {unmatchedJournal && ( <ErrorMessage> <Icon color="currentColor" size={2}> alert_circle </Icon> Journal is not in the NLM Catalog. </ErrorMessage> )} {duplicates && ( <React.Fragment> <Button onClick={() => this.setState({ prune: true })} primary > Resolve duplicates </Button> <ErrorMessage> <Icon color="currentColor" size={2}> alert_circle </Icon> Submission is likely a duplicate. </ErrorMessage> </React.Fragment> )} </React.Fragment> ) : null, } const manuscriptFiles = { title: 'Files', content: <FileThumbnails files={files} />, edit: <div data-upload />, error: files && files .filter(file => !file.type || SubmissionTypes.includes(file.type)) .some(file => !file.label || !file.type) ? ( <ErrorMessage> <Icon color="currentColor" size={2}> alert_circle </Icon> All files must have a type and a label. </ErrorMessage> ) : null, } const fundingInfo = { title: 'Funding', content: ( <div> {fundingGroup && fundingGroup.length > 0 && ( <p> <B>Grants: </B> {fundingGroup.map((f, t) => ( <span key={f.awardId}> {`${f.fundingSource} ${f.awardId}`} {t !== fundingGroup.length - 1 && ', '} </span> ))} </p> )} {(releaseDelay || typeof releaseDelay === 'number') && ( <p> <B>Embargo: </B> {`${releaseDelay} month${ parseInt(releaseDelay, 10) === 1 ? '' : 's' }`} </p> )} </div> ), edit: ( <GrantSearch changedEmbargo={this.props.updateEmbargo} changedGrants={this.props.updateGrants} selectedEmbargo={releaseDelay} selectedGrants={fundingGroup} /> ), error: !fundingGroup || fundingGroup.length === 0 || !releaseDelay ? ( <ErrorMessage> <Icon color="currentColor" size={2}> alert_circle </Icon> {(!fundingGroup || fundingGroup.length === 0) && 'Grants from Europe PMC Funders must be listed.'} {(!fundingGroup || fundingGroup.length === 0) && !releaseDelay && <br />} {!releaseDelay && 'Embargo period must be set.'} </ErrorMessage> ) : null, } const reviewerSelect = { title: 'Reviewer', content: selectedReviewer && ( <p> {selectedReviewer.id && submitter.user.id === selectedReviewer.id ? ( `Manuscript Submitter (${this.formatName(submitter.alias.name)})` ) : ( <React.Fragment> {this.formatName(selectedReviewer.name)} {selectedReviewer.id && currentUser.id === selectedReviewer.id && ' (Me)'} </React.Fragment> )} </p> ), edit: !reviewer || currentUser.id !== reviewer.id ? ( <ReviewerWithMutations currentUser={currentUser} funding={fundingGroup} manuscriptId={mId} reviewer={reviewer} reviewerNote={reviewerNote} submitter={submitter} /> ) : null, error: !selectedReviewer && ( <ErrorMessage> <Icon color="currentColor" size={2}> alert_circle </Icon> Reviewer must be indicated. </ErrorMessage> ), } const sections = [ citationInformation, manuscriptFiles, fundingInfo, reviewerSelect, ] const highlightTerms = { title: 'Referenced attachments', content: <SubmitHighlights highlights={highlights} />, edit: '', error: '', } if (currentUser.admin && status === 'submitted') { sections.splice(2, 0, highlightTerms) } if ( (reviewer && reviewer.id === currentUser.id && !['in-review', 'submission-error'].includes(status)) || (submitter && submitter.user.id === currentUser.id && !['INITIAL', 'READY', 'submission-error'].includes(status)) ) { return ( <Modal> <H2>Thank you for your submission</H2> <p>{`Your submission is now ${ status === 'submitted' || status === 'in-review' ? 'in review' : 'being processed' }. You will receive email updates as your manuscript is processed. You can also log in to Europe PMC plus at any time to check the status of your submission.`}</p> <Buttons right> <Button onClick={() => this.props.history.push('/')} primary> Done </Button> </Buttons> </Modal> ) } else if (editing) { return ( <Page> <Close> <CloseButton onClick={() => this.setState({ editing: null })} /> </Close> {editing.props['data-upload'] ? ( <div> <H2>Files</H2> <UploadFiles checked files={files} manuscript={mId} types={SubmissionTypes} /> </div> ) : ( <React.Fragment>{editing}</React.Fragment> )} {this.state.error && ( <ErrorMessage> <Icon color="currentColor" size={2}> alert_circle </Icon> {this.state.error} </ErrorMessage> )} <Buttons> <Button onClick={() => this.setState({ editing: null })} primary={!editing.props['data-citation']} > {editing.props['data-citation'] ? 'Cancel' : 'Save'} </Button> </Buttons> </Page> ) } return ( <PreviewPage> <PreviewPanel> <div> <PanelHeader> <H1>Preview submission</H1> </PanelHeader> <PanelContent> <ManuscriptPreview file={files.find(file => file.type === 'manuscript')} textContent={highlights => currentUser.admin && status === 'submitted' ? this.setState({ highlights }) : false } /> </PanelContent> </div> </PreviewPanel> <EditPanel> <div> <PanelHeader> <H2> {(status === 'submission-error' && 'Edit') || (status === 'submitted' && 'Review') || 'Confirm'} {` input & approve`} </H2> </PanelHeader> <PanelContent> <Content> {status === 'submission-error' && formState && ( <ErrorReport>{formState}</ErrorReport> )} </Content> {sections.map(sec => ( <React.Fragment key={sec.title}> <Header error={!!sec.error}> <H3>{sec.title}</H3> {sec.edit && ( <Action id={`edit-${sec.title}`} onClick={() => this.setState({ editing: sec.edit })} > {!!sec.error && <Alert>alert_circle</Alert>} <Icon color="currentColor" size={3}> edit </Icon> </Action> )} </Header> <Content> <div> {sec.content} {sec.error} </div> </Content> </React.Fragment> ))} <SubmitForm currentUser={currentUser} manuscript={this.props.manuscript} sections={sections} /> </PanelContent> </div> </EditPanel> {duplicates && prune && ( <ResolveDuplicates close={() => this.setState({ prune: false })} current={manuscript} duplicates={duplicates} /> )} </PreviewPage> ) } return null } } export default Submit