mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-30 02:32:58 +05:30
#100: form loading state for profile
This commit is contained in:
parent
808f239286
commit
c51bd17259
@ -22,6 +22,7 @@
|
||||
"intl": "^1.2.2",
|
||||
"intl-format-cache": "^2.0.4",
|
||||
"intl-messageformat": "^1.1.0",
|
||||
"promise.prototype.finally": "^1.0.1",
|
||||
"react": "^15.0.0",
|
||||
"react-dom": "^15.0.0",
|
||||
"react-helmet": "^2.3.1",
|
||||
|
@ -108,6 +108,7 @@ export default class ChangeEmail extends Component {
|
||||
|
||||
<Button
|
||||
color="violet"
|
||||
type="submit"
|
||||
block
|
||||
label={this.isLastStep() ? messages.changeEmailButton : messages.sendEmailButton}
|
||||
onClick={this.onSubmit}
|
||||
|
@ -88,7 +88,7 @@ export default class ChangePassword extends Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button color="green" block label={messages.changePasswordButton} />
|
||||
<Button color="green" block label={messages.changePasswordButton} type="submit" />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { FormattedMessage as Message } from 'react-intl';
|
||||
import { Link } from 'react-router';
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import { Input, Button, Form, FormModel } from 'components/ui/form';
|
||||
@ -69,7 +68,7 @@ export default class ChangeUsername extends Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button color="green" block label={messages.changeUsernameButton} />
|
||||
<Button color="green" block label={messages.changeUsernameButton} type="submit" />
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
@ -18,7 +18,7 @@ export default class PasswordRequestForm extends Component {
|
||||
const {form} = this.props;
|
||||
|
||||
return (
|
||||
<Form onSubmit={this.onSubmit}
|
||||
<Form onSubmit={this.onFormSubmit}
|
||||
form={form}
|
||||
>
|
||||
<h2>
|
||||
@ -34,12 +34,12 @@ export default class PasswordRequestForm extends Component {
|
||||
icon="key"
|
||||
placeholder={messages.pleaseEnterPassword}
|
||||
/>
|
||||
<Button color="green" label="OK" block />
|
||||
<Button color="green" label="OK" block type="submit" />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
onSubmit = () => {
|
||||
onFormSubmit = () => {
|
||||
this.props.onSubmit(this.props.form);
|
||||
};
|
||||
}
|
||||
|
@ -29,19 +29,42 @@ export default class Form extends Component {
|
||||
};
|
||||
|
||||
state = {
|
||||
isTouched: false
|
||||
isTouched: false,
|
||||
isLoading: this.props.isLoading || false
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
if (this.props.form) {
|
||||
this.props.form.addLoadingListener(this.onLoading);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.id !== this.props.id) {
|
||||
this.setState({
|
||||
isTouched: false
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof nextProps.isLoading !== 'undefined') {
|
||||
this.setState({
|
||||
isLoading: nextProps.isLoading
|
||||
});
|
||||
}
|
||||
|
||||
if (nextProps.form && nextProps.form !== this.props.form) {
|
||||
throw new Error('The FormModel instance should not be changed during component lifetime');
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.props.form) {
|
||||
this.props.form.removeLoadingListener(this.onLoading);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {isLoading} = this.props;
|
||||
const {isLoading} = this.state;
|
||||
|
||||
return (
|
||||
<form
|
||||
@ -100,4 +123,6 @@ export default class Form extends Component {
|
||||
this.props.onInvalid(errors);
|
||||
}
|
||||
};
|
||||
|
||||
onLoading = (isLoading) => this.setState({isLoading});
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import FormInputComponent from './FormInputComponent';
|
||||
export default class FormModel {
|
||||
fields = {};
|
||||
errors = {};
|
||||
handlers = [];
|
||||
|
||||
/**
|
||||
* Connects form with React's component
|
||||
@ -83,4 +84,31 @@ export default class FormModel {
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind handler to listen for form loading state change
|
||||
*
|
||||
* @param {Function} fn
|
||||
*/
|
||||
addLoadingListener(fn) {
|
||||
this.removeLoadingListener(fn);
|
||||
this.handlers.push(fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove form loading state handler
|
||||
*
|
||||
* @param {Function} fn
|
||||
*/
|
||||
removeLoadingListener(fn) {
|
||||
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
||||
}
|
||||
|
||||
beginLoading() {
|
||||
this.handlers.forEach((fn) => fn(true));
|
||||
}
|
||||
|
||||
endLoading() {
|
||||
this.handlers.forEach((fn) => fn(false));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'babel-polyfill';
|
||||
import 'promise.prototype.finally';
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
@ -50,8 +50,9 @@ export default connect(null, {
|
||||
return routeActions.push('/');
|
||||
},
|
||||
fetchUserData,
|
||||
onSubmit: ({form, sendData}) => (dispatch) =>
|
||||
sendData()
|
||||
onSubmit: ({form, sendData}) => (dispatch) => {
|
||||
form.beginLoading();
|
||||
return sendData()
|
||||
.catch((resp) => {
|
||||
const requirePassword = resp.errors && !!resp.errors.password;
|
||||
|
||||
@ -73,20 +74,24 @@ export default connect(null, {
|
||||
dispatch(createPopup(PasswordRequestForm, (props) => ({
|
||||
form,
|
||||
onSubmit: () => {
|
||||
form.beginLoading();
|
||||
sendData()
|
||||
.catch((resp) => {
|
||||
if (resp.errors) {
|
||||
form.setErrors(resp.errors);
|
||||
}
|
||||
.catch((resp) => {
|
||||
if (resp.errors) {
|
||||
form.setErrors(resp.errors);
|
||||
}
|
||||
|
||||
return Promise.reject(resp);
|
||||
})
|
||||
.then(resolve)
|
||||
.then(props.onClose);
|
||||
return Promise.reject(resp);
|
||||
})
|
||||
.then(resolve)
|
||||
.then(props.onClose)
|
||||
.finally(() => form.endLoading());
|
||||
}
|
||||
})));
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}))
|
||||
.finally(() => form.endLoading());
|
||||
}
|
||||
})(ProfilePage);
|
||||
|
Loading…
Reference in New Issue
Block a user