mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
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:
parent
7dde848d0c
commit
5e784d1188
6 changed files with 229 additions and 81 deletions
|
@ -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%',
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 {}>({
|
||||
|
|
|
@ -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,
|
||||
|
|
170
packages/plugins/ui-theme/src/i18n/crowdin/en-US.json
Normal file
170
packages/plugins/ui-theme/src/i18n/crowdin/en-US.json
Normal 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"
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue