Skip to content
Snippets Groups Projects
Commit daa3e7f6 authored by Alexandru Munteanu's avatar Alexandru Munteanu
Browse files

Add validations and add files to submit wizard

parent fd6e96d4
No related branches found
No related tags found
No related merge requests found
...@@ -3,24 +3,10 @@ import classnames from 'classnames' ...@@ -3,24 +3,10 @@ import classnames from 'classnames'
import classes from './FileDropzone.local.scss' import classes from './FileDropzone.local.scss'
const FileDropzone = ({ ...props }) => ( const FileDropzone = ({ label }) => (
<div className={classnames(classes.dropzone)}> <div className={classnames(classes.dropzone)}>
<span>Drag items here or use the upload button</span> <span>{label}</span>
</div> </div>
) )
// export default compose(
// DropTarget(
// 'item',
// {
// drop(props) {
// console.log('s-a dat drop', props)
// },
// },
// (connect, monitor) => ({
// connectDropTarget: connect.dropTarget(),
// }),
// ),
// )(FileDropzone)
export default FileDropzone export default FileDropzone
...@@ -19,7 +19,7 @@ class FilePicker extends Component { ...@@ -19,7 +19,7 @@ class FilePicker extends Component {
} }
render() { render() {
const { children } = this.props const { children, disabled } = this.props
return ( return (
<div> <div>
<input <input
...@@ -32,7 +32,7 @@ class FilePicker extends Component { ...@@ -32,7 +32,7 @@ class FilePicker extends Component {
{React.cloneElement(children, { {React.cloneElement(children, {
onClick: e => { onClick: e => {
e.preventDefault() e.preventDefault()
this.fileInput.click() !disabled && this.fileInput.click()
}, },
})} })}
</div> </div>
......
...@@ -3,8 +3,8 @@ import PropTypes from 'prop-types' ...@@ -3,8 +3,8 @@ import PropTypes from 'prop-types'
import classnames from 'classnames' import classnames from 'classnames'
import { Icon } from '@pubsweet/ui' import { Icon } from '@pubsweet/ui'
import { DropTarget } from 'react-dnd' import { DropTarget } from 'react-dnd'
import { compose, getContext } from 'recompose'
import { NativeTypes } from 'react-dnd-html5-backend' import { NativeTypes } from 'react-dnd-html5-backend'
import { compose, getContext, withHandlers, withState } from 'recompose'
import { SortableList } from 'pubsweet-components-faraday/src/components' import { SortableList } from 'pubsweet-components-faraday/src/components'
import FileItem from './FileItem' import FileItem from './FileItem'
...@@ -21,6 +21,7 @@ const DragHandle = () => ( ...@@ -21,6 +21,7 @@ const DragHandle = () => (
) )
const FileSection = ({ const FileSection = ({
error,
title, title,
files, files,
listId, listId,
...@@ -37,6 +38,8 @@ const FileSection = ({ ...@@ -37,6 +38,8 @@ const FileSection = ({
connectDropTarget, connectDropTarget,
allowedFileExtensions, allowedFileExtensions,
isFetching, isFetching,
canDropFile,
disabledFilepicker,
}) => }) =>
connectFileDrop( connectFileDrop(
connectDropTarget( connectDropTarget(
...@@ -49,21 +52,32 @@ const FileSection = ({ ...@@ -49,21 +52,32 @@ const FileSection = ({
})} })}
> >
<div className={classnames(classes.header)}> <div className={classnames(classes.header)}>
<span className={classnames(classes.title)}>{title}</span> <div className={classnames(classes['picker-container'])}>
{!isFetching[listId] ? ( <span className={classnames(classes.title)}>{title}</span>
<FilePicker {!isFetching[listId] ? (
allowedFileExtensions={allowedFileExtensions} <FilePicker
onUpload={addFile} allowedFileExtensions={allowedFileExtensions}
> disabled={disabledFilepicker()}
<div className={classnames(classes['upload-button'])}> onUpload={addFile}
<Icon>file-plus</Icon> >
<div
className={classnames({
[classes['upload-button']]: true,
[classes['disabled-picker']]: disabledFilepicker(),
})}
>
<Icon color={disabledFilepicker() ? '#999' : '#333'}>
file-plus
</Icon>
</div>
</FilePicker>
) : (
<div className={classnames(classes.rotate, classes.icon)}>
<Icon size={16}>loader</Icon>
</div> </div>
</FilePicker> )}
) : ( </div>
<div className={classnames(classes.rotate, classes.icon)}> <span className={classnames(classes.error)}>{error}</span>
<Icon size={16}>loader</Icon>
</div>
)}
</div> </div>
<SortableList <SortableList
beginDragProps={['id', 'index', 'name', 'listId']} beginDragProps={['id', 'index', 'name', 'listId']}
...@@ -75,7 +89,7 @@ const FileSection = ({ ...@@ -75,7 +89,7 @@ const FileSection = ({
moveItem={moveItem} moveItem={moveItem}
removeFile={removeFile} removeFile={removeFile}
/> />
<FileDropzone /> <FileDropzone label="Drag files here or use the add button." />
</div>, </div>,
), ),
) )
...@@ -84,15 +98,35 @@ export default compose( ...@@ -84,15 +98,35 @@ export default compose(
getContext({ getContext({
isFetching: PropTypes.object, isFetching: PropTypes.object,
}), }),
withState('error', 'setError', ''),
withHandlers({
clearError: ({ setError }) => () => {
setError(e => '')
},
}),
withHandlers({
setError: ({ setError, clearError }) => err => {
setError(e => err, () => setTimeout(clearError, 3000))
},
disabledFilepicker: ({ files, maxFiles }) => () => files.length >= maxFiles,
}),
DropTarget( DropTarget(
'item', 'item',
{ {
drop({ changeList, listId: toListId }, monitor) { drop(
{ changeList, listId: toListId, maxFiles, files, setError },
monitor,
) {
const { listId: fromListId, id } = monitor.getItem() const { listId: fromListId, id } = monitor.getItem()
if (files.length >= maxFiles) {
setError('No more files of this type can be added.')
return
}
if (toListId === fromListId) return if (toListId === fromListId) return
changeList(fromListId, toListId, id) changeList(fromListId, toListId, id)
}, },
canDrop({ listId: toListId }, monitor) { canDrop({ listId: toListId, setError }, monitor) {
const { listId: fromListId } = monitor.getItem() const { listId: fromListId } = monitor.getItem()
return toListId !== fromListId return toListId !== fromListId
}, },
...@@ -106,18 +140,32 @@ export default compose( ...@@ -106,18 +140,32 @@ export default compose(
DropTarget( DropTarget(
NativeTypes.FILE, NativeTypes.FILE,
{ {
drop({ addFile, allowedFileExtensions }, monitor) { drop(
{ files, maxFiles, addFile, allowedFileExtensions, setError },
monitor,
) {
const [file] = monitor.getItem().files const [file] = monitor.getItem().files
const fileExtention = file.name.split('.')[1] const fileExtention = file.name.split('.')[1]
if (allowedFileExtensions.includes(fileExtention)) { if (files.length >= maxFiles) {
setError('No more files of this type can be added.')
return
}
if (
allowedFileExtensions &&
allowedFileExtensions.includes(fileExtention)
) {
addFile(file) addFile(file)
} else {
setError('File type not allowed for these kind of files.')
} }
}, },
}, },
(connect, monitor) => ({ (connect, monitor) => ({
connectFileDrop: connect.dropTarget(), connectFileDrop: connect.dropTarget(),
isFileOver: monitor.isOver(), isFileOver: monitor.isOver(),
canDropFile: monitor.canDrop(),
}), }),
), ),
)(FileSection) )(FileSection)
...@@ -9,12 +9,28 @@ ...@@ -9,12 +9,28 @@
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.picker-container {
align-items: center;
display: flex;
flex: 1;
}
.error {
color: firebrick;
font-size: 14px;
margin-right: 5px;
}
.upload-button { .upload-button {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
margin-left: 5px; margin-left: 5px;
} }
.disabled-picker {
cursor: default;
}
.title { .title {
margin: 5px; margin: 5px;
text-transform: uppercase; text-transform: uppercase;
......
...@@ -41,6 +41,7 @@ const Files = ({ ...@@ -41,6 +41,7 @@ const Files = ({
files={get(files, 'manuscripts') || []} files={get(files, 'manuscripts') || []}
isFirst isFirst
listId="manuscripts" listId="manuscripts"
maxFiles={Number.POSITIVE_INFINITY}
moveItem={moveItem('manuscripts')} moveItem={moveItem('manuscripts')}
removeFile={removeFile('manuscripts')} removeFile={removeFile('manuscripts')}
title="Main manuscript" title="Main manuscript"
...@@ -50,6 +51,7 @@ const Files = ({ ...@@ -50,6 +51,7 @@ const Files = ({
changeList={changeList} changeList={changeList}
files={get(files, 'supplementary') || []} files={get(files, 'supplementary') || []}
listId="supplementary" listId="supplementary"
maxFiles={Number.POSITIVE_INFINITY}
moveItem={moveItem('supplementary')} moveItem={moveItem('supplementary')}
removeFile={removeFile('supplementary')} removeFile={removeFile('supplementary')}
title="Supplementarry files" title="Supplementarry files"
...@@ -61,6 +63,7 @@ const Files = ({ ...@@ -61,6 +63,7 @@ const Files = ({
files={get(files, 'coverLetter') || []} files={get(files, 'coverLetter') || []}
isLast isLast
listId="coverLetter" listId="coverLetter"
maxFiles={1}
moveItem={moveItem('coverLetter')} moveItem={moveItem('coverLetter')}
removeFile={removeFile('coverLetter')} removeFile={removeFile('coverLetter')}
title="Cover letter" title="Cover letter"
......
...@@ -66,7 +66,6 @@ export default ({ ...@@ -66,7 +66,6 @@ export default ({
) )
}, },
)} )}
<Files />
<div className={classnames(classes.buttons)}> <div className={classnames(classes.buttons)}>
<Button onClick={isFirst ? () => history.push('/') : prevStep}> <Button onClick={isFirst ? () => history.push('/') : prevStep}>
{isFirst {isFirst
......
export { default as Files } from './Files'
export { default as Wizard } from './Wizard' export { default as Wizard } from './Wizard'
export { default as Progress } from './Progress' export { default as Progress } from './Progress'
export { default as WizardPage } from './WizardPage' export { default as WizardPage } from './WizardPage'
......
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
} from '@pubsweet/ui' } from '@pubsweet/ui'
import uploadFileFn from 'xpub-upload' import uploadFileFn from 'xpub-upload'
import { required, minChars, minSize } from 'xpub-validators' import { required, minChars, minSize } from 'xpub-validators'
import { Files } from 'pubsweet-component-wizard/src/components/'
import { AuthorList } from 'pubsweet-components-faraday/src/components' import { AuthorList } from 'pubsweet-components-faraday/src/components'
import { declarations } from './' import { declarations } from './'
...@@ -177,35 +178,39 @@ export default { ...@@ -177,35 +178,39 @@ export default {
title: '4. Manuscript Files Upload', title: '4. Manuscript Files Upload',
children: [ children: [
{ {
fieldId: 'label-manuscript', fieldId: 'file-upload',
renderComponent: Label, renderComponent: Files,
label: 'Main Manuscript', },
}, // {
{ // fieldId: 'label-manuscript',
fieldId: 'files.manuscripts', // renderComponent: Label,
label: 'Main Manuscript', // label: 'Main Manuscript',
renderComponent: Supplementary, // },
}, // {
{ // fieldId: 'files.manuscripts',
fieldId: 'label-supplementary', // label: 'Main Manuscript',
renderComponent: Label, // renderComponent: Supplementary,
label: 'Supplemental Files', // },
}, // {
{ // fieldId: 'label-supplementary',
fieldId: 'files.supplementary', // renderComponent: Label,
label: 'Supplemental Files', // label: 'Supplemental Files',
renderComponent: Supplementary, // },
}, // {
{ // fieldId: 'files.supplementary',
fieldId: 'label-cover', // label: 'Supplemental Files',
renderComponent: Label, // renderComponent: Supplementary,
label: 'Cover Letter', // },
}, // {
{ // fieldId: 'label-cover',
fieldId: 'files.coverLetter', // renderComponent: Label,
label: 'Cover Letter', // label: 'Cover Letter',
renderComponent: Supplementary, // },
}, // {
// fieldId: 'files.coverLetter',
// label: 'Cover Letter',
// renderComponent: Supplementary,
// },
], ],
}, },
], ],
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment