mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 04:20:45 +08:00
Gate netx Web/API/WebCRT with JWT and per-user API tokens, bootstrap an admin with forced password change, and expose users/audit/API-key management under a System section. MCP can reuse data/auth/mcp_token without extra env for local labs. Co-authored-by: Cursor <cursoragent@cursor.com>
741 lines
30 KiB
TypeScript
741 lines
30 KiB
TypeScript
const en = {
|
|
common: {
|
|
help: "Help",
|
|
refresh: "Refresh",
|
|
refreshing: "Refreshing…",
|
|
query: "Search",
|
|
clearFilters: "Clear filters",
|
|
prevPage: "Previous",
|
|
nextPage: "Next",
|
|
perPage: "{{n}}/page",
|
|
pagerMeta: "{{total}} items · page {{page}}/{{pages}}",
|
|
opFailed: "Operation failed",
|
|
empty: "-",
|
|
},
|
|
workbench: {
|
|
title: "Workbench",
|
|
backToWorkbench: "Back to Workbench",
|
|
openInNewTab: "Open in new tab",
|
|
openModule: "Open or switch to this module tab",
|
|
monitoring: "Monitoring",
|
|
operations: "Operations",
|
|
system: "System",
|
|
cards: {
|
|
umeSync: "UME Sync",
|
|
umeSyncDesc: "UME alarms, subscription & inventory",
|
|
managedNe: "NE Management",
|
|
managedNeDesc: "Multi-vendor SSH/Telnet NEs & connectivity test",
|
|
collect: "Batch Collect",
|
|
collectDesc: "Run custom CLI commands on connected NEs and save logs",
|
|
webcrt: "WebCRT",
|
|
webcrtDesc: "Interactive browser login to connected NEs (SSH/Telnet)",
|
|
topology: "Topology",
|
|
topologyDesc: "Drag NE topology maps; discover links via LLDP/CDP",
|
|
users: "Users",
|
|
usersDesc: "Admin: create, disable users and reset passwords",
|
|
audit: "Audit",
|
|
auditDesc: "View login and operation records",
|
|
apiKeys: "API Keys",
|
|
apiKeysDesc: "Issue MCP/script tokens per user with expiry",
|
|
},
|
|
},
|
|
layout: {
|
|
title: "UME Integration",
|
|
titleUme: "UME Sync",
|
|
titleManagedNe: "NE Management",
|
|
titleCollect: "Batch Collect",
|
|
titleWebcrt: "WebCRT",
|
|
titleTopology: "Topology",
|
|
titleUsers: "Users",
|
|
titleAudit: "Audit",
|
|
titleApiKeys: "API Keys",
|
|
navUme: "UME",
|
|
netxApi: "netx api",
|
|
oclawBridge: "oclaw WSS",
|
|
language: "Language",
|
|
moreMenu: "More",
|
|
langZh: "中文",
|
|
langEn: "English",
|
|
},
|
|
auth: {
|
|
loginTitle: "Sign in to NetX",
|
|
loginHint: "Use a local account to access the ops platform",
|
|
username: "Username",
|
|
password: "Password",
|
|
login: "Sign in",
|
|
loggingIn: "Signing in…",
|
|
loginFailed: "Login failed",
|
|
logout: "Sign out",
|
|
usersTitle: "User management",
|
|
usersHint: "Only admins can create and manage local accounts.",
|
|
addUser: "Add user",
|
|
role: "Role",
|
|
roleAdmin: "Admin",
|
|
roleUser: "User",
|
|
status: "Status",
|
|
active: "Active",
|
|
disabled: "Disabled",
|
|
enable: "Enable",
|
|
disable: "Disable",
|
|
actions: "Actions",
|
|
newPassword: "New password",
|
|
resetPassword: "Reset password",
|
|
userCreated: "User created",
|
|
userUpdated: "User updated",
|
|
auditTitle: "Audit log",
|
|
auditHintAdmin: "View login and operation records for all users.",
|
|
auditHintUser: "View your own operation records.",
|
|
filterUsername: "Filter username",
|
|
filterAction: "Filter action",
|
|
colTime: "Time",
|
|
colUser: "User",
|
|
colAction: "Action",
|
|
colMethod: "Method",
|
|
colPath: "Path",
|
|
colStatus: "Status",
|
|
colIp: "IP",
|
|
apiKeysTitle: "API Key management",
|
|
apiKeysHint:
|
|
"Create long-lived tokens for MCP/scripts. The secret is shown only once. Admins can issue keys for other users.",
|
|
tokenName: "Name",
|
|
expiresIn: "Expiry",
|
|
expire7d: "7 days",
|
|
expire30d: "30 days",
|
|
expire90d: "90 days",
|
|
expire365d: "1 year",
|
|
expireNever: "Never",
|
|
tokenOwner: "Owner",
|
|
tokenOwnerSelf: "Myself ({{user}})",
|
|
createToken: "Create key",
|
|
tokenCreated: "API key created",
|
|
tokenRevoked: "Revoked",
|
|
tokenOnceHint: "Copy and store this secret now; it will not be shown again:",
|
|
copyToken: "Copy",
|
|
tokenCopied: "Copied",
|
|
tokenCopyFailed: "Copy failed",
|
|
expiresAt: "Expires",
|
|
lastUsed: "Last used",
|
|
tokenStatusActive: "Active",
|
|
tokenStatusExpired: "Expired",
|
|
tokenStatusRevoked: "Revoked",
|
|
revokeToken: "Revoke",
|
|
revokeConfirm: "Revoke this API key?",
|
|
forceChangeTitle: "Change initial password",
|
|
forceChangeHint: "Account {{user}} is still using the default password. You must change it before continuing.",
|
|
oldPassword: "Current password",
|
|
confirmPassword: "Confirm new password",
|
|
savePassword: "Save new password",
|
|
savingPassword: "Saving…",
|
|
passwordTooShort: "New password must be at least 6 characters",
|
|
passwordMismatch: "New passwords do not match",
|
|
passwordMustChange: "New password must differ from the default/old password",
|
|
},
|
|
collect: {
|
|
create: {
|
|
title: "New collection job",
|
|
hint: "Configure commands and NEs, then create the job. Click Start in the job list to run collection.",
|
|
selectedTitle: "Selected NEs",
|
|
selectedEmpty: "Filter below and add NEs one by one.",
|
|
selectedCount: "{{count}} selected",
|
|
clearSelected: "Clear selection",
|
|
remove: "Remove",
|
|
pickTitle: "Eligible NEs (connectivity passed)",
|
|
pickHint: "Only NEs with connect_status=pass. Run connectivity test in NE Management first.",
|
|
pickEmpty: "No matching NEs.",
|
|
filterKeyword: "Filter",
|
|
filterKeywordPh: "Name / IP / vendor / device type",
|
|
add: "Add",
|
|
addBatch: "Add selected ({{count}})",
|
|
added: "Added",
|
|
create: "Create job",
|
|
creating: "Creating…",
|
|
expand: "Expand",
|
|
collapse: "Collapse",
|
|
meta: "{{ne}} NE(s) selected · {{cmd}} command(s)",
|
|
},
|
|
eligible: {
|
|
title: "Eligible NEs (connectivity passed)",
|
|
hint: "Only NEs with connect_status=pass. Run connectivity test in NE Management first.",
|
|
empty: "No NEs with passed connectivity test.",
|
|
},
|
|
form: {
|
|
title: "Collection setup",
|
|
jobTitle: "Job title",
|
|
jobTitlePh: "Auto-generated if empty",
|
|
commands: "Commands (one per line, # for comments)",
|
|
commandsPh: "display version\ndisplay current-configuration",
|
|
commandsHint: "Commands run in order on each device; output is saved as a text log (legacy NetX format).",
|
|
meta: "{{ne}} NE(s) selected · {{cmd}} command(s)",
|
|
start: "Start collection",
|
|
starting: "Submitting…",
|
|
},
|
|
created: "Collection job created: {{id}}",
|
|
started: "Collection started: {{id}}",
|
|
paused: "Job paused",
|
|
restarted: "Collection restarted",
|
|
retryFailedDone: "Retrying failed devices",
|
|
deleted: "Job deleted",
|
|
nothingToRetry: "No failed devices to retry",
|
|
neBusy: "Some NEs are busy in another collection job; wait for it to finish before starting",
|
|
jobRunning: "This job is already running",
|
|
confirmDelete: "Delete this collection job and its log files?",
|
|
jobs: {
|
|
title: "Collection jobs",
|
|
col: {
|
|
title: "Job",
|
|
status: "Status",
|
|
progress: "Progress",
|
|
created: "Created",
|
|
lastRun: "Last run",
|
|
actions: "Actions",
|
|
},
|
|
ok: "ok",
|
|
fail: "fail",
|
|
expand: "Details",
|
|
collapse: "Hide",
|
|
pause: "Pause",
|
|
start: "Start",
|
|
starting: "Starting…",
|
|
restart: "Restart",
|
|
retryFailed: "Retry failed",
|
|
downloadResults: "Download results",
|
|
delete: "Delete",
|
|
autoRefresh: "Auto-refresh every 2s while jobs are running",
|
|
runsInProgress: "Some devices are still being collected…",
|
|
},
|
|
runs: {
|
|
status: "Status",
|
|
message: "Message",
|
|
download: "Log",
|
|
downloadFile: "Download",
|
|
filterStatus: "Status filter",
|
|
filterDevice: "Device filter",
|
|
deviceKeywordPh: "Name / IP",
|
|
allStatus: "All statuses",
|
|
},
|
|
},
|
|
managedNe: {
|
|
title: "Network Elements",
|
|
credsNotConfigured:
|
|
"NETX_CREDENTIAL_SECRET_KEY is not set. Configure a Fernet key in .env and restart the API to store passwords.",
|
|
add: "Add NE",
|
|
importBtn: "Import",
|
|
downloadTemplate: "Download template",
|
|
importing: "Importing…",
|
|
edit: "Edit",
|
|
delete: "Delete",
|
|
openTerminal: "Terminal",
|
|
confirmDelete: "Delete this network element?",
|
|
batchDelete: "Batch delete",
|
|
batchDeleting: "Deleting…",
|
|
batchDeleteConfirm: "Delete {{n}} selected network element(s)? This cannot be undone.",
|
|
batchDeleteDone: "Deleted {{n}} network element(s)",
|
|
batchDeleteSelectRequired: "Select network elements to delete",
|
|
keywordPh: "name / IP / user / tags",
|
|
allVendors: "All vendors",
|
|
allConnectStatus: "All connect status",
|
|
stats: {
|
|
title: "Overview",
|
|
total: "{{n}} NEs managed",
|
|
pass: "Connected",
|
|
fail: "Failed",
|
|
unknown: "Untested",
|
|
testing: "Testing",
|
|
batchProxy: "Batch add proxy",
|
|
batchTest: "Batch connect-test",
|
|
tagFilter: "Filter by tag",
|
|
all: "All",
|
|
allTag: "All (no tag filter)",
|
|
noTag: "No tags",
|
|
tagStats: "Top tags",
|
|
confirm: "Apply to {{n}} NE(s). Continue?",
|
|
proxyDone: "Proxy applied to {{n}} NE(s)",
|
|
testDone: "Connect-test submitted for {{n}} NE(s)",
|
|
loadingIds: "Loading…",
|
|
},
|
|
col: {
|
|
name: "Name",
|
|
vendor: "Vendor",
|
|
deviceType: "Device type",
|
|
ip: "Management IP",
|
|
port: "Port",
|
|
protocol: "Protocol",
|
|
user: "Username",
|
|
password: "Password",
|
|
tags: "Tags",
|
|
remark: "Remark",
|
|
connect: "Connect",
|
|
testedAt: "Tested at",
|
|
actions: "Actions",
|
|
},
|
|
connect: {
|
|
run: "Connectivity test",
|
|
running: "Testing…",
|
|
submitted: "Submitted tests for {{n}} device(s)",
|
|
retest: "Test again",
|
|
},
|
|
connectDetail: "Details",
|
|
connectDetailTitle: "Connectivity test log",
|
|
connectDetailEmpty:
|
|
"No log yet. Run a connectivity test first; failures store full errors and hop context (passwords excluded).",
|
|
umeSync: {
|
|
sync: "Sync UME NEs",
|
|
syncing: "Syncing…",
|
|
delete: "Delete UME NEs",
|
|
deleting: "Deleting…",
|
|
deleteConfirm: "Delete all managed NEs created from UME sync? This cannot be undone.",
|
|
done: "UME sync done: {{inserted}} inserted, {{updated}} updated, {{deleted}} deleted, {{total}} inventory total",
|
|
deletedDone: "Deleted {{n}} UME-synced NEs",
|
|
},
|
|
account: {
|
|
batchAdd: "Batch add account",
|
|
batchByTag: "Batch account by tag",
|
|
batchTitle: "Batch add account",
|
|
batchHint: "Apply the account info below to {{n}} selected NE(s).",
|
|
batchByTagHint: "Apply the account info below to NEs under the selected tag; leave password blank to update only username.",
|
|
batchDone: "Account updated for {{n}} NE(s)",
|
|
selectRequired: "Select network elements first",
|
|
applying: "Applying…",
|
|
apply: "Apply to NEs",
|
|
usernameOrPasswordRequired: "Enter at least a username or a password",
|
|
passwordOptionalBatch: "leave blank to keep unchanged",
|
|
},
|
|
help:
|
|
"[Bulk import]\n" +
|
|
"· Required columns: device_type, ip, username, port, protocol, name, vendor. Download the template first.\n" +
|
|
"· password may be empty (required for direct login; optional for bastion-managed or batch proxy later).\n" +
|
|
"· Recommended flow: import NEs first, select rows, then use Batch add proxy.\n\n" +
|
|
"[Jump / bastion]\n" +
|
|
"· Bastion SSH username template: {hop_user}@{target_user}@{target_ip} (bastion host is separate); CLI: ssh user@target@ip@bastion-host.\n" +
|
|
"· Bastion-managed: set Jump password (Vault); target password optional. Manual mode needs target password.\n" +
|
|
"· JumpServer/CBH often use port 2222; some sites use 22.\n\n" +
|
|
"[Connectivity / edit]\n" +
|
|
"· NETX_CREDENTIAL_SECRET_KEY required to store passwords.\n" +
|
|
"· Leave password blank on edit to keep unchanged; open Details after failed connect-test for hop context (no secrets).",
|
|
importResult: {
|
|
done: "Import done: {{inserted}} inserted, {{updated}} updated, {{failed}} failed row(s)",
|
|
},
|
|
form: {
|
|
requiredHint: "Fields marked with * are required",
|
|
nameConnectHint: "After a successful connectivity test, name is replaced with the device hostname",
|
|
createTitle: "Add network element",
|
|
editTitle: "Edit network element",
|
|
save: "Save",
|
|
saving: "Saving…",
|
|
cancel: "Cancel",
|
|
created: "Network element created",
|
|
updated: "Network element updated",
|
|
deleted: "Network element deleted",
|
|
passwordRequired: "Password is required",
|
|
passwordOptional: "leave blank to keep unchanged",
|
|
},
|
|
hop: {
|
|
sectionTitle: "Jump host / proxy",
|
|
type: "Jump type",
|
|
enable: "Connect to target via jump host",
|
|
vendor: {
|
|
zte: "ZTE device (CLI jump)",
|
|
huawei: "Huawei device (CLI jump)",
|
|
cisco: "Cisco device (CLI jump)",
|
|
linux: "Linux server (SSH tunnel)",
|
|
bastion: "Bastion host (SSH protocol proxy)",
|
|
},
|
|
zteHint: "Run ssh/telnet on the ZTE device to reach the target; target credentials use secondary auth.",
|
|
huaweiHint: "Run telnet / stelnet (SSH) on the Huawei hop; stelnet is SSH. Target credentials use secondary auth.",
|
|
ciscoHint: "Run Cisco ssh -vrf / telnet /vrf jump commands; target credentials use secondary auth.",
|
|
linuxHint: "SSH to the Linux bastion, then direct-tcpip tunnel to target IP:port (ProxyJump-style).",
|
|
bastionHint:
|
|
"SSH with composite username via bastion protocol proxy. Example: bastion-user@target-user@2.2.2.2@1.1.1.1; password is the bastion/Vault password. JumpServer/CBH often use port 2222.",
|
|
targetAuthMode: "Target credentials",
|
|
targetAuthBastionManaged: "Bastion-managed (target password optional)",
|
|
targetAuthManual: "Manual (secondary auth after connect)",
|
|
targetAuthHint: "Bastion-managed needs only bastion password; manual mode requires target NE password.",
|
|
usernameTemplate: "SSH username template",
|
|
templateHintBastion:
|
|
"Default {hop_user}@{target_user}@{target_ip}. Bastion address is the hop host field. CLI example: ssh bastion-user@target-user@2.2.2.2@1.1.1.1.",
|
|
host: "Jump host",
|
|
port: "Jump port",
|
|
protocol: "Jump protocol",
|
|
protocolSshStelnet: "ssh (stelnet)",
|
|
username: "Jump username",
|
|
password: "Jump password",
|
|
vrf: "Mgmt VRF (optional)",
|
|
vpnInstance: "VPN-Instance (optional)",
|
|
vrfCisco: "VRF (optional, e.g. MGMT)",
|
|
commandTemplate: "Jump command template",
|
|
templateHint:
|
|
"ZTE CLI: telnet {target_ip}, telnet {target_ip} vrf {vrf}, ssh {target_ip}, ssh {target_ip} vrf {vrf}. Auto-suggested from jump protocol/VRF; same when left blank. Target credentials via secondary auth prompts.",
|
|
templateHintHuawei:
|
|
"Huawei CLI: telnet {target_ip}, telnet vpn-instance {vrf} {target_ip}, stelnet {target_ip}, stelnet {target_ip} -vpn-instance {vrf}. SSH protocol maps to stelnet. Auto-suggested when left blank.",
|
|
templateHintCisco:
|
|
"Cisco CLI: ssh {target_ip}, ssh -vrf {vrf} {target_ip}, telnet {target_ip}, telnet {target_ip} /vrf {vrf}. Auto-suggested when left blank.",
|
|
badge: {
|
|
zte: "ZTE hop",
|
|
huawei: "Huawei hop",
|
|
cisco: "Cisco hop",
|
|
linux: "Linux hop",
|
|
bastion: "Bastion",
|
|
},
|
|
hostRequired: "Jump host is required",
|
|
userRequired: "Jump username is required",
|
|
passwordRequired: "Jump password is required",
|
|
batchAdd: "Add proxy",
|
|
batchTitle: "Batch add jump proxy",
|
|
batchHint: "Apply the jump-host settings below to {{n}} selected NE(s) (overwrites existing proxy config).",
|
|
batchDone: "Proxy applied to {{n}} NE(s)",
|
|
selectRequired: "Select network elements first",
|
|
applying: "Applying…",
|
|
apply: "Apply to selected",
|
|
},
|
|
},
|
|
ume: {
|
|
token: {
|
|
title: "UME Token",
|
|
disconnected: "disconnected",
|
|
connected: "connected",
|
|
connectedRenew: "connected (renew required)",
|
|
expiresIn: "expires_in",
|
|
needsRenew: "renew / 0s",
|
|
preview: "preview",
|
|
refreshStatus: "Refresh status",
|
|
renewLogin: "Renew / login",
|
|
renewing: "Renewing…",
|
|
disconnect: "Disconnect token",
|
|
disconnecting: "Disconnecting…",
|
|
renewOkChanged: "Token renewed and updated",
|
|
renewOkSame: "Renew completed (unchanged)",
|
|
disconnectOk: "UME token disconnected",
|
|
renewHint: "Token missing expiry or expired. Use Renew / login or wait for background keepalive.",
|
|
},
|
|
subscription: {
|
|
title: "UME alarm subscription (WebSocket)",
|
|
help:
|
|
"Subscriptions must be created/cancelled manually. After establish (or on restart if a valid subscription exists in DB), the backend auto-connects WSS for live alarms. Pause/resume on runtime task alarms_current_ws_consumer stops/resumes WSS only (does not cancel the UME subscription).",
|
|
sub: "subscription",
|
|
subActive: "active",
|
|
subInactive: "inactive",
|
|
wssPaused: "paused",
|
|
wssModeBanner:
|
|
"Current alarms are maintained via WSS (mode: {{mode}}); scheduled REST full sync is paused. Use Sync current alarms below for full reconcile.",
|
|
serverLostBanner:
|
|
"UME server subscription is missing or expired; local state may still show active. Clear local record and re-subscribe.",
|
|
establish: "Establish subscription",
|
|
establishing: "Establishing…",
|
|
reestablish: "Clear local & re-subscribe",
|
|
reestablishing: "Re-subscribing…",
|
|
cancel: "Cancel subscription",
|
|
cancelling: "Cancelling…",
|
|
refreshStatus: "Refresh subscription",
|
|
clearLocalOnly: "Clear local only",
|
|
clearing: "Clearing…",
|
|
opFailed: "Subscription operation failed",
|
|
confirmClearDefault:
|
|
"UME alarm subscription no longer exists or has expired.\n\nClear local subscription record? You can establish again afterwards.",
|
|
confirmReestablish: "Clear local record and re-establish subscription on UME. Continue?",
|
|
titleLoginFirst: "Log in to UME token first",
|
|
titleReestablish: "Clear stale local record and re-establish on UME",
|
|
establishInvalid: "Establish did not return a valid id/uri",
|
|
establishExists: "Subscription already exists (WSS will stay/connect)",
|
|
establishOk: "Subscription established; WSS will connect",
|
|
clearLocalOk: "Local subscription cleared; you can establish again",
|
|
serverLostMsg: "UME subscription lost. Clear local record and re-subscribe?",
|
|
cancelFailed: "Cancel failed: subscription may still exist on UME",
|
|
cancelOkMissing: "Local cleared (UME subscription was already missing)",
|
|
cancelOk: "Subscription cancelled",
|
|
wsLogs: "WSS runtime log",
|
|
wsActivity: "Last activity {{time}}",
|
|
wsAutoRefresh: "Auto refresh",
|
|
wsLogsEmpty: "No logs yet (connect WSS after establishing subscription)",
|
|
},
|
|
keyAlert: {
|
|
title: "AI alarm monitor (OClaw WhatsApp)",
|
|
showPanel: "Expand",
|
|
hidePanel: "Collapse",
|
|
help: "Exact match by notificationId, or substring match on alarm description (case-insensitive; nativeProbableCause, etc.). Optionally restrict to UME inventory ne_type values (multi-select; empty = all devices). Pushed via OClaw WebSocket. Shares NETX_OCLAW_ANALYZE_TOKEN.",
|
|
ws: "OClaw WSS",
|
|
wsConnected: "connected",
|
|
wsDisconnected: "disconnected",
|
|
wsDisabled: "disabled",
|
|
wsPaused: "paused",
|
|
publishedOk: "published ok",
|
|
publishedFail: "published fail",
|
|
queue: "queue",
|
|
matchType: "Match by",
|
|
matchNotificationId: "notificationId",
|
|
matchKeyword: "description keyword",
|
|
matchValuePhNotificationId: "Enter notificationId",
|
|
matchValuePhKeyword: "Enter keyword (case-insensitive)",
|
|
label: "Rule description",
|
|
labelPh: "Required, e.g. BGP Down",
|
|
neTypesLabel: "Device types (optional, multi-select)",
|
|
neTypesHint: "Leave empty to match all device types. Options come from synced UME Inventory ne_type.",
|
|
neTypesEmpty: "No device types yet — sync Inventory first",
|
|
neTypesAll: "All",
|
|
forwardOnClear: "Push on alarm clear",
|
|
forwardOnClearHelp: "Global switch for all monitor rules. By default only new/updated alarms are pushed; when enabled, clear notifications are also sent when UME reports alarms cleared.",
|
|
add: "Add rules",
|
|
adding: "Adding…",
|
|
delete: "Delete",
|
|
edit: "Edit",
|
|
editTitle: "Edit monitor rule",
|
|
save: "Save",
|
|
saving: "Saving…",
|
|
cancel: "Cancel",
|
|
editOk: "Rule updated",
|
|
pickFromAlarms: "Load alarm hints",
|
|
emptyRules: "No monitor rules yet",
|
|
colType: "type",
|
|
colMatch: "match",
|
|
colLabel: "description",
|
|
colNeTypes: "device types",
|
|
colForwardClear: "on clear",
|
|
colPublished: "published",
|
|
colAttempts: "attempts",
|
|
colLast: "last push",
|
|
colActions: "actions",
|
|
colMonitor: "monitor",
|
|
monitorOn: "on",
|
|
monitorOff: "off",
|
|
filterKeywordPh: "Filter match / label",
|
|
filterMatchAll: "All types",
|
|
filterEnabledAll: "All states",
|
|
filterEnabledOn: "Monitoring on",
|
|
filterEnabledOff: "Monitoring off",
|
|
addOk: "Monitor rule added",
|
|
deleteOk: "Deleted",
|
|
confirmDelete: "Delete this monitor rule?",
|
|
yes: "yes",
|
|
no: "no",
|
|
},
|
|
sync: {
|
|
title: "UME sync",
|
|
inventory: "Sync inventory",
|
|
alarmsCurrent: "Sync current alarms",
|
|
full: "Full sync",
|
|
failed: "Sync failed",
|
|
},
|
|
tasks: {
|
|
currentTitle: "Running jobs",
|
|
running: "running",
|
|
noRunning: "No running jobs",
|
|
runtimeTitle: "Background tasks",
|
|
runtimeOpFailed: "Background task operation failed",
|
|
noRuntime: "No background task status",
|
|
intervalTitle: "Configured sleep between loop iterations (clamped at process start)",
|
|
lastRunTitle: "Last finished sync for scheduled tasks; refreshed at each loop tick",
|
|
deletedTitle: "Reconcile deletes: inventory = NE rows; alarms_current = current alarm rows",
|
|
lastErrorCol: "last_error",
|
|
runtimeError: {
|
|
startup_alarm_sync_before_ws: "Starting up: syncing current alarms (WSS connects after completion)…",
|
|
startup_gate_waiting: "Startup REST snapshot pending; scheduled REST and WSS on standby",
|
|
wss_active_skip_rest: "WSS receiving live alarms; REST sync skipped",
|
|
pulling_alarms_current: "Pulling UME current alarms…",
|
|
alarms_sync_in_progress_skip: "Another current-alarm REST sync in progress; skipped",
|
|
pulling_inventory: "Pulling UME inventory…",
|
|
ume_ws_disabled_no_base_url: "Disabled or UME_BASE_URL not configured",
|
|
oclaw_fwd_disabled: "Disabled or NETX_OCLAW_ALARM_WS / token / url not configured",
|
|
resumed_sync_soon: "Resumed: skipping debounce wait, sync soon",
|
|
resumed_wss_reconnect: "Resumed: reconnecting WSS soon",
|
|
resumed_oclaw_wss_reconnect: "Resumed: reconnecting OClaw WSS soon",
|
|
resumed: "Resumed",
|
|
keepalive_failed: "Token keepalive failed",
|
|
},
|
|
wsState: {
|
|
init: "Initializing",
|
|
connected: "Connected",
|
|
connecting: "Connecting",
|
|
disconnected: "Disconnected",
|
|
no_subscription: "No subscription",
|
|
waiting_token: "Waiting for token",
|
|
paused: "Paused",
|
|
error: "Connection error",
|
|
reconnecting: "Reconnecting",
|
|
subscription_lost: "UME subscription lost",
|
|
disabled_no_base_url: "Disabled or UME_BASE_URL not configured",
|
|
},
|
|
fwdState: {
|
|
paused: "Paused",
|
|
disabled: "Disabled",
|
|
connecting: "Connecting",
|
|
connected: "Connected",
|
|
},
|
|
runtimeTask: {
|
|
token_keepalive: "UME token keepalive",
|
|
alarms_current_auto_sync: "Current alarms auto sync",
|
|
alarms_current_ws_consumer: "UME alarm WSS",
|
|
oclaw_alarm_forwarder: "OClaw key-alert WSS",
|
|
inventory_auto_sync: "Inventory auto sync",
|
|
},
|
|
},
|
|
syncStatus: {
|
|
title: "Sync history",
|
|
showPanel: "Expand",
|
|
hidePanel: "Collapse",
|
|
empty: "No sync records",
|
|
},
|
|
ne: {
|
|
title: "Network elements",
|
|
showPanel: "Expand",
|
|
hidePanel: "Collapse",
|
|
keywordPh: "keyword(ne_id/ne_name/user_label/ip/host_name)",
|
|
clearTitle: "Clear keyword and reset to page 1",
|
|
expand: "Expand details",
|
|
collapse: "Collapse details",
|
|
cliConnect: "CLI connect",
|
|
},
|
|
tabs: {
|
|
main: "UME sync",
|
|
cli: "CLI connect",
|
|
},
|
|
cli: {
|
|
title: "UME CLI connection profile",
|
|
showPanel: "Expand",
|
|
hidePanel: "Collapse",
|
|
hint: "Unified SSH credentials and hop/bastion for UME inventory NEs. OClaw MCP can exec show commands via ume_ne_id without per-device managed_ne entries.",
|
|
statusReady: "CLI profile is ready for UME NE command execution.",
|
|
statusNotReady: "Set target username and hop/bastion settings (if enabled).",
|
|
profileName: "Profile name",
|
|
targetUsername: "Target SSH username",
|
|
targetPassword: "Target SSH password",
|
|
passwordKeep: "Leave blank to keep unchanged",
|
|
newProfile: "New profile",
|
|
deleteConfirm: "Delete this CLI profile?",
|
|
deleted: "Profile deleted",
|
|
saved: "CLI profile saved",
|
|
connectTestTitle: "Sample NE connectivity test",
|
|
sampleNePh: "ume_ne_id (copy from NE list below)",
|
|
sampleNeRequired: "ume_ne_id is required",
|
|
connectTestSubmitted: "Connectivity test submitted",
|
|
connectTestWaiting: "Waiting for test result…",
|
|
connectTestRunning: "Connectivity test in progress…",
|
|
connectTestResult: "Test result",
|
|
existingProfiles: "Existing profiles",
|
|
default: "default",
|
|
},
|
|
alarms: {
|
|
title: "Current alarms",
|
|
showPanel: "Expand",
|
|
hidePanel: "Collapse",
|
|
keywordPh: "keyword(alarm key/cause/ne_name/host_name/ip…)",
|
|
hostNamePh: "host_name (contains)",
|
|
allSeverity: "All severities",
|
|
clearedAll: "is_cleared: all",
|
|
clearTitle: "Clear filters and reset to page 1",
|
|
filterByHost: "Filter by this host",
|
|
noHostName: "No host_name (sync inventory first)",
|
|
},
|
|
},
|
|
webcrt: {
|
|
title: "WebCRT",
|
|
deviceList: "Device list",
|
|
sessionManager: "Device list",
|
|
connect: "Connect",
|
|
hint: "Pick an NE and open an interactive terminal in the browser. Credentials stay on the server.",
|
|
hintCrt: "Click an NE on the left to open a terminal. Includes managed and UME inventory; search + paging for large fleets.",
|
|
filterKeyword: "Filter",
|
|
filterKeywordPh: "Filter by name / IP / tag",
|
|
empty: "No matching NEs. Switch source or refine the search.",
|
|
open: "Open terminal",
|
|
opening: "Connecting…",
|
|
opened: "Opened {{name}}",
|
|
disconnect: "Disconnect",
|
|
closed: "Session closed",
|
|
termPlaceholder: "No terminal session open",
|
|
sessionMeta: "{{name}} · {{ip}}",
|
|
source: {
|
|
all: "All",
|
|
managed: "Managed",
|
|
ume: "UME",
|
|
},
|
|
status: {
|
|
idle: "Idle",
|
|
connecting: "Connecting",
|
|
connected: "Connected",
|
|
error: "Error",
|
|
closed: "Closed",
|
|
},
|
|
actions: {
|
|
reconnect: "Reconnect",
|
|
recordLog: "Record log",
|
|
clear: "Clear",
|
|
copy: "Copy",
|
|
recording: "Recording",
|
|
recordingOn: "Log recording started",
|
|
recordingSaved: "Log saved",
|
|
copied: "Copied to clipboard",
|
|
copyEmpty: "Terminal is empty",
|
|
copyFailed: "Copy failed",
|
|
},
|
|
err: {
|
|
sessionLimit: "Session limit reached; close other terminals first",
|
|
neNotFound: "Network element not found",
|
|
credsIncomplete: "Incomplete username/password on this NE",
|
|
cliProfile: "UME NEs require a CLI connect profile (default account / hop)",
|
|
connectFailed: "Device login failed: {{detail}}",
|
|
},
|
|
},
|
|
topology: {
|
|
title: "Topology",
|
|
maps: "Maps",
|
|
newMap: "New",
|
|
newMapName: "New topology",
|
|
rename: "Rename",
|
|
renamePrompt: "Topology map name",
|
|
renameHint: "Double-click to rename",
|
|
renamed: "Topology map renamed",
|
|
deleteMap: "Delete map",
|
|
deleteMapConfirm: "Delete map \"{{name}}\"? Nodes and edges will be removed.",
|
|
emptyMaps: "No maps yet. Create one to start.",
|
|
palette: "NE library",
|
|
paletteHint: "Click to add to canvas",
|
|
filterPh: "Filter name / IP",
|
|
save: "Save",
|
|
saving: "Saving…",
|
|
saved: "Topology saved",
|
|
discover: "Discover links",
|
|
discovering: "Discovering…",
|
|
discovered: "Discovery done: +{{added}} updated {{updated}} missing {{stale}}",
|
|
discoverFail: "Discovery failed: {{detail}}",
|
|
selectMap: "Select or create a topology map",
|
|
canvasHint: "Add NEs from the left; blue dashed=found, red dashed=missing (deletable)",
|
|
selected: "Selected",
|
|
selectedEdge: "Selected edge",
|
|
openWebcrt: "Open terminal",
|
|
openNe: "NE details",
|
|
removeNode: "Remove from canvas",
|
|
removeEdge: "Delete edge",
|
|
noNeLink: "Not linked to a managed NE",
|
|
edgeManual: "Manual",
|
|
edgeDiscovered: "Discovered",
|
|
edgeStale: "Missing",
|
|
fit: "Fit view",
|
|
display: "Display",
|
|
hideIp: "Hide IP",
|
|
hideVendor: "Hide vendor",
|
|
hidePorts: "Hide ports",
|
|
edgeFlow: "Edge flow",
|
|
collapseSidebar: "Collapse sidebar",
|
|
expandSidebar: "Expand sidebar",
|
|
hideAdded: "Hide added",
|
|
paletteEmpty: "No matching NEs.",
|
|
paletteHiddenAll: "Added NEs are hidden; uncheck to show them again.",
|
|
paletteSource: "NE source",
|
|
paletteManaged: "Managed",
|
|
paletteUme: "UME",
|
|
paletteLoading: "Loading…",
|
|
discoverReport: "Discovery progress",
|
|
discoverClose: "Close",
|
|
discoverProgress: "Scanning {{count}} managed NE(s) on the map (serial LLDP; please wait)…",
|
|
discoverProgressLive: "Scanning {{index}}/{{total}}: {{name}}",
|
|
discoverSummary: "Scanned {{scanned}} · added {{added}} · updated {{updated}} · missing {{stale}} · failed {{failed}}",
|
|
discoverNeOk: "neighbors {{neighbors}} · added {{added}} · updated {{updated}}",
|
|
discoverNeFail: "Collect failed",
|
|
discoverNoTargets:
|
|
"No scannable NEs on the map. Add managed NEs, or UME NEs with a CLI connect profile.",
|
|
removeStale: "Clear missing ({{count}})",
|
|
removeStaleHint: "Delete red-marked missing edges",
|
|
staleRemoved: "Removed {{count}} missing edge(s)",
|
|
},
|
|
};
|
|
|
|
export default en;
|