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

feat(submission-flow): add wizard author list

parent acee298f
No related branches found
No related tags found
1 merge request!43Sprint #19
import React, { Fragment } from 'react'
import { isNumber } from 'lodash'
import styled from 'styled-components'
import { reduxForm } from 'redux-form'
import { reduxForm, Field } from 'redux-form'
import { th } from '@pubsweet/ui-toolkit'
import { required } from 'xpub-validators'
import { H3, ValidatedField, TextField, Checkbox } from '@pubsweet/ui'
import { compose, setDisplayName, withStateHandlers } from 'recompose'
import {
compose,
withState,
withProps,
withHandlers,
setDisplayName,
} from 'recompose'
import { Tag, Label, Row, Item, PersonInfo, IconButton } from './'
const Empty = () => <div />
// #region AuthorTitle
const AuthorTitle = ({
editMode,
......@@ -87,7 +95,10 @@ const AuthorEdit = ({
saveChanges={handleSubmit}
toggleEditMode={toggleEditMode}
/>
<Row>
<Field component={Empty} name="id" />
<Field component={Empty} name="isSubmitting" />
<Item vertical withRightMargin>
<Label required>Email</Label>
<ValidatedField
......@@ -126,9 +137,13 @@ const AuthorEdit = ({
// #endregion
const EnhancedAuthorEdit = compose(
withProps(({ author }) => ({
initialValues: {
...author,
},
})),
reduxForm({
form: 'author-edit',
onSubmit: values => {},
}),
)(AuthorEdit)
......@@ -145,45 +160,49 @@ const Author = ({ author, listIndex, toggleEditMode }) => (
)
const AuthorCard = ({
author,
item,
editMode,
dragHandle,
toggleEditMode,
listIndex = null,
toggleEdit,
index = null,
saveNewAuthor,
editExistingAuthor,
authorEditorSubmit,
isOver,
isDragging,
}) => (
<Root>
<Root isDragging={isDragging} isOver={isOver}>
{!editMode &&
(typeof dragHandle === 'function' ? dragHandle() : dragHandle)}
{editMode ? (
<EnhancedAuthorEdit
author={author}
author={item}
editExistingAuthor={editExistingAuthor}
editMode={editMode}
listIndex={listIndex}
toggleEditMode={toggleEditMode}
listIndex={index}
onSubmit={authorEditorSubmit}
saveNewAuthor={saveNewAuthor}
toggleEditMode={toggleEdit(index)}
/>
) : (
<Author
author={author}
author={item}
editMode={editMode}
listIndex={listIndex}
toggleEditMode={toggleEditMode}
listIndex={index}
toggleEditMode={toggleEdit(index)}
/>
)}
</Root>
)
export default compose(
withStateHandlers(
{ editMode: false },
{
toggleEditMode: ({ editMode }, { onEdit }) => () => {
typeof onEdit === 'function' && onEdit()
return {
editMode: !editMode,
}
},
withState('editMode', 'setEditMode', ({ item }) => item.id === 'newAuthor'),
withHandlers({
toggleEdit: ({ setEditMode, onEdit }) => index => () => {
onEdit(index)
setEditMode(e => !e)
},
),
}),
setDisplayName('AuthorCard'),
)(AuthorCard)
......@@ -201,11 +220,13 @@ const AuthorContainer = styled.div`
display: flex;
flex: 1;
flex-direction: column;
padding: ${th('gridUnit')};
padding: calc(${th('gridUnit')} * 2);
`
const Root = styled.div`
align-items: center;
background-color: ${props =>
props.isOver ? th('colorFurniture') : th('colorBackgroundHue')};
border-radius: ${th('borderRadius')};
box-shadow: ${th('boxShadow')};
display: flex;
......
......@@ -13,11 +13,11 @@ const author = {
<div>
<AuthorCard
onEdit={() => console.log('s-a dat click pe edit')}
listIndex={0}
author={author}
index={0}
item={author}
/>
<AuthorCard onEdit={() => console.log('s-a dat click pe edit')} listIndex={1} author={author} />
<AuthorCard onEdit={() => console.log('s-a dat click pe edit')} listIndex={2} author={author} />
<AuthorCard onEdit={() => console.log('s-a dat click pe edit')} index={1} item={author} />
<AuthorCard onEdit={() => console.log('s-a dat click pe edit')} index={2} item={author} />
</div>
```
......@@ -33,5 +33,5 @@ const author = {
isCorresponding: true,
};
<AuthorCard author={author} dragHandle={DragHandle} />
<AuthorCard item={author} dragHandle={DragHandle} />
```
......@@ -2,7 +2,7 @@ import React from 'react'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { FilePicker } from '@pubsweet/ui'
import { compose, withStateHandlers, withProps } from 'recompose'
import { compose, withState, withHandlers, withProps } from 'recompose'
import { radiusHelpers } from './styledHelpers'
import { withNativeFileDrop, withFileSectionDrop } from './helpers'
......@@ -53,7 +53,6 @@ const FileSection = ({
isFirst={isFirst}
isLast={isLast}
>
{error}
<Row alignItems="center">
<Item>
<Label required={required}>{title}</Label>
......@@ -86,18 +85,26 @@ const FileSection = ({
onDownload={onDownload}
onPreview={onPreview}
/>
{error && (
<Row>
<Text error>{error}</Text>
</Row>
)}
</Root>
)
export default compose(
withStateHandlers(
{ error: '' },
{
setError: () => error => ({
error,
}),
withState('error', 'setStateError', ''),
withHandlers({
clearError: ({ setStateError }) => () => {
setStateError(e => '')
},
),
}),
withHandlers({
setError: ({ setStateError, clearError }) => err => {
setStateError(e => err, () => setTimeout(clearError, 2000))
},
}),
withProps(({ allowedFileExtensions = [] }) => ({
supportedFormats: allowedFileExtensions
.map(ext => EXTENSIONS[ext.toLowerCase()])
......
......@@ -64,7 +64,7 @@ const Item = ({
{React.createElement(listItem, {
...rest,
dragHandle: connectDragSource(
<div style={{ display: 'flex' }}>
<div style={{ display: 'flex', alignSelf: 'stretch' }}>
{React.createElement(dragHandle)}
</div>,
),
......
import React, { Fragment } from 'react'
import styled from 'styled-components'
import { th } from '@pubsweet/ui-toolkit'
import { compose, withState, withHandlers } from 'recompose'
import {
Row,
Item,
Label,
DragHandle,
AuthorCard,
ActionLink,
SortableList,
} from './'
const WizardAuthors = ({
authors,
moveAuthor,
addNewAuthor,
setAuthorEdit,
saveNewAuthor,
editExistingAuthor,
authorEditorSubmit,
}) => (
<Fragment>
<Row alignItems="center" justify="flex-start" pl={1} pr={1}>
<Item>
<Label>Authors</Label>
<ActionLink icon="plus" onClick={addNewAuthor}>
ADD AUTHOR
</ActionLink>
</Item>
<Item justify="flex-end">
<ActionLink
icon="link"
iconPosition="right"
to="https://www.hindawi.com/journals/jl/guidelines/"
>
Journal Author Submission Guidelines
</ActionLink>
</Item>
</Row>
<SortableContainer>
<SortableList
authorEditorSubmit={authorEditorSubmit}
dragHandle={DragHandle}
editExistingAuthor={editExistingAuthor}
itemKey="id"
items={authors}
listItem={AuthorCard}
moveItem={moveAuthor}
onEdit={setAuthorEdit}
saveNewAuthor={saveNewAuthor}
/>
</SortableContainer>
</Fragment>
)
const defaultAuthors = [
{
id: 'auth-1',
email: 'author.here1@gmail.com',
firstName: 'Sebastian',
lastName: 'Teodorescu',
affiliation: 'PSD',
isSubmitting: true,
isCorresponding: true,
},
{
id: 'auth-2',
email: 'author.here2@gmail.com',
firstName: 'Bogdan',
lastName: 'Cochior',
affiliation: 'PSD',
isSubmitting: false,
isCorresponding: true,
},
{
id: 'auth-3',
email: 'author.here3@gmail.com',
firstName: 'Alexandru',
lastName: 'Munteanu',
affiliation: 'PSD',
isSubmitting: false,
isCorresponding: true,
},
]
export default compose(
withState(
'authors',
'setAuthors',
({ authors }) => authors || defaultAuthors,
),
withHandlers({
addNewAuthor: ({ authors, setAuthors }) => () => {
if (authors.some(a => a.id === 'newAuthor')) {
return
}
setAuthors([...authors, { id: 'newAuthor' }])
},
moveAuthor: ({ authors, setAuthors }) => (dragIndex, hoverIndex) => {
const newAuthors = SortableList.moveItem(authors, dragIndex, hoverIndex)
setAuthors(newAuthors)
},
setAuthorEdit: ({ authors, setAuthors }) => index => {
setAuthors(authors.filter(a => a.id !== 'newAuthor'))
},
saveNewAuthor: ({ authors, setAuthors }) => author => {
const newAuthors = [...authors.filter(a => a.id !== 'newAuthor'), author]
setAuthors(newAuthors)
},
editExistingAuthor: ({ authors, setAuthors }) => editedAuthor => {
const newAuthors = authors.map(
a => (a.id === editedAuthor.id ? editedAuthor : a),
)
setAuthors(newAuthors)
},
}),
withHandlers({
authorEditorSubmit: ({ saveNewAuthor, editExistingAuthor }) => (
values,
dispatch,
{ toggleEditMode },
) => {
if (values.id === 'newAuthor') {
saveNewAuthor({
...values,
id: String(Math.floor(Math.random() * 10000000)),
})
} else {
editExistingAuthor(values)
setTimeout(toggleEditMode, 10)
}
},
}),
)(WizardAuthors)
// #region styles
const SortableContainer = styled.div`
background-color: ${th('colorBackground')};
border-radius: ${th('borderRadius')};
padding: ${th('gridUnit')};
`
// #endregion
A sortable author list.
```js
<WizardAuthors
authors={[
{
id: 'auth-3',
email: 'author.here3@gmail.com',
firstName: 'Alexandru',
lastName: 'Munteanu',
affiliation: 'PSD',
isSubmitting: false,
isCorresponding: true,
},
]}
/>
```
import { get } from 'lodash'
import styled from 'styled-components'
import { marginHelper } from '../styledHelpers'
import { marginHelper, paddingHelper } from '../styledHelpers'
/** @component */
export default styled.div.attrs({
......@@ -16,4 +16,5 @@ export default styled.div.attrs({
width: 100%;
${marginHelper};
${paddingHelper};
`
......@@ -16,6 +16,7 @@ export { default as PersonInfo } from './PersonInfo'
export { default as SortableList } from './SortableList'
export { default as Tag } from './Tag'
export { default as Text } from './Text'
export { default as WizardAuthors } from './WizardAuthors'
// modals
export * from './modals'
......
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