Webatrice: improve language dropdown (#4589)
* useLocaleSort hook, translate language dropdown * add pt-BR translation * fix pt-BR flag Co-authored-by: Jeremy Letto <jeremy.letto@datasite.com>
This commit is contained in:
parent
21f7dd5eba
commit
533045445a
10 changed files with 314 additions and 278 deletions
1
webclient/public/locales/pt-BR/translation.json
Normal file
1
webclient/public/locales/pt-BR/translation.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -274,6 +274,12 @@
|
|||
"YE": "Yemen",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabwe"
|
||||
},
|
||||
"languages": {
|
||||
"en-US": "English - US",
|
||||
"fr": "French",
|
||||
"nl": "Dutch",
|
||||
"pt-BR": "Portuguese - Brazil"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,24 @@
|
|||
// eslint-disable-next-line
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Select, MenuItem } from '@material-ui/core';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useLocaleSort } from 'hooks';
|
||||
import { Images } from 'images/Images';
|
||||
import { CountryCode } from 'types';
|
||||
import { countryCodes } from 'types';
|
||||
|
||||
|
||||
import './CountryDropdown.css';
|
||||
|
||||
const CountryDropdown = ({ input: { onChange } }) => {
|
||||
const [state, setState] = useState('');
|
||||
const [sortedCountries, setSortedCountries] = useState([]);
|
||||
const { t, i18n } = useTranslation();
|
||||
const [value, setValue] = useState('');
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => onChange(state), [state]);
|
||||
useEffect(() => onChange(value), [value]);
|
||||
|
||||
useEffect(() => {
|
||||
const collator = new Intl.Collator(i18n.language);
|
||||
|
||||
setSortedCountries(Object.keys(CountryCode).sort((a, b) =>
|
||||
collator.compare(t(`Common.countries.${a}`), t(`Common.countries.${b}`))
|
||||
));
|
||||
}, [i18n.language]);
|
||||
const translateCountry = country => t(`Common.countries.${country}`);
|
||||
const sortedCountries = useLocaleSort(countryCodes, translateCountry);
|
||||
|
||||
return (
|
||||
<FormControl variant='outlined' className='CountryDropdown'>
|
||||
|
@ -33,9 +28,9 @@ const CountryDropdown = ({ input: { onChange } }) => {
|
|||
labelId='CountryDropdown-label'
|
||||
label='Country'
|
||||
margin='dense'
|
||||
value={state}
|
||||
value={value}
|
||||
fullWidth={true}
|
||||
onChange={e => setState(e.target.value as string)}
|
||||
onChange={e => setValue(e.target.value as string)}
|
||||
>
|
||||
<MenuItem value={''} key={-1}>
|
||||
<div className="CountryDropdown-item">
|
||||
|
@ -48,7 +43,7 @@ const CountryDropdown = ({ input: { onChange } }) => {
|
|||
<MenuItem value={country} key={index}>
|
||||
<div className="CountryDropdown-item">
|
||||
<img className="CountryDropdown-item__image" src={Images.Countries[country.toLowerCase()]} />
|
||||
<span className="CountryDropdown-item__label">{t(`Common.countries.${country}`)}</span>
|
||||
<span className="CountryDropdown-item__label">{translateCountry(country)}</span>
|
||||
</div>
|
||||
</MenuItem>
|
||||
))
|
||||
|
|
|
@ -6,12 +6,12 @@ import FormControl from '@material-ui/core/FormControl';
|
|||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
|
||||
import { Images } from 'images/Images';
|
||||
import { Language, LanguageCountry } from 'types';
|
||||
import { Language, LanguageCountry, LanguageNative } from 'types';
|
||||
|
||||
import './LanguageDropdown.css';
|
||||
|
||||
const LanguageDropdown = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const { t, i18n } = useTranslation();
|
||||
const [language, setLanguage] = useState(i18n.resolvedLanguage);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -30,14 +30,20 @@ const LanguageDropdown = () => {
|
|||
onChange={e => setLanguage(e.target.value as Language)}
|
||||
>
|
||||
{
|
||||
Object.keys(LanguageCountry).map((lang) => {
|
||||
Object.keys(Language).map((lang) => {
|
||||
const country = LanguageCountry[lang];
|
||||
|
||||
return (
|
||||
<MenuItem value={lang} key={lang}>
|
||||
<div className="LanguageDropdown-item">
|
||||
<img className="LanguageDropdown-item__image" src={Images.Countries[country]} />
|
||||
<span className="LanguageDropdown-item__label">{lang}</span>
|
||||
<span className="LanguageDropdown-item__label">
|
||||
{LanguageNative[lang]} {
|
||||
LanguageNative[lang] !== t(`Common.languages.${lang}`) && (
|
||||
<>({ t(`Common.languages.${lang}`) })</>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</MenuItem>
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export * from './useAutoConnect';
|
||||
export * from './useFireOnce';
|
||||
export * from './useDebounce';
|
||||
export * from './useLocaleSort';
|
||||
export * from './useReduxEffect';
|
||||
|
|
18
webclient/src/hooks/useLocaleSort.ts
Normal file
18
webclient/src/hooks/useLocaleSort.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function useLocaleSort(arr: string[], valueGetter: (value: string) => string) {
|
||||
const [state] = useState<string[]>(arr);
|
||||
const [sorted, setSorted] = useState<string[]>([]);
|
||||
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
const collator = new Intl.Collator(i18n.language);
|
||||
const sorter = (a, b) => collator.compare(valueGetter(a), valueGetter(b));
|
||||
|
||||
setSorted(state.sort(sorter));
|
||||
}, [state, i18n.language]);
|
||||
|
||||
return sorted;
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -17,9 +17,9 @@ i18n
|
|||
.use(initReactI18next)
|
||||
// for all options read: https://www.i18next.com/overview/configuration-options
|
||||
.init({
|
||||
fallbackLng: Language['en'],
|
||||
fallbackLng: Language['en-US'],
|
||||
resources: {
|
||||
[Language['en']]: { translation },
|
||||
[Language['en-US']]: { translation },
|
||||
},
|
||||
partialBundledLanguages: true,
|
||||
|
||||
|
|
|
@ -1,252 +1,252 @@
|
|||
export enum CountryCode {
|
||||
'AF' = 'AF',
|
||||
'AX' = 'AX',
|
||||
'AL' = 'AL',
|
||||
'DZ' = 'DZ',
|
||||
'AS' = 'AS',
|
||||
'AD' = 'AD',
|
||||
'AO' = 'AO',
|
||||
'AI' = 'AI',
|
||||
'AQ' = 'AQ',
|
||||
'AG' = 'AG',
|
||||
'AR' = 'AR',
|
||||
'AM' = 'AM',
|
||||
'AW' = 'AW',
|
||||
'AU' = 'AU',
|
||||
'AT' = 'AT',
|
||||
'AZ' = 'AZ',
|
||||
'BH' = 'BH',
|
||||
'BS' = 'BS',
|
||||
'BD' = 'BD',
|
||||
'BB' = 'BB',
|
||||
'BY' = 'BY',
|
||||
'BE' = 'BE',
|
||||
'BZ' = 'BZ',
|
||||
'BJ' = 'BJ',
|
||||
'BM' = 'BM',
|
||||
'BT' = 'BT',
|
||||
'BO' = 'BO',
|
||||
'BQ' = 'BQ',
|
||||
'BA' = 'BA',
|
||||
'BW' = 'BW',
|
||||
'BV' = 'BV',
|
||||
'BR' = 'BR',
|
||||
'IO' = 'IO',
|
||||
'BN' = 'BN',
|
||||
'BG' = 'BG',
|
||||
'BF' = 'BF',
|
||||
'BI' = 'BI',
|
||||
'KH' = 'KH',
|
||||
'CM' = 'CM',
|
||||
'CA' = 'CA',
|
||||
'CV' = 'CV',
|
||||
'KY' = 'KY',
|
||||
'CF' = 'CF',
|
||||
'TD' = 'TD',
|
||||
'CL' = 'CL',
|
||||
'CN' = 'CN',
|
||||
'CX' = 'CX',
|
||||
'CC' = 'CC',
|
||||
'CO' = 'CO',
|
||||
'KM' = 'KM',
|
||||
'CG' = 'CG',
|
||||
'CD' = 'CD',
|
||||
'CK' = 'CK',
|
||||
'CR' = 'CR',
|
||||
'CI' = 'CI',
|
||||
'HR' = 'HR',
|
||||
'CU' = 'CU',
|
||||
'CW' = 'CW',
|
||||
'CY' = 'CY',
|
||||
'CZ' = 'CZ',
|
||||
'DK' = 'DK',
|
||||
'DJ' = 'DJ',
|
||||
'DM' = 'DM',
|
||||
'DO' = 'DO',
|
||||
'EC' = 'EC',
|
||||
'EG' = 'EG',
|
||||
'SV' = 'SV',
|
||||
'GQ' = 'GQ',
|
||||
'ER' = 'ER',
|
||||
'EE' = 'EE',
|
||||
'ET' = 'ET',
|
||||
'EU' = 'EU',
|
||||
'FK' = 'FK',
|
||||
'FO' = 'FO',
|
||||
'FJ' = 'FJ',
|
||||
'FI' = 'FI',
|
||||
'FR' = 'FR',
|
||||
'GF' = 'GF',
|
||||
'PF' = 'PF',
|
||||
'TF' = 'TF',
|
||||
'GA' = 'GA',
|
||||
'GM' = 'GM',
|
||||
'GE' = 'GE',
|
||||
'DE' = 'DE',
|
||||
'GH' = 'GH',
|
||||
'GI' = 'GI',
|
||||
'GR' = 'GR',
|
||||
'GL' = 'GL',
|
||||
'GD' = 'GD',
|
||||
'GP' = 'GP',
|
||||
'GU' = 'GU',
|
||||
'GT' = 'GT',
|
||||
'GG' = 'GG',
|
||||
'GN' = 'GN',
|
||||
'GW' = 'GW',
|
||||
'GY' = 'GY',
|
||||
'HT' = 'HT',
|
||||
'HM' = 'HM',
|
||||
'VA' = 'VA',
|
||||
'HN' = 'HN',
|
||||
'HK' = 'HK',
|
||||
'HU' = 'HU',
|
||||
'IS' = 'IS',
|
||||
'IN' = 'IN',
|
||||
'ID' = 'ID',
|
||||
'IR' = 'IR',
|
||||
'IQ' = 'IQ',
|
||||
'IE' = 'IE',
|
||||
'IM' = 'IM',
|
||||
'IL' = 'IL',
|
||||
'IT' = 'IT',
|
||||
'JM' = 'JM',
|
||||
'JP' = 'JP',
|
||||
'JE' = 'JE',
|
||||
'JO' = 'JO',
|
||||
'KZ' = 'KZ',
|
||||
'KE' = 'KE',
|
||||
'KI' = 'KI',
|
||||
'KP' = 'KP',
|
||||
'KR' = 'KR',
|
||||
'KW' = 'KW',
|
||||
'KG' = 'KG',
|
||||
'LA' = 'LA',
|
||||
'LV' = 'LV',
|
||||
'LB' = 'LB',
|
||||
'LS' = 'LS',
|
||||
'LR' = 'LR',
|
||||
'LY' = 'LY',
|
||||
'LI' = 'LI',
|
||||
'LT' = 'LT',
|
||||
'LU' = 'LU',
|
||||
'MO' = 'MO',
|
||||
'MK' = 'MK',
|
||||
'MG' = 'MG',
|
||||
'MW' = 'MW',
|
||||
'MY' = 'MY',
|
||||
'MV' = 'MV',
|
||||
'ML' = 'ML',
|
||||
'MT' = 'MT',
|
||||
'MH' = 'MH',
|
||||
'MQ' = 'MQ',
|
||||
'MR' = 'MR',
|
||||
'MU' = 'MU',
|
||||
'YT' = 'YT',
|
||||
'MX' = 'MX',
|
||||
'FM' = 'FM',
|
||||
'MD' = 'MD',
|
||||
'MC' = 'MC',
|
||||
'MN' = 'MN',
|
||||
'ME' = 'ME',
|
||||
'MS' = 'MS',
|
||||
'MA' = 'MA',
|
||||
'MZ' = 'MZ',
|
||||
'MM' = 'MM',
|
||||
'NA' = 'NA',
|
||||
'NR' = 'NR',
|
||||
'NP' = 'NP',
|
||||
'NL' = 'NL',
|
||||
'NC' = 'NC',
|
||||
'NZ' = 'NZ',
|
||||
'NI' = 'NI',
|
||||
'NE' = 'NE',
|
||||
'NG' = 'NG',
|
||||
'NU' = 'NU',
|
||||
'NF' = 'NF',
|
||||
'MP' = 'MP',
|
||||
'NO' = 'NO',
|
||||
'OM' = 'OM',
|
||||
'PK' = 'PK',
|
||||
'PW' = 'PW',
|
||||
'PS' = 'PS',
|
||||
'PA' = 'PA',
|
||||
'PG' = 'PG',
|
||||
'PY' = 'PY',
|
||||
'PE' = 'PE',
|
||||
'PH' = 'PH',
|
||||
'PN' = 'PN',
|
||||
'PL' = 'PL',
|
||||
'PT' = 'PT',
|
||||
'PR' = 'PR',
|
||||
'QA' = 'QA',
|
||||
'RE' = 'RE',
|
||||
'RO' = 'RO',
|
||||
'RU' = 'RU',
|
||||
'RW' = 'RW',
|
||||
'BL' = 'BL',
|
||||
'SH' = 'SH',
|
||||
'KN' = 'KN',
|
||||
'LC' = 'LC',
|
||||
'MF' = 'MF',
|
||||
'PM' = 'PM',
|
||||
'VC' = 'VC',
|
||||
'WS' = 'WS',
|
||||
'SM' = 'SM',
|
||||
'ST' = 'ST',
|
||||
'SA' = 'SA',
|
||||
'SN' = 'SN',
|
||||
'RS' = 'RS',
|
||||
'SC' = 'SC',
|
||||
'SL' = 'SL',
|
||||
'SG' = 'SG',
|
||||
'SX' = 'SX',
|
||||
'SK' = 'SK',
|
||||
'SI' = 'SI',
|
||||
'SB' = 'SB',
|
||||
'SO' = 'SO',
|
||||
'ZA' = 'ZA',
|
||||
'GS' = 'GS',
|
||||
'SS' = 'SS',
|
||||
'ES' = 'ES',
|
||||
'LK' = 'LK',
|
||||
'SD' = 'SD',
|
||||
'SR' = 'SR',
|
||||
'SJ' = 'SJ',
|
||||
'SZ' = 'SZ',
|
||||
'SE' = 'SE',
|
||||
'CH' = 'CH',
|
||||
'SY' = 'SY',
|
||||
'TW' = 'TW',
|
||||
'TJ' = 'TJ',
|
||||
'TZ' = 'TZ',
|
||||
'TH' = 'TH',
|
||||
'TL' = 'TL',
|
||||
'TG' = 'TG',
|
||||
'TK' = 'TK',
|
||||
'TO' = 'TO',
|
||||
'TT' = 'TT',
|
||||
'TN' = 'TN',
|
||||
'TR' = 'TR',
|
||||
'TM' = 'TM',
|
||||
'TC' = 'TC',
|
||||
'TV' = 'TV',
|
||||
'UG' = 'UG',
|
||||
'UA' = 'UA',
|
||||
'AE' = 'AE',
|
||||
'GB' = 'GB',
|
||||
'US' = 'US',
|
||||
'UM' = 'UM',
|
||||
'UY' = 'UY',
|
||||
'UZ' = 'UZ',
|
||||
'VU' = 'VU',
|
||||
'VE' = 'VE',
|
||||
'VN' = 'VN',
|
||||
'VG' = 'VG',
|
||||
'VI' = 'VI',
|
||||
'WF' = 'WF',
|
||||
'EH' = 'EH',
|
||||
'YE' = 'YE',
|
||||
'ZM' = 'ZM',
|
||||
'ZW' = 'ZW',
|
||||
};
|
||||
export const countryCodes = [
|
||||
'AF',
|
||||
'AX',
|
||||
'AL',
|
||||
'DZ',
|
||||
'AS',
|
||||
'AD',
|
||||
'AO',
|
||||
'AI',
|
||||
'AQ',
|
||||
'AG',
|
||||
'AR',
|
||||
'AM',
|
||||
'AW',
|
||||
'AU',
|
||||
'AT',
|
||||
'AZ',
|
||||
'BH',
|
||||
'BS',
|
||||
'BD',
|
||||
'BB',
|
||||
'BY',
|
||||
'BE',
|
||||
'BZ',
|
||||
'BJ',
|
||||
'BM',
|
||||
'BT',
|
||||
'BO',
|
||||
'BQ',
|
||||
'BA',
|
||||
'BW',
|
||||
'BV',
|
||||
'BR',
|
||||
'IO',
|
||||
'BN',
|
||||
'BG',
|
||||
'BF',
|
||||
'BI',
|
||||
'KH',
|
||||
'CM',
|
||||
'CA',
|
||||
'CV',
|
||||
'KY',
|
||||
'CF',
|
||||
'TD',
|
||||
'CL',
|
||||
'CN',
|
||||
'CX',
|
||||
'CC',
|
||||
'CO',
|
||||
'KM',
|
||||
'CG',
|
||||
'CD',
|
||||
'CK',
|
||||
'CR',
|
||||
'CI',
|
||||
'HR',
|
||||
'CU',
|
||||
'CW',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DK',
|
||||
'DJ',
|
||||
'DM',
|
||||
'DO',
|
||||
'EC',
|
||||
'EG',
|
||||
'SV',
|
||||
'GQ',
|
||||
'ER',
|
||||
'EE',
|
||||
'ET',
|
||||
'EU',
|
||||
'FK',
|
||||
'FO',
|
||||
'FJ',
|
||||
'FI',
|
||||
'FR',
|
||||
'GF',
|
||||
'PF',
|
||||
'TF',
|
||||
'GA',
|
||||
'GM',
|
||||
'GE',
|
||||
'DE',
|
||||
'GH',
|
||||
'GI',
|
||||
'GR',
|
||||
'GL',
|
||||
'GD',
|
||||
'GP',
|
||||
'GU',
|
||||
'GT',
|
||||
'GG',
|
||||
'GN',
|
||||
'GW',
|
||||
'GY',
|
||||
'HT',
|
||||
'HM',
|
||||
'VA',
|
||||
'HN',
|
||||
'HK',
|
||||
'HU',
|
||||
'IS',
|
||||
'IN',
|
||||
'ID',
|
||||
'IR',
|
||||
'IQ',
|
||||
'IE',
|
||||
'IM',
|
||||
'IL',
|
||||
'IT',
|
||||
'JM',
|
||||
'JP',
|
||||
'JE',
|
||||
'JO',
|
||||
'KZ',
|
||||
'KE',
|
||||
'KI',
|
||||
'KP',
|
||||
'KR',
|
||||
'KW',
|
||||
'KG',
|
||||
'LA',
|
||||
'LV',
|
||||
'LB',
|
||||
'LS',
|
||||
'LR',
|
||||
'LY',
|
||||
'LI',
|
||||
'LT',
|
||||
'LU',
|
||||
'MO',
|
||||
'MK',
|
||||
'MG',
|
||||
'MW',
|
||||
'MY',
|
||||
'MV',
|
||||
'ML',
|
||||
'MT',
|
||||
'MH',
|
||||
'MQ',
|
||||
'MR',
|
||||
'MU',
|
||||
'YT',
|
||||
'MX',
|
||||
'FM',
|
||||
'MD',
|
||||
'MC',
|
||||
'MN',
|
||||
'ME',
|
||||
'MS',
|
||||
'MA',
|
||||
'MZ',
|
||||
'MM',
|
||||
'NA',
|
||||
'NR',
|
||||
'NP',
|
||||
'NL',
|
||||
'NC',
|
||||
'NZ',
|
||||
'NI',
|
||||
'NE',
|
||||
'NG',
|
||||
'NU',
|
||||
'NF',
|
||||
'MP',
|
||||
'NO',
|
||||
'OM',
|
||||
'PK',
|
||||
'PW',
|
||||
'PS',
|
||||
'PA',
|
||||
'PG',
|
||||
'PY',
|
||||
'PE',
|
||||
'PH',
|
||||
'PN',
|
||||
'PL',
|
||||
'PT',
|
||||
'PR',
|
||||
'QA',
|
||||
'RE',
|
||||
'RO',
|
||||
'RU',
|
||||
'RW',
|
||||
'BL',
|
||||
'SH',
|
||||
'KN',
|
||||
'LC',
|
||||
'MF',
|
||||
'PM',
|
||||
'VC',
|
||||
'WS',
|
||||
'SM',
|
||||
'ST',
|
||||
'SA',
|
||||
'SN',
|
||||
'RS',
|
||||
'SC',
|
||||
'SL',
|
||||
'SG',
|
||||
'SX',
|
||||
'SK',
|
||||
'SI',
|
||||
'SB',
|
||||
'SO',
|
||||
'ZA',
|
||||
'GS',
|
||||
'SS',
|
||||
'ES',
|
||||
'LK',
|
||||
'SD',
|
||||
'SR',
|
||||
'SJ',
|
||||
'SZ',
|
||||
'SE',
|
||||
'CH',
|
||||
'SY',
|
||||
'TW',
|
||||
'TJ',
|
||||
'TZ',
|
||||
'TH',
|
||||
'TL',
|
||||
'TG',
|
||||
'TK',
|
||||
'TO',
|
||||
'TT',
|
||||
'TN',
|
||||
'TR',
|
||||
'TM',
|
||||
'TC',
|
||||
'TV',
|
||||
'UG',
|
||||
'UA',
|
||||
'AE',
|
||||
'GB',
|
||||
'US',
|
||||
'UM',
|
||||
'UY',
|
||||
'UZ',
|
||||
'VU',
|
||||
'VE',
|
||||
'VN',
|
||||
'VG',
|
||||
'VI',
|
||||
'WF',
|
||||
'EH',
|
||||
'YE',
|
||||
'ZM',
|
||||
'ZW',
|
||||
];
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
export enum Language {
|
||||
'en' = 'en',
|
||||
'en-US' = 'en-US',
|
||||
'fr' = 'fr',
|
||||
'nl' = 'nl',
|
||||
'pt-BR' = 'pt-BR',
|
||||
}
|
||||
|
||||
export enum LanguageCountry {
|
||||
'en' = 'us',
|
||||
'en-US' = 'us',
|
||||
'fr' = 'fr',
|
||||
'nl' = 'nl',
|
||||
'pt-BR' = 'br'
|
||||
}
|
||||
|
||||
export enum LanguageNative {
|
||||
'en-US' = 'English - US',
|
||||
'fr' = 'Français',
|
||||
'nl' = 'Nederlands',
|
||||
'pt-BR' = 'Portugues do Brasil',
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue