diff --git a/web/static/css/style.css b/web/static/css/style.css index 4441cbbd..134b6e4b 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -9289,6 +9289,7 @@ header { margin-bottom: 0; display: -webkit-box; -webkit-line-clamp: 2; + line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } @@ -13231,6 +13232,9 @@ header { font-variant-numeric: tabular-nums; white-space: nowrap; flex-shrink: 0; + justify-self: end; + text-align: right; + min-width: 3.5rem; } /* External MCP 健康度:能力总览中专门一行的 N/N + 状态徽章 */ diff --git a/web/static/i18n/en-US.json b/web/static/i18n/en-US.json index 78326120..71ddf2a5 100644 --- a/web/static/i18n/en-US.json +++ b/web/static/i18n/en-US.json @@ -125,7 +125,7 @@ "lastUpdated": "Last updated", "viewAll": "View all →", "recentVulns": "Recent vulnerabilities", - "noVulnYet": "No vulnerabilities yet — start your first scan", + "noVulnYet": "No recent vulnerabilities", "capabilities": "Capabilities", "mcpTools": "MCP tools", "rolesLabel": "Roles", @@ -184,7 +184,7 @@ "recoCheckMonitorDesc": "View failed request details in MCP monitor", "recoSetupMcp": "Configure your first MCP tool", "recoSetupMcpDesc": "Install MCP server before Agent can invoke specific capabilities", - "recoStartScan": "Start your first scan", + "recoStartScan": "Start a scan from chat", "recoStartScanDesc": "Describe your target in chat, AI will help execute", "recentEvents": "Recent Events", "eventUntitled": "Event", @@ -193,7 +193,7 @@ "mcpPartialDown_one": "{{count}} stopped", "mcpPartialDown_other": "{{count}} stopped", "mcpAllDown": "All stopped", - "noVulnDesc": "System looks safe — start a scan to discover potential issues", + "noVulnDesc": "This list shows recent records; new results appear here when detection completes in chat", "startScanBtn": "Go to chat to scan" }, "chat": { diff --git a/web/static/i18n/zh-CN.json b/web/static/i18n/zh-CN.json index 335d22af..6d447c1a 100644 --- a/web/static/i18n/zh-CN.json +++ b/web/static/i18n/zh-CN.json @@ -125,7 +125,7 @@ "lastUpdated": "上次更新", "viewAll": "查看全部 →", "recentVulns": "最近漏洞", - "noVulnYet": "暂无漏洞,开始你的第一次扫描吧", + "noVulnYet": "暂无最近漏洞", "capabilities": "能力总览", "mcpTools": "MCP 工具", "rolesLabel": "角色", @@ -174,7 +174,7 @@ "recoCheckMonitorDesc": "在 MCP 监控中查看失败的请求详情", "recoSetupMcp": "配置首个 MCP 工具", "recoSetupMcpDesc": "安装 MCP 服务后 Agent 才能调用具体能力", - "recoStartScan": "开始第一次扫描", + "recoStartScan": "在对话中发起扫描", "recoStartScanDesc": "在对话中描述目标,让 AI 协助执行", "recentEvents": "最近事件", "eventUntitled": "事件", @@ -182,7 +182,7 @@ "mcpAllRunning": "全部运行", "mcpPartialDown": "{{count}} 个未运行", "mcpAllDown": "全部未运行", - "noVulnDesc": "系统目前安全,开始一次扫描可以发现潜在问题", + "noVulnDesc": "此处展示近期漏洞记录;在对话中完成检测后,新结果会出现在这里", "startScanBtn": "前往对话发起扫描" }, "chat": { diff --git a/web/static/js/dashboard.js b/web/static/js/dashboard.js index a312cce5..3f39184b 100644 --- a/web/static/js/dashboard.js +++ b/web/static/js/dashboard.js @@ -662,8 +662,8 @@ function getHitlPendingCount(res) { // 「最近事件」内联展示:取通知摘要里最重要的前 N 条 // 设计原则: -// - 不重复 alert banner / KPI 已经表达过的信息(漏洞、HITL 等会被过滤掉避免冗余) -// - 只显示 p0/p1 优先级,p2 作为兜底(当 p0/p1 不够时) +// - 不重复 alert banner / KPI 已表达的「新漏洞」通知(vulnerability_created 仍过滤) +// - HITL 待审批在推荐操作等处也会提示,但仍在此展示时间线,便于与任务完成等并列查看 // - 整个 section 在没有可显示内容时整个隐藏,避免空模块占地方 function renderRecentEvents(notifRes) { var section = document.getElementById('dashboard-section-events'); @@ -671,8 +671,8 @@ function renderRecentEvents(notifRes) { if (!section || !listEl) return; var items = (notifRes && Array.isArray(notifRes.items)) ? notifRes.items : []; - // 过滤:只看有意义的事件,去掉 actionable 已处理的、以及类型已经在仪表盘其他位置覆盖的 - var coveredTypes = { 'vulnerability_created': true, 'hitl_pending': true }; + // 过滤:去掉新漏洞类型(与「最近漏洞」等板块避免重复);HITL 不再过滤 + var coveredTypes = { 'vulnerability_created': true }; var filtered = items.filter(function (it) { if (!it || !it.type) return false; if (coveredTypes[it.type]) return false; @@ -685,8 +685,8 @@ function renderRecentEvents(notifRes) { var la = levelOrder[a.level] != null ? levelOrder[a.level] : 9; var lb = levelOrder[b.level] != null ? levelOrder[b.level] : 9; if (la !== lb) return la - lb; - var ta = a.createdAt || a.created_at || 0; - var tb = b.createdAt || b.created_at || 0; + var ta = a.ts || a.createdAt || a.created_at || 0; + var tb = b.ts || b.createdAt || b.created_at || 0; return new Date(tb).getTime() - new Date(ta).getTime(); }); @@ -701,8 +701,9 @@ function renderRecentEvents(notifRes) { listEl.innerHTML = top.map(function (it) { var level = it.level || 'p2'; var title = esc(it.title || it.message || dt('dashboard.eventUntitled', null, '事件')); - var msg = esc(it.message || it.summary || ''); - var when = esc(timeAgoStr(it.createdAt || it.created_at)); + var msg = esc(it.message || it.summary || it.desc || ''); + var whenRaw = timeAgoStr(it.ts || it.createdAt || it.created_at); + var when = esc(whenRaw || '—'); return ( '