From 85c3868211b168254cc683ef29186923403b6db7 Mon Sep 17 00:00:00 2001
From: malexsan <alexandru.munt@gmail.com>
Date: Fri, 7 Dec 2018 10:59:04 +0200
Subject: [PATCH] feat(adminUsers): create graphql hoc with user queries and
 mutations

---
 .../src/helpers/withRoles.js                  | 31 ++++----
 .../src/modals/FormModal.js                   | 74 ++++++++++---------
 .../src/modals/ValidatedMenuField.js          |  1 +
 .../src/components/Admin/AddUser.js           | 38 ----------
 .../src/components/Admin/AdminUsers.js        | 48 ++----------
 .../src/components/Admin/OpenUserForm.js      | 29 ++++++++
 .../src/components/Admin/index.js             |  4 +-
 .../src/components/Admin/utils.js             | 39 +---------
 .../src/components/Admin/withUsersGQL.js      | 54 ++++++++++++++
 9 files changed, 151 insertions(+), 167 deletions(-)
 delete mode 100644 packages/components-faraday/src/components/Admin/AddUser.js
 create mode 100644 packages/components-faraday/src/components/Admin/OpenUserForm.js
 create mode 100644 packages/components-faraday/src/components/Admin/withUsersGQL.js

diff --git a/packages/component-faraday-ui/src/helpers/withRoles.js b/packages/component-faraday-ui/src/helpers/withRoles.js
index aa0e7a719..e6f1b0387 100644
--- a/packages/component-faraday-ui/src/helpers/withRoles.js
+++ b/packages/component-faraday-ui/src/helpers/withRoles.js
@@ -1,15 +1,20 @@
 import { get } from 'lodash'
-import { withProps } from 'recompose'
+import { withJournal } from 'xpub-journal'
+import { compose, withProps } from 'recompose'
 
-export default withProps(({ journal }) => ({
-  roles: Object.entries(get(journal, 'roles', {})).reduce(
-    (acc, el) => [
-      ...acc,
-      {
-        value: el[0],
-        label: el[1],
-      },
-    ],
-    [],
-  ),
-}))
+export default compose(
+  withJournal,
+  withProps(({ journal }) => ({
+    titles: get(journal, 'title', []),
+    roles: Object.entries(get(journal, 'roles', {})).reduce(
+      (acc, el) => [
+        ...acc,
+        {
+          value: el[0],
+          label: el[1],
+        },
+      ],
+      [],
+    ),
+  })),
+)
diff --git a/packages/component-faraday-ui/src/modals/FormModal.js b/packages/component-faraday-ui/src/modals/FormModal.js
index a9b280c64..b2ab96ffb 100644
--- a/packages/component-faraday-ui/src/modals/FormModal.js
+++ b/packages/component-faraday-ui/src/modals/FormModal.js
@@ -14,6 +14,8 @@ import {
   IconButton,
   RowOverrideAlert,
   ItemOverrideAlert,
+  withRoles,
+  withCountries,
 } from 'pubsweet-component-faraday-ui'
 
 import ValidatedMenuField from './ValidatedMenuField'
@@ -175,15 +177,6 @@ import ValidatedMenuField from './ValidatedMenuField'
 
 // #endregion
 
