From 36f0725ccdb0a1a4f3d7b558561e7ed6b4b635c6 Mon Sep 17 00:00:00 2001 From: malexsan <alexandru.munt@gmail.com> Date: Wed, 12 Dec 2018 13:27:12 +0200 Subject: [PATCH] feat(adminUsers): add error handling --- .../src/{modals => }/ValidatedMenuField.js | 0 packages/component-faraday-ui/src/index.js | 1 + .../component-faraday-ui/src/modals/MyMenu.js | 26 -------- .../src/modals/OpenModal.js | 5 ++ .../component-faraday-ui/src/modals/index.js | 1 - packages/component-user/resolvers.js | 51 +++++++--------- packages/component-user/typeDefs.js | 11 ++-- packages/component-user/user.js | 34 +++++++++++ .../src/components/Admin/AdminUserForm.js} | 51 ++++++++-------- .../src/components/Admin/AdminUsers.js | 1 - .../src/components/Admin/OpenUserForm.js | 4 +- .../src/components/Admin/withUsersGQL.js | 59 ++++++++++++++----- 12 files changed, 138 insertions(+), 106 deletions(-) rename packages/component-faraday-ui/src/{modals => }/ValidatedMenuField.js (100%) delete mode 100644 packages/component-faraday-ui/src/modals/MyMenu.js rename packages/{component-faraday-ui/src/modals/FormModal.js => components-faraday/src/components/Admin/AdminUserForm.js} (86%) diff --git a/packages/component-faraday-ui/src/modals/ValidatedMenuField.js b/packages/component-faraday-ui/src/ValidatedMenuField.js similarity index 100% rename from packages/component-faraday-ui/src/modals/ValidatedMenuField.js rename to packages/component-faraday-ui/src/ValidatedMenuField.js diff --git a/packages/component-faraday-ui/src/index.js b/packages/component-faraday-ui/src/index.js index 2d3859c78..6d5f3b1be 100644 --- a/packages/component-faraday-ui/src/index.js +++ b/packages/component-faraday-ui/src/index.js @@ -51,6 +51,7 @@ export { default as EditorialReportCard } from './EditorialReportCard' export { default as ReviewerReportAuthor } from './ReviewerReportAuthor' export { default as PasswordValidation } from './PasswordValidation' export { default as MenuCountry } from './MenuCountry' +export { default as ValidatedMenuField } from './ValidatedMenuField' export { SubmitRevision } from './submissionRevision' diff --git a/packages/component-faraday-ui/src/modals/MyMenu.js b/packages/component-faraday-ui/src/modals/MyMenu.js deleted file mode 100644 index 9fe37eb41..000000000 --- a/packages/component-faraday-ui/src/modals/MyMenu.js +++ /dev/null @@ -1,26 +0,0 @@ -import React, { Fragment } from 'react' -import { compose, withStateHandlers } from 'recompose' - -const MyMenu = ({ open, toggleMenu, field, form }) => ( - <div onClick={toggleMenu}> - Click to open - {open && ( - <Fragment> - <span onClick={() => form.setFieldValue(field.name, 1)}>Option 1</span> - <span onClick={() => form.setFieldValue(field.name, 2)}>Option 2</span> - <span onClick={() => form.setFieldValue(field.name, 3)}>Option 3</span> - </Fragment> - )} - </div> -) - -export default compose( - withStateHandlers( - { open: false }, - { - toggleMenu: ({ open }) => () => ({ - open: !open, - }), - }, - ), -)(MyMenu) diff --git a/packages/component-faraday-ui/src/modals/OpenModal.js b/packages/component-faraday-ui/src/modals/OpenModal.js index 16ac00971..12c944512 100644 --- a/packages/component-faraday-ui/src/modals/OpenModal.js +++ b/packages/component-faraday-ui/src/modals/OpenModal.js @@ -6,6 +6,11 @@ import { MultiAction, SingleActionModal, FormModal } from './' const OpenModal = ({ showModal, children }) => children(showModal) const selectModalComponent = props => { + if (props.component) { + return { + modalComponent: props.component, + } + } if (props.single) { return { modalComponent: SingleActionModal, diff --git a/packages/component-faraday-ui/src/modals/index.js b/packages/component-faraday-ui/src/modals/index.js index f45d22615..fb4d8875a 100644 --- a/packages/component-faraday-ui/src/modals/index.js +++ b/packages/component-faraday-ui/src/modals/index.js @@ -1,4 +1,3 @@ export { default as OpenModal } from './OpenModal' -export { default as FormModal } from './FormModal' export { default as MultiAction } from './MultiAction' export { default as SingleActionModal } from './SingleActionModal' diff --git a/packages/component-user/resolvers.js b/packages/component-user/resolvers.js index 3d04170be..71f393a2b 100644 --- a/packages/component-user/resolvers.js +++ b/packages/component-user/resolvers.js @@ -1,47 +1,36 @@ -const Chance = require('chance') -const { omit } = require('lodash') const Notification = require('./notifications/notification') -const chance = new Chance() +const { parseUserFromAdmin } = require('./user') + const resolvers = { Mutation: { - async addUserWithConfirmationEmail(_, { input }, ctx) { + async addUserAsAdmin(_, { input }, ctx) { const reqUser = await ctx.connectors.User.fetchOne(ctx.user, ctx) if (!reqUser.admin) { throw new Error('Unauthorized') } - const roles = { - admin: false, - editorInChief: false, - handlingEditor: false, - } - if (input.role !== 'author') { - roles[input.role] = true - } - - input = { - ...omit(input, ['role']), - ...roles, - isActive: true, - isConfirmed: false, - notifications: { - email: { - system: true, - user: true, - }, - }, - accessTokens: { - confirmation: chance.hash(), - unsubscribe: chance.hash(), - }, - } - try { - const user = await ctx.connectors.User.create(input, ctx) + const user = await ctx.connectors.User.create( + parseUserFromAdmin(input), + ctx, + ) const notification = new Notification(user) await notification.notifyUserAddedByAdmin(input.role) + return user + } catch (e) { + return e + } + }, + async editUserAsAdmin(_, { id, input }, ctx) { + try { + const user = await ctx.connectors.User.update( + id, + parseUserFromAdmin(input), + ctx, + ) + return user } catch (e) { return e diff --git a/packages/component-user/typeDefs.js b/packages/component-user/typeDefs.js index c6f217394..b20d4d078 100644 --- a/packages/component-user/typeDefs.js +++ b/packages/component-user/typeDefs.js @@ -1,9 +1,4 @@ module.exports = ` - type Creasta { - id: String! - name: String - } - extend type User { affiliation: String country: String @@ -22,11 +17,13 @@ module.exports = ` title: String country: String affiliation: String - role: AllowedRole! + role: AllowedRole + isActive: Boolean } extend type Mutation { - addUserWithConfirmationEmail(input: UserInput!): User + addUserAsAdmin(id:ID!, input: UserInput!): User + editUserAsAdmin(id: ID!, input: UserInput!): User } enum AllowedRole { diff --git a/packages/component-user/user.js b/packages/component-user/user.js index e69de29bb..07a5b0657 100644 --- a/packages/component-user/user.js +++ b/packages/component-user/user.js @@ -0,0 +1,34 @@ +const Chance = require('chance') +const { omit } = require('lodash') + +const chance = new Chance() + +module.exports = { + parseUserFromAdmin: input => { + const roles = { + admin: false, + editorInChief: false, + handlingEditor: false, + } + if (input.role !== 'author') { + roles[input.role] = true + } + + return { + ...omit(input, ['role']), + ...roles, + isActive: true, + isConfirmed: false, + notifications: { + email: { + system: true, + user: true, + }, + }, + accessTokens: { + confirmation: chance.hash(), + unsubscribe: chance.hash(), + }, + } + }, +} diff --git a/packages/component-faraday-ui/src/modals/FormModal.js b/packages/components-faraday/src/components/Admin/AdminUserForm.js similarity index 86% rename from packages/component-faraday-ui/src/modals/FormModal.js rename to packages/components-faraday/src/components/Admin/AdminUserForm.js index af161bf39..4a3c3bba4 100644 --- a/packages/component-faraday-ui/src/modals/FormModal.js +++ b/packages/components-faraday/src/components/Admin/AdminUserForm.js @@ -20,30 +20,25 @@ import { IconButton, RowOverrideAlert, ItemOverrideAlert, + ValidatedMenuField, withRoles, withFetching, withCountries, } from 'pubsweet-component-faraday-ui' -import ValidatedMenuField from './ValidatedMenuField' - const FormModal = ({ - edit, - user, roles, title, titles, onClose, - subtitle, + onSubmit, onConfirm, countries, - confirmText = 'OK', - cancelText = 'Cancel', - onSubmit, - initialValues, - // isFetching, fetchingError, + initialValues, + confirmText = 'OK', + cancelText = 'Cancel', }) => ( <Root> <IconButton icon="x" onClick={onClose} right={5} secondary top={5} /> @@ -54,11 +49,11 @@ const FormModal = ({ validate={values => { const errors = {} - if (values.email === '') { + if (get(values, 'email', '') === '') { errors.email = 'Required' } - if (values.affiliation === '') { + if (get(values, 'affiliation', '') === '') { errors.affiliation = 'Required' } @@ -72,6 +67,7 @@ const FormModal = ({ <Label required>Email</Label> <ValidatedFieldFormik component={TextField} + inline name="email" validate={[required]} /> @@ -85,11 +81,19 @@ const FormModal = ({ <Row mb={2}> <Item mr={1} vertical> <Label>First Name</Label> - <ValidatedFieldFormik component={TextField} name="firstName" /> + <ValidatedFieldFormik + component={TextField} + inline + name="firstName" + /> </Item> <Item ml={1} vertical> <Label>Last Name</Label> - <ValidatedFieldFormik component={TextField} name="lastName" /> + <ValidatedFieldFormik + component={TextField} + inline + name="lastName" + /> </Item> </Row> @@ -104,10 +108,14 @@ const FormModal = ({ </ItemOverrideAlert> </RowOverrideAlert> - <Row mb={!edit && 3}> + <Row mb={3}> <Item vertical> <Label required>Affiliation</Label> - <ValidatedFieldFormik component={TextField} name="affiliation" /> + <ValidatedFieldFormik + component={TextField} + inline + name="affiliation" + /> </Item> </Row> @@ -135,6 +143,9 @@ const FormModal = ({ // #region FormHelpers const setInitialRole = a => { + if (get(a, 'admin')) { + return 'admin' + } if (get(a, 'handlingEditor')) { return 'handlingEditor' } @@ -144,14 +155,6 @@ 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( diff --git a/packages/components-faraday/src/components/Admin/AdminUsers.js b/packages/components-faraday/src/components/Admin/AdminUsers.js index 0e0555f57..f9a925292 100644 --- a/packages/components-faraday/src/components/Admin/AdminUsers.js +++ b/packages/components-faraday/src/components/Admin/AdminUsers.js @@ -15,7 +15,6 @@ import { Pagination, ActionLink, handleError, - withFetching, withPagination, } from 'pubsweet-component-faraday-ui' diff --git a/packages/components-faraday/src/components/Admin/OpenUserForm.js b/packages/components-faraday/src/components/Admin/OpenUserForm.js index 847237c69..ae406374e 100644 --- a/packages/components-faraday/src/components/Admin/OpenUserForm.js +++ b/packages/components-faraday/src/components/Admin/OpenUserForm.js @@ -6,10 +6,12 @@ import { IconButton, } from 'pubsweet-component-faraday-ui' +import AdminUserForm from './AdminUserForm' + const OpenUserForm = ({ edit, user, onSubmit, modalKey }) => ( <OpenModal + component={AdminUserForm} edit={edit} - formModal modalKey={modalKey} onSubmit={onSubmit} user={user} diff --git a/packages/components-faraday/src/components/Admin/withUsersGQL.js b/packages/components-faraday/src/components/Admin/withUsersGQL.js index b9aab6051..d15b4ad5c 100644 --- a/packages/components-faraday/src/components/Admin/withUsersGQL.js +++ b/packages/components-faraday/src/components/Admin/withUsersGQL.js @@ -5,6 +5,8 @@ import { compose, withHandlers, withProps } from 'recompose' const userFragment = gql` fragment userDetails on User { id + handlingEditor + editorInChief admin email title @@ -25,46 +27,73 @@ const getUsersQuery = gql` ${userFragment} ` -const addUserMutation = gql` - mutation addUser($user: UserInput) { - createUser(input: $user) { +const addUserAsAdmin = gql` + mutation addUserAsAdmin($id: ID!, $input: UserInput!) { + addUserAsAdmin(id: $id, input: $input) { ...userDetails } } ${userFragment} ` -const updateUserMutation = gql` - mutation updateUser($id: ID, $input: UserInput) { - updateUser(id: $id, input: $input) { +const editUserAsAdmin = gql` + mutation editUserAsAdmin($id: ID!, $input: UserInput!) { + editUserAsAdmin(id: $id, input: $input) { ...userDetails } } ${userFragment} ` -const parseFormValues = ({ admin, ...input }) => input - export default compose( graphql(getUsersQuery), - graphql(addUserMutation, { + graphql(addUserAsAdmin, { name: 'addUser', + options: { + refetchQueries: [{ query: getUsersQuery }], + }, }), - graphql(updateUserMutation, { + graphql(editUserAsAdmin, { name: 'updateUser', }), withHandlers({ - addUser: ({ addUser }) => (values, props) => {}, + addUser: ({ addUser }) => ( + { __typename, id, admin, ...input }, + { props: { hideModal, setFetching } }, + ) => { + setFetching(true) + addUser({ + variables: { + id, + input: { + ...input, + username: input.email, + }, + }, + }).then(() => { + setFetching(false) + hideModal() + }) + }, updateUser: ({ updateUser }) => ( - { __typename, id, ...formValues }, - { props: { hideModal } }, + { __typename, id, admin, handlingEditor, editorInChief, ...input }, + { props: { hideModal, setFetching, setError } }, ) => { + setFetching(true) updateUser({ variables: { id, - input: parseFormValues(formValues), + input, }, - }).then(hideModal) + }) + .then(() => { + setFetching(false) + hideModal() + }) + .catch(e => { + setFetching(false) + setError(e.message) + }) }, }), withProps(({ data }) => ({ -- GitLab