Skip to content

Commit

Permalink
Adding interface for translating API error codes. Using this translat…
Browse files Browse the repository at this point in the history
…ion in login form.
  • Loading branch information
Martin Krulis committed Oct 3, 2019
1 parent 1ed4db8 commit ce99c37
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 14 deletions.
14 changes: 6 additions & 8 deletions src/components/forms/LoginForm/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { EmailField, PasswordField } from '../Fields';
import { Alert } from 'react-bootstrap';
import Button from '../../widgets/FlatButton';

const LoginForm = ({ invalid, handleSubmit, submitFailed: hasFailed, submitting, hasSucceeded }) => (
const LoginForm = ({ invalid, handleSubmit, submitFailed: hasFailed, submitting, hasSucceeded, error }) => (
<FormBox
title={<FormattedMessage id="app.loginForm.title" defaultMessage="Sign into ReCodEx" />}
type={hasSucceeded ? 'success' : undefined}
Expand All @@ -21,7 +21,7 @@ const LoginForm = ({ invalid, handleSubmit, submitFailed: hasFailed, submitting,
{!submitting ? (
hasSucceeded ? (
<span>
<SuccessIcon />{' '}
<SuccessIcon gapRight />
<FormattedMessage id="app.loginForm.success" defaultMessage="You are successfully signed in" />
</span>
) : (
Expand All @@ -32,17 +32,14 @@ const LoginForm = ({ invalid, handleSubmit, submitFailed: hasFailed, submitting,
)
) : (
<span>
<LoadingIcon /> <FormattedMessage id="app.loginForm.processing" defaultMessage="Signing in..." />
<LoadingIcon gapRight />
<FormattedMessage id="app.loginForm.processing" defaultMessage="Signing in..." />
</span>
)}
</Button>
</div>
}>
{hasFailed && (
<Alert bsStyle="danger">
<FormattedMessage id="app.loginForm.failed" defaultMessage="Login failed. Please check your credentials." />
</Alert>
)}
{hasFailed && error && <Alert bsStyle="danger">{error}</Alert>}

<Field
name="email"
Expand All @@ -68,6 +65,7 @@ LoginForm.propTypes = {
submitting: PropTypes.bool,
hasSucceeded: PropTypes.bool,
submitFailed: PropTypes.bool,
error: PropTypes.any,
};

const validate = ({ email, password }) => {
Expand Down
21 changes: 21 additions & 0 deletions src/locales/apiErrorMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';

const apiErrorCodes = {
'400-101': <FormattedMessage id="app.apiErrorCodes.400-101" defaultMessage="The credentials are not valid." />,
'403-001': <FormattedMessage id="app.apiErrorCodes.403-001" defaultMessage="The user account does not exist." />,
'403-002': <FormattedMessage id="app.apiErrorCodes.403-002" defaultMessage="The user account has been disabled." />,
};

export const getErrorMessage = error => {
const code = error && error.code;
if (code && apiErrorCodes[code]) {
return apiErrorCodes[code];
} else {
return (
(error && error.message) || (
<FormattedMessage id="app.apiErrorCodes.unknown" defaultMessage="Unknown API error." />
)
);
}
};
5 changes: 4 additions & 1 deletion src/locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
"app.addUserContainer.emptyQuery": "Žádné výsledky. Zadejte vyhledávací dotaz...",
"app.allowUserButton.confirmAllow": "Uživatel mohl být zablokován z dobrého důvodu. Opravdu si přejete povolit účet?",
"app.allowUserButton.confirmDisallow": "Pokud zakážete tento uživatelský účet, uživatel nebude moci provést žádnou operaci ani vidět žádná data. Opravdu si přejete účet zakázat?",
"app.apiErrorCodes.400-101": "Nesprávné přihlašovací údaje.",
"app.apiErrorCodes.403-001": "Uživatelský účet neexistuje.",
"app.apiErrorCodes.403-002": "Uživatelský účet byl zablokován.",
"app.apiErrorCodes.unknown": "Neznámá chyba API.",
"app.archive.archivedGroups": "Všechny skupiny včetně archivních",
"app.archive.description": "Seznam archivních skupin.",
"app.archive.title": "Archiv",
Expand Down Expand Up @@ -862,7 +866,6 @@
"app.login.resetPassword": "Obnovte si své heslo.",
"app.login.title": "Přihlásit se",
"app.loginForm.email": "E-mailová adresa:",
"app.loginForm.failed": "Přihlášení selhalo. Prosíme zkontrolujte své přihlašovací údaje.",
"app.loginForm.login": "Přihlásit se",
"app.loginForm.password": "Heslo:",
"app.loginForm.processing": "Ověřují se přihlašovací údaje...",
Expand Down
5 changes: 4 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
"app.addUserContainer.emptyQuery": "No results. Enter a search query...",
"app.allowUserButton.confirmAllow": "The user may have been disabled for a reason. Do you really wish to enable the account?",
"app.allowUserButton.confirmDisallow": "If you disable the account, the user will not be able to perform any operation nor access any data. Do you wish to disable it?",
"app.apiErrorCodes.400-101": "The credentials are not valid.",
"app.apiErrorCodes.403-001": "The user account does not exist.",
"app.apiErrorCodes.403-002": "The user account has been disabled.",
"app.apiErrorCodes.unknown": "Unknown API error.",
"app.archive.archivedGroups": "All Groups Including Archived",
"app.archive.description": "List of archived groups.",
"app.archive.title": "Archive",
Expand Down Expand Up @@ -862,7 +866,6 @@
"app.login.resetPassword": "Reset your password.",
"app.login.title": "Sign in",
"app.loginForm.email": "E-mail address:",
"app.loginForm.failed": "Login failed. Please check your credentials.",
"app.loginForm.login": "Sign in",
"app.loginForm.password": "Password:",
"app.loginForm.processing": "Signing in...",
Expand Down
5 changes: 4 additions & 1 deletion src/locales/whitelist_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
"app.addUserContainer.emptyQuery",
"app.allowUserButton.confirmAllow",
"app.allowUserButton.confirmDisallow",
"app.apiErrorCodes.400-101",
"app.apiErrorCodes.403-001",
"app.apiErrorCodes.403-002",
"app.apiErrorCodes.unknown",
"app.archive.archivedGroups",
"app.archive.description",
"app.archive.title",
Expand Down Expand Up @@ -862,7 +866,6 @@
"app.login.resetPassword",
"app.login.title",
"app.loginForm.email",
"app.loginForm.failed",
"app.loginForm.login",
"app.loginForm.password",
"app.loginForm.processing",
Expand Down
12 changes: 10 additions & 2 deletions src/pages/Login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { reset } from 'redux-form';
import { reset, SubmissionError } from 'redux-form';
import { Row, Col } from 'react-bootstrap';

import PageContent from '../../components/layout/PageContent';
Expand All @@ -15,6 +15,7 @@ import { login } from '../../redux/modules/auth';
import { isLoggedIn, selectedInstanceId } from '../../redux/selectors/auth';
import { loggedInUserSelector } from '../../redux/selectors/users';
import { getConfigVar } from '../../helpers/config';
import { getErrorMessage } from '../../locales/apiErrorMessages';

import withLinks from '../../helpers/withLinks';

Expand Down Expand Up @@ -70,7 +71,14 @@ class Login extends Component {
*/
loginAndRedirect = credentials => {
const { login } = this.props;
login(credentials).then(this.redirectAfterLogin);
return login(credentials)
.then(this.redirectAfterLogin)
.catch(e =>
// Translate fetch response error into form error message...
e.json().then(body => {
throw new SubmissionError({ _error: getErrorMessage(body && body.error) });
})
);
};

render() {
Expand Down
2 changes: 1 addition & 1 deletion src/redux/helpers/api/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ const detectUnreachableServer = (err, dispatch) => {
};

/**
* Process the standardized formatof the response.
* Process the standardized format of the response.
* @param {Promise} call
* @param {Function} dispatch
* @returns {Promise}
Expand Down

0 comments on commit ce99c37

Please sign in to comment.