mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
feat(i18n): add bahasa indonesia translation
This commit is contained in:
+1
-1
@@ -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 = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
|
||||
const localePaths = ["az", "en", "es", "id", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
|
||||
|
||||
describe("AI assistant write confirmation replacement", () => {
|
||||
it("renders a localized confirmation from the backend's semantic event", () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { BackendErrorException, formatError, normalizeBackendError, sanitizeBack
|
||||
import az from "@/i18n/locales/az";
|
||||
import en from "@/i18n/locales/en";
|
||||
import es from "@/i18n/locales/es";
|
||||
import id from "@/i18n/locales/id";
|
||||
import it from "@/i18n/locales/it";
|
||||
import ja from "@/i18n/locales/ja";
|
||||
import ko from "@/i18n/locales/ko";
|
||||
@@ -20,6 +21,7 @@ const LOCALES = {
|
||||
az,
|
||||
en,
|
||||
es,
|
||||
id,
|
||||
it,
|
||||
ja,
|
||||
ko,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import id from "../locales/id";
|
||||
import it_ from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
@@ -15,6 +16,7 @@ const locales: Array<[string, Record<string, unknown>]> = [
|
||||
["az", az],
|
||||
["en", en],
|
||||
["es", es],
|
||||
["id", id],
|
||||
["it", it_],
|
||||
["ja", ja],
|
||||
["ko", ko],
|
||||
|
||||
@@ -12,8 +12,8 @@ function localeSource(name: string): string {
|
||||
return readFileSync(new URL(`../locales/${name}.ts`, import.meta.url), "utf8");
|
||||
}
|
||||
|
||||
// Source of truth: `supportedLocales` in ../index.ts (11 entries, `ru` included).
|
||||
const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr"] as const;
|
||||
// Source of truth: `supportedLocales` in ../index.ts (12 entries, `ru` included).
|
||||
const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr", "id"] as const;
|
||||
|
||||
function declaredString(source: string, key: string): string | undefined {
|
||||
return source.match(new RegExp(String.raw`^\s*${key}:\s*"((?:[^"\\]|\\.)*)",\s*$`, "m"))?.[1];
|
||||
|
||||
+3
-2
@@ -3,6 +3,7 @@ import { createI18n } from "vue-i18n";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import id from "../locales/id";
|
||||
import itLocale from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
@@ -20,9 +21,9 @@ import zhTW from "../locales/zh-TW";
|
||||
vi.mock("../locales/fallback", () => ({ withEnglishFallback: (messages: Record<string, unknown>) => messages }));
|
||||
|
||||
type Messages = Record<string, unknown>;
|
||||
type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW";
|
||||
type Locale = "az" | "en" | "es" | "id" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW";
|
||||
|
||||
const declared: Record<Locale, Messages> = { az, en, es, it: itLocale, ja, ko, "pt-BR": ptBR, ru, tr, "zh-CN": zhCN, "zh-TW": zhTW };
|
||||
const declared: Record<Locale, Messages> = { az, en, es, id, it: itLocale, ja, ko, "pt-BR": ptBR, ru, tr, "zh-CN": zhCN, "zh-TW": zhTW };
|
||||
const ALL_LOCALES = Object.keys(declared) as Locale[];
|
||||
const EXCEPT_AZ_TR = ALL_LOCALES.filter((locale) => locale !== "az" && locale !== "tr");
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import id from "../locales/id";
|
||||
import it_ from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
@@ -15,6 +16,7 @@ const locales: Array<[string, Record<string, unknown>]> = [
|
||||
["az", az],
|
||||
["en", en],
|
||||
["es", es],
|
||||
["id", id],
|
||||
["it", it_],
|
||||
["ja", ja],
|
||||
["ko", ko],
|
||||
|
||||
@@ -15,7 +15,7 @@ function historyKindsCluster(source: string): string | undefined {
|
||||
return (source.match(/kinds: \{[^}]*\}/g) ?? []).find((cluster) => cluster.includes("redis_command:"));
|
||||
}
|
||||
|
||||
const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr"] as const;
|
||||
const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr", "id"] as const;
|
||||
|
||||
describe("history kinds mcp label parity", () => {
|
||||
it.each(LOCALES)("%s: history.kinds declares mcp", (name) => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import id from "../locales/id";
|
||||
import itLocale from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
@@ -24,6 +25,7 @@ import zhTW from "../locales/zh-TW";
|
||||
const locales: Array<[string, Record<string, unknown>]> = [
|
||||
["az", az as Record<string, unknown>],
|
||||
["es", es as Record<string, unknown>],
|
||||
["id", id as Record<string, unknown>],
|
||||
["it", itLocale as Record<string, unknown>],
|
||||
["ja", ja as Record<string, unknown>],
|
||||
["ko", ko as Record<string, unknown>],
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import id from "../locales/id";
|
||||
import it_ from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
@@ -19,6 +20,7 @@ const locales: Array<[string, Record<string, unknown>]> = [
|
||||
["en", en as Record<string, unknown>],
|
||||
["az", az as Record<string, unknown>],
|
||||
["es", es],
|
||||
["id", id],
|
||||
["it", it_],
|
||||
["ja", ja],
|
||||
["ko", ko],
|
||||
|
||||
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
||||
import az from "../locales/az";
|
||||
import en from "../locales/en";
|
||||
import es from "../locales/es";
|
||||
import id from "../locales/id";
|
||||
import it_ from "../locales/it";
|
||||
import ja from "../locales/ja";
|
||||
import ko from "../locales/ko";
|
||||
@@ -20,6 +21,7 @@ const locales: Array<[string, Record<string, unknown>]> = [
|
||||
["en", en as Record<string, unknown>],
|
||||
["az", az as Record<string, unknown>],
|
||||
["es", es],
|
||||
["id", id],
|
||||
["it", it_],
|
||||
["ja", ja],
|
||||
["ko", ko],
|
||||
|
||||
@@ -3,19 +3,20 @@ import en from "./locales/en";
|
||||
import { safeLocalStorageGet } from "@/lib/backend/safeStorage";
|
||||
import { persistAppLocale } from "@/lib/app/appAppearance";
|
||||
|
||||
export type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW";
|
||||
export type Locale = "az" | "en" | "es" | "id" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW";
|
||||
type LocaleMessages = Record<string, unknown>;
|
||||
type I18nGlobal = {
|
||||
locale: { value: Locale };
|
||||
setLocaleMessage: (locale: Locale, messages: LocaleMessages) => void;
|
||||
};
|
||||
|
||||
const supportedLocales: Locale[] = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
|
||||
const supportedLocales: Locale[] = ["az", "en", "es", "id", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"];
|
||||
const defaultLocale: Locale = "en";
|
||||
const loadedLocales = new Set<Locale>([defaultLocale]);
|
||||
const localeLoaders: Record<Exclude<Locale, "en">, () => Promise<{ default: LocaleMessages }>> = {
|
||||
az: () => import("./locales/az"),
|
||||
es: () => import("./locales/es"),
|
||||
id: () => import("./locales/id"),
|
||||
it: () => import("./locales/it"),
|
||||
ja: () => import("./locales/ja"),
|
||||
ko: () => import("./locales/ko"),
|
||||
@@ -45,6 +46,7 @@ export function localeFromLanguageTag(value: string | null | undefined): Locale
|
||||
if (normalized === "az" || normalized.startsWith("az-")) return "az";
|
||||
if (normalized === "en" || normalized.startsWith("en-")) return "en";
|
||||
if (normalized === "es" || normalized.startsWith("es-")) return "es";
|
||||
if (normalized === "id" || normalized.startsWith("id-")) return "id";
|
||||
if (normalized === "it" || normalized.startsWith("it-")) return "it";
|
||||
if (normalized === "ja" || normalized.startsWith("ja-")) return "ja";
|
||||
if (normalized === "ko" || normalized.startsWith("ko-")) return "ko";
|
||||
|
||||
@@ -0,0 +1,472 @@
|
||||
import type { ConsulMessages } from "./consulUi";
|
||||
|
||||
export const consulIdMessages = {
|
||||
ui: {
|
||||
unknown: "Tidak diketahui",
|
||||
peeringPending: "Menunggu",
|
||||
peeringEstablishing: "Sedang dibangun",
|
||||
peeringActive: "Aktif",
|
||||
peeringFailing: "Gagal",
|
||||
peeringDeleting: "Sedang dihapus",
|
||||
peeringTerminated: "Dihentikan",
|
||||
refresh: "Segarkan",
|
||||
cancel: "Batal",
|
||||
create: "Buat",
|
||||
update: "Perbarui",
|
||||
save: "Simpan",
|
||||
delete: "Hapus",
|
||||
edit: "Edit",
|
||||
apply: "Terapkan",
|
||||
close: "Tutup",
|
||||
hide: "Sembunyikan",
|
||||
reveal: "Tampilkan",
|
||||
copy: "Salin",
|
||||
copied: "Disalin",
|
||||
copyFailed: "Gagal menyalin",
|
||||
copyOnce: "Salin sekali",
|
||||
pause: "Jeda",
|
||||
watchAction: "Pantau",
|
||||
watchPrefix: "Pantau prefiks",
|
||||
watchModePrefix: "Prefiks",
|
||||
watchModeKey: "Kunci persis",
|
||||
sessionProtected: "Dilindungi Sesi",
|
||||
sessionProtectedHint: "Penyuntingan dan penghapusan dinonaktifkan untuk melindungi kunci terdistribusi ini.",
|
||||
atomicTransaction: "Transaksi atomik",
|
||||
nonAtomicBatches: "Tidak atomik antar {count} batch",
|
||||
batchOperation: "Batch {batch} · OpIndex {op}",
|
||||
operationTotals: "Berhasil {succeeded} · Konflik {conflicted} · Dilewati {skipped} · Gagal {failed}",
|
||||
deleteOperationTotals: "Berhasil {succeeded} · Konflik {conflicted} · Gagal {failed}",
|
||||
clientSideMigration: "DBX membaca dari sumber dan menulis ke target. Ini bukan replikasi antar-Datacenter native Consul.",
|
||||
bundleFileType: "Paket KV Consul DBX",
|
||||
sourceKeyMissingModifyIndex: "Kunci sumber tidak memiliki ModifyIndex",
|
||||
transactionRejected: "Consul menolak transaksi",
|
||||
overview: "Ringkasan klaster",
|
||||
capabilities: "Kapabilitas",
|
||||
probeLoading: "Memuat",
|
||||
probeReady: "Siap",
|
||||
probeForbidden: "Terlarang",
|
||||
probeUnsupported: "Tidak didukung",
|
||||
probeError: "Galat",
|
||||
autopilotHealth: "Kesehatan Autopilot",
|
||||
datacenter: "Datacenter",
|
||||
agentNode: "Node Agent",
|
||||
agentAddress: "Alamat Agent",
|
||||
version: "Versi",
|
||||
mode: "Mode",
|
||||
server: "Server",
|
||||
client: "Klien",
|
||||
leader: "Leader",
|
||||
raftPeers: "Peer Raft",
|
||||
membersAlive: "Anggota hidup",
|
||||
members: "Anggota",
|
||||
node: "Node",
|
||||
address: "Alamat",
|
||||
status: "Status",
|
||||
alive: "hidup",
|
||||
leaving: "keluar",
|
||||
failed: "gagal",
|
||||
previousPage: "Halaman sebelumnya",
|
||||
nextPage: "Halaman berikutnya",
|
||||
pageStatus: "{page} / {pages} · total {total}",
|
||||
searchAllServices: "Cari semua layanan",
|
||||
searchAllNodes: "Cari semua node",
|
||||
searchLocalServices: "Cari layanan Agent lokal",
|
||||
query: "Kueri",
|
||||
searchHealthChecks: "Cari nama, ID, node, layanan, output, atau catatan pemeriksaan",
|
||||
allCheckTypes: "Semua jenis pemeriksaan",
|
||||
clearFilters: "Bersihkan filter",
|
||||
healthResultCount: "{filtered} dari {total} pemeriksaan",
|
||||
services: "Layanan",
|
||||
nodes: "Node",
|
||||
service: "Layanan",
|
||||
catalogServices: "Layanan katalog",
|
||||
catalogNodes: "Node katalog",
|
||||
noVisibleServices: "Tidak ada layanan yang terlihat",
|
||||
noVisibleNodes: "Tidak ada node yang terlihat",
|
||||
noMatchingServices: "Tidak ada layanan yang cocok",
|
||||
noMatchingNodes: "Tidak ada node yang cocok",
|
||||
agentTarget: "Target Agent: {target}",
|
||||
agentTargetVerifying: "Memverifikasi target Agent",
|
||||
unknownWritesDisabled: "tidak diketahui - penulisan dinonaktifkan",
|
||||
targetAgent: "Agent target",
|
||||
agentWriteReady: "Dapat ditulis",
|
||||
agentReadOnly: "Baca saja",
|
||||
agentWriteDisabledHint: "Tidak ada target Agent yang cocok dikonfigurasi, sehingga pemeliharaan dan pembatalan pendaftaran dinonaktifkan. Agent yang terdeteksi: {target}.",
|
||||
agentWriteBlocked: {
|
||||
connectionUnavailable: "Konfigurasi koneksi tidak tersedia. Sambungkan kembali sebelum menulis.",
|
||||
readOnly: "Koneksi ini baca saja. Pembatalan pendaftaran layanan dinonaktifkan.",
|
||||
transport: "Penulisan Agent tidak tersedia melalui Transport Layer. Sambungkan langsung ke Agent target.",
|
||||
targetRequired: "Sunting koneksi dan konfigurasikan node serta alamat target Agent. Node harus cocok dengan Agent saat ini, dan alamat harus cocok dengan endpoint koneksi.",
|
||||
identityUnavailable: "Tidak dapat membaca identitas Agent. Penulisan dinonaktifkan. Periksa koneksi dan izin baca Agent, lalu segarkan.",
|
||||
nodeMismatch: "Node target yang dikonfigurasi tidak cocok dengan Agent saat ini. Periksa pengaturan koneksi.",
|
||||
directAddressRequired: "Penulisan Agent memerlukan endpoint IP langsung atau localhost. Alamat DNS dan load-balanced tidak didukung.",
|
||||
addressMismatch: "Alamat target Agent tidak cocok dengan endpoint koneksi. Periksa pengaturan koneksi.",
|
||||
invalidAddress: "Alamat koneksi Consul tidak valid. Periksa pengaturan koneksi.",
|
||||
},
|
||||
register: "Daftarkan",
|
||||
registrationHint: "Pendaftaran HTTP Agent dimiliki oleh runtime Agent target dan tidak mengubah berkas konfigurasi permanennya.",
|
||||
name: "Nama",
|
||||
id: "ID",
|
||||
port: "Port",
|
||||
tags: "Tag (dipisahkan koma)",
|
||||
registerOn: "Daftarkan di {node}",
|
||||
catalogInstances: "Instansi katalog",
|
||||
nodeServices: "Layanan node",
|
||||
serviceId: "ID layanan",
|
||||
localAgentServices: "Layanan Agent lokal",
|
||||
enableMaintenance: "Aktifkan mode pemeliharaan",
|
||||
disableMaintenance: "Nonaktifkan mode pemeliharaan",
|
||||
deregister: "Batalkan pendaftaran",
|
||||
deregisterService: "Batalkan pendaftaran layanan lokal {id} dari {node}?",
|
||||
deregistering: "Membatalkan pendaftaran",
|
||||
deregisterServiceHint: "Ini menghapus pendaftaran layanan dan pemeriksaan terkait. Katalog akan disinkronkan setelahnya. Proses layanan tetap berjalan dan dapat mendaftarkan dirinya kembali.",
|
||||
deregisterServiceSucceeded: "Pendaftaran layanan {id} dari {node} dibatalkan. Sinkronisasi katalog dapat memakan waktu; layanan dapat muncul kembali jika aplikasi mendaftarkannya lagi.",
|
||||
deregisterRefreshFailed: "Layanan dibatalkan pendaftarannya, tetapi penyegaran gagal. Segarkan secara manual",
|
||||
maintenanceReason: "Permintaan pengguna DBX",
|
||||
serviceDetails: "Detail {service}",
|
||||
kind: "Jenis",
|
||||
serviceKind: "ServiceKind",
|
||||
standard: "standar",
|
||||
metadata: "Metadata",
|
||||
nodeMeta: "Metadata node",
|
||||
serviceMeta: "Metadata layanan",
|
||||
nodeId: "ID node",
|
||||
serviceWeights: "Baik / Peringatan",
|
||||
taggedAddresses: "TaggedAddresses",
|
||||
enableTagOverride: "EnableTagOverride",
|
||||
agent: "Agent",
|
||||
watch: "Pantau",
|
||||
writeOperation: "Operasi tulis",
|
||||
localServiceDetails: "Detail layanan lokal",
|
||||
agentIdentityRequestTimedOut: "Pemuatan identitas Agent kehabisan waktu.",
|
||||
localServicesRequestTimedOut: "Pemuatan layanan Agent lokal kehabisan waktu.",
|
||||
localChecksRequestTimedOut: "Pemuatan pemeriksaan Agent lokal kehabisan waktu.",
|
||||
healthChecks: "Pemeriksaan kesehatan",
|
||||
state: "Status",
|
||||
nodeName: "Nama node",
|
||||
allStates: "Semua status",
|
||||
passing: "Baik",
|
||||
warning: "Peringatan",
|
||||
critical: "Kritis",
|
||||
watchPaused: "Pemantauan dijeda",
|
||||
watchingIndex: "Memantau indeks {index}",
|
||||
pauseWatch: "Jeda pemantauan",
|
||||
startWatch: "Mulai pemantauan",
|
||||
checkRegistrationHint: "Pemeriksaan Agent adalah pendaftaran runtime pada {node} dan tidak disimpan ke berkas konfigurasi Agent.",
|
||||
type: "Jenis",
|
||||
ttl: "TTL",
|
||||
http: "HTTP",
|
||||
tcp: "TCP",
|
||||
grpc: "gRPC",
|
||||
docker: "Docker",
|
||||
script: "Script",
|
||||
arguments: "Argumen",
|
||||
containerId: "ID kontainer",
|
||||
endpoint: "Endpoint",
|
||||
interval: "Interval",
|
||||
timeout: "Batas waktu",
|
||||
commandArguments: "Argumen perintah",
|
||||
clusterHealth: "Kesehatan klaster",
|
||||
nodeHealth: "Kesehatan node: {node}",
|
||||
serviceHealth: "Kesehatan layanan: {service}",
|
||||
noMatchingHealthChecks: "Tidak ada pemeriksaan kesehatan yang cocok",
|
||||
serviceInstances: "Instansi layanan",
|
||||
localAgentChecks: "Pemeriksaan Agent lokal",
|
||||
maintenance: "pemeliharaan",
|
||||
ttlPass: "TTL lulus",
|
||||
ttlWarn: "TTL peringatan",
|
||||
ttlFail: "TTL gagal",
|
||||
deregisterCheck: "Batalkan pendaftaran pemeriksaan {id} dari {node}?",
|
||||
checkDetails: "Detail {check}",
|
||||
checkId: "ID pemeriksaan",
|
||||
notes: "Catatan",
|
||||
output: "Output",
|
||||
definition: "Definisi",
|
||||
indexes: "CreateIndex / ModifyIndex",
|
||||
sessionsAndLocks: "Sesi dan kunci",
|
||||
sessions: "Sesi",
|
||||
sessionDescription: "Sesi adalah kontrak mirip lease yang digunakan oleh kunci KV Consul. Sesi TTL memerlukan pembaruan berkala; Sesi tanpa TTL tetap ada hingga secara eksplisit dihancurkan atau divalidasi oleh pemeriksaannya.",
|
||||
createSession: "Buat Sesi",
|
||||
searchSessions: "Cari nama, ID, node, atau pemeriksaan Sesi",
|
||||
sessionResultCount: "Menampilkan {filtered} dari {total} Sesi",
|
||||
noMatchingSessions: "Tidak ada Sesi yang cocok",
|
||||
allSessionTypes: "Semua jenis Sesi",
|
||||
ttlSessions: "Sesi TTL",
|
||||
persistentSessions: "Sesi tanpa TTL",
|
||||
allBehaviors: "Semua perilaku",
|
||||
aclFilteredSessions: "Daftar Sesi difilter oleh ACL",
|
||||
sessionRequestTimedOut: "Pemuatan Sesi kehabisan waktu. Periksa koneksi Consul dan coba lagi.",
|
||||
complete: "Lengkap",
|
||||
lock: "Kunci",
|
||||
lockManagement: "Pengelolaan kunci KV",
|
||||
lockIndex: "LockIndex {index}",
|
||||
lockDelay: "Penundaan kunci",
|
||||
lockDelayHint: "0s–60s; menunda pengambilan ulang setelah invalidasi.",
|
||||
nodeOptional: "Node (opsional)",
|
||||
behavior: "Perilaku",
|
||||
behaviorRelease: "release",
|
||||
behaviorDelete: "delete",
|
||||
behaviorHint: "release mempertahankan kunci yang dipegang; delete menghapusnya saat Sesi berakhir.",
|
||||
releaseLocks: "Lepaskan kunci",
|
||||
deleteKeys: "Hapus kunci",
|
||||
deleteBehaviorWarning: "Perilaku=delete menghapus setiap kunci yang dipegang oleh Sesi ini saat Sesi divalidasi. Lanjutkan?",
|
||||
checks: "Pemeriksaan",
|
||||
nodeChecks: "Pemeriksaan node",
|
||||
serviceChecks: "Pemeriksaan layanan",
|
||||
nodeCheckShort: "Node",
|
||||
serviceCheckShort: "Layanan",
|
||||
serviceChecksPlaceholder: "service:api:health{'@'}namespace-a",
|
||||
serviceChecksHint: "ID pemeriksaan dipisahkan koma; gunakan ID{'@'}namespace untuk pemeriksaan tercakup.",
|
||||
lockHint: "Periksa kunci, pilih Sesi, lalu ambil atau lepaskan kunci advisori.",
|
||||
key: "Kunci",
|
||||
inspectKey: "Periksa kunci",
|
||||
keyExists: "Kunci ada",
|
||||
keyNotFound: "Kunci tidak ada",
|
||||
keyUnlocked: "Kunci saat ini tidak dipegang",
|
||||
keyHeldBy: "Dipegang oleh Sesi {session}",
|
||||
sessionValue: "Sesi {id}",
|
||||
modifyIndexValue: "ModifyIndex {index}",
|
||||
createIndex: "CreateIndex",
|
||||
modifyIndexLabel: "ModifyIndex",
|
||||
selectSession: "Pilih Sesi",
|
||||
sessionId: "ID Sesi",
|
||||
expectedModifyIndex: "ModifyIndex yang diharapkan (0 untuk kunci baru)",
|
||||
value: "Nilai",
|
||||
releaseMatchingSession: "Lepaskan",
|
||||
acquire: "Ambil",
|
||||
unnamedSession: "Sesi tanpa nama",
|
||||
heldKeys: "Kunci yang dipegang",
|
||||
heldKeysIncomplete: "Hasil tidak lengkap atau terfilter ACL",
|
||||
stop: "Hentikan",
|
||||
renewNow: "Perbarui sekarang",
|
||||
autoRenew: "Perbarui otomatis",
|
||||
autoRenewPageHint: "Pembaruan otomatis hanya berjalan selama koneksi dan halaman ini tetap aktif.",
|
||||
noRenewRequired: "Tidak perlu pembaruan",
|
||||
noTtl: "Tanpa TTL",
|
||||
ttlOptional: "TTL (opsional)",
|
||||
ttlRangeHint: "Biarkan kosong untuk Sesi persisten, atau gunakan 10s–24h.",
|
||||
invalidSessionTtl: "TTL harus kosong atau durasi valid dari 10s hingga 24h.",
|
||||
invalidLockDelay: "Penundaan kunci harus berupa durasi valid dari 0s hingga 60s.",
|
||||
destroy: "Hancurkan",
|
||||
noHeldKeys: "Tidak ada kunci yang dipegang",
|
||||
noVisibleSessions: "Tidak ada Sesi yang terlihat",
|
||||
destroySession: "Hancurkan Sesi {id}? Kunci yang menggunakan Sesi ini dapat dilepaskan atau dihapus oleh Perilakunya.",
|
||||
destroySessionImpact: "Hancurkan Sesi {id}? Perilaku: {behavior}. Kunci yang dipegang ({count}): {keys}",
|
||||
sessionImpactIncomplete: "Dampak Sesi tidak lengkap atau terfilter ACL. Penghancuran diblokir.",
|
||||
sessionDetails: "TTL {ttl} · {behavior} · pemeriksaan {checks}",
|
||||
tokens: "Token",
|
||||
policies: "Kebijakan",
|
||||
roles: "Peran",
|
||||
authMethods: "Metode autentikasi",
|
||||
bindingRules: "Aturan pengikatan",
|
||||
templatedPolicies: "Kebijakan templat",
|
||||
capability: "Kapabilitas: {status}",
|
||||
capabilitySupported: "Didukung",
|
||||
capabilityUnsupported: "Tidak didukung",
|
||||
capabilityDisabled: "Dinonaktifkan",
|
||||
capabilityForbidden: "Tidak ada izin",
|
||||
capabilityUnknown: "Tidak diketahui",
|
||||
loading: "Memuat...",
|
||||
viewOrEdit: "Lihat atau edit",
|
||||
cloneToken: "Klon token",
|
||||
deleteAndInspectReferences: "Hapus dan periksa referensi",
|
||||
noResources: "Tidak ada sumber daya",
|
||||
editResource: "Edit {kind}",
|
||||
createResource: "Buat {kind}",
|
||||
knownImpact: "Dampak yang diketahui: {tokens} token, {roles} peran, {bindingRules} aturan pengikatan",
|
||||
incomplete: "(tidak lengkap)",
|
||||
reviewAclChanges: "Tinjau perubahan ACL",
|
||||
deleteResource: "Hapus {label}",
|
||||
tokenReferences: "Referensi token: {tokens} · Referensi peran: {roles} · Referensi aturan pengikatan: {bindingRules}",
|
||||
impactBlocked: "Dampak tidak lengkap atau terfilter ACL. Penghapusan diblokir.",
|
||||
cloneTokenDescription: "Deskripsi untuk token klon",
|
||||
scope: "Cakupan Consul",
|
||||
adminPartition: "Admin Partition",
|
||||
namespace: "Namespace",
|
||||
default: "default",
|
||||
applyScope: "Terapkan cakupan",
|
||||
enterpriseCapability: "Kapabilitas Enterprise: {status}. Tindakan siklus hidup tidak tersedia.",
|
||||
namespaces: "Namespace",
|
||||
lifecycleImpact: "Dampak sumber daya tercakup",
|
||||
inspectImpactAndDelete: "Periksa dampak dan hapus",
|
||||
impactAclFiltered: "Consul melaporkan hasil yang terfilter ACL; penghapusan diblokir.",
|
||||
impactUnavailable: "Tidak dapat menghitung: {resources}",
|
||||
impactResource: {
|
||||
services: "Layanan",
|
||||
nodes: "Node",
|
||||
kvKeys: "Kunci KV",
|
||||
healthChecks: "Pemeriksaan kesehatan",
|
||||
sessions: "Sesi",
|
||||
configEntries: "Entri konfigurasi",
|
||||
intentions: "Intention",
|
||||
peerings: "Peering",
|
||||
namespaces: "Namespace",
|
||||
aclTokens: "Token ACL",
|
||||
aclPolicies: "Kebijakan ACL",
|
||||
aclRoles: "Peran ACL",
|
||||
aclAuthMethods: "Metode autentikasi ACL",
|
||||
aclBindingRules: "Aturan pengikatan ACL",
|
||||
},
|
||||
configEntries: "Entri Konfigurasi",
|
||||
intentions: "Intention",
|
||||
discoveryChain: "Discovery Chain",
|
||||
peering: "Peering",
|
||||
exportedServices: "Layanan yang diekspor",
|
||||
configEntryKind: "Jenis entri konfigurasi",
|
||||
loadKind: "Muat jenis",
|
||||
newJson: "JSON baru",
|
||||
modifyIndex: "ModifyIndex {index}",
|
||||
rawJson: "JSON mentah",
|
||||
newIntention: "Intention baru",
|
||||
sourceService: "Layanan sumber",
|
||||
destinationService: "Layanan tujuan",
|
||||
check: "Periksa",
|
||||
matchSource: "Cocokkan sumber",
|
||||
matchDestination: "Cocokkan tujuan",
|
||||
allowed: "Diizinkan",
|
||||
denied: "Ditolak",
|
||||
matchedIntentions: "Mencocokkan {count} intention",
|
||||
details: "Detail",
|
||||
serviceName: "Nama layanan",
|
||||
compile: "Kompilasi",
|
||||
defaultProtocol: "protokol default",
|
||||
configuredDatacenter: "datacenter yang dikonfigurasi",
|
||||
start: "Mulai",
|
||||
next: "Berikutnya: {nodes}",
|
||||
terminalTarget: "Terminal / target",
|
||||
upstreamTargets: "Target upstream ({count})",
|
||||
peerName: "Nama peer",
|
||||
peeringToken: "Token peering untuk membangun peering",
|
||||
generateToken: "Buat token",
|
||||
establish: "Bangun",
|
||||
editExportedServices: "Edit entri exported-services",
|
||||
serviceMeshConfigEntry: "Entri konfigurasi Service Mesh",
|
||||
applyWithCas: "Terapkan dengan CAS",
|
||||
reviewMeshChanges: "Tinjau perubahan Service Mesh",
|
||||
deleteConfig: "Hapus {kind}/{name}?",
|
||||
deleteIntention: "Hapus intention {id}?",
|
||||
deleteIntentionExact: "Hapus intention {source} -> {destination}?",
|
||||
deletePeering: "Hapus peering {name}?",
|
||||
permissions: "{count} izin",
|
||||
actionRule: "aturan aksi",
|
||||
tools: "Alat Consul",
|
||||
preparedQueries: "Prepared query",
|
||||
events: "Event",
|
||||
coordinates: "Koordinat jaringan",
|
||||
queryName: "Nama kueri",
|
||||
targetService: "Layanan target",
|
||||
targetServiceValue: "Layanan target: {service}",
|
||||
cancelEdit: "Batalkan edit",
|
||||
execute: "Jalankan",
|
||||
explain: "Jelaskan",
|
||||
eventName: "Nama event",
|
||||
payload: "Payload",
|
||||
fire: "Picu",
|
||||
deletePreparedQuery: "Hapus prepared query {id}?",
|
||||
nodesDatacenter: "{count} node · {datacenter}",
|
||||
coordinateError: "{segment} · galat {error}",
|
||||
preparedQueriesDescription:
|
||||
"Kueri service-discovery yang dapat digunakan ulang dan tersimpan di Consul. Eksekusi me-resolve instansi layanan sehat yang cocok; Jelaskan menampilkan kueri efektif. Editor sederhana hanya mengubah nama dan layanan target, dengan mempertahankan field lanjutan yang sudah tersimpan oleh Consul.",
|
||||
eventsDescription: "Pesan ringan best-effort yang didistribusikan melalui gossip Consul. Event adalah diagnostik atau notifikasi sementara, bukan antrean pesan permanen.",
|
||||
coordinatesDescription: "Koordinat jaringan baca saja yang diestimasi Consul untuk membandingkan kedekatan jaringan. Ini bukan lokasi geografis.",
|
||||
noPreparedQueries: "Tidak ada prepared query",
|
||||
noEvents: "Tidak ada event terbaru",
|
||||
noCoordinates: "Tidak ada koordinat jaringan",
|
||||
queryExecutionResult: "Hasil eksekusi · {count} instansi · {datacenter}",
|
||||
noQueryNodes: "Tidak ada instansi layanan yang cocok dengan kueri ini",
|
||||
queryExplanation: "Kueri efektif",
|
||||
eventNodeFilter: "Regex node (opsional)",
|
||||
eventServiceFilter: "Regex layanan (opsional)",
|
||||
eventTagFilter: "Regex tag (opsional)",
|
||||
eventPayloadBytes: "Payload {count} / 100 byte",
|
||||
segment: "Segmen",
|
||||
error: "Galat",
|
||||
adjustment: "Penyesuaian",
|
||||
height: "Tinggi",
|
||||
operatorReadOnly: "Operator (baca saja)",
|
||||
snapshot: "Snapshot",
|
||||
snapshotRestore: "Pemulihan snapshot",
|
||||
targetDatacenter: "Datacenter target",
|
||||
restoreSnapshot: "Pulihkan snapshot",
|
||||
restoreSnapshotConfirmation: "RESTORE SNAPSHOT {datacenter}",
|
||||
autopilotUpdate: "Pembaruan Autopilot",
|
||||
cleanupDeadServers: "Bersihkan server mati",
|
||||
updateAutopilot: "Perbarui Autopilot",
|
||||
updateAutopilotConfirmation: "UPDATE AUTOPILOT",
|
||||
raftOperations: "Operasi Raft",
|
||||
serverId: "ID server",
|
||||
peerAddress: "Alamat peer (hanya penghapusan)",
|
||||
reenterIdAddress: "Masukkan ulang ID atau alamat",
|
||||
transferLeader: "Transfer leader",
|
||||
removePeer: "Hapus peer",
|
||||
gossipKeyring: "Keyring gossip",
|
||||
operation: "Operasi",
|
||||
install: "Pasang",
|
||||
use: "Gunakan",
|
||||
remove: "Hapus",
|
||||
gossipKey: "Kunci gossip",
|
||||
changeKeyring: "Ubah keyring",
|
||||
changeKeyringConfirmation: "CHANGE KEYRING",
|
||||
licenseUpdate: "Pembaruan lisensi",
|
||||
license: "Lisensi",
|
||||
updateLicense: "Perbarui lisensi",
|
||||
updateLicenseConfirmation: "UPDATE LICENSE",
|
||||
},
|
||||
tools: {
|
||||
search: "Cari",
|
||||
searchTitle: "Cari KV Consul",
|
||||
searchQuery: "Teks yang dicari",
|
||||
prefixOptional: "Prefiks (opsional)",
|
||||
searchAll: "Kunci dan nilai",
|
||||
searchKeys: "Hanya kunci",
|
||||
searchValues: "Hanya nilai",
|
||||
caseSensitive: "Peka huruf besar/kecil",
|
||||
scanned: "Memindai {count} kunci",
|
||||
searchLimited: "Hasil dibatasi untuk melindungi koneksi.",
|
||||
noSearchResults: "Tidak ada kunci yang cocok",
|
||||
searchSummary: "{matched} kecocokan dari {scanned} kunci yang dipindai",
|
||||
exportSearchResults: "Ekspor hasil",
|
||||
searchResultsFileType: "Hasil pencarian KV Consul",
|
||||
searchResultsExported: "{count} hasil pencarian diekspor",
|
||||
exportPrefix: "Ekspor prefiks",
|
||||
prefix: "Prefiks",
|
||||
emptyPrefixAll: "Biarkan kosong untuk semua kunci yang dapat diakses",
|
||||
exportLimitHint: "Ekspor mencakup cakupan saat ini dan mempertahankan metadata kunci yang diperlukan untuk impor yang aman.",
|
||||
exported: "{count} kunci diekspor",
|
||||
import: "Impor",
|
||||
importTitle: "Impor paket KV Consul",
|
||||
invalidBundle: "Berkas ini bukan paket KV Consul DBX yang valid",
|
||||
importApplied: "{count} kunci diimpor",
|
||||
migrate: "Migrasikan",
|
||||
migrateTitle: "Migrasikan KV Consul",
|
||||
sourcePrefix: "Prefiks sumber",
|
||||
targetConnection: "Koneksi target",
|
||||
selectTarget: "Pilih koneksi target",
|
||||
targetReadOnly: "Koneksi target bersifat baca saja.",
|
||||
conflictPolicy: "Kebijakan konflik",
|
||||
policyAbort: "Batalkan saat konflik",
|
||||
policySkip: "Lewati konflik",
|
||||
policyCas: "Gunakan CAS",
|
||||
bundleSummary: "{count} kunci · Datacenter {dc} · Namespace {ns} · Partition {partition}",
|
||||
creates: "Buat {count}",
|
||||
updates: "Perbarui {count}",
|
||||
unchanged: "Tidak berubah {count}",
|
||||
skipped: "Dilewati {count}",
|
||||
conflicts: "Konflik {count}",
|
||||
loadPreview: "Muat pratinjau",
|
||||
loadingPreview: "Memuat pratinjau...",
|
||||
apply: "Terapkan",
|
||||
preview: "Pratinjau",
|
||||
deletePrefix: "Hapus prefiks",
|
||||
deletePrefixTitle: "Hapus prefiks KV Consul",
|
||||
deletePrefixPlaceholder: "Prefiks yang akan dihapus",
|
||||
deletePrefixWarning: "Operasi ini menghapus setiap kunci yang terlihat di bawah prefiks. Tinjau pratinjau sebelum mengonfirmasi.",
|
||||
candidates: "Kandidat {count}",
|
||||
lockedCount: "Terkunci {count}",
|
||||
filtered: "terfilter",
|
||||
complete: "lengkap",
|
||||
confirmDeletePrefix: "Hapus kunci yang dikonfirmasi",
|
||||
prefixDeleted: "{count} kunci dihapus",
|
||||
operation: { create: "Buat", update: "Perbarui", unchanged: "Tidak berubah", skipped: "Dilewati", conflict: "Konflik", locked: "Terkunci", succeeded: "Berhasil", conflicted: "Konflik", failed: "Gagal" },
|
||||
},
|
||||
} satisfies ConsulMessages;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@ export const LOCALE_OPTIONS: { value: Locale; flag: string; label: string }[] =
|
||||
{ value: "en", flag: "🇺🇸", label: "English" },
|
||||
{ value: "az", flag: "🇦🇿", label: "Azərbaycan" },
|
||||
{ value: "es", flag: "🇪🇸", label: "Español" },
|
||||
{ value: "id", flag: "🇮🇩", label: "Bahasa Indonesia" },
|
||||
{ value: "it", flag: "🇮🇹", label: "Italiano" },
|
||||
{ value: "ja", flag: "🇯🇵", label: "日本語" },
|
||||
{ value: "ko", flag: "🇰🇷", label: "한국어" },
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ const runtimeHost = readFileSync("apps/desktop/src/components/sidebar/SidebarTre
|
||||
const connectionMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarConnectionMutationRuntime.ts", "utf8");
|
||||
const databaseSpecificMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarDatabaseSpecificMutationRuntime.ts", "utf8");
|
||||
const tableMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarTableMutationRuntime.ts", "utf8");
|
||||
const localeSources = Object.fromEntries(["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")]));
|
||||
const localeSources = Object.fromEntries(["az", "en", "es", "id", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")]));
|
||||
|
||||
function functionBody(name: string): string {
|
||||
const source = [runtimeHost, connectionMutationRuntime, databaseSpecificMutationRuntime, tableMutationRuntime].find((candidate) => candidate.includes(`function ${name}(`));
|
||||
|
||||
@@ -730,6 +730,7 @@ enum LocaleFamily {
|
||||
Japanese,
|
||||
Korean,
|
||||
Spanish,
|
||||
Indonesian,
|
||||
Italian,
|
||||
Portuguese,
|
||||
Russian,
|
||||
@@ -759,6 +760,8 @@ fn locale_family(locale: &str) -> LocaleFamily {
|
||||
LocaleFamily::Azerbaijani
|
||||
} else if is_language("es") {
|
||||
LocaleFamily::Spanish
|
||||
} else if is_language("id") {
|
||||
LocaleFamily::Indonesian
|
||||
} else if is_language("tr") {
|
||||
LocaleFamily::Turkish
|
||||
} else if is_language("it") {
|
||||
@@ -780,6 +783,7 @@ fn tray_menu_labels_for_locale(locale: &str) -> (&'static str, &'static str) {
|
||||
LocaleFamily::Korean => ("DBX 표시", "DBX 종료"),
|
||||
LocaleFamily::Azerbaijani => ("DBX-i göstər", "DBX-dən çıx"),
|
||||
LocaleFamily::Spanish => ("Mostrar DBX", "Salir de DBX"),
|
||||
LocaleFamily::Indonesian => ("Tampilkan DBX", "Keluar dari DBX"),
|
||||
LocaleFamily::Italian => ("Mostra DBX", "Esci da DBX"),
|
||||
LocaleFamily::Turkish => ("DBX'i Göster", "DBX'ten Çık"),
|
||||
LocaleFamily::Portuguese => ("Mostrar DBX", "Sair do DBX"),
|
||||
@@ -798,6 +802,7 @@ fn app_menu_copy_support_info_label(locale: &str) -> &'static str {
|
||||
LocaleFamily::Korean => "지원 정보 복사",
|
||||
LocaleFamily::Azerbaijani => "Dəstək məlumatlarını kopyala",
|
||||
LocaleFamily::Spanish => "Copiar información",
|
||||
LocaleFamily::Indonesian => "Salin Info Dukungan",
|
||||
LocaleFamily::Italian => "Copia informazioni",
|
||||
LocaleFamily::Turkish => "Destek bilgilerini kopyala",
|
||||
LocaleFamily::Portuguese => "Copiar informações",
|
||||
@@ -815,6 +820,7 @@ fn app_menu_close_tab_label(locale: &str) -> &'static str {
|
||||
LocaleFamily::Korean => "탭 닫기",
|
||||
LocaleFamily::Azerbaijani => "Vərəqi bağla",
|
||||
LocaleFamily::Spanish => "Cerrar pestaña",
|
||||
LocaleFamily::Indonesian => "Tutup Tab",
|
||||
LocaleFamily::Italian => "Chiudi scheda",
|
||||
LocaleFamily::Turkish => "Sekmeyi kapat",
|
||||
LocaleFamily::Portuguese => "Fechar aba",
|
||||
@@ -831,6 +837,7 @@ fn app_menu_quit_label(locale: &str, app_name: &str) -> String {
|
||||
LocaleFamily::Korean => format!("{app_name} 종료"),
|
||||
LocaleFamily::Azerbaijani => format!("{app_name}-dən çıx"),
|
||||
LocaleFamily::Spanish => format!("Salir de {app_name}"),
|
||||
LocaleFamily::Indonesian => format!("Keluar dari {app_name}"),
|
||||
LocaleFamily::Italian => format!("Esci da {app_name}"),
|
||||
LocaleFamily::Turkish => format!("{app_name} Uygulamasından Çık"),
|
||||
LocaleFamily::Portuguese => format!("Sair do {app_name}"),
|
||||
@@ -1044,6 +1051,7 @@ mod tests {
|
||||
assert_eq!(tray_menu_labels_for_locale("ko-KR"), ("DBX 표시", "DBX 종료"));
|
||||
assert_eq!(tray_menu_labels_for_locale("az-AZ"), ("DBX-i göstər", "DBX-dən çıx"));
|
||||
assert_eq!(tray_menu_labels_for_locale("es-ES"), ("Mostrar DBX", "Salir de DBX"));
|
||||
assert_eq!(tray_menu_labels_for_locale("id-ID"), ("Tampilkan DBX", "Keluar dari DBX"));
|
||||
assert_eq!(tray_menu_labels_for_locale("it-IT"), ("Mostra DBX", "Esci da DBX"));
|
||||
assert_eq!(tray_menu_labels_for_locale("pt-BR"), ("Mostrar DBX", "Sair do DBX"));
|
||||
assert_eq!(tray_menu_labels_for_locale("tr-TR"), ("DBX'i Göster", "DBX'ten Çık"));
|
||||
@@ -1063,6 +1071,7 @@ mod tests {
|
||||
assert_eq!(app_menu_quit_label("tr-TR", "DBX"), "DBX Uygulamasından Çık");
|
||||
assert_eq!(app_menu_quit_label("ru-RU", "DBX"), "Выйти из DBX");
|
||||
assert_eq!(app_menu_quit_label("az-AZ", "DBX"), "DBX-dən çıx");
|
||||
assert_eq!(app_menu_quit_label("id-ID", "DBX"), "Keluar dari DBX");
|
||||
assert_eq!(app_menu_quit_label("en-US", "DBX"), "Quit DBX");
|
||||
assert_eq!(app_menu_quit_label("", "DBX"), "Quit DBX");
|
||||
assert_eq!(app_menu_copy_support_info_label("zh-CN"), "复制支持信息");
|
||||
@@ -1071,6 +1080,7 @@ mod tests {
|
||||
assert_eq!(app_menu_copy_support_info_label("tr-TR"), "Destek bilgilerini kopyala");
|
||||
assert_eq!(app_menu_copy_support_info_label("ru-RU"), "Копировать сведения о поддержке");
|
||||
assert_eq!(app_menu_copy_support_info_label("az-AZ"), "Dəstək məlumatlarını kopyala");
|
||||
assert_eq!(app_menu_copy_support_info_label("id-ID"), "Salin Info Dukungan");
|
||||
assert_eq!(app_menu_copy_support_info_label("en-US"), "Copy Support Info");
|
||||
assert_eq!(app_menu_close_tab_label("zh-CN"), "关闭标签页");
|
||||
assert_eq!(app_menu_close_tab_label("zh-TW"), "關閉分頁");
|
||||
|
||||
Reference in New Issue
Block a user