WIP: locale

This commit is contained in:
Paulo Gustavo Veiga 2021-02-12 18:00:54 -08:00
parent db6da3d75e
commit d57cec6f80
6 changed files with 76 additions and 24 deletions

View File

@ -89,6 +89,9 @@
"export.document": {
"defaultMessage": "Mindmap Tools: Export your mindmap in thirdparty mindmap tool formats"
},
"export.document-label": {
"defaultMessage": "Document: Export your mindmap in a self-contained document ready to share"
},
"export.image": {
"defaultMessage": "Image: Get a graphic representation of your map including all colors and shapes."
},
@ -96,7 +99,7 @@
"defaultMessage": "Export"
},
"export.warning": {
"defaultMessage": "Exporting to Image (SVG,PNG,JPEG )is available only in the editor toolbar."
"defaultMessage": "Exporting to Image (SVG,PNG,JPEG,PDF) is only available in the editor toolbar."
},
"footer.aboutus": {
"defaultMessage": "About Us"
@ -197,6 +200,12 @@
"info.title": {
"defaultMessage": "Info"
},
"language.change": {
"defaultMessage": "Change Language"
},
"languange.help": {
"defaultMessage": "Help to Translate"
},
"login.desc": {
"defaultMessage": "Log into your account"
},

View File

@ -59,9 +59,11 @@ export type AccountInfo = {
firstName: string;
lastName: string;
email: string;
language: string;
language: LocaleCode;
}
export type LocaleCode = 'en' | 'es' | 'fr' | 'de';
interface Client {
importMap(model: ImportMapInfo): Promise<number>
createMap(map: BasicMapInfo): Promise<number>;
@ -70,6 +72,7 @@ interface Client {
renameMap(id: number, basicInfo: BasicMapInfo): Promise<void>;
fetchAllMaps(): Promise<MapInfo[]>;
duplicateMap(id: number, basicInfo: BasicMapInfo): Promise<number>;
updateAccountLanguage(locale: LocaleCode): Promise<void>;
updateStarred(id: number, starred: boolean): Promise<void>;
updateMapToPublic(id: number, starred: boolean): Promise<void>;

View File

@ -1,5 +1,5 @@
import { Language } from '@material-ui/icons';
import Client, { AccountInfo, BasicMapInfo, ChangeHistory, ImportMapInfo, Label, MapInfo, NewUser} from '..';
import Client, { AccountInfo, BasicMapInfo, ChangeHistory, ImportMapInfo, Label, LocaleCode, MapInfo, NewUser } from '..';
class MockClient implements Client {
private maps: MapInfo[] = [];
private labels: Label[] = [];
@ -8,7 +8,7 @@ class MockClient implements Client {
// Remove, just for develop ....
function createMapInfo(
id: number,
id: number,
starred: boolean,
title: string,
labels: number[],
@ -34,16 +34,23 @@ class MockClient implements Client {
];
}
updateAccountLanguage(locale: LocaleCode): Promise<void> {
localStorage.setItem('locale', locale);
return Promise.resolve();
}
importMap(model: ImportMapInfo): Promise<number> {
return Promise.resolve(10);
}
fetchAccountInfo(): Promise<AccountInfo> {
const locale: LocaleCode | null = localStorage.getItem('locale') as LocaleCode;
return Promise.resolve({
firstName: 'Costme',
lastName: 'Fulanito',
email: 'test@example.com',
language: 'en'
language: locale ? locale : 'en'
});
}
deleteMaps(ids: number[]): Promise<void> {

View File

@ -1,5 +1,5 @@
import axios from 'axios';
import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label, ChangeHistory, AccountInfo, ImportMapInfo } from '..';
import Client, { ErrorInfo, MapInfo, BasicMapInfo, NewUser, Label, ChangeHistory, AccountInfo, ImportMapInfo, LocaleCode } from '..';
export default class RestClient implements Client {
private baseUrl: string;
@ -9,6 +9,11 @@ export default class RestClient implements Client {
this.baseUrl = baseUrl;
this.sessionExpired = sessionExpired;
}
updateAccountLanguage(locale: LocaleCode): Promise<void> {
throw "Method not implemented";
}
importMap(model: ImportMapInfo): Promise<number> {
const handler = (success: (mapId: number) => void, reject: (error: ErrorInfo) => void) => {
axios.post(this.baseUrl + `/c/restful/maps?title=${model.title}&description=${model.description ? model.description : ''}`,
@ -22,7 +27,8 @@ export default class RestClient implements Client {
reject(errorInfo);
});
}
return new Promise(handler); }
return new Promise(handler);
}
fetchAccountInfo(): Promise<AccountInfo> {
const handler = (success: (account: AccountInfo) => void, reject: (error: ErrorInfo) => void) => {
@ -33,11 +39,12 @@ export default class RestClient implements Client {
}
).then(response => {
const account = response.data;
const locale: LocaleCode | null = account.locale;
success({
lastName: account.lastName ? account.lastName : '',
firstName: account.fistName ? account.fistName : '',
email: account.email,
language: "en"
language: locale ? locale : 'en'
});
}).catch(error => {
const errorInfo = this.parseResponseOnError(error.response);

View File

@ -115,7 +115,7 @@ const ExportDialog = (props: ExportDialogProps) => {
className={classes.label}
value="document"
control={<Radio color="primary" />}
label={intl.formatMessage({ id: "export.document", defaultMessage: "Document: Export your mindmap in a self-contained document ready to share" })}
label={intl.formatMessage({ id: "export.document-label", defaultMessage: "Document: Export your mindmap in a self-contained document ready to share" })}
color="secondary" />
{exportGroup == 'document' &&
(<Select onChange={handleOnExportFormatChange}

View File

@ -1,18 +1,31 @@
import { Button, Divider, Link, ListItemIcon, Menu, MenuItem, Tooltip } from '@material-ui/core';
import { ExitToAppOutlined, SettingsApplicationsOutlined, TranslateTwoTone } from '@material-ui/icons';
import { Button, Divider, Menu, MenuItem, Tooltip } from '@material-ui/core';
import { TranslateTwoTone } from '@material-ui/icons';
import React from "react";
import { FormattedMessage } from "react-intl";
import { useQuery } from "react-query";
import Client, { ErrorInfo, AccountInfo } from "../../../client";
import { useMutation, useQuery, useQueryClient } from "react-query";
import Client, { ErrorInfo, AccountInfo, LocaleCode } from "../../../client";
import { useSelector } from 'react-redux';
import { activeInstance } from '../../../redux/clientSlice';
import { FormattedMessage, useIntl } from 'react-intl';
const localeToStr = new Map<LocaleCode, string>([["en", "English"], ["es", "Español"], ["fr", "Français"], ["de", "Deutsch"]]);
const LanguageMenu = () => {
const queryClient = useQueryClient();
const client: Client = useSelector(activeInstance);
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const intl = useIntl();
const mutation = useMutation((locale: LocaleCode) => client.updateAccountLanguage(locale),
{
onSuccess: () => {
queryClient.invalidateQueries('account')
handleClose();
}
}
);
const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
@ -22,13 +35,18 @@ const LanguageMenu = () => {
setAnchorEl(null);
};
const handleOnClick = (event: React.MouseEvent<HTMLElement>) => {
const localeCode = event.target['id'];
mutation.mutate(localeCode);
}
const { data } = useQuery<unknown, ErrorInfo, AccountInfo>('account', () => {
return client.fetchAccountInfo();
});
return (
<span>
<Tooltip title="Change Language">
<Tooltip title={intl.formatMessage({ id: 'language.change', defaultMessage: 'Change Language' })}>
<Button
size="small"
variant="outlined"
@ -37,7 +55,7 @@ const LanguageMenu = () => {
onClick={handleMenu}
startIcon={<TranslateTwoTone />}
>
{data?.language == "en" ? "English" : "Español"}
{localeToStr.get(data?.language ? data?.language : 'en')}
</Button>
</Tooltip>
<Menu id="appbar-language"
@ -55,17 +73,25 @@ const LanguageMenu = () => {
horizontal: 'right',
}}
>
<MenuItem onClick={handleClose}>
English
<MenuItem onClick={handleOnClick} id="en">
{localeToStr.get('en')}
</MenuItem>
<MenuItem onClick={handleClose}>
Español
<MenuItem onClick={handleOnClick} id="es">
{localeToStr.get('es')}
</MenuItem>
<MenuItem onClick={handleOnClick} id="fr">
{localeToStr.get('fr')}
</MenuItem>
<MenuItem onClick={handleOnClick} id="de">
{localeToStr.get('de')}
</MenuItem>
<Divider />
<MenuItem onClick={handleClose}>
Help to Translate
<MenuItem onClick={handleOnClick}>
<FormattedMessage id="language.help" defaultMessage=" Help to Translate" />
</MenuItem>
</Menu>
</span>);