-const parseUser = ({ email, role, ...rest }) => ({
-  email,
-  username: email,
-  admin: role === 'admin',
-  editorInChief: role === 'editorInChief',
-  handlingEditor: role === 'handlingEditor',
-  ...rest,
-})
-
 const FormModal = ({
   edit,
   user,
@@ -194,23 +187,23 @@ const FormModal = ({
   subtitle,
   onConfirm,
   countries,
-  modalError,
-  isFetching,
-  handleSubmit,
   confirmText = 'OK',
   cancelText = 'Cancel',
   //
-  addUser,
+  onSubmit,
+  initialValues,
 }) => (
   <Root>
     <IconButton icon="x" onClick={onClose} right={5} secondary top={5} />
     <H2>{title}</H2>
     <Formik
-      onSubmit={values => {
-        addUser({ variables: { user: parseUser(values) } })
-      }}
+      // onSubmit={values => {
+      //   addUser({ variables: { user: parseUser(values) } })
+      // }}
+      initialValues={initialValues}
+      onSubmit={onSubmit}
     >
-      {ceva => (
+      {({ handleSubmit }) => (
         <Fragment>
           <Row alignItems="baseline" mb={1} mt={1}>
             <Item mr={1} vertical>
@@ -258,22 +251,17 @@ const FormModal = ({
 
           <Row>
             <Button onClick={onClose}>Cancel</Button>
-            <Button onClick={ceva.handleSubmit} primary>
-              Save user
+            <Button onClick={handleSubmit} primary>
+              {confirmText}
             </Button>
           </Row>
         </Fragment>
       )}
     </Formik>
-
-    {modalError && (
-      <Row mb={1}>
-        <Text error>{modalError}</Text>
-      </Row>
-    )}
   </Root>
 )
 
+// #region FormHelpers
 const setInitialRole = a => {
   if (get(a, 'handlingEditor')) {
     return 'handlingEditor'
@@ -284,27 +272,41 @@ const setInitialRole = a => {
   return 'author'
 }
 
+const parseValues = ({ email, role, ...rest }) => ({
+  email,
+  username: email,
+  admin: role === 'admin',
+  editorInChief: role === 'editorInChief',
+  handlingEditor: role === 'handlingEditor',
+  ...rest,
+})
+// #endregion
+
 export default compose(
+  withRoles,
+  withCountries,
+  withProps(({ user, edit }) => ({
+    initialValues: {
+      ...user,
+      role: setInitialRole(user),
+    },
+    confirmText: edit ? 'EDIT USER' : 'SAVE USER',
+    title: edit ? 'Edit User' : 'Add User',
+  })),
   withHandlers({
-    onConfirm: ({ onConfirm, ...props }) => () => {
-      if (onConfirm && typeof onConfirm === 'function') {
-        onConfirm(props)
+    onSubmit: ({ onSubmit, ...props }) => (values, formProps) => {
+      if (typeof onSubmit === 'function') {
+        onSubmit({ values: parseValues(values), formProps, props })
       }
     },
     onClose: ({ onCancel, ...props }) => () => {
-      if (onCancel && typeof onCancel === 'function') {
+      if (typeof onCancel === 'function') {
         onCancel(props)
       }
       props.hideModal()
     },
   }),
-  withProps(({ user, edit }) => ({
-    initialValues: {
-      ...user,
-      role: setInitialRole(user),
-    },
-    confirmText: edit ? 'EDIT USER' : 'SAVE USER',
-  })),
+
   setDisplayName('FormModal'),
 )(FormModal)
 
diff --git a/packages/component-faraday-ui/src/modals/ValidatedMenuField.js b/packages/component-faraday-ui/src/modals/ValidatedMenuField.js
index b8b4c1efb..d1c2bb117 100644
--- a/packages/component-faraday-ui/src/modals/ValidatedMenuField.js
+++ b/packages/component-faraday-ui/src/modals/ValidatedMenuField.js
@@ -11,6 +11,7 @@ const ValidatedMenuField = ({ options, name }) => (
           form.setFieldValue(name, v)
         }}
         options={options}
+        value={field.value}
       />
     )}
   </Field>
diff --git a/packages/components-faraday/src/components/Admin/AddUser.js b/packages/components-faraday/src/components/Admin/AddUser.js
deleted file mode 100644
index 1a90ce17c..000000000
--- a/packages/components-faraday/src/components/Admin/AddUser.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import React from 'react'
-import { get } from 'lodash'
-import { compose } from 'recompose'
-import { withJournal } from 'xpub-journal'
-
-import {
-  OpenModal,
-  ActionLink,
-  IconButton,
-  withRoles,
-  withFetching,
-  withCountries,
-} from 'pubsweet-component-faraday-ui'
-
-const AddUser = ({ edit, journal, addUser, ...rest }) => (
-  <OpenModal
-    addUser={addUser}
-    edit={edit}
-    formModal
-    title={edit ? 'Edit User' : 'Add User'}
-    titles={get(journal, 'title', [])}
-    {...rest}
-  >
-    {showModal =>
-      edit ? (
-        <IconButton icon="edit-2" iconSize={2} onClick={showModal} pt={1 / 2} />
-      ) : (
-        <ActionLink icon="plus" onClick={showModal}>
-          ADD USER
-        </ActionLink>
-      )
-    }
-  </OpenModal>
-)
-
-export default compose(withJournal, withCountries, withRoles, withFetching)(
-  AddUser,
-)
diff --git a/packages/components-faraday/src/components/Admin/AdminUsers.js b/packages/components-faraday/src/components/Admin/AdminUsers.js
index 76664a223..83e388f62 100644
--- a/packages/components-faraday/src/components/Admin/AdminUsers.js
+++ b/packages/components-faraday/src/components/Admin/AdminUsers.js
@@ -6,8 +6,6 @@ import { th } from '@pubsweet/ui-toolkit'
 import { withJournal } from 'xpub-journal'
 import { compose, withHandlers, withProps } from 'recompose'
 
-import gql from 'graphql-tag'
-import { graphql } from 'react-apollo'
 import {
   Row,
   Text,
@@ -21,36 +19,8 @@ import {
   withPagination,
 } from 'pubsweet-component-faraday-ui'
 
-import { AddUser } from './'
-import { updateUserStatus, onSubmit } from './utils'
-
-const GET_USERS = gql`
-  {
-    users {
-      id
-      admin
-      email
-      country
-      username
-      lastName
-      isActive
-      firstName
-      affiliation
-      isConfirmed
-      editorInChief
-      handlingEditor
-    }
-  }
-`
-
-const ADD_USER = gql`
-  mutation addUser($user: UserInput) {
-    createUser(input: $user) {
-      id
-      email
-    }
-  }
-`
+import { updateUserStatus } from './utils'
+import { OpenUserForm, withUsersGQL } from './'
 
 const Users = ({
   page,
@@ -82,11 +52,9 @@ const Users = ({
         >
           Admin Dashboard
         </ActionLink>
-        <AddUser
-          addUser={addUser}
-          form="add-user"
-          getUsers={getUsers}
+        <OpenUserForm
           modalKey="addUser"
+          onSubmit={v => console.log('GQL add mutation here:', v)} // eslint-disable-line
         />
       </Item>
 
@@ -135,11 +103,10 @@ const Users = ({
 
             <HiddenCell>
               <Item alignItems="center" justify="flex-end">
-                <AddUser
+                <OpenUserForm
                   edit
-                  getUsers={getUsers}
                   modalKey={`edit-${user.id}`}
-                  onSubmit={onSubmit}
+                  onSubmit={v => console.log('GQL edit mutation here:', v)} // eslint-disable-line
                   user={user}
                 />
                 <OpenModal
@@ -174,8 +141,7 @@ const Users = ({
 export default compose(
   withJournal,
   withFetching,
-  graphql(GET_USERS),
-  graphql(ADD_USER, { name: 'addUser' }),
+  withUsersGQL,
   withProps(({ journal: { roles = {} }, data: { users } }) => ({
     roles: Object.keys(roles),
     items: users,
diff --git a/packages/components-faraday/src/components/Admin/OpenUserForm.js b/packages/components-faraday/src/components/Admin/OpenUserForm.js
new file mode 100644
index 000000000..847237c69
--- /dev/null
+++ b/packages/components-faraday/src/components/Admin/OpenUserForm.js
@@ -0,0 +1,29 @@
+import React from 'react'
+
+import {
+  OpenModal,
+  ActionLink,
+  IconButton,
+} from 'pubsweet-component-faraday-ui'
+
+const OpenUserForm = ({ edit, user, onSubmit, modalKey }) => (
+  <OpenModal
+    edit={edit}
+    formModal
+    modalKey={modalKey}
+    onSubmit={onSubmit}
+    user={user}
+  >
+    {showModal =>
+      edit ? (
+        <IconButton icon="edit-2" iconSize={2} onClick={showModal} pt={1 / 2} />
+      ) : (
+        <ActionLink icon="plus" onClick={showModal}>
+          ADD USER
+        </ActionLink>
+      )
+    }
+  </OpenModal>
+)
+
+export default OpenUserForm
diff --git a/packages/components-faraday/src/components/Admin/index.js b/packages/components-faraday/src/components/Admin/index.js
index 2bc308a26..0bb7e9bed 100644
--- a/packages/components-faraday/src/components/Admin/index.js
+++ b/packages/components-faraday/src/components/Admin/index.js
@@ -1,4 +1,6 @@
-export { default as AddUser } from './AddUser'
+export { default as withUsersGQL } from './withUsersGQL'
+
 export { default as AdminUsers } from './AdminUsers'
 export { default as AdminRoute } from './AdminRoute'
+export { default as OpenUserForm } from './OpenUserForm'
 export { default as AdminDashboard } from './AdminDashboard'
diff --git a/packages/components-faraday/src/components/Admin/utils.js b/packages/components-faraday/src/components/Admin/utils.js
index a923d2077..14835de25 100644
--- a/packages/components-faraday/src/components/Admin/utils.js
+++ b/packages/components-faraday/src/components/Admin/utils.js
@@ -1,6 +1,5 @@
 import { pick, omit, isBoolean, replace } from 'lodash'
-import { handleError } from 'pubsweet-component-faraday-ui'
-import { update, create } from 'pubsweet-client/src/helpers/api'
+import { update } from 'pubsweet-client/src/helpers/api'
 
 const generatePasswordHash = () =>
   Array.from({ length: 4 }, () =>
@@ -85,39 +84,3 @@ export const updateUserStatus = user => {
   const updatedUser = toggleUserStatus(user)
   return update(`/users/${user.id}`, parseUpdateUser(updatedUser))
 }
-
-export const onSubmit = (
-  values,
-  dispatch,
-  { edit, setFetching, getUsers, hideModal, setModalError },
-) => {
-  setFetching(true)
-  if (!edit) {
-    const newValues = setAdmin(values)
-    return create('/users', newValues)
-      .then(r => {
-        create(`/emails`, {
-          email: r.email,
-          type: 'invite',
-          role: values.role,
-        })
-        setFetching(false)
-        getUsers()
-        hideModal()
-      })
-      .catch(err => {
-        setFetching(false)
-        handleError(setModalError)(err)
-      })
-  }
-  return update(`/users/${values.id}`, parseUpdateUser(values))
-    .then(() => {
-      setFetching(false)
-      getUsers()
-      hideModal()
-    })
-    .catch(err => {
-      setFetching(false)
-      handleError(setModalError)(err)
-    })
-}
diff --git a/packages/components-faraday/src/components/Admin/withUsersGQL.js b/packages/components-faraday/src/components/Admin/withUsersGQL.js
new file mode 100644
index 000000000..e5015dc1d
--- /dev/null
+++ b/packages/components-faraday/src/components/Admin/withUsersGQL.js
@@ -0,0 +1,54 @@
+import gql from 'graphql-tag'
+import { compose } from 'recompose'
+import { graphql } from 'react-apollo'
+
+const userFragment = gql`
+  fragment userDetails on User {
+    id
+    admin
+    email
+    title
+    country
+    username
+    lastName
+    isActive
+    firstName
+    affiliation
+    isConfirmed
+    editorInChief
+    handlingEditor
+  }
+`
+
+const getUsersQuery = gql`
+  {
+    users {
+      ...userDetails
+    }
+  }
+  ${userFragment}
+`
+
+const addUserMutation = gql`
+  mutation addUser($user: UserInput) {
+    createUser(input: $user) {
+      ...userDetails
+    }
+  }
+  ${userFragment}
+`
+
+const updateUserMutation = gql`
+  mutation updateUser($id: ID, $input: UserInput) {
+    updateUser(id: $id, input: $input) {
+      ...userDetails
+    }
+  }
+  ${userFragment}
+`
+
+export default compose(
+  graphql(getUsersQuery),
+  graphql(addUserMutation, { name: 'addUser' }),
+  graphql(updateUserMutation, { name: 'updateUser' }),
+)
-- 
GitLab