diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index bd20678..a315e33 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -389,6 +389,34 @@ const en = { bPort: "Port B", lastSeen: "Last seen", }, + jobStatus: { + running: "Running", + pending: "Pending", + paused: "Paused", + done: "Done", + failed: "Failed", + cancelled: "Cancelled", + }, + triggerMode: { + manual: "Manual", + schedule: "Scheduled", + topology: "Topology canvas", + }, + jobScope: { + all: "All NEs", + ne_ids: "Selected NEs", + selected: "Selected NEs", + }, + itemResult: { + ok: "OK", + warn: "Warn", + fail: "Fail", + }, + edgeSource: { + lldp: "LLDP", + manual: "Manual", + stale: "Stale", + }, }, configSync: { title: "Config sync", @@ -1601,6 +1629,15 @@ const en = { linkUme: "UME", linkBoth: "Managed+UME", linkOrphaned: "Detached", + roleCore: "Core", + roleAggregation: "Aggregation", + roleAccess: "Access", + roleUnknown: "Unknown", + sourceManual: "Manual", + sourceUmeSync: "UME sync", + sourceLldp: "LLDP placeholder", + sourceTopology: "Topology placeholder", + sourceWebcrt: "WebCRT", regexTitle: "Regex find", patternPh: "Regex, e.g. ^CORE- or -BJ-", fieldName: "Name", diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 02981ae..ac4e5f5 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -385,6 +385,34 @@ const zh = { bPort: "对端口", lastSeen: "最近看见", }, + jobStatus: { + running: "运行中", + pending: "排队中", + paused: "已暂停", + done: "已完成", + failed: "失败", + cancelled: "已取消", + }, + triggerMode: { + manual: "手动", + schedule: "周期", + topology: "拓扑画布", + }, + jobScope: { + all: "全部网元", + ne_ids: "指定网元", + selected: "指定网元", + }, + itemResult: { + ok: "成功", + warn: "警告", + fail: "失败", + }, + edgeSource: { + lldp: "LLDP", + manual: "手动", + stale: "陈旧", + }, }, configSync: { title: "配置同步", @@ -1586,10 +1614,19 @@ const zh = { filterLinkLinked: "已关联库存", filterLinkOrphaned: "已解绑", colLink: "关联", - linkManaged: "Managed", + linkManaged: "托管", linkUme: "UME", - linkBoth: "Managed+UME", + linkBoth: "托管+UME", linkOrphaned: "已解绑", + roleCore: "核心", + roleAggregation: "汇聚", + roleAccess: "接入", + roleUnknown: "未知", + sourceManual: "手动", + sourceUmeSync: "UME 同步", + sourceLldp: "LLDP 占位", + sourceTopology: "拓扑占位", + sourceWebcrt: "WebCRT", regexTitle: "正则查找", patternPh: "正则,如 ^CORE- 或 -BJ-", fieldName: "名称", diff --git a/web/src/pages/network/LldpLinksPage.tsx b/web/src/pages/network/LldpLinksPage.tsx index 37703d3..de88ec1 100644 --- a/web/src/pages/network/LldpLinksPage.tsx +++ b/web/src/pages/network/LldpLinksPage.tsx @@ -25,6 +25,51 @@ const POLL_MS = 2500; const TARGET_PAGE_SIZE = 20; const SEP = " · "; +function lldpJobStatusLabel(t: (k: string) => string, status: string): string { + const s = String(status || "").trim().toLowerCase(); + const key = `lldpLinks.jobStatus.${s}`; + const label = t(key); + return label === key ? status || "—" : label; +} + +function lldpTriggerLabel(t: (k: string) => string, mode: string): string { + const s = String(mode || "").trim().toLowerCase(); + const key = `lldpLinks.triggerMode.${s}`; + const label = t(key); + return label === key ? mode || "—" : label; +} + +function lldpScopeLabel(t: (k: string) => string, scope: string): string { + const s = String(scope || "").trim().toLowerCase(); + const key = `lldpLinks.jobScope.${s}`; + const label = t(key); + return label === key ? scope || "—" : label; +} + +function lldpItemResultLabel( + t: (k: string) => string, + it: { ok?: boolean; parser_stub?: boolean | string | null; unmatched_count?: number; unmatched?: unknown[] }, +): string { + if (!it.ok) return t("lldpLinks.itemResult.fail"); + const unmatchedCount = it.unmatched_count ?? (it.unmatched?.length || 0); + if (it.parser_stub || unmatchedCount > 0) return t("lldpLinks.itemResult.warn"); + return t("lldpLinks.itemResult.ok"); +} + +function lldpEdgeStatusLabel(t: (k: string) => string, status: string): string { + const s = status === "stale" ? "missing" : String(status || "").trim().toLowerCase(); + if (s === "active") return t("lldpLinks.edgeStatusActive"); + if (s === "missing") return t("lldpLinks.edgeStatusMissing"); + return status || "—"; +} + +function lldpEdgeSourceLabel(t: (k: string) => string, source: string): string { + const s = String(source || "").trim().toLowerCase(); + const key = `lldpLinks.edgeSource.${s}`; + const label = t(key); + return label === key ? source || "—" : label; +} + export function LldpLinksPage() { const { t } = useI18n(); const { showOk, showError } = useToast(); @@ -545,7 +590,7 @@ export function LldpLinksPage() { const st = e.status === "stale" ? "missing" : e.status; return (