feat(i18n): add Turkish locale

This commit is contained in:
Sinan Eldem authored and GitHub committed 2026-09-04 02:22:21 +08:00
1 parent 232426ced2
commit 79dbda2a8f
26 files changed
+9540 -18

No files matched your search

@@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8");
const localePaths = ["en", "es", "it", "ja", "ko", "pt-BR", "zh-CN", "zh-TW"];
const localePaths = ["en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"];
describe("AI assistant write confirmation replacement", () => {
it("renders a localized confirmation from the backend's semantic event", () => {
@@ -104,7 +104,7 @@ describe("EditorSettingsDialog live preview placement", () => {
it("describes the execute shortcut below the mode selector in every supported locale", () => {
expect(editorSection.indexOf("executeModeDescription")).toBeGreaterThan(editorSection.indexOf("executeModeLabel"));
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR"]) {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(source, locale).toContain("executeModeDescription:");
}
@@ -115,7 +115,7 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(editorSection).toContain("{{ completionTriggerModeDescription }}");
expect(editorSection).not.toContain('t("settings.completionTriggerModeDescription")');
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR"]) {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
for (const key of ["completionTriggerModeManualDescription", "completionTriggerModeRequirePrefixDescription", "completionTriggerModePositionalDescription"]) {
expect(source, `${locale}:${key}`).toContain(`${key}:`);
@@ -174,7 +174,7 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(dataSection.match(/editDataGridFilterEditorView = '(quick|conditions|text)'/g)).toHaveLength(3);
expect(dataSection).not.toContain('<SelectTrigger id="data-grid-filter-view"');
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR"]) {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
for (const key of ["dataGridFilterViewPreview", "dataGridFilterViewPreviewExpand", "dataGridFilterViewPreviewCollapse"]) {
expect(source, `${locale}:${key}`).toContain(`${key}:`);
@@ -215,7 +215,7 @@ describe("EditorSettingsDialog live preview placement", () => {
expect(editorPreview.indexOf('t("settings.previewSyntaxErrorHint")')).toBeGreaterThan(preview);
});
it.each(["en", "zh-CN", "zh-TW", "es", "pt-BR", "it", "ja", "ko"])("locale %s translates settings.previewSyntaxErrorHint", (locale) => {
it.each(["en", "zh-CN", "zh-TW", "es", "pt-BR", "it", "ja", "ko", "tr"])("locale %s translates settings.previewSyntaxErrorHint", (locale) => {
const localeSource = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(localeSource).toMatch(/previewSyntaxErrorHint: ".+"/);
});
@@ -10,6 +10,7 @@ import "dayjs/locale/it";
import "dayjs/locale/ja";
import "dayjs/locale/ko";
import "dayjs/locale/pt-br";
import "dayjs/locale/tr";
import { Copy, FileText, ListChecks, Settings } from "@lucide/vue";
import * as api from "@/lib/backend/api";
import type { MeilisearchIndexOverview } from "@/lib/backend/tauri";
@@ -29,6 +30,7 @@ const DAYJS_LOCALES: Record<string, string> = {
it: "it",
ja: "ja",
ko: "ko",
tr: "tr",
};
const props = defineProps<{
@@ -5,6 +5,7 @@ import itLocale from "../locales/it";
import ja from "../locales/ja";
import ko from "../locales/ko";
import ptBR from "../locales/pt-BR";
import tr from "../locales/tr";
import zhCN from "../locales/zh-CN";
import zhTW from "../locales/zh-TW";
@@ -16,6 +17,7 @@ const locales: Array<[string, Messages]> = [
["ja", ja],
["ko", ko],
["pt-BR", ptBR],
["tr", tr],
["zh-CN", zhCN],
["zh-TW", zhTW],
];
+2
View File
@@ -9,6 +9,7 @@ import it from "@/i18n/locales/it";
import ja from "@/i18n/locales/ja";
import ko from "@/i18n/locales/ko";
import ptBR from "@/i18n/locales/pt-BR";
import tr from "@/i18n/locales/tr";
import zhCN from "@/i18n/locales/zh-CN";
import zhTW from "@/i18n/locales/zh-TW";
import { PHOENIX_DRIVER_NOT_INSTALLED_ERROR, PHOENIX_JDBC_PLUGIN_NOT_INSTALLED_ERROR } from "@/lib/database/phoenixConnection";
@@ -20,6 +21,7 @@ const LOCALES = {
ja,
ko,
"pt-BR": ptBR,
tr,
"zh-CN": zhCN,
"zh-TW": zhTW,
} as const;
@@ -6,6 +6,7 @@ import it from "@/i18n/locales/it";
import ja from "@/i18n/locales/ja";
import ko from "@/i18n/locales/ko";
import ptBR from "@/i18n/locales/pt-BR";
import tr from "@/i18n/locales/tr";
import zhCN from "@/i18n/locales/zh-CN";
import zhTW from "@/i18n/locales/zh-TW";
@@ -23,6 +24,7 @@ describe("cached result messages", () => {
["Japanese", ja],
["Korean", ko],
["Brazilian Portuguese", ptBR],
["Turkish", tr],
["Simplified Chinese", zhCN],
["Traditional Chinese", zhTW],
])("provides the missing-result actions in %s", (_locale, messages) => {
@@ -6,6 +6,7 @@ import it_ from "../locales/it";
import ja from "../locales/ja";
import ko from "../locales/ko";
import ptBR from "../locales/pt-BR";
import tr from "../locales/tr";
import zhCN from "../locales/zh-CN";
import zhTW from "../locales/zh-TW";
@@ -16,6 +17,7 @@ const locales: Array<[string, Record<string, unknown>]> = [
["ja", ja],
["ko", ko],
["pt-BR", ptBR],
["tr", tr],
["zh-CN", zhCN],
["zh-TW", zhTW],
];
+2 -1
View File
@@ -5,6 +5,7 @@ import itLocale from "@/i18n/locales/it";
import ja from "@/i18n/locales/ja";
import ko from "@/i18n/locales/ko";
import ptBR from "@/i18n/locales/pt-BR";
import tr from "@/i18n/locales/tr";
import zhCN from "@/i18n/locales/zh-CN";
import zhTW from "@/i18n/locales/zh-TW";
@@ -13,7 +14,7 @@ type Messages = {
contextMenu: typeof en.contextMenu;
};
const locales = { es, it: itLocale, ja, ko, "pt-BR": ptBR, "zh-CN": zhCN, "zh-TW": zhTW } as unknown as Record<string, Messages>;
const locales = { es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW } as unknown as Record<string, Messages>;
describe("custom type translations", () => {
it("provides localized labels in every supported non-English locale", () => {
@@ -5,6 +5,7 @@ import it_ from "../locales/docs/it";
import ja from "../locales/docs/ja";
import ko from "../locales/docs/ko";
import ptBR from "../locales/docs/pt-BR";
import tr from "../locales/docs/tr";
import zhCN from "../locales/docs/zh-CN";
import zhTW from "../locales/docs/zh-TW";
@@ -21,6 +22,7 @@ const locales: Array<[string, Record<string, unknown>]> = [
["ja", ja],
["ko", ko],
["pt-BR", ptBR],
["tr", tr],
["zh-CN", zhCN],
["zh-TW", zhTW],
];
@@ -5,6 +5,7 @@ import it_ from "../locales/it";
import ja from "../locales/ja";
import ko from "../locales/ko";
import ptBR from "../locales/pt-BR";
import tr from "../locales/tr";
import zhCN from "../locales/zh-CN";
import zhTW from "../locales/zh-TW";
@@ -16,6 +17,7 @@ const locales: Array<[string, Messages]> = [
["ja", ja],
["ko", ko],
["pt-BR", ptBR],
["tr", tr],
["zh-CN", zhCN],
["zh-TW", zhTW],
];
@@ -5,6 +5,7 @@ import it from "@/i18n/locales/it";
import ja from "@/i18n/locales/ja";
import ko from "@/i18n/locales/ko";
import ptBR from "@/i18n/locales/pt-BR";
import tr from "@/i18n/locales/tr";
import zhCN from "@/i18n/locales/zh-CN";
import zhTW from "@/i18n/locales/zh-TW";
@@ -21,6 +22,7 @@ describe("SQLite rebuild notice", () => {
["Japanese", ja],
["Korean", ko],
["Brazilian Portuguese", ptBR],
["Turkish", tr],
["Simplified Chinese", zhCN],
["Traditional Chinese", zhTW],
])("warns about retained backup, forced CAST conversion, lossy values, and rollback in %s", (_locale, messages) => {
@@ -5,6 +5,7 @@ import itLocale from "@/i18n/locales/it";
import ja from "@/i18n/locales/ja";
import ko from "@/i18n/locales/ko";
import ptBR from "@/i18n/locales/pt-BR";
import tr from "@/i18n/locales/tr";
import zhCN from "@/i18n/locales/zh-CN";
import zhTW from "@/i18n/locales/zh-TW";
@@ -15,7 +16,7 @@ describe("user administration Host translations", () => {
});
it("provides localized Host-change labels in every non-English locale", () => {
const locales = { es, it: itLocale, ja, ko, "pt-BR": ptBR, "zh-CN": zhCN, "zh-TW": zhTW };
const locales = { es, it: itLocale, ja, ko, "pt-BR": ptBR, tr, "zh-CN": zhCN, "zh-TW": zhTW };
for (const [locale, messages] of Object.entries(locales)) {
expect(messages.userAdmin.changeHost, locale).not.toBe(en.userAdmin.changeHost);
expect(messages.userAdmin.newHost, locale).not.toBe(en.userAdmin.newHost);
+4 -2
View File
@@ -3,14 +3,14 @@ import en from "./locales/en";
import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/backend/safeStorage";
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
export type Locale = "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "zh-CN" | "zh-TW";
export type Locale = "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "tr" | "zh-CN" | "zh-TW";
type LocaleMessages = Record<string, unknown>;
type I18nGlobal = {
locale: { value: Locale };
setLocaleMessage: (locale: Locale, messages: LocaleMessages) => void;
};
const supportedLocales: Locale[] = ["en", "es", "it", "ja", "ko", "pt-BR", "zh-CN", "zh-TW"];
const supportedLocales: Locale[] = ["en", "es", "it", "ja", "ko", "pt-BR", "tr", "zh-CN", "zh-TW"];
const defaultLocale: Locale = "en";
const loadedLocales = new Set<Locale>([defaultLocale]);
const localeLoaders: Record<Exclude<Locale, "en">, () => Promise<{ default: LocaleMessages }>> = {
@@ -19,6 +19,7 @@ const localeLoaders: Record<Exclude<Locale, "en">, () => Promise<{ default: Loca
ja: () => import("./locales/ja"),
ko: () => import("./locales/ko"),
"pt-BR": () => import("./locales/pt-BR"),
tr: () => import("./locales/tr"),
"zh-CN": () => import("./locales/zh-CN"),
"zh-TW": () => import("./locales/zh-TW"),
};
@@ -45,6 +46,7 @@ export function localeFromLanguageTag(value: string | null | undefined): Locale
if (normalized === "ja" || normalized.startsWith("ja-")) return "ja";
if (normalized === "ko" || normalized.startsWith("ko-")) return "ko";
if (normalized === "pt" || normalized.startsWith("pt-")) return "pt-BR";
if (normalized === "tr" || normalized.startsWith("tr-")) return "tr";
return null;
}
+69
View File
@@ -0,0 +1,69 @@
export default {
title: "Dokümantasyon",
groupBySchema: "Şemalar",
groupByTableGroup: "Tablo Grupları",
noGroup: "(grup yok)",
noSchema: "(şema yok)",
search: "Tablo, sütun, grup ara…",
columns: "Sütunlar",
indexes: "Dizinler",
references: "Başvurular",
referencedBy: "Başvuranlar",
localNote: "YEREL",
shadowedComment: "Veritabanı açıklaması: {comment}",
addNote: "Not ekle",
editNote: "Notu düzenle",
newGroup: "Yeni grup…",
groupName: "Grup adı",
groupColour: "Renk",
deleteGroup: "Grubu sil",
enumValues: "Değerler",
usedBy: "Kullananlar",
openDiagram: "Şema diyagramını aç",
saving: "Kaydediliyor…",
saved: "Kaydedildi",
saveFailed: "Notlar kaydedilemedi: {error}",
overview: "Genel Bakış",
groupBy: "Gruplama ölçütü",
searchLabel: "Ara",
groups: "Gruplar",
relationships: "İlişkiler",
columnHeader: "Sütun",
typeHeader: "Tür",
settingsHeader: "Ayarlar",
noteHeader: "Not",
nameHeader: "Ad",
definitionHeader: "Tanım",
noOutgoingRelationships: "Bu tablo başka bir tabloya başvurmuyor.",
noIncomingRelationships: "Hiçbir tablo buna başvurmuyor.",
diagram: "Diyagram",
language: "Dil",
theme: "Tema",
themeLight: "Açık",
themeDark: "Koyu",
exportHtml: "HTML olarak dışa aktar…",
exporting: "Dışa aktarılıyor…",
exportFailed: "Dışa aktarılamadı: {error}",
warnings: {
tableSkipped: {
title: "Bir tablo belgelenemedi",
detail: "{table} atlandı: {reason}. Bu dokümantasyonda yer almıyor.",
},
noForeignKeyMetadata: {
title: "İlişki bilgisi yok",
detail: "{engine} yabancı anahtar meta verisi bildirmediği için ilişki bağlantıları türetilemedi. Diyagram, bu motor için eksiksizdir.",
},
commentsUnsupported: {
title: "Veritabanı açıklamaları kullanılamıyor",
detail: "{engine} tablo veya sütun açıklamalarını desteklemiyor, bu yüzden buradaki her açıklama bu projenin kendi notlarından gelir.",
},
orphanedNotes: {
title: "Bazı notlar artık hiçbir şeyle eşleşmiyor",
detail: "{count} not, artık var olmayan bir tabloya veya sütuna başvuruyor. Hiçbir şey silinmedi — notlar dosyasında yeniden eşleyin ya da kaldırın.",
},
dbmlOmitted: {
title: "DBML'de gösterilemiyor",
detail: "{table} üzerindeki {item} burada belgeleniyor ancak dışa aktarılan DBML'de yer almıyor: {reason}.",
},
},
};
@@ -385,6 +385,34 @@ export const meilisearchManagementMessages = {
deleteTaskHistory: "Excluir histórico",
readOnlyDisabled: "As ações ficam desativadas em conexões somente leitura.",
},
tr: {
...en,
systemManagement: "Sistem yönetimi",
overview: "Genel bakış",
apiKeys: "API Anahtarları",
tasks: "Görevler",
health: "Sağlık",
version: "Sürüm",
indexCount: "Dizinler",
totalDocuments: "Toplam belge",
keyCount: "Anahtarlar",
refresh: "Yenile",
rowActions: "İşlemler",
previous: "Önceki",
next: "Sonraki",
createKey: "Anahtar oluştur",
editKey: "Anahtarı düzenle",
deleteKey: "Anahtarı sil",
noKeys: "API anahtarı yok",
filters: "Filtreler",
applyFilters: "Filtreleri uygula",
receivedDocuments: "Alınan belgeler",
indexedDocuments: "Dizinlenen belgeler",
noTasks: "Görev yok",
cancelTask: "Görevi iptal et",
deleteTaskHistory: "Geçmişi sil",
readOnlyDisabled: "Salt okunur bağlantılarda işlemler devre dışıdır.",
},
} as const;
export const meilisearchManagementEn = meilisearchManagementMessages.en;
@@ -395,3 +423,4 @@ export const meilisearchManagementKo = meilisearchManagementMessages.ko;
export const meilisearchManagementEs = meilisearchManagementMessages.es;
export const meilisearchManagementIt = meilisearchManagementMessages.it;
export const meilisearchManagementPtBR = meilisearchManagementMessages["pt-BR"];
export const meilisearchManagementTr = meilisearchManagementMessages.tr;
File diff suppressed because it is too large. Load diff
@@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest";
const dialogSource = readFileSync(new URL("../../../components/connection/ConnectionDialog.vue", import.meta.url), "utf8");
const enSource = readFileSync(new URL("../../../i18n/locales/en.ts", import.meta.url), "utf8");
const zhCnSource = readFileSync(new URL("../../../i18n/locales/zh-CN.ts", import.meta.url), "utf8");
const fallbackLocaleSources = ["es", "it", "ja", "ko", "pt-BR", "zh-TW"].map((locale) => readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"));
const fallbackLocaleSources = ["es", "it", "ja", "ko", "pt-BR", "tr", "zh-TW"].map((locale) => readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8"));
describe("ZooKeeper connection dialog", () => {
it("binds the existing Select component to the ZooKeeper auth_scheme helper", () => {
@@ -7,6 +7,7 @@ export const LOCALE_OPTIONS: { value: Locale; flag: string; label: string }[] =
{ value: "ja", flag: "🇯🇵", label: "日本語" },
{ value: "ko", flag: "🇰🇷", label: "한국어" },
{ value: "pt-BR", flag: "🇧🇷", label: "Português" },
{ value: "tr", flag: "🇹🇷", label: "Türkçe" },
{ value: "zh-CN", flag: "🇨🇳", label: "简体中文" },
{ value: "zh-TW", flag: "繁", label: "繁體中文" },
];
@@ -101,7 +101,7 @@ describe("settings search", () => {
});
it("defines the WebDAV Web-runtime notice in every supported locale", () => {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR"]) {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(source, locale).toContain("syncWebDavWebDescription:");
}
@@ -212,7 +212,7 @@ describe("settings search", () => {
});
it("defines the performance section title in every supported locale", () => {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR"]) {
for (const locale of ["zh-CN", "zh-TW", "en", "es", "it", "ja", "ko", "pt-BR", "tr"]) {
const source = readFileSync(new URL(`../../../i18n/locales/${locale}.ts`, import.meta.url), "utf8");
expect(source, locale).toContain("performanceSection:");
}