Skip to content

Commit

Permalink
update authform components to use formik #556
Browse files Browse the repository at this point in the history
  • Loading branch information
vbojilova committed Jul 31, 2024
1 parent e01be6b commit 426a606
Show file tree
Hide file tree
Showing 19 changed files with 195 additions and 277 deletions.
106 changes: 58 additions & 48 deletions app/components/formik/AuthForm/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import { Form, Errors } from 'react-redux-form/immutable';
import { Field as FormikField, Form, Formik, ErrorMessage } from 'formik';
import styled from 'styled-components';

import { omit } from 'lodash/object';
import { startCase } from 'lodash/string';

import { validateField } from 'utils/formik';

import appMessages from 'containers/App/messages';

import ButtonCancel from 'components/buttons/ButtonCancel';
Expand All @@ -27,57 +29,60 @@ import Required from '../Required';
import ControlInput from '../ControlInput';

// These props will be omitted before being passed to the Control component
const nonControlProps = ['hint', 'label', 'component', 'controlType', 'children', 'errorMessages'];
const nonControlProps = ['hint', 'label', 'component', 'controlType', 'children', 'errorMessages', 'validators'];

const StyledForm = styled(Form)`
display: table;
width: 100%;
`;

class AuthForm extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
renderError = (name) => (
<ErrorWrapper>
<ErrorMessage
className="errors"
name={name}
show="touched"
/>
</ErrorWrapper>
);
renderLabel = (field) => (
<Label htmlFor={field.id}>
{`${field.label || startCase(field.id)}`}
{field.validators && field.validators.required
&& <Required>*</Required>
}
</Label>
)

renderField = (field) => {
const { id, model, ...props } = omit(field, nonControlProps);
const { id, ...props } = omit(field, nonControlProps);
return (
<ControlInput
id={id}
model={model || `.${id}`}
{...props}
/>
);
}

