Skip to content
Snippets Groups Projects
Commit 307f1f11 authored by Sebastian's avatar Sebastian
Browse files

Merge branch 'faraday-master' of gitlab.coko.foundation:xpub/xpub into faraday-master

parents e7a54d02 26ac1cb3
No related branches found
No related tags found
No related merge requests found
Showing
with 403 additions and 4 deletions
import React from 'react'
import classnames from 'classnames'
import classes from './FileDropzone.local.scss'
const FileDropzone = ({ ...props }) => (
<div className={classnames(classes.dropzone)}>
<span>Drag items here or use the upload button</span>
</div>
)
// export default compose(
// DropTarget(
// 'item',
// {
// drop(props) {
// console.log('s-a dat drop', props)
// },
// },
// (connect, monitor) => ({
// connectDropTarget: connect.dropTarget(),
// }),
// ),
// )(FileDropzone)
export default FileDropzone
.dropzone {
align-items: center;
display: flex;
height: 60px;
justify-content: center;
margin: 10px 0;
span {
color: #888;
font-size: 14px;
}
}
import React from 'react'
import classnames from 'classnames'
import { Icon } from '@pubsweet/ui'
import classes from './FileItem.local.scss'
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`
}
return `${Math.floor(kbSize)} kB`
}
const FileItem = ({ dragHandle, name, size, removeFile }) => (
<div className={classnames(classes['file-item'])}>
{dragHandle}
<div className={classnames(classes.info)}>
<span>{name}</span>
<span>{parseFileSize(size)}</span>
</div>
<div className={classnames(classes.buttons)}>
<button onClick={removeFile(name)} title="Preview">
<Icon color="#666">eye</Icon>
</button>
<button onClick={removeFile(name)} title="Delete">
<Icon color="#666">trash-2</Icon>
</button>
</div>
</div>
)
export default FileItem
.file-item {
align-items: center;
border: 1px solid black;
display: flex;
margin: 5px;
.info {
border-right: 1px solid black;
display: flex;
flex: 1;
justify-content: space-between;
padding: 2px 10px 2px 0;
}
.buttons {
align-items: center;
display: flex;
justify-content: center;
margin: 0 5px;
button {
border: none;
cursor: pointer;
&:active,
&:focus {
outline: none;
}
}
}
}
import React, { Component } from 'react'
class FilePicker extends Component {
handleUpload = e => {
const { onUpload } = this.props
onUpload(e.target.files[0])
this.fileInput.value = null
}
render() {
const { children } = this.props
return (
<div>
<input
onChange={this.handleUpload}
ref={input => (this.fileInput = input)}
style={{ display: 'none' }}
type="file"
/>
{React.cloneElement(children, {
onClick: e => {
e.preventDefault()
this.fileInput.click()
},
})}
</div>
)
}
}
export default FilePicker
import React from 'react'
import { compose } from 'recompose'
import classnames from 'classnames'
import { Icon } from '@pubsweet/ui'
import { DropTarget } from 'react-dnd'
import { NativeTypes } from 'react-dnd-html5-backend'
import { SortableList } from 'pubsweet-components-faraday/src/components'
import FileItem from './FileItem'
import FilePicker from './FilePicker'
import FileDropzone from './FileDropzone'
import classes from './FileSection.local.scss'
const DragHandle = () => (
<div className={classnames(classes['drag-handle'])}>
<Icon size={14}>chevron_up</Icon>
<Icon size={10}>menu</Icon>
<Icon size={14}>chevron_down</Icon>
</div>
)
const FileSection = ({
title,
files,
listId,
isLast,
isFirst,
addFile,
moveItem,
removeFile,
connectDropTarget,
isOver,
canDrop,
connectFileDrop,
isFileOver,
}) =>
connectFileDrop(
connectDropTarget(
<div
className={classnames({
[classes['drop-section']]: true,
[classes['no-border-top']]: !isFirst,
[classes['dashed-border']]: !isLast,
[classes['is-over']]: isFileOver || (isOver && canDrop),
})}
>
<div className={classnames(classes.header)}>
<span className={classnames(classes.title)}>{title}</span>
<FilePicker onUpload={addFile}>
<div className={classnames(classes['upload-button'])}>
<Icon>file-plus</Icon>
</div>
</FilePicker>
</div>
<SortableList
beginDragProps={['index', 'name', 'listId']}
dragHandle={DragHandle}
items={files}
listId={listId}
listItem={FileItem}
moveItem={moveItem}
removeFile={removeFile}
/>
<FileDropzone />
</div>,
),
)
export default compose(
DropTarget(
'item',
{
drop({ changeList, listId: toListId }, monitor) {
const { listId: fromListId, name } = monitor.getItem()
if (toListId === fromListId) return
changeList(fromListId, toListId, name)
},
canDrop({ listId: toListId }, monitor) {
const { listId: fromListId } = monitor.getItem()
return toListId !== fromListId
},
},
(connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
),
DropTarget(
NativeTypes.FILE,
{
drop({ addFile }, monitor) {
const [file] = monitor.getItem().files
addFile(file)
},
},
(connect, monitor) => ({
connectFileDrop: connect.dropTarget(),
isFileOver: monitor.isOver(),
}),
),
)(FileSection)
.drop-section {
border: 1px solid black;
display: flex;
flex-direction: column;
padding: 5px;
.header {
align-items: center;
display: flex;
justify-content: flex-start;
.upload-button {
cursor: pointer;
display: flex;
margin-left: 5px;
}
.title {
margin: 5px;
text-transform: uppercase;
}
}
}
.no-border-top {
border-top: none;
}
.dashed-border {
border-bottom: 1px dashed black;
}
.drag-handle {
align-items: center;
border-right: 1px solid black;
cursor: move;
display: flex;
flex-direction: column;
justify-content: center;
margin-right: 10px;
padding: 3px;
}
.is-over {
background-color: #ddd;
}
import React from 'react'
import { compose, withState, withHandlers } from 'recompose'
import { SortableList } from 'pubsweet-components-faraday/src/components'
import FileSection from './FileSection'
const Files = ({ files, addFile, moveItem, removeFile, changeList }) => (
<div>
<FileSection
addFile={addFile('main')}
changeList={changeList}
files={files.main}
isFirst
listId="main"
moveItem={moveItem('main')}
removeFile={removeFile('main')}
title="Main manuscript"
/>
<FileSection
addFile={addFile('supplemental')}
changeList={changeList}
files={files.supplemental}
listId="supplemental"
moveItem={moveItem('supplemental')}
removeFile={removeFile('supplemental')}
title="Supplemental files"
/>
<FileSection
addFile={addFile('letter')}
changeList={changeList}
files={files.letter}
isLast
listId="letter"
moveItem={moveItem('letter')}
removeFile={removeFile('letter')}
title="Cover letter"
/>
</div>
)
export default compose(
withState('files', 'changeFiles', { main: [], supplemental: [], letter: [] }),
withHandlers({
changeList: ({ files, changeFiles }) => (fromListId, toListId, name) => {
const changedFile = files[fromListId].find(f => f.name === name)
changeFiles(prev => ({
...prev,
[fromListId]: prev[fromListId].filter(f => f.name !== name),
[toListId]: [...prev[toListId], changedFile],
}))
},
addFile: ({ changeFiles }) => type => file => {
changeFiles(prev => ({
...prev,
[type]: [...prev[type], { name: file.name, size: file.size }],
}))
},
moveItem: ({ changeFiles }) => type => (dragIndex, hoverIndex) => {
changeFiles(prev => ({
...prev,
[type]: SortableList.moveItem(prev[type], dragIndex, hoverIndex),
}))
},
removeFile: ({ changeFiles }) => type => name => e => {
e.preventDefault()
changeFiles(prev => ({
...prev,
[type]: prev[type].filter(f => f.name !== name),
}))
},
}),
)(Files)
.file-item {
align-items: center;
border: 1px solid black;
display: flex;
margin: 5px;
.info {
border-right: 1px solid black;
display: flex;
flex: 1;
padding: 2px 0;
}
.buttons {
align-items: center;
display: flex;
justify-content: center;
margin: 0 5px;
button {
border: none;
cursor: pointer;
&:active,
&:focus {
outline: none;
}
}
}
}
...@@ -6,6 +6,8 @@ import { withJournal } from 'xpub-journal' ...@@ -6,6 +6,8 @@ import { withJournal } from 'xpub-journal'
import { ConnectPage } from 'xpub-connect' import { ConnectPage } from 'xpub-connect'
import { selectCollection, selectFragment } from 'xpub-selectors' import { selectCollection, selectFragment } from 'xpub-selectors'
import { compose, withHandlers, withState, withContext } from 'recompose' import { compose, withHandlers, withState, withContext } from 'recompose'
import HTML5Backend from 'react-dnd-html5-backend'
import { DragDropContext } from 'react-dnd'
import Wizard from './Wizard' import Wizard from './Wizard'
...@@ -78,4 +80,5 @@ export default compose( ...@@ -78,4 +80,5 @@ export default compose(
toggleConfirmation, toggleConfirmation,
}), }),
), ),
DragDropContext(HTML5Backend),
)(Wizard) )(Wizard)
...@@ -5,6 +5,7 @@ import { ValidatedField, Button } from '@pubsweet/ui' ...@@ -5,6 +5,7 @@ import { ValidatedField, Button } from '@pubsweet/ui'
import classes from './WizardStep.local.scss' import classes from './WizardStep.local.scss'
import AutosaveIndicator from './AutosaveIndicator' import AutosaveIndicator from './AutosaveIndicator'
import Files from './Files'
export default ({ export default ({
children: stepChildren, children: stepChildren,
...@@ -65,6 +66,7 @@ export default ({ ...@@ -65,6 +66,7 @@ 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
......
...@@ -63,6 +63,7 @@ const Authors = ({ ...@@ -63,6 +63,7 @@ const Authors = ({
/> />
) : ( ) : (
<SortableList <SortableList
beginDragProps={['index']}
dragHandle={DragHandle} dragHandle={DragHandle}
dropItem={dropItem} dropItem={dropItem}
editedAuthor={editedAuthor} editedAuthor={editedAuthor}
......
...@@ -31,9 +31,9 @@ export default ({ ...@@ -31,9 +31,9 @@ export default ({
key={a.firstName} key={a.firstName}
{...a} {...a}
countryParser={countryParser} countryParser={countryParser}
index={index}
parseAuthorType={parseAuthorType} parseAuthorType={parseAuthorType}
removeAuthor={removeAuthor} removeAuthor={removeAuthor}
index={index}
{...rest} {...rest}
/> />
), ),
......
import React from 'react' import React from 'react'
import { pick } from 'lodash'
import { compose } from 'recompose' import { compose } from 'recompose'
import { findDOMNode } from 'react-dom' import { findDOMNode } from 'react-dom'
import HTML5Backend from 'react-dnd-html5-backend' import HTML5Backend from 'react-dnd-html5-backend'
...@@ -6,7 +7,9 @@ import { DragSource, DropTarget, DragDropContext } from 'react-dnd' ...@@ -6,7 +7,9 @@ import { DragSource, DropTarget, DragDropContext } from 'react-dnd'
const itemSource = { const itemSource = {
beginDrag(props) { beginDrag(props) {
return { index: props.index } console.log('beginning drag', props)
// return { index: props.index }
return pick(props, props.beginDragProps)
}, },
} }
...@@ -124,4 +127,5 @@ SortableList.moveItem = (items, dragIndex, hoverIndex) => { ...@@ -124,4 +127,5 @@ SortableList.moveItem = (items, dragIndex, hoverIndex) => {
] ]
} }
export default DragDropContext(HTML5Backend)(SortableList) // export default DragDropContext(HTML5Backend)(SortableList)
export default SortableList
...@@ -2,3 +2,4 @@ export { default as SortableList } from './SortableList/SortableList' ...@@ -2,3 +2,4 @@ export { default as SortableList } from './SortableList/SortableList'
export { default as AuthorList } from './AuthorList/AuthorList' export { default as AuthorList } from './AuthorList/AuthorList'
export { Dropdown, Logo } from './UIComponents' export { Dropdown, Logo } from './UIComponents'
export { DragHandle } from './AuthorList/FormItems'
...@@ -24,7 +24,7 @@ module.exports = { ...@@ -24,7 +24,7 @@ module.exports = {
'pubsweet-client': { 'pubsweet-client': {
API_ENDPOINT: '/api', API_ENDPOINT: '/api',
'login-redirect': '/', 'login-redirect': '/',
'redux-log': true, 'redux-log': false,
theme: process.env.PUBSWEET_THEME, theme: process.env.PUBSWEET_THEME,
}, },
'mail-transport': { 'mail-transport': {
......
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