i18n: exposes languages in grafana/data (#102958)

* i18n: exposes languages in grafana/data

* Chore: updates after PR feedback
This commit is contained in:
Hugo Häggmark
2025-04-07 11:53:04 +02:00
committed by GitHub
parent c63cfc11e2
commit 3de09fe457
5 changed files with 65 additions and 179 deletions

View File

@ -10,4 +10,4 @@
*/
// This is a dummy export so typescript doesn't error importing an "empty module"
export const unstable = {};
export { DEFAULT_LANGUAGE, LANGUAGES } from './utils/i18n';

View File

@ -0,0 +1,54 @@
const ENGLISH_US = 'en-US';
const FRENCH_FRANCE = 'fr-FR';
const SPANISH_SPAIN = 'es-ES';
const GERMAN_GERMANY = 'de-DE';
const BRAZILIAN_PORTUGUESE = 'pt-BR';
const CHINESE_SIMPLIFIED = 'zh-Hans';
const ITALIAN_ITALY = 'it-IT';
const JAPANESE_JAPAN = 'ja-JP';
const INDONESIAN_INDONESIA = 'id-ID';
const KOREAN_KOREA = 'ko-KR';
const RUSSIAN_RUSSIA = 'ru-RU';
const CZECH_CZECHIA = 'cs-CZ';
const DUTCH_NETHERLANDS = 'nl-NL';
const HUNGARIAN_HUNGARY = 'hu-HU';
const PORTUGUESE_PORTUGAL = 'pt-PT';
const POLISH_POLAND = 'pl-PL';
const SWEDISH_SWEDEN = 'sv-SE';
const TURKISH_TURKEY = 'tr-TR';
const CHINESE_TRADITIONAL = 'zh-Hant';
/**
* Default language.
*/
export const DEFAULT_LANGUAGE = ENGLISH_US;
interface TranslationDefinition {
code: string;
name: string;
}
/**
* Supported languages for translation.
*/
export const LANGUAGES: TranslationDefinition[] = [
{ code: ENGLISH_US, name: 'English' },
{ code: FRENCH_FRANCE, name: 'Français' },
{ code: SPANISH_SPAIN, name: 'Español' },
{ code: GERMAN_GERMANY, name: 'Deutsch' },
{ code: CHINESE_SIMPLIFIED, name: '中文(简体)' },
{ code: BRAZILIAN_PORTUGUESE, name: 'Português Brasileiro' },
{ code: CHINESE_TRADITIONAL, name: '中文(繁體)' },
{ code: ITALIAN_ITALY, name: 'Italiano' },
{ code: JAPANESE_JAPAN, name: '日本語' },
{ code: INDONESIAN_INDONESIA, name: 'Bahasa Indonesia' },
{ code: KOREAN_KOREA, name: '한국어' },
{ code: RUSSIAN_RUSSIA, name: 'Русский' },
{ code: CZECH_CZECHIA, name: 'Čeština' },
{ code: DUTCH_NETHERLANDS, name: 'Nederlands' },
{ code: HUNGARIAN_HUNGARY, name: 'Magyar' },
{ code: PORTUGUESE_PORTUGAL, name: 'Português' },
{ code: POLISH_POLAND, name: 'Polski' },
{ code: SWEDISH_SWEDEN, name: 'Svenska' },
{ code: TURKISH_TURKEY, name: 'Türkçe' },
];

View File

@ -1,32 +1,12 @@
import { ResourceKey } from 'i18next';
import { uniq } from 'lodash';
export const ENGLISH_US = 'en-US';
export const FRENCH_FRANCE = 'fr-FR';
export const SPANISH_SPAIN = 'es-ES';
export const GERMAN_GERMANY = 'de-DE';
export const BRAZILIAN_PORTUGUESE = 'pt-BR';
export const CHINESE_SIMPLIFIED = 'zh-Hans';
export const ITALIAN_ITALY = 'it-IT';
export const JAPANESE_JAPAN = 'ja-JP';
export const INDONESIAN_INDONESIA = 'id-ID';
export const KOREAN_KOREA = 'ko-KR';
export const RUSSIAN_RUSSIA = 'ru-RU';
export const CZECH_CZECHIA = 'cs-CZ';
export const DUTCH_NETHERLANDS = 'nl-NL';
export const HUNGARIAN_HUNGARY = 'hu-HU';
export const PORTUGUESE_PORTUGAL = 'pt-PT';
export const POLISH_POLAND = 'pl-PL';
export const SWEDISH_SWEDEN = 'sv-SE';
export const TURKISH_TURKEY = 'tr-TR';
export const CHINESE_TRADITIONAL = 'zh-Hant';
export const PSEUDO_LOCALE = 'pseudo';
export const DEFAULT_LANGUAGE = ENGLISH_US;
import { LANGUAGES as SUPPORTED_LANGUAGES } from '@grafana/data/unstable';
export type LocaleFileLoader = () => Promise<ResourceKey>;
export const PSEUDO_LOCALE = 'pseudo';
export interface LanguageDefinition<Namespace extends string = string> {
/** IETF language tag for the language e.g. en-US */
code: string;
@ -38,159 +18,10 @@ export interface LanguageDefinition<Namespace extends string = string> {
loader: Record<Namespace, LocaleFileLoader>;
}
export const LANGUAGES: LanguageDefinition[] = [
{
code: ENGLISH_US,
name: 'English',
loader: {
grafana: () => import('../../../locales/en-US/grafana.json'),
},
},
{
code: FRENCH_FRANCE,
name: 'Français',
loader: {
grafana: () => import('../../../locales/fr-FR/grafana.json'),
},
},
{
code: SPANISH_SPAIN,
name: 'Español',
loader: {
grafana: () => import('../../../locales/es-ES/grafana.json'),
},
},
{
code: GERMAN_GERMANY,
name: 'Deutsch',
loader: {
grafana: () => import('../../../locales/de-DE/grafana.json'),
},
},
{
code: CHINESE_SIMPLIFIED,
name: '中文(简体)',
loader: {
grafana: () => import('../../../locales/zh-Hans/grafana.json'),
},
},
{
code: BRAZILIAN_PORTUGUESE,
name: 'Português Brasileiro',
loader: {
grafana: () => import('../../../locales/pt-BR/grafana.json'),
},
},
{
code: CHINESE_TRADITIONAL,
name: '中文(繁體)',
loader: {
grafana: () => import('../../../locales/zh-Hant/grafana.json'),
},
},
{
code: ITALIAN_ITALY,
name: 'Italiano',
loader: {
grafana: () => import('../../../locales/it-IT/grafana.json'),
},
},
{
code: JAPANESE_JAPAN,
name: '日本語',
loader: {
grafana: () => import('../../../locales/ja-JP/grafana.json'),
},
},
{
code: INDONESIAN_INDONESIA,
name: 'Bahasa Indonesia',
loader: {
grafana: () => import('../../../locales/id-ID/grafana.json'),
},
},
{
code: KOREAN_KOREA,
name: '한국어',
loader: {
grafana: () => import('../../../locales/ko-KR/grafana.json'),
},
},
{
code: RUSSIAN_RUSSIA,
name: 'Русский',
loader: {
grafana: () => import('../../../locales/ru-RU/grafana.json'),
},
},
{
code: CZECH_CZECHIA,
name: 'Čeština',
loader: {
grafana: () => import('../../../locales/cs-CZ/grafana.json'),
},
},
{
code: DUTCH_NETHERLANDS,
name: 'Nederlands',
loader: {
grafana: () => import('../../../locales/nl-NL/grafana.json'),
},
},
{
code: HUNGARIAN_HUNGARY,
name: 'Magyar',
loader: {
grafana: () => import('../../../locales/hu-HU/grafana.json'),
},
},
{
code: PORTUGUESE_PORTUGAL,
name: 'Português',
loader: {
grafana: () => import('../../../locales/pt-PT/grafana.json'),
},
},
{
code: POLISH_POLAND,
name: 'Polski',
loader: {
grafana: () => import('../../../locales/pl-PL/grafana.json'),
},
},
{
code: SWEDISH_SWEDEN,
name: 'Svenska',
loader: {
grafana: () => import('../../../locales/sv-SE/grafana.json'),
},
},
{
code: TURKISH_TURKEY,
name: 'Türkçe',
loader: {
grafana: () => import('../../../locales/tr-TR/grafana.json'),
},
},
] satisfies Array<LanguageDefinition<'grafana'>>;
export const LANGUAGES: LanguageDefinition[] = SUPPORTED_LANGUAGES.map((def) => ({
...def,
loader: { grafana: () => import(`../../../locales/${def.code}/grafana.json`) },
}));
if (process.env.NODE_ENV === 'development') {
LANGUAGES.push({

View File

@ -4,9 +4,10 @@ import { ReactElement, useMemo } from 'react';
import { Trans as I18NextTrans, initReactI18next } from 'react-i18next'; // eslint-disable-line no-restricted-imports
import { usePluginContext } from '@grafana/data';
import { DEFAULT_LANGUAGE } from '@grafana/data/unstable';
import { setTransComponent, setUseTranslateHook, TransProps } from '@grafana/runtime/unstable';
import { DEFAULT_LANGUAGE, NAMESPACES, VALID_LANGUAGES } from './constants';
import { NAMESPACES, VALID_LANGUAGES } from './constants';
import { loadTranslations } from './loadTranslations';
let tFunc: TFunction<string[], undefined> | undefined;

View File

@ -8,10 +8,10 @@ import {
PluginMeta,
throwIfAngular,
} from '@grafana/data';
import { DEFAULT_LANGUAGE } from '@grafana/data/unstable';
import { config } from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { getI18next } from 'app/core/internationalization';
import { DEFAULT_LANGUAGE } from 'app/core/internationalization/constants';
import { GenericDataSourcePlugin } from '../datasources/types';