yangdx
commited on
Commit
·
9d25a00
1
Parent(s):
d1d2286
Add French and Arabic language support
Browse files
lightrag_webui/src/components/AppSettings.tsx
CHANGED
@@ -22,7 +22,7 @@ export default function AppSettings({ className }: AppSettingsProps) {
|
|
22 |
const setTheme = useSettingsStore.use.setTheme()
|
23 |
|
24 |
const handleLanguageChange = useCallback((value: string) => {
|
25 |
-
setLanguage(value as 'en' | 'zh')
|
26 |
}, [setLanguage])
|
27 |
|
28 |
const handleThemeChange = useCallback((value: string) => {
|
@@ -47,6 +47,8 @@ export default function AppSettings({ className }: AppSettingsProps) {
|
|
47 |
<SelectContent>
|
48 |
<SelectItem value="en">English</SelectItem>
|
49 |
<SelectItem value="zh">中文</SelectItem>
|
|
|
|
|
50 |
</SelectContent>
|
51 |
</Select>
|
52 |
</div>
|
|
|
22 |
const setTheme = useSettingsStore.use.setTheme()
|
23 |
|
24 |
const handleLanguageChange = useCallback((value: string) => {
|
25 |
+
setLanguage(value as 'en' | 'zh' | 'fr' | 'ar')
|
26 |
}, [setLanguage])
|
27 |
|
28 |
const handleThemeChange = useCallback((value: string) => {
|
|
|
47 |
<SelectContent>
|
48 |
<SelectItem value="en">English</SelectItem>
|
49 |
<SelectItem value="zh">中文</SelectItem>
|
50 |
+
<SelectItem value="fr">Français</SelectItem>
|
51 |
+
<SelectItem value="ar">العربية</SelectItem>
|
52 |
</SelectContent>
|
53 |
</Select>
|
54 |
</div>
|
lightrag_webui/src/i18n.js
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
import i18n from "i18next";
|
2 |
-
import { initReactI18next } from "react-i18next";
|
3 |
-
import { useSettingsStore } from "./stores/settings";
|
4 |
-
|
5 |
-
import en from "./locales/en.json";
|
6 |
-
import zh from "./locales/zh.json";
|
7 |
-
|
8 |
-
const getStoredLanguage = () => {
|
9 |
-
try {
|
10 |
-
const settingsString = localStorage.getItem('settings-storage');
|
11 |
-
if (settingsString) {
|
12 |
-
const settings = JSON.parse(settingsString);
|
13 |
-
return settings.state?.language || 'en';
|
14 |
-
}
|
15 |
-
} catch (e) {
|
16 |
-
console.error('Failed to get stored language:', e);
|
17 |
-
}
|
18 |
-
return 'en';
|
19 |
-
};
|
20 |
-
|
21 |
-
i18n
|
22 |
-
.use(initReactI18next)
|
23 |
-
.init({
|
24 |
-
resources: {
|
25 |
-
en: { translation: en },
|
26 |
-
zh: { translation: zh }
|
27 |
-
},
|
28 |
-
lng: getStoredLanguage(), // 使用存储的语言设置
|
29 |
-
fallbackLng: "en",
|
30 |
-
interpolation: {
|
31 |
-
escapeValue: false
|
32 |
-
}
|
33 |
-
});
|
34 |
-
|
35 |
-
export default i18n;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lightrag_webui/src/i18n.ts
CHANGED
@@ -4,34 +4,44 @@ import { useSettingsStore } from '@/stores/settings'
|
|
4 |
|
5 |
import en from './locales/en.json'
|
6 |
import zh from './locales/zh.json'
|
|
|
|
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
|
14 |
-
|
|
|
15 |
resources: {
|
16 |
en: { translation: en },
|
17 |
-
zh: { translation: zh }
|
|
|
|
|
18 |
},
|
19 |
-
lng:
|
20 |
fallbackLng: 'en',
|
21 |
interpolation: {
|
22 |
escapeValue: false
|
23 |
}
|
24 |
})
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
return i18n
|
35 |
-
}
|
36 |
|
37 |
export default i18n
|
|
|
4 |
|
5 |
import en from './locales/en.json'
|
6 |
import zh from './locales/zh.json'
|
7 |
+
import fr from './locales/fr.json'
|
8 |
+
import ar from './locales/ar.json'
|
9 |
|
10 |
+
const getStoredLanguage = () => {
|
11 |
+
try {
|
12 |
+
const settingsString = localStorage.getItem('settings-storage')
|
13 |
+
if (settingsString) {
|
14 |
+
const settings = JSON.parse(settingsString)
|
15 |
+
return settings.state?.language || 'en'
|
16 |
+
}
|
17 |
+
} catch (e) {
|
18 |
+
console.error('Failed to get stored language:', e)
|
19 |
+
}
|
20 |
+
return 'en'
|
21 |
+
}
|
22 |
|
23 |
+
i18n
|
24 |
+
.use(initReactI18next)
|
25 |
+
.init({
|
26 |
resources: {
|
27 |
en: { translation: en },
|
28 |
+
zh: { translation: zh },
|
29 |
+
fr: { translation: fr },
|
30 |
+
ar: { translation: ar }
|
31 |
},
|
32 |
+
lng: getStoredLanguage(), // 使用存储的语言设置
|
33 |
fallbackLng: 'en',
|
34 |
interpolation: {
|
35 |
escapeValue: false
|
36 |
}
|
37 |
})
|
38 |
|
39 |
+
// Subscribe to language changes
|
40 |
+
useSettingsStore.subscribe((state) => {
|
41 |
+
const currentLanguage = state.language
|
42 |
+
if (i18n.language !== currentLanguage) {
|
43 |
+
i18n.changeLanguage(currentLanguage)
|
44 |
+
}
|
45 |
+
})
|
|
|
|
|
|
|
46 |
|
47 |
export default i18n
|
lightrag_webui/src/locales/ar.json
CHANGED
@@ -12,11 +12,26 @@
|
|
12 |
"retrieval": "الاسترجاع",
|
13 |
"api": "واجهة برمجة التطبيقات",
|
14 |
"projectRepository": "مستودع المشروع",
|
|
|
15 |
"themeToggle": {
|
16 |
"switchToLight": "التحويل إلى السمة الفاتحة",
|
17 |
"switchToDark": "التحويل إلى السمة الداكنة"
|
18 |
}
|
19 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
"documentPanel": {
|
21 |
"clearDocuments": {
|
22 |
"button": "مسح",
|
@@ -96,7 +111,9 @@
|
|
96 |
"zoomControl": {
|
97 |
"zoomIn": "تكبير",
|
98 |
"zoomOut": "تصغير",
|
99 |
-
"resetZoom": "إعادة تعيين التكبير"
|
|
|
|
|
100 |
},
|
101 |
"layoutsControl": {
|
102 |
"startAnimation": "بدء حركة التخطيط",
|
@@ -148,6 +165,11 @@
|
|
148 |
"degree": "الدرجة",
|
149 |
"properties": "الخصائص",
|
150 |
"relationships": "العلاقات",
|
|
|
|
|
|
|
|
|
|
|
151 |
"propertyNames": {
|
152 |
"description": "الوصف",
|
153 |
"entity_id": "الاسم",
|
@@ -174,7 +196,8 @@
|
|
174 |
"noLabels": "لم يتم العثور على تسميات",
|
175 |
"label": "التسمية",
|
176 |
"placeholder": "ابحث في التسميات...",
|
177 |
-
"andOthers": "و {{count}} آخرون"
|
|
|
178 |
}
|
179 |
},
|
180 |
"retrievePanel": {
|
|
|
12 |
"retrieval": "الاسترجاع",
|
13 |
"api": "واجهة برمجة التطبيقات",
|
14 |
"projectRepository": "مستودع المشروع",
|
15 |
+
"logout": "تسجيل الخروج",
|
16 |
"themeToggle": {
|
17 |
"switchToLight": "التحويل إلى السمة الفاتحة",
|
18 |
"switchToDark": "التحويل إلى السمة الداكنة"
|
19 |
}
|
20 |
},
|
21 |
+
"login": {
|
22 |
+
"description": "الرجاء إدخال حسابك وكلمة المرور لتسجيل الدخول إلى النظام",
|
23 |
+
"username": "اسم المستخدم",
|
24 |
+
"usernamePlaceholder": "الرجاء إدخال اسم المستخدم",
|
25 |
+
"password": "كلمة المرور",
|
26 |
+
"passwordPlaceholder": "الرجاء إدخال كلمة المرور",
|
27 |
+
"loginButton": "تسجيل الدخول",
|
28 |
+
"loggingIn": "جاري تسجيل الدخول...",
|
29 |
+
"successMessage": "تم تسجيل الدخول بنجاح",
|
30 |
+
"errorEmptyFields": "الرجاء إدخال اسم المستخدم وكلمة المرور",
|
31 |
+
"errorInvalidCredentials": "فشل تسجيل الدخول، يرجى التحقق من اسم المستخدم وكلمة المرور",
|
32 |
+
"authDisabled": "تم تعطيل المصادقة. استخدام وضع بدون تسجيل دخول.",
|
33 |
+
"guestMode": "وضع بدون تسجيل دخول"
|
34 |
+
},
|
35 |
"documentPanel": {
|
36 |
"clearDocuments": {
|
37 |
"button": "مسح",
|
|
|
111 |
"zoomControl": {
|
112 |
"zoomIn": "تكبير",
|
113 |
"zoomOut": "تصغير",
|
114 |
+
"resetZoom": "إعادة تعيين التكبير",
|
115 |
+
"rotateCamera": "تدوير في اتجاه عقارب الساعة",
|
116 |
+
"rotateCameraCounterClockwise": "تدوير عكس اتجاه عقارب الساعة"
|
117 |
},
|
118 |
"layoutsControl": {
|
119 |
"startAnimation": "بدء حركة التخطيط",
|
|
|
165 |
"degree": "الدرجة",
|
166 |
"properties": "الخصائص",
|
167 |
"relationships": "العلاقات",
|
168 |
+
"expandNode": "توسيع العقدة",
|
169 |
+
"pruneNode": "تقليم العقدة",
|
170 |
+
"deleteAllNodesError": "رفض حذف جميع العقد في الرسم البياني",
|
171 |
+
"nodesRemoved": "تم إزالة {{count}} عقدة، بما في ذلك العقد اليتيمة",
|
172 |
+
"noNewNodes": "لم يتم العثور على عقد قابلة للتوسيع",
|
173 |
"propertyNames": {
|
174 |
"description": "الوصف",
|
175 |
"entity_id": "الاسم",
|
|
|
196 |
"noLabels": "لم يتم العثور على تسميات",
|
197 |
"label": "التسمية",
|
198 |
"placeholder": "ابحث في التسميات...",
|
199 |
+
"andOthers": "و {{count}} آخرون",
|
200 |
+
"refreshTooltip": "إعادة تحميل بيانات الرسم البياني"
|
201 |
}
|
202 |
},
|
203 |
"retrievePanel": {
|
lightrag_webui/src/locales/fr.json
CHANGED
@@ -12,11 +12,26 @@
|
|
12 |
"retrieval": "Récupération",
|
13 |
"api": "API",
|
14 |
"projectRepository": "Référentiel du projet",
|
|
|
15 |
"themeToggle": {
|
16 |
"switchToLight": "Passer au thème clair",
|
17 |
"switchToDark": "Passer au thème sombre"
|
18 |
}
|
19 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
"documentPanel": {
|
21 |
"clearDocuments": {
|
22 |
"button": "Effacer",
|
@@ -96,7 +111,9 @@
|
|
96 |
"zoomControl": {
|
97 |
"zoomIn": "Zoom avant",
|
98 |
"zoomOut": "Zoom arrière",
|
99 |
-
"resetZoom": "Réinitialiser le zoom"
|
|
|
|
|
100 |
},
|
101 |
"layoutsControl": {
|
102 |
"startAnimation": "Démarrer l'animation de mise en page",
|
@@ -148,6 +165,11 @@
|
|
148 |
"degree": "Degré",
|
149 |
"properties": "Propriétés",
|
150 |
"relationships": "Relations",
|
|
|
|
|
|
|
|
|
|
|
151 |
"propertyNames": {
|
152 |
"description": "Description",
|
153 |
"entity_id": "Nom",
|
@@ -174,7 +196,8 @@
|
|
174 |
"noLabels": "Aucune étiquette trouvée",
|
175 |
"label": "Étiquette",
|
176 |
"placeholder": "Rechercher des étiquettes...",
|
177 |
-
"andOthers": "Et {{count}} autres"
|
|
|
178 |
}
|
179 |
},
|
180 |
"retrievePanel": {
|
|
|
12 |
"retrieval": "Récupération",
|
13 |
"api": "API",
|
14 |
"projectRepository": "Référentiel du projet",
|
15 |
+
"logout": "Déconnexion",
|
16 |
"themeToggle": {
|
17 |
"switchToLight": "Passer au thème clair",
|
18 |
"switchToDark": "Passer au thème sombre"
|
19 |
}
|
20 |
},
|
21 |
+
"login": {
|
22 |
+
"description": "Veuillez entrer votre compte et mot de passe pour vous connecter au système",
|
23 |
+
"username": "Nom d'utilisateur",
|
24 |
+
"usernamePlaceholder": "Veuillez saisir un nom d'utilisateur",
|
25 |
+
"password": "Mot de passe",
|
26 |
+
"passwordPlaceholder": "Veuillez saisir un mot de passe",
|
27 |
+
"loginButton": "Connexion",
|
28 |
+
"loggingIn": "Connexion en cours...",
|
29 |
+
"successMessage": "Connexion réussie",
|
30 |
+
"errorEmptyFields": "Veuillez saisir votre nom d'utilisateur et mot de passe",
|
31 |
+
"errorInvalidCredentials": "Échec de la connexion, veuillez vérifier le nom d'utilisateur et le mot de passe",
|
32 |
+
"authDisabled": "L'authentification est désactivée. Utilisation du mode sans connexion.",
|
33 |
+
"guestMode": "Mode sans connexion"
|
34 |
+
},
|
35 |
"documentPanel": {
|
36 |
"clearDocuments": {
|
37 |
"button": "Effacer",
|
|
|
111 |
"zoomControl": {
|
112 |
"zoomIn": "Zoom avant",
|
113 |
"zoomOut": "Zoom arrière",
|
114 |
+
"resetZoom": "Réinitialiser le zoom",
|
115 |
+
"rotateCamera": "Rotation horaire",
|
116 |
+
"rotateCameraCounterClockwise": "Rotation antihoraire"
|
117 |
},
|
118 |
"layoutsControl": {
|
119 |
"startAnimation": "Démarrer l'animation de mise en page",
|
|
|
165 |
"degree": "Degré",
|
166 |
"properties": "Propriétés",
|
167 |
"relationships": "Relations",
|
168 |
+
"expandNode": "Développer le nœud",
|
169 |
+
"pruneNode": "Élaguer le nœud",
|
170 |
+
"deleteAllNodesError": "Refus de supprimer tous les nœuds du graphe",
|
171 |
+
"nodesRemoved": "{{count}} nœuds supprimés, y compris les nœuds orphelins",
|
172 |
+
"noNewNodes": "Aucun nœud développable trouvé",
|
173 |
"propertyNames": {
|
174 |
"description": "Description",
|
175 |
"entity_id": "Nom",
|
|
|
196 |
"noLabels": "Aucune étiquette trouvée",
|
197 |
"label": "Étiquette",
|
198 |
"placeholder": "Rechercher des étiquettes...",
|
199 |
+
"andOthers": "Et {{count}} autres",
|
200 |
+
"refreshTooltip": "Recharger les données du graphe"
|
201 |
}
|
202 |
},
|
203 |
"retrievePanel": {
|
lightrag_webui/src/main.tsx
CHANGED
@@ -2,7 +2,7 @@ import { StrictMode } from 'react'
|
|
2 |
import { createRoot } from 'react-dom/client'
|
3 |
import './index.css'
|
4 |
import AppRouter from './AppRouter'
|
5 |
-
import './i18n';
|
6 |
|
7 |
|
8 |
|
|
|
2 |
import { createRoot } from 'react-dom/client'
|
3 |
import './index.css'
|
4 |
import AppRouter from './AppRouter'
|
5 |
+
import './i18n.ts';
|
6 |
|
7 |
|
8 |
|
lightrag_webui/src/stores/settings.ts
CHANGED
@@ -5,7 +5,7 @@ import { defaultQueryLabel } from '@/lib/constants'
|
|
5 |
import { Message, QueryRequest } from '@/api/lightrag'
|
6 |
|
7 |
type Theme = 'dark' | 'light' | 'system'
|
8 |
-
type Language = 'en' | 'zh'
|
9 |
type Tab = 'documents' | 'knowledge-graph' | 'retrieval' | 'api'
|
10 |
|
11 |
interface SettingsState {
|
|
|
5 |
import { Message, QueryRequest } from '@/api/lightrag'
|
6 |
|
7 |
type Theme = 'dark' | 'light' | 'system'
|
8 |
+
type Language = 'en' | 'zh' | 'fr' | 'ar'
|
9 |
type Tab = 'documents' | 'knowledge-graph' | 'retrieval' | 'api'
|
10 |
|
11 |
interface SettingsState {
|