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