diff --git a/packages/component-faraday-ui/src/FormikMenuCountry.js b/packages/component-faraday-ui/src/FormikMenuCountry.js index d8442ad9cc637e5a9bab53212c45b55d0a3f266e..03d9b3a7f8f7a9b40783ee207d864992270a9826 100644 --- a/packages/component-faraday-ui/src/FormikMenuCountry.js +++ b/packages/component-faraday-ui/src/FormikMenuCountry.js @@ -5,17 +5,15 @@ import { MenuCountry } from './' const FormikMenuCountry = ({ name }) => ( <Field name={name}> - {({ field, form }) => - console.log({ field, form }) || ( - <MenuCountry - onChange={v => { - // field.onChange(v) - form.setFieldValue(field.name, v) - }} - value={field.value} - /> - ) - } + {({ field, form }) => ( + <MenuCountry + onChange={v => { + // field.onChange(v) + form.setFieldValue(field.name, v) + }} + value={field.value} + /> + )} </Field> ) diff --git a/packages/component-faraday-ui/src/ValidatedFormField.js b/packages/component-faraday-ui/src/ValidatedFormField.js new file mode 100644 index 0000000000000000000000000000000000000000..f34967f63a1d061daa66e56c05ea7c4d0e515683 --- /dev/null +++ b/packages/component-faraday-ui/src/ValidatedFormField.js @@ -0,0 +1,95 @@ +import React, { Fragment } from 'react' +import { get } from 'lodash' +import { Field } from 'formik' +import PropTypes from 'prop-types' +import styled from 'styled-components' +import { th } from '@pubsweet/ui-toolkit' +import { compose, withHandlers, withProps } from 'recompose' + +const WrappedComponent = compose( + withHandlers({ + onChange: ({ field: { onChange, name }, form: { setFieldValue } }) => v => { + if (typeof v === 'object') { + onChange(v) + } else { + setFieldValue(name, v) + } + }, + }), + withProps(({ form: { errors, touched, submitCount }, name }) => ({ + hasError: (get(touched, name) || submitCount > 0) && get(errors, name), + })), + withProps(({ name, hasError, form: { errors } }) => ({ + error: hasError && get(errors, name), + validationStatus: hasError ? 'error' : 'default', + })), +)( + ({ + error, + onChange, + validationStatus, + component: Component, + field: { name, value, onBlur }, + form: { errors, setFieldValue, touched, values, submitCount }, + ...props + }) => ( + <Fragment> + <Component + name={name} + onBlur={onBlur} + onChange={onChange} + value={value} + {...props} + validationStatus={validationStatus} + /> + <MessageWrapper role="alert"> + {error && <ErrorMessage>{error}</ErrorMessage>} + </MessageWrapper> + </Fragment> + ), +) + +const ValidatedFormField = ({ name, component, validateFn, ...props }) => ( + <Field name={name} validate={validateFn}> + {fieldProps => ( + <WrappedComponent + component={component} + name={name} + {...props} + {...fieldProps} + /> + )} + </Field> +) + +ValidatedFormField.propTypes = { + component: PropTypes.oneOfType([ + PropTypes.node, + PropTypes.func, + PropTypes.string, + ]).isRequired, +} + +export default withProps(({ validate }) => ({ + validateFn: value => + validate.filter(fn => fn(value)).reduce((acc, fn) => fn(value), ''), +}))(ValidatedFormField) + +// #region styles +const MessageWrapper = styled.div` + font-family: ${th('fontInterface')}; + display: flex; +` + +const Message = styled.div` + &:not(:last-child) { + margin-bottom: ${th('gridUnit')}; + } + font-size: ${th('fontSizeBaseSmall')}; + line-height: ${th('lineHeightBaseSmall')}; +` + +const ErrorMessage = styled(Message)` + color: ${th('colorError')}; +` +// #endregion diff --git a/packages/component-faraday-ui/src/ValidatedMenuField.js b/packages/component-faraday-ui/src/ValidatedMenuField.js deleted file mode 100644 index 9221c1025500265c60facb2f0a70d497e8a3a012..0000000000000000000000000000000000000000 --- a/packages/component-faraday-ui/src/ValidatedMenuField.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' -import { Field } from 'formik' -import { Menu } from '@pubsweet/ui' - -const ValidatedMenuField = ({ options, name }) => ( - <Field name={name}> - {({ field, form }) => ( - <Menu - onChange={v => { - // field.onChange(v) - form.setFieldValue(field.name, v) - }} - options={options} - value={field.value} - /> - )} - </Field> -) - -export default ValidatedMenuField diff --git a/packages/component-faraday-ui/src/index.js b/packages/component-faraday-ui/src/index.js index f16ba298ecee239c06b53ec3088d3572d4dfe380..20bb0b7c054789b3af4f5817f6c99202df2052ab 100644 --- a/packages/component-faraday-ui/src/index.js +++ b/packages/component-faraday-ui/src/index.js @@ -51,7 +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 { default as ValidatedFormField } from './ValidatedFormField' export { default as FormikMenuCountry } from './FormikMenuCountry' export { SubmitRevision } from './submissionRevision' diff --git a/packages/component-user/app/components/AdminUserForm.js b/packages/component-user/app/components/AdminUserForm.js index 5db406ab50cbc4be69fa6b70668d76abe80448a4..6faff2f37f6ff08c86bf31cc0db3fc6041add299 100644 --- a/packages/component-user/app/components/AdminUserForm.js +++ b/packages/component-user/app/components/AdminUserForm.js @@ -3,15 +3,8 @@ import { get } from 'lodash' import { Formik } from 'formik' import styled from 'styled-components' import { th } from '@pubsweet/ui-toolkit' -import { required } from 'xpub-validators' +import { H2, Menu, Button, Spinner, TextField } from '@pubsweet/ui' import { compose, setDisplayName, withHandlers, withProps } from 'recompose' -import { - H2, - Button, - Spinner, - TextField, - ValidatedFieldFormik, -} from '@pubsweet/ui' import { Row, Item, @@ -20,11 +13,11 @@ import { IconButton, RowOverrideAlert, ItemOverrideAlert, - FormikMenuCountry, - ValidatedMenuField, + ValidatedFormField, withRoles, withFetching, withCountries, + MenuCountry, } from 'pubsweet-component-faraday-ui' // #region helpers @@ -52,6 +45,9 @@ const validate = values => { } // #endregion +const min3 = value => (value.toString().length < 4 ? 'Too short!' : '') +const max6 = value => (value.toString().length > 6 ? 'Too long!' : '') + const FormModal = ({ edit, roles, @@ -87,15 +83,21 @@ const FormModal = ({ <Row alignItems="baseline" mb={1} mt={1}> <ItemOverrideAlert mr={1} vertical> <Label required>Email</Label> - <ValidatedFieldFormik + <ValidatedFormField component={TextField} inline name="email" + validate={[min3, max6]} /> </ItemOverrideAlert> + <ItemOverrideAlert ml={1} vertical> <Label required>Role</Label> - <ValidatedMenuField name="role" options={roles} /> + <ValidatedFormField + component={Menu} + name="role" + options={roles} + /> </ItemOverrideAlert> </Row> )} @@ -103,15 +105,16 @@ const FormModal = ({ <Row mb={2}> <Item mr={1} vertical> <Label>First Name</Label> - <ValidatedFieldFormik + <ValidatedFormField component={TextField} inline name="firstName" /> </Item> + <Item ml={1} vertical> <Label>Last Name</Label> - <ValidatedFieldFormik + <ValidatedFormField component={TextField} inline name="lastName" @@ -122,11 +125,16 @@ const FormModal = ({ <RowOverrideAlert alignItems="center" mb={2}> <ItemOverrideAlert mr={1} vertical> <Label>Title</Label> - <ValidatedMenuField name="title" options={titles} /> + <ValidatedFormField + component={Menu} + name="title" + options={titles} + /> </ItemOverrideAlert> + <ItemOverrideAlert ml={1} vertical> <Label>Country</Label> - <FormikMenuCountry name="country" /> + <ValidatedFormField component={MenuCountry} name="country" /> </ItemOverrideAlert> </RowOverrideAlert> @@ -134,12 +142,16 @@ const FormModal = ({ {edit && ( <ItemOverrideAlert mr={1} vertical> <Label required>Role</Label> - <ValidatedMenuField name="role" options={roles} /> + <ValidatedFormField + component={Menu} + name="role" + options={roles} + /> </ItemOverrideAlert> )} <Item ml={edit && 1} vertical> <Label>Affiliation</Label> - <ValidatedFieldFormik + <ValidatedFormField component={TextField} inline name="affiliation" diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js index 741e21c893f457c7994e983f8076249eb6e2b8d1..937096cb3a04434bf0f998a56725a40e5e65de02 100644 --- a/packages/xpub-faraday/config/default.js +++ b/packages/xpub-faraday/config/default.js @@ -51,7 +51,7 @@ module.exports = { API_ENDPOINT: '/api', baseUrl: process.env.CLIENT_BASE_URL || 'http://localhost:3000', 'login-redirect': '/', - 'redux-log': process.env.NODE_ENV !== 'production', + 'redux-log': false, //process.env.NODE_ENV !== 'production', theme: process.env.PUBSWEET_THEME, }, orcid: {