i18n(panel): migrate hardcoded panel strings to en-US and translate all locales

Surface ~400 hardcoded English labels, tooltips, placeholders, dt/divider
text, modal okText/cancelText, and Spin loading from the panel pages
(clients/groups/inbounds/nodes/settings/xray/sub/index) into
web/translation/en-US.json under existing pages.<page>.* namespaces, with
JSX swapped to t(...). Brand and protocol identifiers (TLS, MTU, SNI,
NordVPN, Cloudflare WARP, etc.) stay literal.

Sync all 12 non-English locales (ar-EG, es-ES, fa-IR, id-ID, ja-JP,
pt-BR, ru-RU, tr-TR, uk-UA, vi-VN, zh-CN, zh-TW) to match en-US's
structure and translate the 521 new key paths per locale. Every locale
file now has 1539 lines, mirroring en-US ordering.

Also remove a dead duplicate "info": "Info" key under pages.inbounds
that collided with the new pages.inbounds.info.* object.

Backend: bulk attach/detach errors in web/service/client.go now route
through logger.Warningf (so they appear under /panel/api/server/logs/)
instead of only living on the response payload.
This commit is contained in:
MHSanaei
2026-05-28 18:03:07 +02:00
parent 0829f1ecd4
commit 72b97efa8a
34 changed files with 6391 additions and 1125 deletions
+299 -3
View File
@@ -396,7 +396,6 @@
},
"telegramDesc": "Please provide Telegram Chat ID. (use '/id' command in the bot) or ({'@'}userinfobot)",
"subscriptionDesc": "To find your subscription URL, navigate to the 'Details'. Additionally, you can use the same name for several clients.",
"info": "Info",
"same": "Same",
"inboundData": "Inbound's Data",
"exportInbound": "Export Inbound",
@@ -433,6 +432,139 @@
"getNewmldsa65Error": "Error while obtaining mldsa65.",
"getNewVlessEncError": "Error while obtaining VlessEnc."
},
"form": {
"moveUp": "Move up",
"moveDown": "Move down",
"addAll": "Add all",
"addAllFallbackTooltip": "Add a fallback row for every eligible inbound not yet wired up",
"peers": "Peers",
"addPeer": "Add peer",
"keepAlive": "Keep-alive",
"autoSystemRoutesTooltip": "Windows-only. CIDRs added to the system routing table automatically so matching traffic goes through TUN.",
"autoOutboundsInterface": "Auto outbounds interface",
"autoOutboundsInterfaceTooltip": "Physical interface for outbound traffic. Use 'auto' to detect; auto-enabled when Auto system routes is set.",
"rewriteAddress": "Rewrite address",
"rewritePort": "Rewrite port",
"allowedNetwork": "Allowed network",
"followRedirect": "Follow redirect",
"accounts": "Accounts",
"allowTransparent": "Allow transparent",
"encryptionMethod": "Encryption method",
"visionTestseed": "Vision testseed",
"version": "Version",
"udpIdleTimeout": "UDP idle timeout (s)",
"masquerade": "Masquerade",
"type": "Type",
"upstreamUrl": "Upstream URL",
"rewriteHost": "Rewrite Host",
"skipTlsVerify": "Skip TLS verify",
"directory": "Directory",
"statusCode": "Status code",
"body": "Body",
"headers": "Headers",
"proxyProtocol": "Proxy Protocol",
"requestVersion": "Request version",
"requestMethod": "Request method",
"requestPath": "Request path",
"requestHeaders": "Request headers",
"responseVersion": "Response version",
"responseStatus": "Response status",
"responseReason": "Response reason",
"responseHeaders": "Response headers",
"heartbeatPeriod": "Heartbeat Period",
"serviceName": "Service Name",
"authority": "Authority",
"multiMode": "Multi Mode",
"maxBufferedUpload": "Max Buffered Upload",
"maxUploadSize": "Max Upload Size (Byte)",
"streamUpServer": "Stream-Up Server",
"serverMaxHeaderBytes": "Server Max Header Bytes",
"paddingBytes": "Padding Bytes",
"uplinkHttpMethod": "Uplink HTTP Method",
"paddingObfsMode": "Padding Obfs Mode",
"paddingKey": "Padding Key",
"paddingHeader": "Padding Header",
"paddingPlacement": "Padding Placement",
"paddingMethod": "Padding Method",
"sessionPlacement": "Session Placement",
"sessionKey": "Session Key",
"sequencePlacement": "Sequence Placement",
"sequenceKey": "Sequence Key",
"uplinkDataPlacement": "Uplink Data Placement",
"uplinkDataKey": "Uplink Data Key",
"noSseHeader": "No SSE Header",
"ttiMs": "TTI (ms)",
"uplinkMbps": "Uplink (MB/s)",
"downlinkMbps": "Downlink (MB/s)",
"cwndMultiplier": "CWND Multiplier",
"maxSendingWindow": "Max Sending Window",
"externalProxy": "External Proxy",
"sniPlaceholder": "SNI (defaults to host)",
"fingerprint": "Fingerprint",
"defaultOption": "Default",
"routeMark": "Route Mark",
"tcpKeepAliveInterval": "TCP Keep Alive Interval",
"tcpKeepAliveIdle": "TCP Keep Alive Idle",
"tcpMaxSeg": "TCP Max Seg",
"tcpUserTimeout": "TCP User Timeout",
"tcpWindowClamp": "TCP Window Clamp",
"tcpFastOpen": "TCP Fast Open",
"multipathTcp": "Multipath TCP",
"penetrate": "Penetrate",
"v6Only": "V6 Only",
"tcpCongestion": "TCP Congestion",
"dialerProxy": "Dialer Proxy",
"trustedXForwardedFor": "Trusted X-Forwarded-For",
"addressPortStrategy": "Address+port strategy",
"tryDelayMs": "Try delay (ms)",
"prioritizeIPv6": "Prioritize IPv6",
"interleave": "Interleave",
"maxConcurrentTry": "Max concurrent try",
"customSockopt": "Custom sockopt",
"addCustomOption": "Add custom option",
"serverNameIndication": "Server Name Indication",
"cipherSuites": "Cipher Suites",
"autoOption": "Auto",
"minMaxVersion": "Min/Max Version",
"rejectUnknownSni": "Reject Unknown SNI",
"disableSystemRoot": "Disable System Root",
"sessionResumption": "Session Resumption",
"oneTimeLoading": "One Time Loading",
"usageOption": "Usage Option",
"buildChain": "Build Chain",
"echKey": "ECH key",
"echConfig": "ECH config",
"getNewEchCert": "Get New ECH Cert",
"show": "Show",
"xver": "Xver",
"target": "Target",
"maxTimeDiff": "Max Time Diff (ms)",
"minClientVer": "Min Client Ver",
"maxClientVer": "Max Client Ver",
"shortIds": "Short IDs",
"spiderX": "SpiderX",
"getNewCert": "Get New Cert",
"mldsa65Seed": "mldsa65 Seed",
"mldsa65Verify": "mldsa65 Verify",
"getNewSeed": "Get New Seed"
},
"info": {
"mode": "Mode",
"grpcServiceName": "grpc serviceName",
"grpcMultiMode": "grpc multiMode",
"interfaceName": "Interface name",
"mtu": "MTU",
"gateway": "Gateway",
"dns": "DNS",
"outboundsInterface": "Outbounds interface",
"autoSystemRoutes": "Auto system routes",
"followRedirect": "FollowRedirect",
"auth": "Auth",
"noKernelTun": "No-kernel TUN",
"keepAlive": "Keep alive",
"peerNumber": "Peer {n}",
"peerNumberConfig": "Peer {n} config"
},
"stream": {
"general": {
"request": "Request",
@@ -777,6 +909,8 @@
"subEnable": "Subscription Service",
"subEnableDesc": "Enable/Disable the subscription service.",
"subJsonEnable": "Enable/Disable the JSON subscription endpoint independently.",
"subJsonEnableTitle": "JSON subscription",
"subClashEnableTitle": "Clash / Mihomo subscription",
"subTitle": "Subscription Title",
"subTitleDesc": "Title shown in VPN client",
"subSupportUrl": "Support URL",
@@ -822,6 +956,54 @@
"fragmentSett": "Fragmentation Settings",
"noisesDesc": "Enable Noises.",
"noisesSett": "Noises Settings",
"trustedProxyCidrs": "Trusted proxy CIDRs",
"trustedProxyCidrsDesc": "Comma-separated IPs/CIDRs allowed to set forwarded host, proto, and client IP headers.",
"ldap": {
"enable": "Enable LDAP sync",
"host": "LDAP host",
"port": "LDAP port",
"useTls": "Use TLS (LDAPS)",
"bindDn": "Bind DN",
"passwordConfigured": "Configured; leave blank to keep current password.",
"passwordUnconfigured": "Not configured.",
"passwordPlaceholder": "Configured - enter a new value to replace",
"baseDn": "Base DN",
"userFilter": "User filter",
"userAttr": "User attribute (username/email)",
"vlessField": "VLESS flag attribute",
"flagField": "Generic flag attribute (optional)",
"flagFieldDesc": "If set, overrides VLESS flag — e.g. shadowInactive.",
"truthyValues": "Truthy values",
"truthyValuesDesc": "Comma-separated; default: true,1,yes,on",
"invertFlag": "Invert flag",
"invertFlagDesc": "Enable when the attribute means disabled (e.g. shadowInactive).",
"syncSchedule": "Sync schedule",
"syncScheduleDesc": "Cron-like string, e.g. @every 1m",
"inboundTags": "Inbound tags",
"inboundTagsDesc": "Inbounds that LDAP sync may auto-create or auto-delete clients on.",
"noInbounds": "No inbounds found. Create one in Inbounds first.",
"autoCreate": "Auto create clients",
"autoDelete": "Auto delete clients",
"defaultTotalGb": "Default total (GB)",
"defaultExpiryDays": "Default expiry (days)",
"defaultIpLimit": "Default IP limit"
},
"subFormats": {
"packets": "Packets",
"length": "Length",
"interval": "Interval",
"maxSplit": "Max split",
"noises": "Noises",
"noiseItem": "Noise №{n}",
"type": "Type",
"packet": "Packet",
"delayMs": "Delay (ms)",
"applyTo": "Apply to",
"addNoise": "+ Noise",
"concurrency": "Concurrency",
"xudpConcurrency": "xudp concurrency",
"xudpUdp443": "xudp UDP 443"
},
"mux": "Mux",
"muxDesc": "Transmit multiple independent data streams within an established data stream.",
"muxSett": "Mux Settings",
@@ -877,6 +1059,9 @@
"save": "Save",
"restart": "Restart Xray",
"restartSuccess": "Xray has been successfully relaunched.",
"restartOutputTitle": "Xray restart output",
"restartConfirmTitle": "Restart xray?",
"restartConfirmContent": "Reloads the xray service with the saved configuration.",
"stopSuccess": "Xray has been successfully stopped.",
"restartError": "There was an error when rebooting the Xray.",
"stopError": "There was an error when stopping the Xray.",
@@ -951,7 +1136,74 @@
"info": "Info",
"add": "Add Rule",
"edit": "Edit Rule",
"useComma": "Comma-separated items"
"useComma": "Comma-separated list"
},
"routing": {
"dragToReorder": "Drag to reorder"
},
"ruleForm": {
"sourceIps": "Source IPs",
"sourcePort": "Source port",
"vlessRoute": "VLESS route",
"attributes": "Attributes",
"value": "Value",
"user": "User",
"inboundTags": "Inbound tags",
"outboundTag": "Outbound tag",
"balancerTag": "Balancer tag",
"balancerTagTooltip": "Routes traffic through one of the configured load balancers"
},
"outboundForm": {
"tagDuplicate": "Tag already used by another outbound",
"tagRequired": "Tag is required",
"tagPlaceholder": "unique-tag",
"localIpPlaceholder": "local IP",
"addressRequired": "Address is required",
"portRequired": "Port is required",
"optional": "optional",
"udpOverTcp": "UDP over TCP",
"uotVersion": "UoT version",
"inboundTag": "Inbound tag",
"inboundTagPlaceholder": "inbound tag used in routing rules",
"responseType": "Response type",
"rewriteNetwork": "Rewrite network",
"unchanged": "(unchanged)",
"unchangedAddress": "(unchanged) e.g. 1.1.1.1",
"rules": "Rules",
"ruleN": "Rule {n}",
"action": "Action",
"redirect": "Redirect",
"fragment": "Fragment",
"finalRules": "Final Rules",
"overrideXrayPrivateIp": "Override Xray's default private-IP block",
"blockDelay": "Block delay (ms)",
"reverseSniffing": "Reverse Sniffing",
"workers": "Workers",
"reserved": "Reserved",
"minUploadInterval": "Min upload interval (ms)",
"maxUploadSizeBytes": "Max upload size (bytes)",
"uplinkChunkSize": "Uplink chunk size",
"noGrpcHeader": "No gRPC header",
"maxConcurrency": "Max concurrency",
"maxConnections": "Max connections",
"maxReuseTimes": "Max reuse times",
"maxRequestTimes": "Max request times",
"maxReusableSecs": "Max reusable secs",
"keepAlivePeriod": "Keep alive period",
"authPassword": "Auth password",
"visionTestpre": "Vision testpre",
"serverNamePlaceholder": "server name",
"verifyPeerName": "Verify peer name",
"pinnedSha256": "Pinned SHA256",
"shortId": "Short ID",
"sockopts": "Sockopts",
"keepAliveInterval": "Keep alive interval",
"markFwmark": "Mark (fwmark)",
"interface": "Interface",
"ipv6Only": "IPv6 only",
"acceptProxyProtocol": "Accept proxy protocol",
"tcpUserTimeoutMs": "TCP user timeout (ms)",
"tcpKeepAliveIdleS": "TCP keep-alive idle (s)"
},
"outbound": {
"addOutbound": "Add Outbound",
@@ -981,6 +1233,8 @@
"testSuccess": "Test successful",
"testFailed": "Test failed",
"testError": "Failed to test outbound",
"testModeTooltip": "TCP: fast dial-only probe. HTTP: full request through xray.",
"testAll": "Test all",
"nordvpn": "NordVPN",
"accessToken": "Access Token",
"country": "Country",
@@ -997,6 +1251,16 @@
"balancerSelectors": "Selectors",
"tag": "Tag",
"tagDesc": "Unique Tag",
"tagDuplicate": "Tag already used by another balancer",
"tagPlaceholder": "unique balancer tag",
"selector": "Selector",
"fallback": "Fallback",
"expected": "Expected",
"expectedPlaceholder": "optimal node count",
"maxRtt": "Max RTT",
"tolerance": "Tolerance",
"baselines": "Baselines",
"costs": "Costs",
"balancerDesc": "It is not possible to use balancerTag and outboundTag at the same time. If used at the same time, only outboundTag will work."
},
"wireguard": {
@@ -1013,6 +1277,38 @@
"userLevel": "User Level",
"userLevelDesc": "All connections made through this inbound will use this user level. Default is 0"
},
"nord": {
"accessToken": "Access token",
"privateKey": "Private key",
"noServers": "No servers found for the selected country",
"noPublicKey": "Selected server does not advertise a NordLynx public key.",
"outboundAdded": "NordVPN outbound added",
"outboundUpdated": "NordVPN outbound updated"
},
"warp": {
"licenseError": "Failed to set WARP license.",
"fetchFirst": "Fetch the WARP config first.",
"createAccount": "Create WARP account",
"accessToken": "Access token",
"deviceId": "Device ID",
"licenseKey": "License key",
"privateKey": "Private key",
"deleteAccount": "Delete account",
"settings": "Settings",
"licenseKeyLabel": "WARP / WARP+ license key",
"key": "Key",
"keyPlaceholder": "26-char WARP+ key",
"accountInfo": "Account info",
"deviceName": "Device name",
"deviceModel": "Device model",
"deviceEnabled": "Device enabled",
"accountType": "Account type",
"role": "Role",
"warpPlusData": "WARP+ data",
"quota": "Quota",
"usage": "Usage",
"addOutbound": "Add outbound"
},
"dns": {
"enable": "Enable DNS",
"enableDesc": "Enable built-in DNS server",
@@ -1240,4 +1536,4 @@
"chooseInbound": "Choose an Inbound"
}
}
}
}