feat(i18n): add multi-language support (ja/ko/vi/ru/zh-TW) with system auto-detection
- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru - Auto-detect system language via navigator.languages; fallback to English - Add BCP47 locale mapping for date formatting and sorting - Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each) - Update language selector with native language names - Extend locale key parity test to cover all 7 languages (70 assertions) - Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features - Add credential encryption, host metrics, session backup crypto, and zmodem bridge - Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
This commit is contained in:
1 parent
fea6d8db04
commit
b0d0e3a5f3
301 files changed
+28002
-2705
No files matched your search
@@ -0,0 +1,237 @@
|
||||
{
|
||||
"sidebar": {
|
||||
"quickConnect": "Quick connect",
|
||||
"quickConnectShort": "Connect",
|
||||
"newSession": "New session",
|
||||
"newSessionShort": "New",
|
||||
"searchPlaceholder": "Search sessions...",
|
||||
"batchMode": "Batch actions",
|
||||
"exitBatchMode": "Exit batch mode",
|
||||
"batchSelected": "{{count}} SSH selected",
|
||||
"batchExcludedDesktop": " · RDP/VNC excluded",
|
||||
"selectAllVisible": "Select all in view",
|
||||
"deselectAllVisible": "Clear selection in view",
|
||||
"batchExec": "Batch exec",
|
||||
"settings": "Settings",
|
||||
"resizeHint": "Drag to resize; double-click to collapse"
|
||||
},
|
||||
"tree": {
|
||||
"selectSession": "Select session",
|
||||
"noMatchTitle": "No matching sessions",
|
||||
"noMatchDesc": "Try a different keyword",
|
||||
"emptyTitle": "No sessions yet",
|
||||
"emptyDesc": "Quick connect or create a session; double-click to open a terminal",
|
||||
"emptyAction": "New session"
|
||||
},
|
||||
"contextMenu": {
|
||||
"blank": {
|
||||
"newGroup": "New group",
|
||||
"newSession": "New session"
|
||||
},
|
||||
"group": {
|
||||
"newSessionHere": "New session here",
|
||||
"newGroup": "New group",
|
||||
"renameGroup": "Rename group",
|
||||
"deleteEmptyGroup": "Delete empty group"
|
||||
},
|
||||
"session": {
|
||||
"open": "Open",
|
||||
"edit": "Edit",
|
||||
"duplicate": "Duplicate",
|
||||
"delete": "Delete"
|
||||
}
|
||||
},
|
||||
"groups": {
|
||||
"default": "Default",
|
||||
"new": {
|
||||
"title": "New group",
|
||||
"message": "Enter a group name",
|
||||
"placeholder": "e.g. Production",
|
||||
"confirm": "Create"
|
||||
},
|
||||
"rename": {
|
||||
"title": "Rename group",
|
||||
"message": "Rename \"{{name}}\" to",
|
||||
"placeholder": "Group name",
|
||||
"confirm": "Save"
|
||||
},
|
||||
"deleteBlocked": {
|
||||
"title": "Cannot delete",
|
||||
"message": "Group \"{{name}}\" still has sessions. Move or delete them first.",
|
||||
"confirm": "Got it"
|
||||
},
|
||||
"newOption": "New group…",
|
||||
"hint": "Default group is used unless you pick or create another"
|
||||
},
|
||||
"deleteSession": {
|
||||
"title": "Delete session",
|
||||
"message": "Delete session \"{{name}}\"?",
|
||||
"confirm": "Delete"
|
||||
},
|
||||
"welcome": {
|
||||
"tagline": "Remote terminal · SFTP · Port forwarding",
|
||||
"sectionStart": "Get started",
|
||||
"sectionDesktop": "Remote desktop",
|
||||
"sectionRecent": "Recent sessions",
|
||||
"quickConnect": {
|
||||
"title": "Quick connect",
|
||||
"desc": "One-off SSH; not saved to the library"
|
||||
},
|
||||
"newSession": {
|
||||
"title": "New session",
|
||||
"desc": "Save hosts; double-click in the sidebar to connect"
|
||||
},
|
||||
"localShell": {
|
||||
"title": "Local shell",
|
||||
"selectShell": "Choose shell",
|
||||
"default": "Default"
|
||||
},
|
||||
"rdp": {
|
||||
"title": "RDP remote desktop",
|
||||
"desc": "Windows · NLA / CredSSP"
|
||||
},
|
||||
"vnc": {
|
||||
"title": "VNC remote desktop",
|
||||
"desc": "RFB · cross-platform graphical session"
|
||||
},
|
||||
"recentEmpty": {
|
||||
"title": "No saved sessions",
|
||||
"desc": "Try quick connect, or create a session to reuse later"
|
||||
}
|
||||
},
|
||||
"launcher": {
|
||||
"searchPlaceholder": "Search hosts, groups, or tabs"
|
||||
},
|
||||
"quickConnect": {
|
||||
"title": "Quick connect",
|
||||
"target": "Target",
|
||||
"targetPlaceholder": "root@192.168.1.10:22",
|
||||
"targetHint": "Supports host, user@host, user@host:port",
|
||||
"password": "Password",
|
||||
"passwordOptional": "Optional · leave empty when using a key",
|
||||
"connect": "Connect",
|
||||
"errorInvalidTarget": "Enter a host, e.g. root@192.168.1.10 or opsbase.cn:5555",
|
||||
"errorConnectFailed": "Connection failed"
|
||||
},
|
||||
"dialog": {
|
||||
"create": "New session",
|
||||
"edit": "Edit session",
|
||||
"subtitle": "One-line target · advanced options collapsed",
|
||||
"saving": "Saving…",
|
||||
"save": "Save",
|
||||
"createAndSave": "Create and save",
|
||||
"basic": "Basic",
|
||||
"login": "Sign-in",
|
||||
"advanced": "Advanced",
|
||||
"advancedCollapsed": "Proxy · jump host · tags",
|
||||
"collapse": "Collapse",
|
||||
"protocol": "Protocol",
|
||||
"displayName": "Display name (optional)",
|
||||
"displayNamePlaceholder": "Defaults to user@host or vnc:host",
|
||||
"host": "Host",
|
||||
"hostPlaceholder": "192.168.1.10",
|
||||
"hostHint": "IP or hostname; host:port is also accepted",
|
||||
"port": "Port",
|
||||
"username": "Username",
|
||||
"usernamePlaceholderRdp": "Administrator",
|
||||
"usernamePlaceholderSsh": "root",
|
||||
"width": "Width",
|
||||
"height": "Height",
|
||||
"group": "Group",
|
||||
"authPassword": "Password",
|
||||
"authKey": "Key",
|
||||
"password": "Password",
|
||||
"domain": "Domain (optional)",
|
||||
"domainPlaceholder": "Rarely needed unless using a domain account",
|
||||
"keySource": "Key source",
|
||||
"keyFile": "File",
|
||||
"keyText": "Text",
|
||||
"privateKeyPath": "Private key path",
|
||||
"privateKeyText": "Private key text",
|
||||
"privateKeyTextHint": "Pasted keys are encrypted on disk like passwords",
|
||||
"pickKeyFile": "Browse…",
|
||||
"pickKeyDialogTitle": "Choose private key file",
|
||||
"allFilesFilter": "All files",
|
||||
"passphrase": "Key passphrase (optional)",
|
||||
"passphrasePlaceholder": "Optional",
|
||||
"tags": "Tags",
|
||||
"tagsPlaceholder": "prod, web",
|
||||
"startupCommand": "Startup command (optional)",
|
||||
"startupCommandPlaceholder": "Run after connect, e.g. cd /var/log",
|
||||
"proxy": "Proxy",
|
||||
"proxyNone": "None",
|
||||
"proxyHostPlaceholder": "Proxy host",
|
||||
"proxyPortPlaceholder": "Port",
|
||||
"proxyUserPlaceholder": "Username (optional)",
|
||||
"proxyPasswordPlaceholder": "Password (optional)",
|
||||
"jumpHost": "Jump host (optional)",
|
||||
"jumpNone": "No jump host",
|
||||
"jumpNoneAlt": "No jump host",
|
||||
"jumpHint": "One saved session can be used as a jump host"
|
||||
},
|
||||
"batch": {
|
||||
"title": "Batch exec",
|
||||
"subtitle": "{{selected}} selected · concurrency {{concurrency}} · results discarded when tab closes",
|
||||
"dialogTitle": "Batch command",
|
||||
"dialogDesc": "{{selected}}/{{total}} hosts selected · max concurrency {{concurrency}}",
|
||||
"targetCount": "{{count}} targets",
|
||||
"runningProgress": "Running {{completed}}/{{total}}",
|
||||
"execute": "Run on {{count}} hosts",
|
||||
"executeAgain": "Run again",
|
||||
"success": "{{count}} succeeded",
|
||||
"failed": "{{count}} failed",
|
||||
"command": "Remote command",
|
||||
"commandPlaceholder": "e.g. uptime",
|
||||
"targets": "Target hosts",
|
||||
"filterPlaceholder": "Name, IP, group, or tag",
|
||||
"filterAria": "Filter hosts",
|
||||
"noMatchHosts": "No matching hosts",
|
||||
"resultMatrix": "Result matrix",
|
||||
"resultMatrixHint": "Host × status × output",
|
||||
"emptySelection": "Pick targets on the left, or open from sidebar batch mode with a selection",
|
||||
"noOutput": "(no output)",
|
||||
"errorReadConfig": "Could not read session config",
|
||||
"errorConnectFailed": "Connection failed",
|
||||
"errorExecFailed": "Command execution failed",
|
||||
"results": "Results",
|
||||
"resultsHint": "Output is kept only in this dialog",
|
||||
"ctrlEnterHint": "Ctrl/⌘ + Enter to run",
|
||||
"executeTo": "Run on {{count}} hosts",
|
||||
"selectFromLeft": "Select targets on the left"
|
||||
},
|
||||
"importExport": {
|
||||
"exportTitle": "Export sessions",
|
||||
"exportDefaultPath": "opsxshell-sessions.bak",
|
||||
"exportFilterBak": "OpsXShell backup",
|
||||
"exportFilterJson": "JSON",
|
||||
"exportSuccess": "Exported {{count}} sessions to:\n{{path}}",
|
||||
"exportWriteFailed": "Failed to write export file",
|
||||
"exportFailed": "Session export failed",
|
||||
"exportFailedDetail": "Session export failed: {{message}}",
|
||||
"exportPasswordTitle": "Set backup password",
|
||||
"exportPasswordMessage": "The export file will encrypt host groups, private keys, passwords, and other secrets. Choose a backup password.",
|
||||
"exportPasswordPlaceholder": "Enter backup password",
|
||||
"exportPasswordConfirmTitle": "Confirm backup password",
|
||||
"exportPasswordConfirmMessage": "Enter the backup password again to confirm.",
|
||||
"exportPasswordConfirmPlaceholder": "Re-enter backup password",
|
||||
"exportPasswordMismatch": "Passwords do not match",
|
||||
"exportPasswordRequired": "A backup password is required to export",
|
||||
"importTitle": "Import sessions",
|
||||
"importFilterBak": "OpsXShell backup",
|
||||
"importFilterJson": "JSON",
|
||||
"importFilterSshConfig": "SSH Config",
|
||||
"importFilterAll": "All files",
|
||||
"readFileFailed": "Failed to read file",
|
||||
"readFileFailedDetail": "Failed to read file: {{message}}",
|
||||
"importPasswordTitle": "Enter backup password",
|
||||
"importPasswordMessage": "This file is encrypted. Enter the password set at export to import host groups and credentials.",
|
||||
"importPasswordPlaceholder": "Enter backup password",
|
||||
"importPasswordRequired": "A password is required to import an encrypted backup",
|
||||
"importPasswordInvalid": "Incorrect backup password, or the file is corrupted",
|
||||
"noSessionsFound": "No importable sessions found",
|
||||
"noValidSessions": "No valid session entries in the file",
|
||||
"importSuccess": "Imported {{created}}/{{total}} sessions",
|
||||
"importFailed": "Session import failed",
|
||||
"importFailedDetail": "Session import failed: {{message}}"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user