Skip to content
Snippets Groups Projects
Submit.jsx 13.8 KiB
Newer Older
import React from 'react'
import styled, { withTheme } from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { Button, Action, CheckboxGroup, H1, H2, H3, Icon } from '@pubsweet/ui'
import {
  Page,
  Buttons,
  CloseModal,
  PreviewPage,
Audrey Hamelers's avatar
Audrey Hamelers committed
  PreviewFooter,
  PreviewPanel,
  EditPanel,
  PanelHeader,
  PanelContent,
  SectionContent as Content,
  SectionHeader as Header,
} from '../ui'
import UploadFiles, { SubmissionTypes } from '../upload-files'
import ManuscriptPreview from '../ManuscriptPreview'
ahamelers's avatar
ahamelers committed
import { NoteMutations } from '../SubmissionMutations'
import SubmissionCancel from '../SubmissionCancel'
Audrey Hamelers's avatar
Audrey Hamelers committed
import ResolveDuplicates from '../ResolveDuplicates'
import SubmitText from './SubmitText'
import SubmitComplete from './SubmitComplete'
Audrey Hamelers's avatar
Audrey Hamelers committed
import SubmitApprove from './SubmitApprove'
import submitSections, { ErrorMessage } from './SubmitSections'
import SubmissionErrorReport, { adminOptions } from '../SubmissionErrorReport'
import ReviewerErrorReport from './ReviewerErrorReport'

const Alert = withTheme(({ children, theme }) => (
ahamelers's avatar
ahamelers committed
  <Icon color={theme.colorError} size={2.75}>
    {children}
  </Icon>
))

const CloseEdit = styled(CloseModal)`
Audrey Hamelers's avatar
Audrey Hamelers committed
  margin: calc(${th('gridUnit')} * 6) auto calc(${th('gridUnit')} * 2);
`
const ErrorReport = styled.p`
  white-space: pre-wrap;
  font-style: italic;
  margin-top: 0;
  color: ${th('colorError')};
`
Audrey Hamelers's avatar
Audrey Hamelers committed
const DuplicatesWithMutations = NoteMutations(ResolveDuplicates)

class Submit extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
Audrey Hamelers's avatar
Audrey Hamelers committed
      approve: false,
      cancel: false,
Audrey Hamelers's avatar
Audrey Hamelers committed
      checkedBoxes: [],
      editing: null,
      highlights: '',
      error: '',
      prune: false,
      reject: false,
      message: '',
    }
  }
  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)