renderBody = (fields) => (
renderBody = (fieldConfigs) => (
<FormBody>
<ViewPanel>
<Main bottom>
<FieldGroupWrapper>
{fields.map((field, i) => (
<Field key={i}>
{ field.label !== false
&& (
<Label htmlFor={field.id}>
{`${field.label || startCase(field.id)}`}
{ field.validators && field.validators.required
&& <Required>*</Required>
}
</Label>
)
}
{this.renderField(field)}
{
field.errorMessages
&& (
<ErrorWrapper>
<Errors
className="errors"
model={field.model}
show="touched"
messages={field.errorMessages}
/>
</ErrorWrapper>
)
}
</Field>
{fieldConfigs.map((fieldConfig, i) => (
<FormikField
key={i}
name={fieldConfig.id}
validate={(value) => validateField(value, fieldConfig)}>
{({ field, meta }) => (
<Field>
{field.label !== false && this.renderLabel(fieldConfig)}
{this.renderField({ ...fieldConfig, ...field })}
{meta.touched && meta.error && this.renderError(field.name)}
</Field>
)}
</FormikField>
))}
</FieldGroupWrapper>
</Main>
Expand All @@ -87,24 +92,30 @@ class AuthForm extends React.PureComponent { // eslint-disable-line react/prefer

render() {
const {
fields, model, handleSubmit, handleCancel, labels,
initialValues, fields, handleSubmit, handleCancel, labels,
} = this.props;

return (
<FormWrapper>
<StyledForm model={model} onSubmit={handleSubmit}>
{ fields && this.renderBody(fields) }
<FormFooter>
<FormFooterButtons>
<ButtonCancel type="button" onClick={handleCancel}>
<FormattedMessage {...appMessages.buttons.cancel} />
</ButtonCancel>
<ButtonSubmit type="submit" disabled={this.props.sending}>
{labels.submit}
</ButtonSubmit>
</FormFooterButtons>
<Clear />
</FormFooter>
</StyledForm>
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
>
<StyledForm>
{fields && this.renderBody(fields)}
<FormFooter>
<FormFooterButtons>
<ButtonCancel type="button" onClick={handleCancel}>
<FormattedMessage {...appMessages.buttons.cancel} />
</ButtonCancel>
<ButtonSubmit type="submit" disabled={this.props.sending}>
{labels.submit}
</ButtonSubmit>
</FormFooterButtons>
<Clear />
</FormFooter>
</StyledForm>
</Formik>
</FormWrapper>
);
}
Expand All @@ -114,7 +125,6 @@ AuthForm.propTypes = {
handleSubmit: PropTypes.func.isRequired,
handleCancel: PropTypes.func.isRequired,
labels: PropTypes.object,
model: PropTypes.string,
fields: PropTypes.array,
sending: PropTypes.bool,
};
Expand Down
5 changes: 5 additions & 0 deletions app/containers/UserLogin/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
*/
export const LOGIN = 'impactoss/UserLogin/LOGIN';
export const LOGIN_WITH_AZURE = 'impactoss/UserLogin/LOGIN_WITH_AZURE';

export const FORM_INITIAL = {
email: '',
password: '',
};
42 changes: 15 additions & 27 deletions app/containers/UserLogin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,19 @@ import { FormattedMessage, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import HelmetCanonical from 'components/HelmetCanonical';
import styled from 'styled-components';
import { actions as formActions } from 'react-redux-form/immutable';

import {
getEmailFormField,
getPasswordField,
} from 'utils/forms';

} from 'utils/formik';

import ButtonHero from 'components/buttons/ButtonHero';
import Messages from 'components/Messages';
import Loading from 'components/Loading';
import Icon from 'components/Icon';
import ContentNarrow from 'components/ContentNarrow';
import ContentHeader from 'components/ContentHeader';
import AuthForm from 'components/forms/AuthForm';
import AuthForm from 'components/formik/AuthForm';
import A from 'components/styled/A';

import { selectQueryMessages } from 'containers/App/selectors';
Expand All @@ -36,6 +34,7 @@ import messages from './messages';

import { login, loginWithAzure } from './actions';
import { selectDomain } from './selectors';
import { FORM_INITIAL } from './constants';

const BottomLinks = styled.div`
padding: 2em 0;
Expand All @@ -48,9 +47,6 @@ const AzureButton = styled(ButtonHero)`


export class UserLogin extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
UNSAFE_componentWillMount() {
this.props.initialiseForm();
}

render() {
const { intl } = this.props;
Expand Down Expand Up @@ -108,21 +104,17 @@ export class UserLogin extends React.PureComponent { // eslint-disable-line reac
}
{!ENABLE_AZURE && (
<>
{this.props.viewDomain.get('form')
&& (
<AuthForm
model="userLogin.form.data"
sending={authSending}
handleSubmit={(formData) => handleSubmit(formData)}
handleCancel={handleCancel}
labels={{ submit: intl.formatMessage(messages.submit) }}
fields={[
getEmailFormField(intl.formatMessage, '.email'),
getPasswordField(intl.formatMessage, '.password'),
]}
/>
)
}
<AuthForm
sending={authSending}
handleSubmit={(formData) => handleSubmit(formData)}
handleCancel={handleCancel}
initialValues={FORM_INITIAL}
labels={{ submit: intl.formatMessage(messages.submit) }}
fields={[
getEmailFormField(intl.formatMessage),
getPasswordField(intl.formatMessage),
]}
/>
<BottomLinks>
<p>
<FormattedMessage {...messages.registerLinkBefore} />
Expand Down Expand Up @@ -176,7 +168,6 @@ UserLogin.propTypes = {
handleSubmitWithAzure: PropTypes.func.isRequired,
handleCancel: PropTypes.func.isRequired,
handleLink: PropTypes.func.isRequired,
initialiseForm: PropTypes.func,
onDismissQueryMessages: PropTypes.func,
queryMessages: PropTypes.object,
intl: PropTypes.object.isRequired,
Expand All @@ -189,11 +180,8 @@ const mapStateToProps = (state) => ({

export function mapDispatchToProps(dispatch) {
return {
initialiseForm: () => {
dispatch(formActions.reset('userLogin.form.data'));
},
handleSubmit: (formData) => {
dispatch(login(formData.toJS()));
dispatch(login(formData));
dispatch(dismissQueryMessages());
},
handleSubmitWithAzure: () => {
Expand Down
10 changes: 0 additions & 10 deletions app/containers/UserLogin/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@

import { fromJS } from 'immutable';
import { LOCATION_CHANGE } from 'react-router-redux';

import { combineReducers } from 'redux-immutable';
import { combineForms } from 'react-redux-form/immutable';

import { checkResponseError } from 'utils/request';

Expand Down Expand Up @@ -46,14 +44,6 @@ function userLoginReducer(state = initialState, action) {
}
}

const formData = fromJS({
email: '',
password: '',
});

export default combineReducers({
page: userLoginReducer,
form: combineForms({
data: formData,
}, 'userLogin.form'),
});
7 changes: 6 additions & 1 deletion app/containers/UserPassword/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
* UserPassword constants
*
*/

export const SAVE = 'impactoss/UserPassword/SAVE';
export const PASSWORD_SENDING = 'impactoss/UserPassword/PASSWORD_SENDING';
export const PASSWORD_SUCCESS = 'impactoss/UserPassword/PASSWORD_SUCCESS';
export const PASSWORD_ERROR = 'impactoss/UserPassword/PASSWORD_ERROR';

export const FORM_INITIAL = {
password: '',
passwordNew: '',
passwordConfirmation: '',
};
Loading

0 comments on commit 426a606

Please sign in to comment.