From 3f1250c2cd9ca72da2c32c23f187be0f6cbfbd5c Mon Sep 17 00:00:00 2001 From: Alf Eaton <eaton.alf@gmail.com> Date: Mon, 3 Jul 2017 13:21:56 +0100 Subject: [PATCH] Add editors story --- app/components/Editor.js | 91 ------------------------------ app/components/EditorForm.js | 45 +++++++++++++++ app/components/EditorList.js | 27 +++++++++ app/containers/EditorsContainer.js | 52 +++++++++++++++++ app/routes.jsx | 6 +- stories/data/projects.js | 25 +++++--- stories/index.js | 10 ++++ 7 files changed, 154 insertions(+), 102 deletions(-) delete mode 100644 app/components/Editor.js create mode 100644 app/components/EditorForm.js create mode 100644 app/components/EditorList.js create mode 100644 app/containers/EditorsContainer.js diff --git a/app/components/Editor.js b/app/components/Editor.js deleted file mode 100644 index ee7c844a1..000000000 --- a/app/components/Editor.js +++ /dev/null @@ -1,91 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { connect } from 'react-redux' -import { updateCollection } from 'pubsweet-client/src/actions/collections' -import FRC from 'formsy-react-components' -import { Button, ListGroup, ListGroupItem } from 'react-bootstrap' -import uuid from 'uuid' -import { LinkContainer } from 'react-router-bootstrap' - -class Editor extends React.Component { - addEditor = user => { - const { project, updateCollection } = this.props - - const { roles } = project - roles.editor = roles.editor || {} - roles.editor[uuid()] = { user } - - updateCollection({ - id: project.id, - roles - }) - - this.editorForm.reset() - } - - render () { - const { project } = this.props - - if (!project) return null - - const { roles } = project - - // TODO: only return editor details from the server to authorised users - // TODO: implement role status (+ invitations property?) - // TODO: autocomplete search from a list of editors with roles on this journal - - return ( - <div className="content-metadata"> - <h1>Editor</h1> - - <div className="content-interactive"> - <FRC.Form ref={form => (this.editorForm = form)} onSubmit={this.addEditor} validateOnSubmit={true} - layout="vertical"> - <div> - <FRC.Input type="text" name="name" label="Editor name"/> - </div> - - <div style={{ marginTop: 20 }}> - <Button type="submit" bsStyle="primary">Save</Button> - </div> - </FRC.Form> - </div> - - {roles.editor && ( - <ListGroup style={{marginTop: 20}}> - {Object.keys(roles.editor).map(id => { - const role = roles.editor[id] - - // TODO: use role.id instead of key - - return ( - <LinkContainer key={id} to={`/projects/${project.id}/roles/editor/${id}`} style={{textDecoration: 'none'}}> - <ListGroupItem header={role.user.name} className="clearfix"> - <span style={{float: 'right'}}>{role.status || 'Pending'}</span> - </ListGroupItem> - </LinkContainer> - ) - })} - </ListGroup> - )} - </div> - ) - } -} - -Editor.propTypes = { - params: PropTypes.object.isRequired, - project: PropTypes.object, - updateCollection: PropTypes.func.isRequired -} - -export default connect( - (state, ownProps) => ({ - project: state.collections.find(collection => { - return collection.id === ownProps.params.project - }) - }), - { - updateCollection - } -)(Editor) diff --git a/app/components/EditorForm.js b/app/components/EditorForm.js new file mode 100644 index 000000000..21175f2be --- /dev/null +++ b/app/components/EditorForm.js @@ -0,0 +1,45 @@ +import React from 'react' +import PropTypes from 'prop-types' +import FRC from 'formsy-react-components' +import { Button } from 'react-bootstrap' +import uuid from 'uuid' + +// TODO: autocomplete search from a list of editors with roles on this journal + +class EditorForm extends React.Component { + addEditor = user => { + const { project, updateCollection } = this.props + + const { roles } = project + roles.editor = roles.editor || {} + roles.editor[uuid()] = { user } + + updateCollection({ + id: project.id, + roles + }) + + this.editorForm.reset() + } + + render () { + return ( + <FRC.Form ref={form => (this.editorForm = form)} onSubmit={this.addEditor} validateOnSubmit={true} layout="vertical"> + <div> + <FRC.Input type="text" name="name" label="Editor name"/> + </div> + + <div style={{ marginTop: 20 }}> + <Button type="submit" bsStyle="primary">Save</Button> + </div> + </FRC.Form> + ) + } +} + +EditorForm.propTypes = { + project: PropTypes.object.isRequired, + updateCollection: PropTypes.func.isRequired +} + +export default EditorForm diff --git a/app/components/EditorList.js b/app/components/EditorList.js new file mode 100644 index 000000000..2071ab878 --- /dev/null +++ b/app/components/EditorList.js @@ -0,0 +1,27 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { ListGroup, ListGroupItem } from 'react-bootstrap' +import { LinkContainer } from 'react-router-bootstrap' + +const EditorList = ({ project, roles }) => ( + <ListGroup style={{ marginTop: 20 }}> + {Object.keys(roles).map(id => { + const role = roles[id] + + return ( + <LinkContainer key={id} to={`/projects/${project.id}/roles/editor/${id}`} style={{ textDecoration: 'none' }}> + <ListGroupItem header={role.user.name} className="clearfix"> + <span style={{ float: 'right' }}>{role.status || 'Pending'}</span> + </ListGroupItem> + </LinkContainer> + ) + })} + </ListGroup> +) + +EditorList.propTypes = { + project: PropTypes.object.isRequired, + roles: PropTypes.object.isRequired +} + +export default EditorList diff --git a/app/containers/EditorsContainer.js b/app/containers/EditorsContainer.js new file mode 100644 index 000000000..6448eacc0 --- /dev/null +++ b/app/containers/EditorsContainer.js @@ -0,0 +1,52 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { connect } from 'react-redux' +import { updateCollection } from 'pubsweet-client/src/actions/collections' +import EditorForm from '../components/EditorForm' +import EditorList from '../components/EditorList' + +class EditorsContainer extends React.Component { + render () { + const { project, updateCollection } = this.props + + if (!project) return null + + const { roles } = project + + // TODO: only return editor details from the server to authorised users + // TODO: implement role status (+ invitations property?) + + return ( + <div className="content-metadata"> + <h1>Editor</h1> + + <div className="content-interactive"> + <EditorForm project={project} updateCollection={updateCollection()}/> + </div> + + {roles.editor && ( + <div className="content-metadata"> + <EditorList project={project} roles={roles.editor}/> + </div> + )} + </div> + ) + } +} + +EditorsContainer.propTypes = { + params: PropTypes.object.isRequired, + project: PropTypes.object, + updateCollection: PropTypes.func.isRequired +} + +export default connect( + (state, ownProps) => ({ + project: state.collections.find(collection => { + return collection.id === ownProps.params.project + }) + }), + { + updateCollection + } +)(EditorsContainer) diff --git a/app/routes.jsx b/app/routes.jsx index 0438b9f96..375f10c85 100644 --- a/app/routes.jsx +++ b/app/routes.jsx @@ -23,9 +23,9 @@ export default ( <IndexRoute component={chunk(import('./containers/SnapshotsContainer'))}/> <Route path="declarations" - component={chunk(import('./components/Declarations'))}/> - <Route path="editor" - component={chunk(import('./components/Editor'))}/> + component={chunk(import('./containers/DeclarationsContainer'))}/> + <Route path="editors" + component={chunk(import('./containers/EditorsContainer'))}/> <Route path="reviewers" component={chunk(import('./components/Reviewers'))}/> <Route path="roles/:roleType/:role" diff --git a/stories/data/projects.js b/stories/data/projects.js index 5a8d308e4..2e4e1209c 100644 --- a/stories/data/projects.js +++ b/stories/data/projects.js @@ -1,31 +1,40 @@ export default [ { - id: 'project-1', + id: 'project-imported', status: 'imported', statusDate: '2017-06-01T12:00:00Z', title: 'An imported project', roles: { owner: { - 'user-1': { + 'user-foo': { user: { - id: 'user-1', - username: 'admin' + id: 'user-foo', + username: 'foo' } } } } }, { - id: 'project-2', + id: 'project-submitted', status: 'submitted', statusDate: '2017-06-29T12:00:00Z', title: 'A submitted project', roles: { owner: { - 'user-1': { + 'user-foo': { user: { - id: 'user-1', - username: 'admin' + id: 'user-foo', + username: 'foo' + } + } + }, + editor: { + 'user-bar': { + user: { + id: 'user-bar', + username: 'bar', + name: 'Bar Bar' } } } diff --git a/stories/index.js b/stories/index.js index ccff0b371..6267b0cd9 100644 --- a/stories/index.js +++ b/stories/index.js @@ -22,6 +22,8 @@ import RemoveProject from '../app/components/RemoveProject' import RolesSummaryItem from '../app/components/RolesSummaryItem' import Snapshots from '../app/components/Snapshots' import Upload from '../app/components/Upload' +import EditorList from '../app/components/EditorList' +import EditorForm from '../app/components/EditorForm' // storiesOf('Welcome', module) // .add('to Storybook', () => <Welcome showApp={linkTo('Button')} />) @@ -36,6 +38,14 @@ storiesOf('Declarations', module) <DeclarationAnswers declarations={submittedProject.declarations}/> )) +storiesOf('Editors', module) + .add('form', () => ( + <EditorForm project={submittedProject} updateCollection={action('update collection')}/> + )) + .add('list', () => ( + <EditorList project={submittedProject} roles={submittedProject.roles.editor}/> + )) + storiesOf('Project', module) .add('title', () => ( <Project project={importedProject}/> -- GitLab