diff --git a/packages/component-faraday-ui/src/AuthorCard.js b/packages/component-faraday-ui/src/AuthorCard.js index f99341d555750e85380dbaba4019142a5b2ffdfa..3467971c1057dc949fec9d29a3c2c6211ae13a0e 100644 --- a/packages/component-faraday-ui/src/AuthorCard.js +++ b/packages/component-faraday-ui/src/AuthorCard.js @@ -1,14 +1,22 @@ 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; diff --git a/packages/component-faraday-ui/src/AuthorCard.md b/packages/component-faraday-ui/src/AuthorCard.md index 7b9aa3c8609027cc60a929d0a30ba39dd8e5bf02..53b2664b1c6f9f8d1dfed5071e680ec7a60f70e3 100644 --- a/packages/component-faraday-ui/src/AuthorCard.md +++ b/packages/component-faraday-ui/src/AuthorCard.md @@ -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} /> ``` diff --git a/packages/component-faraday-ui/src/FileSection.js b/packages/component-faraday-ui/src/FileSection.js index 3901be09f8f18889f611962ce4ea012186c407ba..af49341a1d8b80a3de9a009571bde45fac0ea477 100644 --- a/packages/component-faraday-ui/src/FileSection.js +++ b/packages/component-faraday-ui/src/FileSection.js @@ -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()]) diff --git a/packages/component-faraday-ui/src/SortableList.js b/packages/component-faraday-ui/src/SortableList.js index 1c6595d653c344dfae39953ab9ed0ecbe2153919..f6bd63d6e33fc049676783818ffb6378691fb58a 100644 --- a/packages/component-faraday-ui/src/SortableList.js +++ b/packages/component-faraday-ui/src/SortableList.js @@ -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>, ), diff --git a/packages/component-faraday-ui/src/WizardAuthors.js b/packages/component-faraday-ui/src/WizardAuthors.js new file mode 100644 index 0000000000000000000000000000000000000000..4a9afb711f6261a8d090e5038825bb7b7b61d433 --- /dev/null +++ b/packages/component-faraday-ui/src/WizardAuthors.js @@ -0,0 +1,145 @@ +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 diff --git a/packages/component-faraday-ui/src/WizardAuthors.md b/packages/component-faraday-ui/src/WizardAuthors.md new file mode 100644 index 0000000000000000000000000000000000000000..b3be1ddfc1df3ef6fe06279feec6246236eb13f2 --- /dev/null +++ b/packages/component-faraday-ui/src/WizardAuthors.md @@ -0,0 +1,17 @@ +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, + }, + ]} +/> +``` diff --git a/packages/component-faraday-ui/src/gridItems/Row.js b/packages/component-faraday-ui/src/gridItems/Row.js index 06ab4eff0c9810a5f09356ea405a95bf047bf4cf..bfcb56cda9351cef32fd77a5ea0cbe1f9d398b93 100644 --- a/packages/component-faraday-ui/src/gridItems/Row.js +++ b/packages/component-faraday-ui/src/gridItems/Row.js @@ -1,7 +1,7 @@ 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}; ` diff --git a/packages/component-faraday-ui/src/index.js b/packages/component-faraday-ui/src/index.js index 0dd450ad6f3c3c6dae64914edfcc16120bc69644..6dcf59beacea57e94813d269dcefb0cde6abb64d 100644 --- a/packages/component-faraday-ui/src/index.js +++ b/packages/component-faraday-ui/src/index.js @@ -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'