Refactor PasswordRecoveryForm: use Form connector from Final Form

This commit is contained in:
Vesa Luusua 2018-04-16 21:20:43 +03:00
parent c415babb83
commit f786ea2a79
3 changed files with 84 additions and 80 deletions

View file

@ -4,6 +4,7 @@ import PasswordRecoveryForm from './PasswordRecoveryForm';
export const Empty = {
component: PasswordRecoveryForm,
props: {
formId: 'PasswordRecoveryFormExample',
onSubmit(values) {
console.log('submit forgotten password email:', values);
},

View file

@ -2,98 +2,104 @@ import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
import { Form as FinalForm } from 'react-final-form';
import classNames from 'classnames';
import { propTypes } from '../../util/types';
import * as validators from '../../util/validators';
import { isPasswordRecoveryEmailNotFoundError } from '../../util/errors';
import { Form, PrimaryButton, TextInputField, NamedLink } from '../../components';
import { Form, PrimaryButton, FieldTextInput, NamedLink } from '../../components';
import css from './PasswordRecoveryForm.css';
const PasswordRecoveryFormComponent = props => {
const {
rootClassName,
className,
handleSubmit,
pristine,
submitting,
form,
initialValues,
intl,
inProgress,
recoveryError,
} = props;
const PasswordRecoveryFormComponent = props => (
<FinalForm
{...props}
render={fieldRenderProps => {
const {
rootClassName,
className,
formId,
handleSubmit,
pristine,
submitting,
initialValues,
intl,
inProgress,
recoveryError,
} = fieldRenderProps;
// email
const emailLabel = intl.formatMessage({
id: 'PasswordRecoveryForm.emailLabel',
});
const emailPlaceholder = intl.formatMessage({
id: 'PasswordRecoveryForm.emailPlaceholder',
});
const emailRequiredMessage = intl.formatMessage({
id: 'PasswordRecoveryForm.emailRequired',
});
const emailNotFoundMessage = intl.formatMessage({
id: 'PasswordRecoveryForm.emailNotFound',
});
const emailInvalidMessage = intl.formatMessage({
id: 'PasswordRecoveryForm.emailInvalid',
});
// email
const emailLabel = intl.formatMessage({
id: 'PasswordRecoveryForm.emailLabel',
});
const emailPlaceholder = intl.formatMessage({
id: 'PasswordRecoveryForm.emailPlaceholder',
});
const emailRequiredMessage = intl.formatMessage({
id: 'PasswordRecoveryForm.emailRequired',
});
const emailNotFoundMessage = intl.formatMessage({
id: 'PasswordRecoveryForm.emailNotFound',
});
const emailInvalidMessage = intl.formatMessage({
id: 'PasswordRecoveryForm.emailInvalid',
});
const emailRequired = validators.required(emailRequiredMessage);
const emailValid = validators.emailFormatValid(emailInvalidMessage);
const emailRequired = validators.required(emailRequiredMessage);
const emailValid = validators.emailFormatValid(emailInvalidMessage);
// In case a given email is not found, pass a custom error message
// to be rendered with the input component
const customErrorText = isPasswordRecoveryEmailNotFoundError(recoveryError)
? emailNotFoundMessage
: null;
const initialEmail = initialValues ? initialValues.email : null;
// In case a given email is not found, pass a custom error message
// to be rendered with the input component
const customErrorText = isPasswordRecoveryEmailNotFoundError(recoveryError)
? emailNotFoundMessage
: null;
const initialEmail = initialValues ? initialValues.email : null;
const classes = classNames(rootClassName || css.root, className);
const submitInProgress = submitting || inProgress;
const submitDisabled = (pristine && !initialEmail) || submitInProgress;
const classes = classNames(rootClassName || css.root, className);
const submitInProgress = submitting || inProgress;
const submitDisabled = (pristine && !initialEmail) || submitInProgress;
const loginLink = (
<NamedLink name="LoginPage" className={css.modalHelperLink}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkText" />
</NamedLink>
);
const loginLink = (
<NamedLink name="LoginPage" className={css.modalHelperLink}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkText" />
</NamedLink>
);
return (
<Form className={classes} onSubmit={handleSubmit}>
<TextInputField
className={css.email}
type="email"
name="email"
autoComplete="email"
id={`${form}.email`}
label={emailLabel}
placeholder={emailPlaceholder}
validate={[emailRequired, emailValid]}
customErrorText={customErrorText}
/>
return (
<Form className={classes} onSubmit={handleSubmit}>
<FieldTextInput
className={css.email}
type="email"
id={formId ? `${formId}.email` : 'email'}
name="email"
autoComplete="email"
label={emailLabel}
placeholder={emailPlaceholder}
validate={validators.composeValidators(emailRequired, emailValid)}
customErrorText={customErrorText}
/>
<div className={css.bottomWrapper}>
<p className={css.bottomWrapperText}>
<span className={css.modalHelperText}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkInfo" values={{ loginLink }} />
</span>
</p>
<div className={css.bottomWrapper}>
<p className={css.bottomWrapperText}>
<span className={css.modalHelperText}>
<FormattedMessage id="PasswordRecoveryForm.loginLinkInfo" values={{ loginLink }} />
</span>
</p>
<PrimaryButton type="submit" inProgress={submitInProgress} disabled={submitDisabled}>
<FormattedMessage id="PasswordRecoveryForm.sendInstructions" />
</PrimaryButton>
</div>
</Form>
);
};
<PrimaryButton type="submit" inProgress={submitInProgress} disabled={submitDisabled}>
<FormattedMessage id="PasswordRecoveryForm.sendInstructions" />
</PrimaryButton>
</div>
</Form>
);
}}
/>
);
PasswordRecoveryFormComponent.defaultProps = {
rootClassName: null,
className: null,
formId: null,
inProgress: false,
recoveryError: null,
};
@ -101,9 +107,9 @@ PasswordRecoveryFormComponent.defaultProps = {
const { bool, string } = PropTypes;
PasswordRecoveryFormComponent.propTypes = {
...formPropTypes,
rootClassName: string,
className: string,
formId: string,
inProgress: bool,
recoveryError: propTypes.error,
@ -112,10 +118,7 @@ PasswordRecoveryFormComponent.propTypes = {
intl: intlShape.isRequired,
};
const defaultFormName = 'PasswordRecoveryForm';
const PasswordRecoveryForm = compose(reduxForm({ form: defaultFormName }), injectIntl)(
PasswordRecoveryFormComponent
);
const PasswordRecoveryForm = compose(injectIntl)(PasswordRecoveryFormComponent);
PasswordRecoveryForm.displayName = 'PasswordRecoveryForm';
export default PasswordRecoveryForm;

View file

@ -36,7 +36,7 @@ exports[`ContactDetailsPage matches snapshot 1`] = `
values={Object {}}
/>
</p>
<ReduxForm
<PasswordRecoveryForm
inProgress={false}
initialValues={
Object {