Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ManuscriptCard.js 4.59 KiB
import React from 'react'
import { get } from 'lodash'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { withJournal } from 'xpub-journal'
import { H3, H4, DateParser } from '@pubsweet/ui'
import { compose, withHandlers, setDisplayName, withProps } from 'recompose'

import {
  Tag,
  Text,
  Row,
  Item,
  IconButton,
  ActionLink,
  TextTooltip,
  AuthorTagList,
  ReviewerBreakdown,
} from './'

import { OpenModal } from './modals'

const ManuscriptCard = ({
  onDelete,
  canDelete,
  onCardClick,
  fragment = {},
  manuscriptType = {},
  collection: { visibleStatus = 'Draft', handlingEditor, customId },
}) => {
  const {
    authors = [],
    metadata = {},
    id: fragmentId,
    submitted = null,
  } = fragment
  const { title = 'No title', journal = '', type = '' } = metadata
  return (
    <Root data-test-id={`fragment-${fragmentId}`} onClick={onCardClick}>
      <MainContainer>
        <Row alignItems="center" justify="space-between">
          <TextTooltip title={title}>
            <H3>{title}</H3>
          </TextTooltip>
          <Tag data-test-id="fragment-status" status>
            {visibleStatus}
          </Tag>
        </Row>
        {authors.length > 0 && (
          <Row alignItems="center" justify="flex-start" mb={1}>
            <AuthorTagList authors={authors} withTooltip />
          </Row>
        )}
        <Row alignItems="center" justify="flex-start" mb={1}>
          <Text customId mr={1}>{`ID ${customId}`}</Text>
          {submitted && (
            <DateParser humanizeThreshold={0} timestamp={submitted}>
              {timestamp => <Text mr={3}>Submitted on {timestamp}</Text>}
            </DateParser>
          )}
          <Text>{manuscriptType.label || type}</Text>
          <Text ml={1}>{journal}</Text>
        </Row>
        <Row alignItems="center" justify="flex-start" mb={1}>
          <H4>Handling editor</H4>
          <Text ml={1} mr={3}>
            {get(handlingEditor, 'name', 'Unassigned')}
          </Text>
          {handlingEditor && (
            <ReviewerBreakdown fragment={fragment} label="Reviewer Reports" />
          )}
          {canDelete && (
            <Item justify="flex-end" onClick={e => e.stopPropagation()}>
              <OpenModal
                confirmText="Delete"
                modalKey={`delete-${customId}`}
                onConfirm={onDelete}
                title="Are you sure you want to delete this submission?"
              >
                {onClickEvent => (
                  <ActionLink icon="trash" onClick={onClickEvent}>
                    Delete
                  </ActionLink>
                )}
              </OpenModal>
            </Item>
          )}
        </Row>
      </MainContainer>
      <SideNavigation>
        <IconButton icon="chevron-right" iconSize={2} />
      </SideNavigation>
    </Root>
  )
}

export default compose(
  withJournal,
  withHandlers({
    onCardClick: ({ onClick, collection = {}, fragment = {} }) => () => {
      onClick(collection, fragment)
    },
  }),
  withProps(
    ({
      fragment: { metadata },
      journal = {},
      collection: { status = 'draft' },
    }) => ({
      manuscriptType: get(journal, 'manuscriptTypes', []).find(
        t => t.value === get(metadata, 'type', ''),
      ),
      canDelete: status === 'draft',
    }),
  ),
  setDisplayName('ManuscriptCard'),
)(ManuscriptCard)

// #region styles
const MainContainer = styled.div`
  justify-content: flex-start;
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: calc(${th('gridUnit')} * 2);
  padding-bottom: ${th('gridUnit')};
  width: calc(100% - (${th('gridUnit')} * 5 / 2));

  ${Row} {
    [data-tooltipped] {
      overflow: hidden;
    }
    ${H3} {
      margin-bottom: 0;
      text-overflow: ellipsis;
      white-space: nowrap;
      overflow: hidden;
      padding-right: ${th('gridUnit')};
      flex: 11;
    }
  }
`

const SideNavigation = styled.div`
  align-items: center;
  background-color: ${th('colorBackgroundHue2')
    ? th('colorBackgroundHue2')
    : th('colorBackgroundHue')};
  border-top-right-radius: ${th('borderRadius')};
  border-bottom-right-radius: ${th('borderRadius')};
  display: flex;
  width: calc(${th('gridUnit')} * 5 / 2);
`

const Root = styled.div`
  background-color: #fff;
  border-radius: ${th('borderRadius')};
  box-shadow: ${th('boxShadow')};
  cursor: pointer;
  display: flex;
  margin: calc(${th('gridUnit')} / 4) calc(${th('gridUnit')} / 4)
    ${th('gridUnit')} calc(${th('gridUnit')} / 4);

  &:hover {
    box-shadow: ${th('dashboardCard.hoverShadow')};
  }

  ${H3} {
    margin: 0;
    margin-bottom: ${th('gridUnit')};
  }
`
// #endregion