refactor: one single file for i18n conf ui (#2440)

* refactor: one single file for i18n conf ui

* add test for crowdin

* cleanup

* space
This commit is contained in:
Juan Picado 2021-09-17 07:17:34 +02:00 committed by GitHub
parent 7dde848d0c
commit 5e784d1188
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 229 additions and 81 deletions

View File

@ -5,6 +5,10 @@ preserve_hierarchy: true
files:
[
{
source: 'packages/plugins/ui-theme/src/i18n/crowdin/**/*',
translation: '/ui/i18n/%locale%/**/%original_file_name%',
},
{
source: '/website/i18n/en/**/*',
translation: '/website/i18n/%locale%/**/%original_file_name%',

View File

@ -2,71 +2,24 @@
import styled from '@emotion/styled';
import { withStyles } from '@material-ui/core/styles';
import LanguageIcon from '@material-ui/icons/Language';
import Flags from 'country-flag-icons/react/3x2';
import i18next, { TFunctionKeys } from 'i18next';
import i18next from 'i18next';
import React, { useCallback, useContext, useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Language } from 'src/i18n/enabledLanguages';
import { AutoComplete } from 'verdaccio-ui/components/AutoComplete/AutoCompleteV2';
import MenuItem from 'verdaccio-ui/components/MenuItem';
import { Theme } from 'verdaccio-ui/design-tokens/theme';
import ThemeContext from 'verdaccio-ui/design-tokens/ThemeContext';
const lngDetails: Record<Language, { translation: TFunctionKeys; icon: React.ReactElement }> = {
'fr-FR': {
translation: 'lng.french',
icon: <Flags.FR />,
},
'pt-BR': {
translation: 'lng.portuguese',
icon: <Flags.BR />,
},
'de-DE': {
translation: 'lng.german',
icon: <Flags.DE />,
},
'es-ES': {
translation: 'lng.spanish',
icon: <Flags.ES />,
},
'zh-CN': {
translation: 'lng.chinese',
icon: <Flags.CN />,
},
'ru-RU': {
translation: 'lng.russian',
icon: <Flags.RU />,
},
'tr-TR': {
translation: 'lng.turkish',
icon: <Flags.TR />,
},
'uk-UA': {
translation: 'lng.ukraine',
icon: <Flags.UA />,
},
'km-KH': {
translation: 'lng.khmer',
icon: <Flags.KH />,
},
'ja-JP': {
translation: 'lng.japanese',
icon: <Flags.JP />,
},
'en-US': {
translation: 'lng.english',
icon: <Flags.US />,
},
'cs-CZ': {
translation: 'lng.czech',
icon: <Flags.CZ />,
},
'zh-TW': {
translation: 'lng.chineseTraditional',
icon: <Flags.TW />,
},
};
import { Language, listLanguages } from '../../i18n/enabledLanguages';
const listConverted = listLanguages.reduce((prev, item) => {
prev[item.lng] = {
translation: item.menuKey,
icon: item.icon,
};
return prev;
}, {});
const LanguageSwitch = () => {
const themeContext = useContext(ThemeContext);
@ -90,10 +43,10 @@ const LanguageSwitch = () => {
const getCurrentLngDetails = useCallback(
(language: Language) => {
const { icon, translation } = lngDetails[language] || lngDetails['en-US'];
const lng = listConverted[language] || listConverted['en-US'];
return {
icon,
translation: t(translation),
icon: <lng.icon />,
translation: t(lng.translation),
};
},
[t]

View File

@ -37,7 +37,7 @@ interface Props<Option extends {}> extends Pick<TextFieldProps, 'variant'> {
inputStartAdornment?: React.ReactNode;
hasClearIcon?: boolean;
className?: string;
onClick?: (option: Option) => void;
onClick?: (option: any) => void;
}
const AutoComplete = <Option extends {}>({

View File

@ -1,11 +1,16 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import { DEFAULT_LANGUAGE, enabledLanguages } from './enabledLanguages';
import {
DEFAULT_LANGUAGE,
LanguageConfiguration,
listLanguages,
listLanguagesAsString,
} from './enabledLanguages';
const languages = enabledLanguages.reduce((acc, lng) => {
acc[lng] = {
translation: require(`./translations/${lng}.json`),
const languages = listLanguages.reduce((acc, item: LanguageConfiguration) => {
acc[item.lng] = {
translation: require(`./translations/${item.lng}.json`),
};
return acc;
}, {});
@ -19,7 +24,7 @@ i18n
// in case window.VEDACCIO_LANGUAGE is undefined,it will fall back to 'en-US'
lng: window?.__VERDACCIO_BASENAME_UI_OPTIONS?.language || DEFAULT_LANGUAGE,
fallbackLng: DEFAULT_LANGUAGE,
whitelist: [...enabledLanguages],
whitelist: [...listLanguagesAsString],
load: 'currentOnly',
resources: languages,
debug: false,

View File

@ -0,0 +1,170 @@
{
"copy-to-clipboard": "Copy to clipboard",
"author-anonymous": "Anonymous",
"author-unknown": "Unknown",
"action-bar-action": {
"visit-home-page": "Visit homepage",
"open-an-issue": "Open an issue",
"download-tarball": "Download tarball"
},
"dialog": {
"registry-info": {
"title": "Registry Info"
}
},
"header": {
"documentation": "Documentation",
"registry-info": "Registry Information",
"registry-info-link": "Learn more",
"registry-no-conf": "No configurations available",
"greetings": "Hi "
},
"search": {
"packages": "Search Packages"
},
"autoComplete": {
"loading": "Loading...",
"no-results-found": "No results found",
"clear": "Clear",
"expand": "Expand",
"collapse": "Collapse"
},
"tab": {
"uplinks": "Uplinks",
"versions": "Versions",
"dependencies": "Dependencies",
"readme": "Readme"
},
"uplinks": {
"title": "Uplinks",
"no-items": "{{name}} has no uplinks."
},
"versions": {
"current-tags": "Current Tags",
"version-history": "Version history",
"not-available": "Not available"
},
"package": {
"published-on": "Published on {{time}} •",
"version": "v{{version}}",
"visit-home-page": "Visit homepage",
"homepage": "Homepage",
"open-an-issue": "Open an issue",
"bugs": "Bugs",
"download": "Download {{what}}",
"the-tar-file": "the tar file",
"tarball": "Tarball"
},
"dependencies": {
"has-no-dependencies": "{{package}} has no dependencies.",
"dependency-block": "{{package}}@{{version}}"
},
"form": {
"username": "Username",
"password": "Password"
},
"form-placeholder": {
"username": "Your username",
"password": "Your strong password"
},
"form-validation": {
"required-field": "This field is required",
"required-min-length": "This field required the min length of {{length}}",
"unable-to-sign-in": "Unable to sign in",
"username-or-password-cant-be-empty": "Username or password can't be empty!"
},
"help": {
"title": "No Package Published Yet.",
"sub-title": "To publish your first package just:",
"first-step": "1. Login",
"first-step-command-line": "npm adduser --registry {{registryUrl}}",
"second-step": "2. Publish",
"second-step-command-line": "npm publish --registry {{registryUrl}}",
"third-step": "3. Refresh this page."
},
"sidebar": {
"detail": {
"latest-version": "Latest v{{version}}",
"version": "v{{version}}"
},
"installation": {
"title": "Installation",
"install-using-yarn": "Install using yarn",
"install-using-yarn-command": "yarn add {{packageName}}",
"install-using-npm": "Install using npm",
"install-using-npm-command": "npm install {{packageName}}",
"install-using-pnpm": "Install using pnpm",
"install-using-pnpm-command": "pnpm install {{packageName}}"
},
"repository": {
"title": "Repository"
},
"author": {
"title": "Author"
},
"distribution": {
"title": "Latest Distribution",
"license": "License",
"size": "Size",
"file-count": "file count"
},
"maintainers": {
"title": "Maintainers"
},
"contributors": {
"title": "Contributors"
},
"engines": {
"npm-version": "NPM Version",
"node-js": "NODE JS"
}
},
"footer": {
"powered-by": "Powered by",
"made-with-love-on": "Made with <0>♥</0> on"
},
"button": {
"close": "Close",
"cancel": "Cancel",
"login": "Login",
"logout": "Logout",
"go-to-the-home-page": "Go to the home page",
"learn-more": "Learn More",
"fund-this-package": "<0>Fund</0> this package"
},
"error": {
"unspecific": "Something went wrong.",
"404": {
"page-not-found": "404 - Page not found",
"sorry-we-could-not-find-it": "Sorry, we couldn't find it..."
},
"app-context-not-correct-used": "The app context was not used correctly",
"theme-context-not-correct-used": "The theme context was not used correctly",
"package-meta-is-required-at-detail-context": "packageMeta is required at DetailContext"
},
"lng": {
"english": "English",
"czech": "Czech",
"japanese": "Japanese",
"portuguese": "Portuguese",
"spanish": "Spanish",
"german": "German",
"chinese": "Chinese",
"chineseTraditional": "Chinese (Traditional)",
"french": "French",
"russian": "Russian",
"turkish": "Turkish",
"ukraine": "Ukraine",
"khmer": "Khmer"
},
"flag": {
"austria": "Austria",
"brazil": "Brazil",
"spain": "Spain",
"nicaragua": "Nicaragua",
"india": "India",
"china": "China",
"germany": "Germany",
"taiwan": "Taiwan"
}
}

View File

@ -1,19 +1,35 @@
import Flags from 'country-flag-icons/react/3x2';
import React from 'react';
export const DEFAULT_LANGUAGE = 'en-US';
export const enabledLanguages = [
DEFAULT_LANGUAGE,
'cs-CZ',
'pt-BR',
'es-ES',
'de-DE',
'fr-FR',
'zh-CN',
'ja-JP',
'ru-RU',
'tr-TR',
'uk-UA',
'km-KH',
'zh-TW',
export type LanguageConfiguration = {
lng: string;
menuKey: string;
icon: React.ReactElement;
};
export const listLanguages: LanguageConfiguration[] = [
{ lng: DEFAULT_LANGUAGE, icon: Flags.US, menuKey: 'lng.english' },
{ lng: 'cs-CZ', icon: Flags.CZ, menuKey: 'lng.czech' },
{ lng: 'pt-BR', icon: Flags.BR, menuKey: 'lng.portuguese' },
{ lng: 'es-ES', icon: Flags.ES, menuKey: 'lng.spanish' },
{ lng: 'de-DE', icon: Flags.DE, menuKey: 'lng.german' },
{ lng: 'fr-FR', icon: Flags.FR, menuKey: 'lng.french' },
{ lng: 'zh-CN', icon: Flags.CN, menuKey: 'lng.chinese' },
{ lng: 'ja-JP', icon: Flags.JP, menuKey: 'lng.japanese' },
{ lng: 'ru-RU', icon: Flags.RU, menuKey: 'lng.russian' },
{ lng: 'tr-TR', icon: Flags.TR, menuKey: 'lng.turkish' },
{ lng: 'uk-UA', icon: Flags.UA, menuKey: 'lng.ukraine' },
{ lng: 'km-KH', icon: Flags.KH, menuKey: 'lng.khme' },
{ lng: 'zh-TW', icon: Flags.TW, menuKey: 'lng.chineseTraditional' },
];
export type Language = keyof typeof enabledLanguages;
const languages = listLanguages.reduce((acc, item: LanguageConfiguration) => {
acc.push(item.lng);
return acc;
}, [] as string[]);
export const listLanguagesAsString = languages;
export type Language = keyof typeof listLanguagesAsString;