2022-10-06 10:34:04 -05:00
|
|
|
import i18n, { BackendModule, ResourceKey } from 'i18next';
|
|
|
|
import React from 'react';
|
|
|
|
import { Trans as I18NextTrans, initReactI18next } from 'react-i18next';
|
2022-06-17 07:41:03 -05:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
import { DEFAULT_LOCALE, ENGLISH_US, FRENCH_FRANCE, SPANISH_SPAIN, PSEUDO_LOCALE, VALID_LOCALES } from './constants';
|
2021-12-15 10:00:37 -06:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
const messageLoaders: Record<string, () => Promise<ResourceKey>> = {
|
|
|
|
[ENGLISH_US]: () => import('../../../locales/en-US/grafana.json'),
|
|
|
|
[FRENCH_FRANCE]: () => import('../../../locales/fr-FR/grafana.json'),
|
|
|
|
[SPANISH_SPAIN]: () => import('../../../locales/es-ES/grafana.json'),
|
|
|
|
[PSEUDO_LOCALE]: () => import('../../../locales/pseudo-LOCALE/grafana.json'),
|
|
|
|
};
|
2022-07-22 09:50:00 -05:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
const loadTranslations: BackendModule = {
|
|
|
|
type: 'backend',
|
|
|
|
init() {},
|
|
|
|
async read(language, namespace, callback) {
|
|
|
|
console.log('using loadTranslations plugin', { language, namespace, callback });
|
|
|
|
const loader = messageLoaders[language];
|
|
|
|
if (!loader) {
|
|
|
|
return callback(new Error('No message loader available for ' + language), null);
|
|
|
|
}
|
2021-12-15 10:00:37 -06:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
// TODO: namespace??
|
|
|
|
const messages = await loader();
|
|
|
|
callback(null, messages);
|
|
|
|
},
|
|
|
|
};
|
2021-12-15 10:00:37 -06:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
export function initializeI18n(locale: string) {
|
|
|
|
const validLocale = VALID_LOCALES.includes(locale) ? locale : DEFAULT_LOCALE;
|
2022-08-26 04:27:14 -05:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
i18n
|
|
|
|
.use(loadTranslations)
|
|
|
|
.use(initReactI18next) // passes i18n down to react-i18next
|
|
|
|
.init({
|
|
|
|
lng: validLocale,
|
2022-07-22 09:50:00 -05:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
// We don't bundle any translations, we load them async
|
|
|
|
partialBundledLanguages: true,
|
|
|
|
resources: {},
|
2021-12-15 10:00:37 -06:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
// If translations are empty strings (no translation), fall back to the default value in source code
|
|
|
|
returnEmptyString: false,
|
2021-12-15 10:00:37 -06:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
export function changeLanguage(locale: string) {
|
|
|
|
const validLocale = VALID_LOCALES.includes(locale) ? locale : DEFAULT_LOCALE;
|
|
|
|
return i18n.changeLanguage(validLocale);
|
2021-12-15 10:00:37 -06:00
|
|
|
}
|
2022-06-17 07:41:03 -05:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
export const Trans: typeof I18NextTrans = (props) => {
|
|
|
|
return <I18NextTrans {...props} />;
|
|
|
|
};
|
2021-12-15 10:00:37 -06:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
export const t = (id: string, defaultMessage: string, values?: Record<string, unknown>) => {
|
|
|
|
return i18n.t(id, defaultMessage, values);
|
|
|
|
};
|
2022-07-25 07:44:11 -05:00
|
|
|
|
2022-10-06 10:34:04 -05:00
|
|
|
export const i18nDate = (value: number | Date | string, format: Intl.DateTimeFormatOptions = {}): string => {
|
|
|
|
if (typeof value === 'string') {
|
|
|
|
return i18nDate(new Date(value), format);
|
|
|
|
}
|
|
|
|
const locale = i18n.options.lng ?? DEFAULT_LOCALE;
|
|
|
|
|
|
|
|
const dateFormatter = new Intl.DateTimeFormat(locale, format);
|
|
|
|
return dateFormatter.format(value);
|
|
|
|
};
|