feat: add i18n framework with Indonesian translation support (#124)
* feat: add i18n support with separate translation files - Extract translations from store.js to separate files for easier management - Add translation files for English (en.js), Indonesian (id.js), Turkish (tr.js), and Chinese (zh.js) - Load translations via window.translations object before Alpine store initialization - Add Bahasa Indonesia option to language selector * feat: translate remaining hardcoded UI strings - Update index.html to use t() for Menu and GitHub labels - Update views to translate Tier, Quota, Live, tier badges, and close button - Update components to use translated error messages and confirmation dialogs - Update utils to use translated validation and error messages - Update app-init.js to use translated OAuth success/error messages
This commit is contained in:
committed by
GitHub
parent
9ffb83ab74
commit
e2d03f9b25
371
public/js/translations/id.js
Normal file
371
public/js/translations/id.js
Normal file
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
* Indonesian (Bahasa Indonesia) Translations
|
||||
*
|
||||
* Panduan Terminologi IT:
|
||||
* - Istilah teknis umum tetap dalam bahasa Inggris (OAuth, API, token, proxy, debug, cache, dll.)
|
||||
* - Istilah UI umum diterjemahkan (Simpan, Hapus, Batal, dll.)
|
||||
* - Pesan error dan status menggunakan campuran yang konsisten
|
||||
*/
|
||||
window.translations = window.translations || {};
|
||||
window.translations.id = {
|
||||
// Navigation
|
||||
dashboard: "Dashboard",
|
||||
models: "Model",
|
||||
accounts: "Akun",
|
||||
logs: "Log",
|
||||
settings: "Pengaturan",
|
||||
|
||||
// Status
|
||||
online: "ONLINE",
|
||||
offline: "OFFLINE",
|
||||
totalAccounts: "TOTAL AKUN",
|
||||
active: "AKTIF",
|
||||
operational: "Berjalan Normal",
|
||||
rateLimited: "DIBATASI",
|
||||
quotasDepleted: "{count}/{total} Kuota Habis",
|
||||
quotasDepletedTitle: "KUOTA HABIS",
|
||||
outOfTracked: "Dari {total} Terpantau",
|
||||
cooldown: "Cooldown",
|
||||
|
||||
// Search & Filters
|
||||
searchPlaceholder: "Cari model...",
|
||||
allAccounts: "Semua Akun",
|
||||
stat: "STATUS",
|
||||
modelIdentity: "IDENTITAS MODEL",
|
||||
globalQuota: "KUOTA GLOBAL",
|
||||
nextReset: "RESET BERIKUTNYA",
|
||||
distribution: "DISTRIBUSI AKUN",
|
||||
|
||||
// System Configuration
|
||||
systemConfig: "Konfigurasi Sistem",
|
||||
language: "Bahasa",
|
||||
pollingInterval: "Interval Polling",
|
||||
maxDisplayLogs: "Maks. Log Ditampilkan",
|
||||
showExhausted: "Tampilkan Model Habis",
|
||||
showExhaustedDesc: "Tampilkan model meskipun kuotanya sudah 0%.",
|
||||
compactMode: "Mode Ringkas",
|
||||
compactModeDesc: "Tampilan tabel lebih padat untuk informasi lebih banyak.",
|
||||
saveChanges: "Simpan Perubahan",
|
||||
|
||||
// Logs
|
||||
autoScroll: "Auto-scroll",
|
||||
clearLogs: "Hapus Log",
|
||||
|
||||
// Account Management
|
||||
accountManagement: "Kelola Akun",
|
||||
manageTokens: "Kelola token akun Google dan status otorisasi",
|
||||
addAccount: "Tambah Akun",
|
||||
status: "STATUS",
|
||||
enabled: "AKTIF",
|
||||
health: "STATUS",
|
||||
accountEmail: "AKUN (EMAIL)",
|
||||
source: "SUMBER",
|
||||
projectId: "PROJECT ID",
|
||||
sessionState: "STATUS SESI",
|
||||
operations: "AKSI",
|
||||
delete: "Hapus",
|
||||
confirmDelete: "Yakin ingin menghapus akun ini?",
|
||||
cannotDeleteDatabase: "Tidak bisa dihapus: Akun ini dari database Antigravity (read-only)",
|
||||
connectGoogle: "Hubungkan Akun Google",
|
||||
reauthenticated: "diautentikasi ulang",
|
||||
added: "ditambahkan",
|
||||
successfully: "berhasil",
|
||||
accountAddedSuccess: "Akun berhasil ditambahkan",
|
||||
accountReauthSuccess: "Akun berhasil diautentikasi ulang",
|
||||
failedToGetAuthUrl: "Gagal mendapatkan URL autentikasi",
|
||||
failedToStartOAuth: "Gagal memulai proses OAuth",
|
||||
oauthInProgress: "Proses OAuth sedang berjalan. Silakan selesaikan autentikasi di jendela popup...",
|
||||
family: "Jenis",
|
||||
model: "Model",
|
||||
activeSuffix: "Aktif",
|
||||
manualReload: "Muat Ulang Konfigurasi",
|
||||
|
||||
// Tabs
|
||||
tabInterface: "Tampilan",
|
||||
tabClaude: "Claude CLI",
|
||||
tabModels: "Model",
|
||||
tabServer: "Server",
|
||||
|
||||
// Dashboard
|
||||
linkedAccounts: "Akun Terhubung",
|
||||
noSignal: "TIDAK ADA SINYAL",
|
||||
establishingUplink: "MENGHUBUNGKAN...",
|
||||
goToAccounts: "Lihat Akun",
|
||||
|
||||
// Settings - Models
|
||||
modelsDesc: "Atur visibilitas model, pin, dan routing request.",
|
||||
modelsPageDesc: "Kuota dan status real-time untuk semua model yang tersedia.",
|
||||
showHidden: "Tampilkan Model Tersembunyi",
|
||||
hideHidden: "Sembunyikan Model Tersembunyi",
|
||||
hiddenOn: "Tersembunyi: YA",
|
||||
hiddenOff: "Tersembunyi: TIDAK",
|
||||
modelId: "ID Model",
|
||||
actions: "Aksi",
|
||||
pinToTop: "Pin ke atas",
|
||||
toggleVisibility: "Tampilkan/Sembunyikan",
|
||||
noModels: "MODEL TIDAK DITEMUKAN",
|
||||
modelMappingHint: "Routing model di sisi server. Pengguna Claude Code: lihat tab 'Claude CLI' untuk pengaturan di sisi klien.",
|
||||
modelMapping: "Mapping (Target Model ID)",
|
||||
|
||||
// Settings - Claude
|
||||
proxyConnection: "Koneksi Proxy",
|
||||
modelSelection: "Pilihan Model",
|
||||
defaultModelAliases: "ALIAS MODEL DEFAULT",
|
||||
opusAlias: "Alias Opus",
|
||||
sonnetAlias: "Alias Sonnet",
|
||||
haikuAlias: "Alias Haiku",
|
||||
claudeSettingsAlertPrefix: "Pengaturan di bawah langsung mengubah",
|
||||
claudeSettingsAlertSuffix: "Restart Claude CLI untuk menerapkan.",
|
||||
applyToClaude: "Simpan ke Claude CLI",
|
||||
|
||||
// Presets
|
||||
configPresets: "Preset Konfigurasi",
|
||||
saveAsPreset: "Simpan sebagai Preset",
|
||||
deletePreset: "Hapus Preset",
|
||||
loadPreset: "Muat preset",
|
||||
load: "Muat",
|
||||
presetHint: "Pilih preset untuk dimuat. Klik \"Simpan ke Claude CLI\" untuk menyimpan.",
|
||||
presetLoaded: "Preset dimuat. Klik \"Simpan ke Claude CLI\" untuk menyimpan.",
|
||||
presetSaved: "Preset tersimpan",
|
||||
presetDeleted: "Preset terhapus",
|
||||
unsavedChangesTitle: "Ada Perubahan Belum Disimpan",
|
||||
unsavedChangesMessage: "Konfigurasi saat ini tidak cocok dengan preset tersimpan. Jika beralih, perubahan akan hilang.",
|
||||
loadAnyway: "Tetap Muat",
|
||||
savePresetTitle: "Simpan Preset",
|
||||
savePresetDesc: "Simpan konfigurasi saat ini sebagai preset.",
|
||||
presetName: "Nama Preset",
|
||||
presetNamePlaceholder: "contoh: Setup Kantor",
|
||||
savePreset: "Simpan Preset",
|
||||
|
||||
// Settings - Server
|
||||
port: "Port",
|
||||
uiVersion: "Versi UI",
|
||||
debugMode: "Mode Debug",
|
||||
environment: "Environment",
|
||||
serverReadOnly: "Pengaturan dikelola melalui config.json. Restart server untuk menerapkan.",
|
||||
advancedSettings: "Pengaturan Lanjutan",
|
||||
reloadConfigTitle: "Muat Ulang Konfigurasi Akun",
|
||||
reloadConfigDesc: "Paksa muat ulang accounts.json dari disk",
|
||||
reload: "Muat Ulang",
|
||||
|
||||
// Config Specific
|
||||
primaryModel: "Model Utama",
|
||||
subAgentModel: "Model Sub-agent",
|
||||
advancedOverrides: "Timpa Model Default",
|
||||
opusModel: "Model Opus",
|
||||
sonnetModel: "Model Sonnet",
|
||||
haikuModel: "Model Haiku",
|
||||
authToken: "Token Auth",
|
||||
saveConfig: "Simpan ke Claude CLI",
|
||||
envVar: "Env",
|
||||
|
||||
// System
|
||||
systemName: "ANTIGRAVITY",
|
||||
systemDesc: "CLAUDE PROXY SYSTEM",
|
||||
connectGoogleDesc: "Hubungkan akun Google Workspace untuk meningkatkan kuota API. Akun akan digunakan untuk meneruskan request Claude via Antigravity.",
|
||||
useCliCommand: "Gunakan Perintah CLI",
|
||||
close: "Tutup",
|
||||
requestVolume: "Volume Request",
|
||||
filter: "Filter",
|
||||
all: "Semua",
|
||||
none: "Tidak Ada",
|
||||
noDataTracked: "Belum ada data tercatat",
|
||||
selectFamilies: "Pilih jenis model untuk ditampilkan",
|
||||
selectModels: "Pilih model untuk ditampilkan",
|
||||
noLogsMatch: "Tidak ada log yang sesuai filter",
|
||||
connecting: "MENGHUBUNGKAN",
|
||||
main: "Utama",
|
||||
system: "Sistem",
|
||||
refreshData: "Refresh Data",
|
||||
connectionLost: "Koneksi Terputus",
|
||||
lastUpdated: "Terakhir Diperbarui",
|
||||
grepLogs: "cari log...",
|
||||
noMatchingModels: "Tidak ada model yang cocok",
|
||||
typeToSearch: "Ketik untuk mencari...",
|
||||
or: "ATAU",
|
||||
|
||||
// Account Operations
|
||||
refreshingAccount: "Memperbarui {email}...",
|
||||
refreshedAccount: "{email} berhasil diperbarui",
|
||||
refreshFailed: "Gagal memperbarui",
|
||||
accountToggled: "Akun {email} {status}",
|
||||
toggleFailed: "Gagal mengubah status",
|
||||
reauthenticating: "Autentikasi ulang {email}...",
|
||||
authUrlFailed: "Gagal mendapatkan URL autentikasi",
|
||||
deletedAccount: "{email} berhasil dihapus",
|
||||
deleteFailed: "Gagal menghapus",
|
||||
accountsReloaded: "Akun berhasil dimuat ulang",
|
||||
reloadFailed: "Gagal memuat ulang",
|
||||
|
||||
// Claude Config
|
||||
claudeConfigSaved: "Konfigurasi Claude tersimpan",
|
||||
claudeConfigRestored: "Claude CLI dikembalikan ke default",
|
||||
saveConfigFailed: "Gagal menyimpan konfigurasi",
|
||||
restoreConfigFailed: "Gagal mengembalikan konfigurasi",
|
||||
restoreDefault: "Reset ke Default",
|
||||
confirmRestoreTitle: "Konfirmasi Reset",
|
||||
confirmRestoreMessage: "Yakin ingin mengembalikan Claude CLI ke pengaturan default? Konfigurasi proxy akan dihapus.",
|
||||
confirmRestore: "Ya, Reset",
|
||||
|
||||
// Status Labels
|
||||
claudeActive: "Claude Aktif",
|
||||
claudeEmpty: "Claude Kosong",
|
||||
geminiActive: "Gemini Aktif",
|
||||
geminiEmpty: "Gemini Kosong",
|
||||
synced: "SINKRON",
|
||||
syncing: "SINKRONISASI...",
|
||||
|
||||
// Time range labels
|
||||
last1Hour: "1 Jam Terakhir",
|
||||
last6Hours: "6 Jam Terakhir",
|
||||
last24Hours: "24 Jam Terakhir",
|
||||
last7Days: "7 Hari Terakhir",
|
||||
allTime: "Semua Waktu",
|
||||
groupBy: "Kelompokkan",
|
||||
|
||||
// Additional
|
||||
reloading: "Memuat ulang...",
|
||||
reloaded: "Dimuat ulang",
|
||||
lines: "baris",
|
||||
enabledSeeLogs: "Aktif (Lihat Log)",
|
||||
production: "Produksi",
|
||||
configSaved: "Konfigurasi Tersimpan",
|
||||
enterPassword: "Masukkan Password Web UI:",
|
||||
ready: "SIAP",
|
||||
depleted: "Habis",
|
||||
timeH: "j",
|
||||
timeM: "m",
|
||||
familyClaude: "Claude",
|
||||
familyGemini: "Gemini",
|
||||
familyOther: "Lainnya",
|
||||
enabledStatus: "diaktifkan",
|
||||
disabledStatus: "dinonaktifkan",
|
||||
logLevelInfo: "INFO",
|
||||
logLevelSuccess: "OK",
|
||||
logLevelWarn: "WARN",
|
||||
logLevelError: "ERROR",
|
||||
totalColon: "Total:",
|
||||
todayColon: "Hari Ini:",
|
||||
hour1Colon: "1j:",
|
||||
frequentModels: "Sering Dipakai",
|
||||
smartTitle: "Otomatis pilih 5 model paling sering dipakai (24 jam)",
|
||||
activeCount: "{count} Aktif",
|
||||
allCaps: "SEMUA",
|
||||
claudeCaps: "CLAUDE",
|
||||
geminiCaps: "GEMINI",
|
||||
|
||||
// System Info
|
||||
systemInfo: "Informasi Sistem",
|
||||
refresh: "Refresh",
|
||||
runtimeConfig: "Konfigurasi Runtime",
|
||||
debugDesc: "Aktifkan log detail (Lihat tab Log)",
|
||||
networkRetry: "Pengaturan Retry Jaringan",
|
||||
maxRetries: "Maks. Retry",
|
||||
retryBaseDelay: "Jeda Awal Retry (ms)",
|
||||
retryMaxDelay: "Jeda Maks. Retry (ms)",
|
||||
persistentSessions: "Sesi Persisten",
|
||||
persistTokenDesc: "Simpan sesi OAuth ke disk agar startup lebih cepat",
|
||||
rateLimiting: "Rate Limiting & Timeout Akun",
|
||||
defaultCooldown: "Cooldown Default",
|
||||
defaultCooldownDesc: "Cooldown bawaan jika API tidak memberikan waktu reset.",
|
||||
maxWaitThreshold: "Batas Tunggu Maksimal",
|
||||
maxWaitDesc: "Jika semua akun terkena rate limit lebih lama dari ini, langsung gagal.",
|
||||
saveConfigServer: "Simpan Konfigurasi",
|
||||
serverRestartAlert: "Tersimpan ke {path}. Restart server untuk menerapkan.",
|
||||
|
||||
// Password
|
||||
changePassword: "Ubah Password WebUI",
|
||||
changePasswordDesc: "Ubah password untuk akses dashboard ini",
|
||||
currentPassword: "Password Saat Ini",
|
||||
newPassword: "Password Baru",
|
||||
confirmNewPassword: "Konfirmasi Password Baru",
|
||||
passwordEmptyDesc: "Kosongkan jika belum ada password",
|
||||
passwordLengthDesc: "Minimal 6 karakter",
|
||||
passwordConfirmDesc: "Masukkan ulang password baru",
|
||||
cancel: "Batal",
|
||||
passwordsNotMatch: "Password tidak cocok",
|
||||
passwordTooShort: "Password minimal 6 karakter",
|
||||
|
||||
// Dashboard drill-down
|
||||
clickToViewAllAccounts: "Klik untuk lihat semua akun",
|
||||
clickToViewModels: "Klik untuk lihat halaman Model",
|
||||
clickToViewLimitedAccounts: "Klik untuk lihat akun yang dibatasi",
|
||||
clickToFilterClaude: "Klik untuk filter model Claude",
|
||||
clickToFilterGemini: "Klik untuk filter model Gemini",
|
||||
|
||||
// Accounts page
|
||||
searchAccounts: "Cari akun...",
|
||||
noAccountsYet: "Belum Ada Akun",
|
||||
noAccountsDesc: "Mulai dengan menambahkan akun Google via OAuth, atau gunakan perintah CLI untuk import kredensial.",
|
||||
addFirstAccount: "Tambah Akun Pertama",
|
||||
noSearchResults: "Tidak ada akun yang cocok",
|
||||
clearSearch: "Reset Pencarian",
|
||||
disabledAccountsNote: "<strong>Akun nonaktif</strong> tidak akan digunakan untuk routing tapi tetap tersimpan di konfigurasi. Statistik dashboard hanya mencakup akun aktif.",
|
||||
dangerousOperation: "⚠️ Operasi Berbahaya",
|
||||
confirmDeletePrompt: "Yakin ingin menghapus akun",
|
||||
deleteWarning: "⚠️ Tindakan ini tidak bisa dibatalkan. Semua pengaturan dan riwayat akan dihapus permanen.",
|
||||
|
||||
// OAuth progress
|
||||
oauthWaiting: "Menunggu otorisasi OAuth...",
|
||||
oauthWaitingDesc: "Silakan selesaikan autentikasi di jendela popup. Proses ini bisa memakan waktu hingga 2 menit.",
|
||||
oauthCancelled: "Otorisasi OAuth dibatalkan",
|
||||
oauthTimeout: "⏱️ Waktu otorisasi OAuth habis. Silakan coba lagi.",
|
||||
oauthWindowClosed: "Jendela OAuth ditutup. Otorisasi mungkin tidak lengkap.",
|
||||
cancelOAuth: "Batal",
|
||||
|
||||
// MCP CLI & Gemini 1M
|
||||
mcpCliExperimental: "MCP CLI (Eksperimental)",
|
||||
mcpCliDesc: "Aktifkan integrasi MCP eksperimental untuk penggunaan tool yang lebih stabil dengan konsumsi konteks lebih rendah.",
|
||||
gemini1mMode: "Mode Konteks Gemini 1M",
|
||||
gemini1mDesc: "Tambahkan suffix [1m] ke model Gemini untuk context window 1M.",
|
||||
gemini1mWarning: "⚠ Konteks besar dapat menurunkan performa Gemini-3-Pro.",
|
||||
clickToSet: "Klik untuk atur...",
|
||||
|
||||
// Quota Distribution
|
||||
quotaDistribution: "Distribusi Kuota",
|
||||
resetsIn: "Reset dalam {time}",
|
||||
noQuotaData: "Data kuota belum tersedia untuk akun ini.",
|
||||
|
||||
// Completed TODOs
|
||||
pageTitle: "Antigravity Console",
|
||||
live: "Live",
|
||||
tier: "Tier",
|
||||
quota: "Kuota",
|
||||
tierUltra: "Ultra",
|
||||
tierPro: "Pro",
|
||||
tierFree: "Gratis",
|
||||
menu: "Menu",
|
||||
github: "GitHub",
|
||||
noData: "Tidak ada data",
|
||||
fix: "Perbaiki",
|
||||
|
||||
// Error Messages
|
||||
operationFailed: "Operasi gagal",
|
||||
unknownError: "Error tidak diketahui",
|
||||
presetNameRequired: "Nama preset wajib diisi",
|
||||
saveFailed: "Gagal menyimpan",
|
||||
failedToSavePreset: "Gagal menyimpan preset",
|
||||
noPresetSelected: "Tidak ada preset dipilih",
|
||||
deletePresetConfirm: "Hapus preset \"{name}\"?",
|
||||
deleteFailed: "Gagal menghapus",
|
||||
failedToDeletePreset: "Gagal menghapus preset",
|
||||
failedToChangePassword: "Gagal mengubah password",
|
||||
passwordChangedSuccess: "Password berhasil diubah",
|
||||
debugModeToggled: "Mode debug {status}",
|
||||
tokenCacheToggled: "Cache token {status}",
|
||||
failedToUpdateTokenCache: "Gagal memperbarui cache token",
|
||||
failedToUpdateDebugMode: "Gagal memperbarui mode debug",
|
||||
failedToRefreshAccount: "Gagal memperbarui akun",
|
||||
failedToDeleteAccount: "Gagal menghapus akun",
|
||||
failedToReloadAccounts: "Gagal memuat ulang akun",
|
||||
failedToUpdateModelConfig: "Gagal memperbarui konfigurasi model",
|
||||
fieldUpdated: "{displayName} diubah menjadi {value}",
|
||||
failedToUpdateField: "Gagal memperbarui {displayName}",
|
||||
|
||||
// Validation
|
||||
mustBeValidNumber: "{fieldName} harus berupa angka valid",
|
||||
mustBeAtLeast: "{fieldName} minimal {min}",
|
||||
mustBeAtMost: "{fieldName} maksimal {max}",
|
||||
cannotBeEmpty: "{fieldName} tidak boleh kosong",
|
||||
mustBeTrueOrFalse: "Nilai harus true atau false",
|
||||
};
|
||||
Reference in New Issue
Block a user