فهرست منبع

chore: (#708) Print key validation errors, translate the language dialog

jamesread 7 ماه پیش
والد
کامیت
217b17a058
8فایلهای تغییر یافته به همراه92 افزوده شده و 9 حذف شده
  1. 4 4
      frontend/resources/vue/App.vue
  2. 0 0
      lang/combined_output.json
  3. 5 1
      lang/de-DE.yaml
  4. 5 1
      lang/en.yaml
  5. 5 1
      lang/es-ES.yaml
  6. 5 1
      lang/it-IT.yaml
  7. 63 0
      lang/main.go
  8. 5 1
      lang/zh-Hans-CN.yaml

+ 4 - 4
frontend/resources/vue/App.vue

@@ -55,19 +55,19 @@
 
     <dialog ref="languageDialog" class="language-dialog" @click="handleDialogClick">
         <div class="dialog-content" @click.stop>
-            <h2>Select Language</h2>
+            <h2>{{ t('language-dialog.title') }}</h2>
             <select v-model="selectedLanguage" @change="changeLanguage" class="language-select">
                 <option v-for="(name, code) in availableLanguages" :key="code" :value="code">
                     {{ name }}
                 </option>
             </select>
             <p class="browser-languages">
-                Browser languages: 
+                {{ t('language-dialog.browser-languages') }}: 
                 <span v-if="browserLanguages.length > 0">{{ browserLanguages.join(', ') }}</span>
-                <span v-else>Not available</span>
+                <span v-else>{{ t('language-dialog.not-available') }}</span>
             </p>
             <div class="dialog-buttons">
-                <button @click="closeLanguageDialog">Close</button>
+                <button @click="closeLanguageDialog">{{ t('language-dialog.close') }}</button>
             </div>
         </div>
     </dialog>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
lang/combined_output.json


+ 5 - 1
lang/de-DE.yaml

@@ -17,4 +17,8 @@ translations:
   logs.status: Status
   logs.no-logs-to-display: Es gibt keine Protokolle zu anzeigen.
   return-to-index: Zurück zur Startseite
-  search-filter: Filter aktuelle Seite
+  search-filter: Filter aktuelle Seite
+  language-dialog.title: Sprache auswählen
+  language-dialog.browser-languages: Browser-Sprachen
+  language-dialog.not-available: Nicht verfügbar
+  language-dialog.close: Schließen

+ 5 - 1
lang/en.yaml

@@ -17,4 +17,8 @@ translations:
   logs.status: Status
   logs.no-logs-to-display: There are no logs to display.
   return-to-index: Return to index
-  search-filter: Filter current page
+  search-filter: Filter current page
+  language-dialog.title: Select Language
+  language-dialog.browser-languages: Browser languages
+  language-dialog.not-available: Not available
+  language-dialog.close: Close

+ 5 - 1
lang/es-ES.yaml

@@ -17,4 +17,8 @@ translations:
   logs.status: Status
   logs.no-logs-to-display: No hay registros para mostrar.
   return-to-index: Volver a la página principal
-  search-filter: Filtrar página actual
+  search-filter: Filtrar página actual
+  language-dialog.title: Seleccionar idioma
+  language-dialog.browser-languages: Idiomas del navegador
+  language-dialog.not-available: No disponible
+  language-dialog.close: Cerrar

+ 5 - 1
lang/it-IT.yaml

@@ -17,4 +17,8 @@ translations:
   logs.status: Status
   logs.no-logs-to-display: Non ci sono registri da mostrare.
   return-to-index: Torna alla pagina principale
-  search-filter: Filtra la pagina corrente
+  search-filter: Filtra la pagina corrente
+  language-dialog.title: Seleziona lingua
+  language-dialog.browser-languages: Lingue del browser
+  language-dialog.not-available: Non disponibile
+  language-dialog.close: Chiudi

+ 63 - 0
lang/main.go

@@ -90,9 +90,72 @@ func getCombinedLanguageContent() *CombinedTranslationsOutput {
 		output.Messages[languageName] = yamlData.Translations
 	}
 
+	validateTranslations(output)
+
 	return output
 }
 
+// getReferenceKeys returns the keys from the "en" translation as the reference set.
+func getReferenceKeys(messages map[string]map[string]string) map[string]bool {
+	enTranslations, exists := messages["en"]
+	if !exists {
+		return nil
+	}
+
+	referenceKeys := make(map[string]bool, len(enTranslations))
+	for key := range enTranslations {
+		referenceKeys[key] = true
+	}
+	return referenceKeys
+}
+
+// findMissingKeys returns the keys that are in referenceKeys but not in translations.
+func findMissingKeys(referenceKeys map[string]bool, translations map[string]string) []string {
+	missing := make([]string, 0)
+	for key := range referenceKeys {
+		if _, exists := translations[key]; !exists {
+			missing = append(missing, key)
+		}
+	}
+	return missing
+}
+
+// findExtraKeys returns the keys that are in translations but not in referenceKeys.
+func findExtraKeys(referenceKeys map[string]bool, translations map[string]string) []string {
+	extra := make([]string, 0)
+	for key := range translations {
+		if !referenceKeys[key] {
+			extra = append(extra, key)
+		}
+	}
+	return extra
+}
+
+// validateTranslations checks all translations against the "en" reference and prints warnings for missing and extra keys.
+func validateTranslations(output *CombinedTranslationsOutput) {
+	referenceKeys := getReferenceKeys(output.Messages)
+	if referenceKeys == nil {
+		log.Warnf("No 'en' translation found, skipping validation")
+		return
+	}
+
+	for langName, translations := range output.Messages {
+		if langName == "en" {
+			continue
+		}
+
+		missing := findMissingKeys(referenceKeys, translations)
+		if len(missing) > 0 {
+			log.Warnf("Translation '%s' is missing %d key(s): %v", langName, len(missing), missing)
+		}
+
+		extra := findExtraKeys(referenceKeys, translations)
+		if len(extra) > 0 {
+			log.Warnf("Translation '%s' has %d extra key(s) not in 'en': %v", langName, len(extra), extra)
+		}
+	}
+}
+
 func filterLanguageFiles(files []os.DirEntry) []os.DirEntry {
 	ret := make([]os.DirEntry, 0)
 

+ 5 - 1
lang/zh-Hans-CN.yaml

@@ -17,4 +17,8 @@ translations:
   logs.status: 状态
   logs.no-logs-to-display: 没有日志可显示。
   return-to-index: 返回首页
-  search-filter: 过滤当前页面
+  search-filter: 过滤当前页面
+  language-dialog.title: 选择语言
+  language-dialog.browser-languages: 浏览器语言
+  language-dialog.not-available: 不可用
+  language-dialog.close: 关闭

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است