-
Bogdan Cochior authored07eb880c
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
/* eslint-disable react/require-default-props */
import React from 'react'
import { last } from 'lodash'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { withProps, withHandlers, compose } from 'recompose'
import { Label, IconButton, Text } from './'
import { marginHelper } from './styledHelpers'
const parseFileSize = size => {
const kbSize = size / 1000
const mbSize = kbSize / 1000
const gbSize = mbSize / 1000
if (Math.floor(gbSize)) {
return `${Math.floor(gbSize)} GB`
} else if (Math.floor(mbSize)) {
return `${Math.floor(mbSize)} MB`
} else if (Math.floor(kbSize)) {
return `${Math.floor(kbSize)} kB`
}
return `${size} bytes`
}
const hasPreview = (name = '') => {
const extension = last(name.split('.')).toLocaleLowerCase()
return ['pdf', 'png', 'jpg'].includes(extension)
}
const FileItem = ({
fileSize,
onPreview,
item: file,
hasPreview,
hasDelete,
onDownload,
onDelete,
dragHandle = null,
...rest
}) => (
<Root data-test-id={`file-${file.id}`} {...rest}>
{typeof dragHandle === 'function' ? dragHandle() : dragHandle}
<FileInfo>
<Text mr={1} secondary whiteSpace="nowrap">
{file.name}
</Text>
<Label>{fileSize}</Label>
</FileInfo>
{hasPreview && (
<IconButton
icon="eye"
iconSize={2}
ml={1}
mr={1}
onClick={onPreview}
secondary
/>
)}
<IconButton
icon="download"
iconSize={2}
ml={hasPreview ? 0 : 1}
mr={1}
onClick={onDownload}
secondary
/>
{hasDelete && (
<IconButton
icon="trash"
iconSize={2}
mr={1}
onClick={onDelete}
secondary
/>
)}
</Root>
)
FileItem.propTypes = {
/** The file. */
item: PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
size: PropTypes.number,
}).isRequired,
/** Used when part of a sortable list. */
dragHandle: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
/** Handler for the preview button. */
onPreview: PropTypes.func,
/** Handler for the download button. */
onDownload: PropTypes.func,
/** Handler for the delete button. */
onDelete: PropTypes.func,
}
export default compose(
withProps(({ item: { name, size }, onDelete }) => ({
hasPreview: hasPreview(name),
hasDelete: !!onDelete,
fileSize: parseFileSize(size),
})),
withHandlers({
onDownload: ({ onDownload, item }) => () => {
typeof onDownload === 'function' && onDownload(item)
},
onPreview: ({ onPreview, item }) => () => {
typeof onPreview === 'function' && onPreview(item)
},
onDelete: ({ onDelete, item }) => () => {
typeof onDelete === 'function' && onDelete(item)
},
}),
)(FileItem)
// #region styles
const Root = styled.div`
align-items: center;
background-color: ${th('colorBackgroundHue')};
box-shadow: ${({ shadow }) => (shadow ? th('boxShadow') : 'none')};
border-radius: ${th('borderRadius')};
display: flex;
border: ${th('borderWidth')} ${th('borderStyle')} ${th('colorBorder')};
height: calc(${th('gridUnit')} * 5);
white-space: nowrap;
${marginHelper};
`
const FileInfo = styled.div`
align-items: center;
display: flex;
flex: 1;
justify-content: space-between;
height: calc(${th('gridUnit')} * 5);
padding: 0 ${th('gridUnit')};
border-right: ${th('borderWidth')} ${th('borderStyle')} ${th('colorBorder')};
`
// #endregion