ahamelers's avatar
ahamelers committed
    this.setState({ editing: null })
  pruneDupes = () => this.setState({ prune: true })
  render() {
ahamelers's avatar
ahamelers committed
    const { currentUser, manuscript, duplicates: checkDupes = [] } = this.props
    const {
      id: mId,
      meta,
      files: allfiles,
      status,
      teams,
      formState,
Audrey Hamelers's avatar
Audrey Hamelers committed
      journal,
    } = manuscript
    if (teams && allfiles) {
      const {
        editing,
        highlights,
        prune,
        cancel,
        approve,
        checkedBoxes,
        reject,
        message,
      } = this.state
      const sections = submitSections(
        manuscript,
        checkDupes,
        this.changeCitation,
        currentUser,
        highlights,
        this.pruneDupes,
        this.props.updateEmbargo,
        this.props.updateGrants,
      )
Audrey Hamelers's avatar
Audrey Hamelers committed
      const { notes, releaseDelay, unmatchedJournal } = meta
      const files = allfiles
        ? allfiles.filter(
            file =>
              !file.type ||
              file.type === 'manuscript' ||
              SubmissionTypes.some(t => t.value === file.type),
          )
        : []
      const xml = allfiles.find(f => f.type === 'PMC') || 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 submitter =
        teams && teams.find(team => team.role === 'submitter')
          ? teams.find(team => team.role === 'submitter').teamMembers[0]
          : null
      const { title, givenNames, surname } = submitter.alias.name
      const submitterName = `${title && `${title} `}${givenNames} ${surname}`
Audrey Hamelers's avatar
Audrey Hamelers committed
      const dupeNote = notes
        ? notes.find(n => n.notesType === 'notDuplicates')
        : null
      const notDupes = dupeNote ? JSON.parse(dupeNote.content) : []
Audrey Hamelers's avatar
Audrey Hamelers committed
      const duplicates = checkDupes.filter(d => !notDupes.includes(d.id))
      return (
        <React.Fragment>
          {(() => {
            if (
              (reviewer &&
                reviewer.id === currentUser.id &&
                !['in-review', 'submission-error'].includes(status)) ||
              (submitter &&
                submitter.user.id === currentUser.id &&
                !['INITIAL', 'READY', 'submission-error'].includes(status))
            ) {
              window.scrollY = 0
              window.pageYOffset = 0
              document.scrollingElement.scrollTop = 0
              return (
                <SubmitComplete
                  cancel={() => this.setState({ cancel: true })}
                  currentUser={currentUser}
                  history={this.props.history}
                  manuscript={manuscript}
              )
            } else if (editing) {
              return (
                <Page>
                  <CloseEdit onClick={() => this.setState({ editing: null })} />
                  {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 (
Audrey Hamelers's avatar
Audrey Hamelers committed
              <React.Fragment>
                <PreviewPage>
                  <PreviewPanel>
                    <div>
                      <PanelHeader>
                        <H1>Preview submission</H1>
                      </PanelHeader>
                      <PanelContent>
                        <ManuscriptPreview
                          file={
                            allfiles.find(file => file.type === 'source') ||
                            allfiles.find(file => file.type === 'manuscript')
                          }
Audrey Hamelers's avatar
Audrey Hamelers committed
                          textContent={highlights =>
                            currentUser.admin && status === 'submitted'
                              ? this.setState({ highlights })
                              : false
                          }
                        />
                      </PanelContent>
                    </div>
                  </PreviewPanel>
                  <EditPanel>
                    <div>
                      <PanelHeader>
                        <H2>Check submission details</H2>
                      </PanelHeader>
                      <PanelContent>
                        {status === 'submission-error' && formState && (
                          <ErrorReport>{formState}</ErrorReport>
                        )}
                        <SubmitText
                          currentUser={currentUser}
                          status={status}
                          teams={teams}
Audrey Hamelers's avatar
Audrey Hamelers committed
                        {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 })
                                  }
                                  style={{
                                    display: 'inline-flex',
                                    alignItems: 'center',
                                  }}
                                >
                                  {!!sec.error && <Alert>alert_circle</Alert>}
                                  <Icon color="currentColor" size={2.5}>
                                    edit
                                  </Icon>
                                  Edit
                                </Action>
                              )}
                            </Header>
                            <Content>
                              <div>
                                {sec.content}
                                {sec.error}
                              </div>
                            </Content>
                          </React.Fragment>
                        ))}
                        {currentUser.admin && status === 'submitted' && (
                          <React.Fragment>
                            <Header>
                              <H3>Report Errors</H3>
                            </Header>
                            <Content>
                              <div>
                                <p>
                                  {`Check the following and select anything that is missing:`}
                                </p>
                                <CheckboxGroup
                                  name="admin-checklist"
                                  onChange={c =>
                                    this.setState({ checkedBoxes: c })
                                  }
                                  options={adminOptions}
                                  value={checkedBoxes}
                                />
                              </div>
                            </Content>
                          </React.Fragment>
                        )}
Audrey Hamelers's avatar
Audrey Hamelers committed
                      </PanelContent>
                    </div>
                  </EditPanel>
                  {duplicates.length > 0 && prune && (
                    <DuplicatesWithMutations
                      close={() => this.setState({ prune: false })}
                      duplicates={duplicates}
                      manuscript={manuscript}
                      note={dupeNote}
                    />
                  )}
                </PreviewPage>
                <PreviewFooter>
                  <div>
                    <div>
                      {currentUser.admin && status === 'submitted' ? (
                        <SubmitApprove
                          adminButton
                          manuscriptId={manuscript.id}
                        />
                      ) : (
                        <Button
                          disabled={sections.some(sec => sec.error)}
                          onClick={() => this.setState({ approve: true })}
                          primary
                        >
                          Submit manuscript
                        </Button>
                      )}
                      {(currentUser.admin ||
                        (reviewer &&
                          reviewer.id === currentUser.id &&
                          status === 'in-review')) && (
                        <Button onClick={() => this.setState({ reject: true })}>
                          Reject submission
                        </Button>
                      )}
                    </div>
Audrey Hamelers's avatar
Audrey Hamelers committed
                    {submitter && submitter.user.id === currentUser.id && (
                      <Action
                        onClick={() => this.setState({ cancel: true })}
                        style={{ display: 'inline-flex', alignItems: 'center' }}
                      >
                        <Icon color="currentColor" size={2.5}>
                          trash-2
                        </Icon>
                        Cancel submission
                      </Action>
                    )}
                  </div>
Audrey Hamelers's avatar
Audrey Hamelers committed
                </PreviewFooter>
              </React.Fragment>
            )
          })()}
          {cancel && (
            <SubmissionCancel
              cancel={() =>
                this.props.deleteMan(() => this.props.history.push('/'))
              }
Audrey Hamelers's avatar
Audrey Hamelers committed
              close={() => this.setState({ cancel: false })}
            />
          )}
          {approve && (
            <SubmitApprove
              checkedBoxes={checkedBoxes}
              close={() => this.setState({ approve: false })}
              currentUser={currentUser}
              journal={journal ? journal.meta.nlmta : unmatchedJournal}
              manuscriptId={manuscript.id}
Audrey Hamelers's avatar
Audrey Hamelers committed
              releaseDelay={releaseDelay}
              setChecked={c => this.setState({ checkedBoxes: c })}
Audrey Hamelers's avatar
Audrey Hamelers committed
            />
          {reject && (
            <Portal transparent>
              <CloseModal onClick={() => this.setState({ reject: false })} />
              {currentUser.admin && status === 'submitted' ? (
                <SubmissionErrorReport
                  checkedBoxes={checkedBoxes}
                  close={() => this.setState({ reject: false })}
                  manuscript={manuscript}
                  teams={teams}
                />
              ) : (
                <ReviewerErrorReport
                  close={() => this.setState({ reject: false })}
                  manuscriptId={manuscript.id}
                  message={message}
                  onChange={message => this.setState({ message })}
                  submitter={submitterName}
                />
              )}
            </Portal>
          )}
        </React.Fragment>
      )
    }
    return null
  }
}

export default Submit