From 47e6b159034a0d6692b940cea2cf9a973679c83a Mon Sep 17 00:00:00 2001 From: Alexandru Munteanu <alexandru.munteanu@thinslices.com> Date: Mon, 22 Jan 2018 14:22:40 +0200 Subject: [PATCH] Add edit on list items --- .../src/components/AuthorList.js | 87 ++++++++++++++++--- .../src/components/AuthorList.local.scss | 12 +++ .../src/components/SortableList.js | 53 ++++++++--- .../component-wizard/src/redux/authors.js | 2 +- 4 files changed, 127 insertions(+), 27 deletions(-) diff --git a/packages/component-wizard/src/components/AuthorList.js b/packages/component-wizard/src/components/AuthorList.js index d29102c1f..b5e78ab55 100644 --- a/packages/component-wizard/src/components/AuthorList.js +++ b/packages/component-wizard/src/components/AuthorList.js @@ -4,7 +4,6 @@ import classnames from 'classnames' import { connect } from 'react-redux' import { get } from 'lodash' import { reduxForm } from 'redux-form' -import { actions } from 'pubsweet-client' import { required } from 'xpub-validators' import { withRouter } from 'react-router-dom' import { selectCurrentUser } from 'xpub-selectors' @@ -125,6 +124,67 @@ const AuthorAdder = ({ authors, editMode, setEditMode, handleSubmit }) => ( </div> ) +const AuthorEdit = ({ setAuthorEdit, handleSubmit }) => ( + <div className={classnames(classes['editor-body'])}> + <div className={classnames(classes.row)}> + <ValidatedTextField isRequired label="First name" name="edit.firstName" /> + <ValidatedTextField label="Middle name" name="edit.middleName" /> + <ValidatedTextField isRequired label="Last name" name="edit.lastName" /> + </div> + + <div className={classnames(classes.row)}> + <ValidatedTextField + isRequired + label="Email" + name="edit.email" + validators={[emailValidator]} + /> + <ValidatedTextField + isRequired + label="Affiliation" + name="edit.affiliation" + /> + <MenuItem label="Country" name="edit.country" options={countries} /> + </div> + + <div className={classnames(classes['form-buttons'])}> + <Button onClick={setAuthorEdit(-1)}>Cancel</Button> + <Button onClick={handleSubmit} primary> + Save + </Button> + </div> + </div> +) + +const Editor = compose( + withRouter, + getContext({ version: PropTypes.object, project: PropTypes.object }), + connect( + (state, { match: { params: { version } } }) => ({ + authors: getFragmentAuthors(state, version), + }), + { + setAuthors, + }, + ), + reduxForm({ + form: 'edit', + onSubmit: ( + values, + dispatch, + { setAuthorEdit, setAuthors, project, version, authors, index, ...rest }, + ) => { + const newAuthors = [ + ...authors.slice(0, index), + values.edit, + ...authors.slice(index + 1), + ] + setAuthors(newAuthors, version.id) + setTimeout(setAuthorEdit(-1), 100) + }, + }), +)(AuthorEdit) + const Adder = compose( connect(state => ({ currentUser: selectCurrentUser(state), @@ -184,6 +244,7 @@ const Author = ({ isCorresponding, setAsCorresponding, parseAuthorType, + ...rest }) => ( <div className={classnames({ @@ -229,6 +290,12 @@ const Author = ({ <Icon>mail</Icon> </div> )} + <div + className={classnames(classes.corresponding)} + onClick={rest.setAuthorEdit(rest.index)} + > + <Icon>edit-2</Icon> + </div> </div> </div> ) @@ -257,6 +324,7 @@ const Authors = ({ <SortableList dragHandle={DragHandle} dropItem={dropItem} + editItem={Editor} items={authors} listItem={Author} moveItem={moveAuthor} @@ -276,7 +344,6 @@ export default compose( addAuthor, setAuthors, moveAuthors, - updateFragment: actions.updateFragment, }, ), lifecycle({ @@ -286,18 +353,17 @@ export default compose( }, }), withState('editMode', 'setEditMode', false), + withState('editedAuthor', 'setEditedAuthor', -1), withHandlers({ + setAuthorEdit: ({ setEditedAuthor }) => editedAuthor => e => { + e && e.preventDefault && e.preventDefault() + setEditedAuthor(prev => editedAuthor) + }, setEditMode: ({ setEditMode }) => mode => e => { e && e.preventDefault() setEditMode(v => mode) }, - dropItem: ({ - updateFragment, - authors, - project, - version, - setAuthors, - }) => () => { + dropItem: ({ authors, project, version, setAuthors }) => () => { setAuthors(authors, version.id) }, countryParser: () => countryCode => @@ -312,7 +378,6 @@ export default compose( moveAuthors, project, version, - updateFragment, match: { params }, }) => (dragIndex, hoverIndex) => { const newAuthors = SortableList.moveItem(authors, dragIndex, hoverIndex) @@ -320,7 +385,6 @@ export default compose( }, removeAuthor: ({ authors, - updateFragment, project, version, setAuthors, @@ -330,7 +394,6 @@ export default compose( }, setAsCorresponding: ({ authors, - updateFragment, setAuthors, version, project, diff --git a/packages/component-wizard/src/components/AuthorList.local.scss b/packages/component-wizard/src/components/AuthorList.local.scss index cb4905b40..38c04b816 100644 --- a/packages/component-wizard/src/components/AuthorList.local.scss +++ b/packages/component-wizard/src/components/AuthorList.local.scss @@ -48,6 +48,18 @@ } } +.editor-body { + border: 1px solid #444; + margin: 10px 0; + padding: 10px; + + .form-buttons { + display: flex; + justify-content: space-around; + margin: 15px 0 0 0; + } +} + .adder { display: flex; flex-direction: column; diff --git a/packages/component-wizard/src/components/SortableList.js b/packages/component-wizard/src/components/SortableList.js index c566f4c63..8a91c9e99 100644 --- a/packages/component-wizard/src/components/SortableList.js +++ b/packages/component-wizard/src/components/SortableList.js @@ -47,9 +47,13 @@ const Item = ({ connectDropTarget, listItem, dragHandle, + isEditing, ...rest -}) => - dragHandle +}) => { + if (isEditing) { + return <div style={{ flex: 1 }}>{React.createElement(listItem, rest)}</div> + } + return dragHandle ? connectDragPreview( connectDropTarget( <div style={{ flex: 1 }}> @@ -69,6 +73,7 @@ const Item = ({ <div style={{ flex: 1 }}>{React.createElement(listItem, rest)}</div>, ), ) +} const DecoratedItem = compose( DropTarget('item', itemTarget, (connect, monitor) => ({ @@ -82,19 +87,39 @@ const DecoratedItem = compose( })), )(Item) -const SortableList = ({ items, moveItem, listItem, dragHandle, ...rest }) => ( +const SortableList = ({ + items, + moveItem, + listItem, + dragHandle, + editItem, + ...rest +}) => ( <div> - {items.map((item, i) => ( - <DecoratedItem - dragHandle={dragHandle} - index={i} - key={item.name || Math.random()} - listItem={listItem} - moveItem={moveItem} - {...item} - {...rest} - /> - ))} + {items.map( + (item, i) => + i === rest.editedAuthor ? ( + React.createElement(editItem, { + key: item.name || Math.random(), + initialValues: { + edit: item, + }, + index: i, + ...rest, + }) + ) : ( + <DecoratedItem + dragHandle={dragHandle} + index={i} + isEditing={rest.editedAuthor !== -1} + key={item.name || Math.random()} + listItem={listItem} + moveItem={moveItem} + {...item} + {...rest} + /> + ), + )} </div> ) diff --git a/packages/component-wizard/src/redux/authors.js b/packages/component-wizard/src/redux/authors.js index 18440cfd0..0ee3777b5 100644 --- a/packages/component-wizard/src/redux/authors.js +++ b/packages/component-wizard/src/redux/authors.js @@ -14,8 +14,8 @@ const _setAuthors = (authors, fragmentId) => ({ // actions export const setAuthors = (authors, fragmentId) => dispatch => { - dispatch(_setAuthors(authors, fragmentId)) dispatch(change('wizard', 'authors', authors)) + dispatch(_setAuthors(authors, fragmentId)) } export const moveAuthors = (authors, fragmentId) => dispatch => { -- GitLab