Skip to content
Snippets Groups Projects
ActivityDetails.jsx 4.44 KiB
Newer Older
import React, { Fragment } from 'react'
ahamelers's avatar
ahamelers committed
import { Mutation } from 'react-apollo'
import { H2, Button } from '@pubsweet/ui'
Yuci Gou's avatar
Yuci Gou committed
import { th } from '@pubsweet/ui-toolkit'
Yuci Gou's avatar
Yuci Gou committed
import styled from 'styled-components'
Yuci Gou's avatar
Yuci Gou committed
import moment from 'moment'
ahamelers's avatar
ahamelers committed
import { Buttons, Close, CloseButton, Table, Portal, TextArea } from '../ui'
ahamelers's avatar
ahamelers committed
import Mailer from '../mailer'
ahamelers's avatar
ahamelers committed
import { CREATE_NOTE } from '../operations'
import EventDescription from './EventDescription'
import { QUERY_ACTIVITY_INFO } from './operations'
Yuci Gou's avatar
Yuci Gou committed
const DetailsTable = styled(Table)`
  width: 100%;
ahamelers's avatar
ahamelers committed
  @media screen and (max-width: 600px) {
    th {
      display: none;
    }
    tr {
      border: ${th('borderWidth')} ${th('borderStyle')} ${th('colorBorder')};
    }
  }
Yuci Gou's avatar
Yuci Gou committed
`
ahamelers's avatar
ahamelers committed
const TD = styled.td`
  font-size: ${th('fontSizeBaseSmall')};
ahamelers's avatar
ahamelers committed
  @media screen and (max-width: 600px) {
    display: inline-block;
    width: 100%;
    border: 0 !important;
  }
ahamelers's avatar
ahamelers committed
`
const TdDate = styled(TD)`
Yuci Gou's avatar
Yuci Gou committed
  vertical-align: top;
ahamelers's avatar
ahamelers committed
  @media screen and (max-width: 600px) {
    width: 50%;
    white-space: normal;
  }
Yuci Gou's avatar
Yuci Gou committed
`
const TdPerson = TdDate

ahamelers's avatar
ahamelers committed
const NewMsgBtn = styled(Button)`
  padding: calc(${th('gridUnit')} / 2) ${th('gridUnit')};
  margin-left: ${th('gridUnit')};
  font-size: ${th('fontSizeBaseSmall')};
`

const DetailsHeading = styled.div`
  display: flex;
  align-items: baseline;
  justify-content: space-between;
`
const NewNote = ({ close, manuscriptId, message, onChange }) => (
  <Mutation
    mutation={CREATE_NOTE}
    refetchQueries={() => [
      {
        query: QUERY_ACTIVITY_INFO,
        variables: { id: manuscriptId },
      },
    ]}
  >
    {(createNote, { data }) => {
      const newNote = async () => {
        await createNote({
          variables: {
            data: {
              manuscriptId,
              notesType: 'userMessage',
              content: JSON.stringify(message),
            },
          },
        })
        onChange('')
        close()
      }
      return (
        <Portal transparent>
          <Close style={{ margin: 0 }}>
            <CloseButton onClick={() => close()} />
          </Close>
          <H2>Add a note</H2>
          <TextArea
            label="Note (visible only to administrators)"
            onChange={e => onChange(e.target.value)}
            value={message}
          />
          <Buttons right>
            <Button disabled={!message} onClick={() => newNote()} primary>
              Save
            </Button>
            <Button onClick={() => close()}>Cancel</Button>
          </Buttons>
        </Portal>
      )
    }}
  </Mutation>
)

Yuci Gou's avatar
Yuci Gou committed
const ActivityList = ({ manuscript }) =>
Yuci Gou's avatar
Yuci Gou committed
  manuscript.audits
    .reduce((reversed, audit) => {
      reversed.unshift(audit)
      return reversed
    }, [])
    .map(audit => (
      <tr key={audit.id}>
        <TdDate>{moment(audit.created).format('DD/MM/YYYY HH:mm')}</TdDate>
Yuci Gou's avatar
Yuci Gou committed
        <TdPerson>{`${audit.user.givenNames} ${audit.user.surname}`}</TdPerson>
ahamelers's avatar
ahamelers committed
        <TD>
          <EventDescription audit={audit} manuscript={manuscript} />
ahamelers's avatar
ahamelers committed
        </TD>
Yuci Gou's avatar
Yuci Gou committed
      </tr>
    ))
Yuci Gou's avatar
Yuci Gou committed
class ActivityDetails extends React.Component {
ahamelers's avatar
ahamelers committed
  state = {
    sendingMail: false,
    newNote: false,
    message: '',
  }
Yuci Gou's avatar
Yuci Gou committed
  render() {
    return (
      <Fragment>
        <DetailsHeading>
          <div>
            <H2>Details</H2>
          </div>
          <div>
ahamelers's avatar
ahamelers committed
            <NewMsgBtn onClick={() => this.setState({ newNote: true })}>
              Add note
            </NewMsgBtn>
Yuci Gou's avatar
Yuci Gou committed
            <NewMsgBtn
              onClick={() => this.setState({ sendingMail: true })}
              primary
            >
ahamelers's avatar
ahamelers committed
              Send email
Yuci Gou's avatar
Yuci Gou committed
            </NewMsgBtn>
          </div>
          {this.state.sendingMail && (
ahamelers's avatar
ahamelers committed
            <Mailer
              close={() => this.setState({ sendingMail: false })}
              currentUser={this.props.currentUser}
              manuscript={this.props.manuscript}
            />
Yuci Gou's avatar
Yuci Gou committed
          )}
ahamelers's avatar
ahamelers committed
          {this.state.newNote && (
            <NewNote
              close={() => this.setState({ newNote: false })}
              manuscriptId={this.props.manuscript.id}
              message={this.state.message}
              onChange={message => this.setState({ message })}
            />
          )}
Yuci Gou's avatar
Yuci Gou committed
        </DetailsHeading>
Yuci Gou's avatar
Yuci Gou committed

Yuci Gou's avatar
Yuci Gou committed
        <DetailsTable>
          <tbody>
            <tr>
              <th>Date</th>
              <th>Person</th>
Yuci Gou's avatar
Yuci Gou committed
              <th>Event</th>
            </tr>
            <ActivityList manuscript={this.props.manuscript} />
          </tbody>
        </DetailsTable>
      </Fragment>
    )
  }
}

export default ActivityDetails