Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I18n #17

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

I18n #17

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/components/MenuAppBar/MenuAppBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ import M from "materialize-css";
import { Link } from "react-router-dom";

import { AuthService, NotificationService } from "services";
import { getLang, setLang } from "i18n/i18n";

class MenuAppBar extends Component {
state = {
lang: getLang()
}

componentDidMount() {
const dropdown = document.querySelectorAll(".dropdown-trigger");
Expand All @@ -22,6 +26,14 @@ class MenuAppBar extends Component {
NotificationService.notifySuccess("Logout realizado com sucesso");
};

handleLangChange = lang => {
setLang(lang)
this.setState({
lang
});
window.location.reload();
}

render() {
const { userConfig } = this.props;

Expand All @@ -47,6 +59,22 @@ class MenuAppBar extends Component {
</ul>
</li>
</ul>
<ul className="right hide-on-med-and-down">
<li>
<Link to="#" className="dropdown-trigger" data-target="language-dropdown">
{this.state.lang}
<i className="material-icons right">arrow_drop_down</i>
</Link>
<ul id="language-dropdown" className="dropdown-content">
<li>
<Link onClick={() => this.handleLangChange('en')} to="#">EN</Link>
</li>
<li>
<Link onClick={() => this.handleLangChange('pt_BR')} to="#">PT-BR</Link>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</header>;
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/en.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default {
}
43 changes: 43 additions & 0 deletions src/i18n/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import ptBr from './pt_BR'
import en from './en'

import LocalStoreService from "services/LocalStoreService";

const langs = {
'pt_BR':ptBr,
'en': en
}

function _accessByString(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1');
s = s.replace(/^\./, '');
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}

function t(key) {
const lang = langs[getLang()]
const result = _accessByString(lang, key)
if (result) {
return result
}
return `{${key}}`;
}

export function getLang() {
return LocalStoreService.getI18n() || 'en'
}

export function setLang(lang) {
LocalStoreService.setI18n(lang)
}

export default t
45 changes: 45 additions & 0 deletions src/i18n/pt_BR.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export default {
unauthorized: "",
login: {
title: "Login",
submit: "Entrar",
usernameLabel: "Usuário",
passwordLabel: "Senha",
successMessage: "Login realizado com sucesso",
failureMessage: "Usuário e/ou senha inválido(s)"
},
boards: {
allOwners: "Todos",
new: "Novo Board",
filter: {
title: 'Filtro',
button: 'Filtrar'
},
nameLabel: "Nome",
ownerLabel: "Dono",
empytBoardList: 'Nenhum board encontrado',
remove: {
success: "Board removido com sucesso",
failure: "Falha ao remover o board"
},
clone: {
success: 'Board duplicado com sucesso',
failure: 'Falha ao duplicar o board'
},
dropdown: {
actions: {
edit: "Configurações",
dynamicFieldConfigs: "Campos Dinâmicos",
leadTimeConfigs: "Configurações de Lead Times",
holidays: "Feriados",
clone: "Duplicar",
remove: "Remover"
}
},
buttons: {
estimates: "Previsibilidade",
issues: "SandBox",
issuePeriods: "Períodos"
}
}
}
46 changes: 31 additions & 15 deletions src/pages/Board/ListBoard/CardBoard/CardBoard.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { AlertService, HttpService, NotificationService } from "services";
import { Button, Col } from "components/ui";
import { Link } from "react-router-dom";

import t from 'i18n/i18n'

import M from "materialize-css";

import "./CardBoard.scss";
Expand Down Expand Up @@ -36,15 +38,15 @@ class CardBoard extends Component {
const willDelete = await AlertService.confirmRemove();
if (willDelete) {
await HttpService.delete(`/boards/${board.id}`);
NotificationService.notifySuccess("Board removido com sucesso");
NotificationService.notifySuccess(t('boards.remove.success'));
this.props.refreshBoards();
}
} catch (e) {
NotificationService.notifyError("Falha ao remover o board");
NotificationService.notifyError(t('boards.remove.failure'));
}
};

copyBoard = async () => {
cloneBoard = async () => {
const { board } = this.props;

try {
Expand All @@ -54,10 +56,10 @@ class CardBoard extends Component {
}
});

NotificationService.notifySuccess("Board duplicado com sucesso");
NotificationService.notifySuccess(t('boards.clone.success'));
this.props.refreshBoards();
} catch (e) {
NotificationService.notifyError("Falha ao duplicar o board");
NotificationService.notifyError(t('boards.clone.failure'));
}
};

Expand All @@ -73,33 +75,47 @@ class CardBoard extends Component {
</Link>
<ul id={"board-dropdown-" + board.id} className="dropdown-content">
<li>
<Link to={`/boards/${board.id}/edit`}>Configurações</Link>
<Link to={`/boards/${board.id}/edit`}>
{t('boards.dropdown.actions.edit')}
</Link>
</li>
<li>
<Link to={`/boards/${board.id}/dynamic-field-configs`}>Campos Dinâmicos</Link>
<Link to={`/boards/${board.id}/dynamic-field-configs`}>
{t('boards.dropdown.actions.dynamicFieldConfigs')}
</Link>
</li>
<li>
<Link to={`/boards/${board.id}/lead-time-configs`}>Configurações de Lead Times</Link>
<Link to={`/boards/${board.id}/lead-time-configs`}>
{t('boards.dropdown.actions.leadTimeConfigs')}
</Link>
</li>
<li>
<Link to={`/boards/${board.id}/holidays`}>Feriados</Link>
<Link to={`/boards/${board.id}/holidays`}>
{t('boards.dropdown.actions.holidays')}
</Link>
</li>
<li>
<Button link onClick={this.copyBoard}>
Duplicar
<Button link onClick={this.cloneBoard}>
{t('boards.dropdown.actions.clone')}
</Button>
</li>
{userConfig.username === board.owner && <li>
<Button link onClick={this.deleteBoard}>
Remover
{t('boards.dropdown.actions.remove')}
</Button>
</li>}
</ul>
</div>
<div className="card-action right-align">
<Link to={`/boards/${board.id}/estimates`}>Previsibilidade</Link>
<Link to={`/boards/${board.id}/issues`}>SandBox</Link>
<Link to={`/boards/${board.id}/issue-periods`}>Períodos</Link>
<Link to={`/boards/${board.id}/estimates`}>
{t('boards.buttons.estimates')}
</Link>
<Link to={`/boards/${board.id}/issues`}>
{t('boards.buttons.issues')}
</Link>
<Link to={`/boards/${board.id}/issue-periods`}>
{t('boards.buttons.issuePeriods')}
</Link>
</div>
</div>
</Col>;
Expand Down
4 changes: 3 additions & 1 deletion src/pages/Board/ListBoard/EmptyBoardAlert/EmptyBoardAlert.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { Col } from "components/ui";

import "./EmptyBoardAlert.scss";

import t from 'i18n/i18n';

export default () =>
<Col s={12} className="center-align empty-board-alert__container">
<h5>Nenhum board encontrado</h5>
<h5>{t('boards.empytBoardList')}</h5>
</Col>;
14 changes: 8 additions & 6 deletions src/pages/Board/ListBoard/ListBoard.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Button, Col, InputField, Link, Pagination, Panel, Preloader, Row, Selec
import CardBoard from "./CardBoard/CardBoard";
import EmptyBoardAlert from "./EmptyBoardAlert/EmptyBoardAlert";

import t from "i18n/i18n";

class ListBoard extends Component {
state = {
boards: {
Expand Down Expand Up @@ -59,7 +61,7 @@ class ListBoard extends Component {
const { data } = await HttpService.get("/boards/owners");
const owners = [
{
label: "Todos",
label: t('boards.allOwners'),
value: "all"
},
...data.map(owner => ({
Expand Down Expand Up @@ -127,27 +129,27 @@ class ListBoard extends Component {
return <Row>
<Col s={12}>
<PageHeader title="Boards" action={
<Link to="/boards/new">Novo board</Link>
<Link to="/boards/new">{t('boards.new')}</Link>
}/>
</Col>

<Col s={12}>
<Panel collapsible defaultClose title="Filtro" actions={
<Panel collapsible defaultClose title={t('boards.filter.title')} actions={
<Button type="submit" onClick={this.handleFilter}>
Filtrar
{t('boards.filter.button')}
</Button>
}>
<Row>
<InputField s={12} l={6}
name="name"
onChange={e => this.changeFilterValue("name", e.target.value)}
value={filter.name}
label="Nome"/>
label={t('boards.nameLabel')}/>

<Col s={12} l={6}>
<Select withoutWrapper
options={owners}
label="Dono"
label={t('boards.ownerLabel')}
onChange={selected => this.changeFilterValue("owner", (selected || {}).value)}
value={filter.owner || userConfig.username}/>
</Col>
Expand Down
29 changes: 17 additions & 12 deletions src/pages/Login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { Button, Col, InputField, Panel, Row } from "components/ui";

import "./Login.scss";

import t from "i18n/i18n";

class Login extends Component {
state = {
username: "",
Expand All @@ -35,16 +37,19 @@ class Login extends Component {

this.redirect();

NotificationService.notifySuccess("Login realizado com sucesso");
NotificationService.notifySuccess(t('login.successMessage'));
} catch (e) {
const response = e.response;
const reason = response.headers['x-auth-fail-reason'];

if (reason) {
NotificationService.notifyError(reason);
} else {
NotificationService.notifyError("Usuário e/ou senha inválido(s)");
}
if (response) {
const reason = response.headers['x-auth-fail-reason'];

if (reason) {
NotificationService.notifyError(reason);
return;
}
}

NotificationService.notifyError(t('login.failureMessage'));
} finally {
this.setState({
isLoading: false
Expand All @@ -71,28 +76,28 @@ class Login extends Component {
<Col s={12} l={6} offsetL={3}>
<Panel loading={isLoading}>
<div className="login-panel__header-container">
<h4 className="login-panel__header center-align">Login</h4>
<h4 className="login-panel__header center-align">{t('login.title')}</h4>
</div>

<Row>
<InputField s={12}
name="username"
onChange={this.handleChange}
label="Usuário"
label={t('login.usernameLabel')}
value={username}
/>

<InputField s={12}
type="password"
name="password"
onChange={this.handleChange}
label="Senha"
label={t('login.passwordLabel')}
value={password}
/>

<Col s={12}>
<Button type="submit" block onClick={this.handleSubmit}>
Entrar
{t('login.submit')}
</Button>
</Col>
</Row>
Expand Down
4 changes: 3 additions & 1 deletion src/services/HttpService.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import store from "stores/store";
import { authActions } from "stores/ducks/auth";
import LocalStoreService from "services/LocalStoreService";

import {getLang} from 'i18n/i18n'

const { REACT_APP_API_URL: API_URL } = process.env;

const instance = axios.create({
baseURL: API_URL,
headers: {
"Accept-Language": "pt-BR"
"Accept-Language": getLang()
},
paramsSerializer: params => querystring.stringify(params)
});
Expand Down
Loading