mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-30 02:32:58 +05:30
Блокировка формы во время обработки запроса
This commit is contained in:
parent
0162d1270f
commit
df9283400d
@ -25,6 +25,7 @@ class PanelTransition extends Component {
|
||||
// context props
|
||||
auth: PropTypes.shape({
|
||||
error: PropTypes.string,
|
||||
isLoading: PropTypes.bool,
|
||||
login: PropTypes.shape({
|
||||
login: PropTypes.string,
|
||||
password: PropTypes.string
|
||||
@ -142,7 +143,12 @@ class PanelTransition extends Component {
|
||||
};
|
||||
|
||||
return (
|
||||
<Form id={panelId} onSubmit={this.onFormSubmit} onInvalid={this.onFormInvalid}>
|
||||
<Form
|
||||
id={panelId}
|
||||
onSubmit={this.onFormSubmit}
|
||||
onInvalid={this.onFormInvalid}
|
||||
isLoading={this.props.auth.isLoading}
|
||||
>
|
||||
<Panel>
|
||||
<PanelHeader>
|
||||
{panels.map((config) => this.getHeader(config))}
|
||||
|
@ -8,7 +8,7 @@ export function login({login = '', password = '', rememberMe = false}) {
|
||||
const LOGIN_REQUIRED = 'error.login_required';
|
||||
const ACTIVATION_REQUIRED = 'error.account_not_activated';
|
||||
|
||||
return (dispatch) =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
request.post(
|
||||
'/api/authentication/login',
|
||||
{login, password, rememberMe}
|
||||
@ -43,7 +43,7 @@ export function login({login = '', password = '', rememberMe = false}) {
|
||||
|
||||
// TODO: log unexpected errors
|
||||
})
|
||||
;
|
||||
);
|
||||
}
|
||||
|
||||
export function changePassword({
|
||||
@ -51,7 +51,7 @@ export function changePassword({
|
||||
newPassword = '',
|
||||
newRePassword = ''
|
||||
}) {
|
||||
return (dispatch) =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
dispatch(changeUserPassword({password, newPassword, newRePassword}))
|
||||
.catch((resp) => {
|
||||
if (resp.errors) {
|
||||
@ -62,7 +62,7 @@ export function changePassword({
|
||||
|
||||
// TODO: log unexpected errors
|
||||
})
|
||||
;
|
||||
);
|
||||
}
|
||||
|
||||
export function register({
|
||||
@ -72,7 +72,7 @@ export function register({
|
||||
rePassword = '',
|
||||
rulesAgreement = false
|
||||
}) {
|
||||
return (dispatch) =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
request.post(
|
||||
'/api/signup',
|
||||
{email, username, password, rePassword, rulesAgreement}
|
||||
@ -94,11 +94,11 @@ export function register({
|
||||
|
||||
// TODO: log unexpected errors
|
||||
})
|
||||
;
|
||||
);
|
||||
}
|
||||
|
||||
export function activate({key = ''}) {
|
||||
return (dispatch) =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
request.post(
|
||||
'/api/signup/confirm',
|
||||
{key}
|
||||
@ -118,7 +118,7 @@ export function activate({key = ''}) {
|
||||
|
||||
// TODO: log unexpected errors
|
||||
})
|
||||
;
|
||||
);
|
||||
}
|
||||
|
||||
export const ERROR = 'error';
|
||||
@ -141,7 +141,7 @@ export function logout() {
|
||||
// TODO: move to oAuth actions?
|
||||
// test request: /oauth?client_id=ely&redirect_uri=http%3A%2F%2Fely.by&response_type=code&scope=minecraft_server_session
|
||||
export function oAuthValidate(oauth) {
|
||||
return (dispatch) =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
request.get(
|
||||
'/api/oauth/validate',
|
||||
getOAuthRequest(oauth)
|
||||
@ -156,11 +156,12 @@ export function oAuthValidate(oauth) {
|
||||
if (resp.statusCode === 401 && resp.error === 'accept_required') {
|
||||
alert('Accept required.');
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export function oAuthComplete(params = {}) {
|
||||
return (dispatch, getState) => {
|
||||
return wrapInLoader((dispatch, getState) => {
|
||||
const oauth = getState().auth.oauth;
|
||||
const query = request.buildQuery(getOAuthRequest(oauth));
|
||||
|
||||
@ -205,7 +206,7 @@ export function oAuthComplete(params = {}) {
|
||||
|
||||
return resp;
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getOAuthRequest(oauth) {
|
||||
@ -283,3 +284,29 @@ export function setScopes(scopes) {
|
||||
payload: scopes
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export const SET_LOADING_STATE = 'set_loading_state';
|
||||
export function setLoadingState(isLoading) {
|
||||
return {
|
||||
type: SET_LOADING_STATE,
|
||||
payload: isLoading
|
||||
};
|
||||
}
|
||||
|
||||
function wrapInLoader(fn) {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(setLoadingState(true));
|
||||
const endLoading = () => dispatch(setLoadingState(false));
|
||||
|
||||
return Reflect.apply(fn, null, [dispatch, getState]).then((resp) => {
|
||||
endLoading();
|
||||
|
||||
return resp;
|
||||
}, (resp) => {
|
||||
endLoading();
|
||||
|
||||
return Promise.reject(resp);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
import { ERROR, SET_CLIENT, SET_OAUTH, SET_OAUTH_RESULT, SET_SCOPES } from './actions';
|
||||
import { ERROR, SET_CLIENT, SET_OAUTH, SET_OAUTH_RESULT, SET_SCOPES, SET_LOADING_STATE } from './actions';
|
||||
|
||||
export default combineReducers({
|
||||
error,
|
||||
isLoading,
|
||||
client,
|
||||
oauth,
|
||||
scopes
|
||||
@ -25,6 +26,20 @@ function error(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function isLoading(
|
||||
state = false,
|
||||
{type, payload = null}
|
||||
) {
|
||||
switch (type) {
|
||||
case SET_LOADING_STATE:
|
||||
return !!payload;
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function client(
|
||||
state = null,
|
||||
{type, payload = {}}
|
||||
|
@ -102,6 +102,7 @@ export class Form extends Component {
|
||||
|
||||
static propTypes = {
|
||||
id: PropTypes.string, // and id, that uniquely identifies form contents
|
||||
isLoading: PropTypes.bool,
|
||||
onSubmit: PropTypes.func,
|
||||
onInvalid: PropTypes.func,
|
||||
children: PropTypes.oneOfType([
|
||||
@ -112,6 +113,7 @@ export class Form extends Component {
|
||||
|
||||
static defaultProps = {
|
||||
id: 'default',
|
||||
isLoading: false,
|
||||
onSubmit() {},
|
||||
onInvalid() {}
|
||||
};
|
||||
@ -129,11 +131,14 @@ export class Form extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {isLoading} = this.props;
|
||||
|
||||
return (
|
||||
<form
|
||||
className={classNames(
|
||||
styles.form,
|
||||
{
|
||||
[styles.isFormLoading]: isLoading,
|
||||
[styles.formTouched]: this.state.isTouched
|
||||
}
|
||||
)}
|
||||
|
@ -234,3 +234,17 @@
|
||||
border-color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
.isFormLoading {
|
||||
// TODO: надо бы разнести from и input на отдельные модули,
|
||||
// так как в текущем контексте isLoading немного не логичен,
|
||||
// пришлось юзать isFormLoading
|
||||
* {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
button {
|
||||
background-image: url('images/loader_button.gif');
|
||||
background-position: center center;
|
||||
}
|
||||
}
|
||||
|
BIN
src/components/ui/images/loader_button.gif
Normal file
BIN
src/components/ui/images/loader_button.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 317 B |
Loading…
Reference in New Issue
Block a user