refactor(translations): replace default namespaces with dynamic loading from filesystem
This commit is contained in:
@@ -32,7 +32,6 @@ import {
|
|||||||
} from '@kit/ui/table';
|
} from '@kit/ui/table';
|
||||||
import { cn } from '@kit/ui/utils';
|
import { cn } from '@kit/ui/utils';
|
||||||
|
|
||||||
import { defaultI18nNamespaces } from '../../../../web/lib/i18n/i18n.settings';
|
|
||||||
import {
|
import {
|
||||||
translateWithAIAction,
|
translateWithAIAction,
|
||||||
updateTranslationAction,
|
updateTranslationAction,
|
||||||
@@ -67,10 +66,6 @@ export function TranslationsComparison({
|
|||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [isTranslating, setIsTranslating] = useState(false);
|
const [isTranslating, setIsTranslating] = useState(false);
|
||||||
|
|
||||||
const [selectedNamespace, setSelectedNamespace] = useState(
|
|
||||||
defaultI18nNamespaces[0] as string,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create RxJS Subject for handling translation updates
|
// Create RxJS Subject for handling translation updates
|
||||||
const subject$ = useMemo(
|
const subject$ = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@@ -85,6 +80,7 @@ export function TranslationsComparison({
|
|||||||
|
|
||||||
const locales = Object.keys(translations);
|
const locales = Object.keys(translations);
|
||||||
const baseLocale = locales[0]!;
|
const baseLocale = locales[0]!;
|
||||||
|
const namespaces = Object.keys(translations[baseLocale] || {});
|
||||||
|
|
||||||
const [selectedLocales, setSelectedLocales] = useState<Set<string>>(
|
const [selectedLocales, setSelectedLocales] = useState<Set<string>>(
|
||||||
new Set(locales),
|
new Set(locales),
|
||||||
@@ -93,6 +89,10 @@ export function TranslationsComparison({
|
|||||||
// Flatten translations for the selected namespace
|
// Flatten translations for the selected namespace
|
||||||
const flattenedTranslations: FlattenedTranslations = {};
|
const flattenedTranslations: FlattenedTranslations = {};
|
||||||
|
|
||||||
|
const [selectedNamespace, setSelectedNamespace] = useState(
|
||||||
|
namespaces[0] as string,
|
||||||
|
);
|
||||||
|
|
||||||
for (const locale of locales) {
|
for (const locale of locales) {
|
||||||
const namespaceData = translations[locale]?.[selectedNamespace];
|
const namespaceData = translations[locale]?.[selectedNamespace];
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ export function TranslationsComparison({
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
|
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{defaultI18nNamespaces.map((namespace: string) => (
|
{namespaces.map((namespace: string) => (
|
||||||
<SelectItem key={namespace} value={namespace}>
|
<SelectItem key={namespace} value={namespace}>
|
||||||
{namespace}
|
{namespace}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
import { readFileSync, readdirSync } from 'node:fs';
|
import { readFileSync, readdirSync } from 'node:fs';
|
||||||
import { join } from 'node:path';
|
import { join } from 'node:path';
|
||||||
|
|
||||||
const defaultI18nNamespaces = [
|
|
||||||
'common',
|
|
||||||
'auth',
|
|
||||||
'account',
|
|
||||||
'teams',
|
|
||||||
'billing',
|
|
||||||
'marketing',
|
|
||||||
];
|
|
||||||
|
|
||||||
export type TranslationData = {
|
export type TranslationData = {
|
||||||
[key: string]: string | TranslationData;
|
[key: string]: string | TranslationData;
|
||||||
};
|
};
|
||||||
@@ -28,16 +19,24 @@ export async function loadTranslations() {
|
|||||||
for (const locale of locales) {
|
for (const locale of locales) {
|
||||||
translations[locale] = {};
|
translations[locale] = {};
|
||||||
|
|
||||||
for (const namespace of defaultI18nNamespaces) {
|
const namespaces = readdirSync(join(localesPath, locale)).filter(
|
||||||
|
(file) => file.endsWith('.json'),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const namespace of namespaces) {
|
||||||
|
const namespaceName = namespace.replace('.json', '');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filePath = join(localesPath, locale, `${namespace}.json`);
|
const filePath = join(localesPath, locale, namespace);
|
||||||
const content = readFileSync(filePath, 'utf8');
|
const content = readFileSync(filePath, 'utf8');
|
||||||
translations[locale][namespace] = JSON.parse(content);
|
|
||||||
|
translations[locale][namespaceName] = JSON.parse(content);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Warning: Translation file not found for locale "${locale}" and namespace "${namespace}"`,
|
`Warning: Translation file not found for locale "${locale}" and namespace "${namespaceName}"`,
|
||||||
);
|
);
|
||||||
translations[locale][namespace] = {};
|
|
||||||
|
translations[locale][namespaceName] = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user