集成指南:统一 Incident Alerts 页面告警交互体验)
Keep 告警详情侧边栏AlertSidebar集成指南统一 Incident Alerts 页面告警交互体验【免费下载链接】keepThe open-source AIOps and alert management platform项目地址: https://gitcode.com/GitHub_Trending/kee/keepKeep开源 AIOps 与告警管理平台在前端keep-ui中通过将事件Incident详情页的告警表格从ViewAlertModal弹窗模式切换为AlertSidebar侧边抽屉模式实现了全应用统一的告警详情查看与操作体验。本文以该集成实现为线索结合源码讲解组件替换、状态管理、交互入口、侧边栏功能与测试覆盖帮助你在 Keep 前端中理解、复现并扩展这套侧边栏方案。集成背景为什么用 AlertSidebar 替换 ViewAlertModal在 Keep 的告警工作流中告警详情通常有两种查看形态弹窗Modal与侧边抽屉Sidebar。ViewAlertModal作为独立弹窗组件存在而主告警表格alert-table.tsx早已使用AlertSidebar。本次集成把事件Incident详情页的告警列表也切换到同一侧边栏组件核心动机是一致性无论从告警流Alert Feed还是事件Incident上下文进入看到的都是同一套侧边栏交互功能对齐侧边栏自带告警菜单AlertMenu、时间线、相关服务拓扑等能力事件上下文同样受益可维护性只维护一个侧边栏组件替代多个弹窗组件降低 UI 代码的重复与分叉。该决策记录于 ALERT_SIDEBAR_INTEGRATION.md/incidents/[id]/alerts/ALERT_SIDEBAR_INTEGRATION.md)实现集中在事件告警页组件incident-alerts.tsx中。组件集成实现剖析incident-alerts.tsx核心改动位于 incident-alerts.tsx/incidents/[id]/alerts/incident-alerts.tsx)。该文件是事件详情页“Alerts”标签页的入口组件接收incident: IncidentDto作为 props负责拉取该事件关联的告警列表、渲染表格并处理行级交互。导入变更移除弹窗、引入侧边栏原实现仅依赖ViewAlertModal集成后同时引入两个组件import { AlertSidebar } from /features/alerts/alert-detail-sidebar; import { ViewAlertModal } from /features/alerts/view-raw-alert;其中AlertSidebar通过 alert-detail-sidebar/index.ts 统一导出实际实现在 ui/alert-sidebar.tsx。保留ViewAlertModal是因为“查看按钮”路径仍走弹窗详见下文交互入口两类组件按需共存。状态管理重构集成将原先单一的viewAlertModal状态拆分为三个独立状态职责更清晰// State for ViewAlertModal (opened by view button) const [viewAlertModal, setViewAlertModal] useStateAlertDto | null(null); // State for AlertSidebar (opened by row click) const [selectedAlert, setSelectedAlert] useStateAlertDto | null(null); const [isSidebarOpen, setIsSidebarOpen] useState(false); // Add state for incident selector modal (needed by AlertSidebar) const [isIncidentSelectorOpen, setIsIncidentSelectorOpen] useState(false);selectedAlert记录当前在侧边栏中展示的告警对象isSidebarOpen控制侧边栏开关isIncidentSelectorOpen供AlertSidebar内部“关联事件Correlate Incident”动作使用——侧边栏内部菜单通过该状态打开事件选择器弹窗。侧边栏关闭统一走handleSidebarClose同时复位两个状态避免关闭后再操作残留旧数据const handleSidebarClose () { setIsSidebarOpen(false); setSelectedAlert(null); };侧边栏挂载与可选 props在 JSX 中侧边栏通过 Headless UI 的Dialog渲染为右侧抽屉挂载于表格之后AlertSidebar isOpen{isSidebarOpen} toggle{handleSidebarClose} alert{selectedAlert} // These optional props are passed to maintain feature parity with the main alerts table setRunWorkflowModalAlert{undefined} setDismissModalAlert{undefined} setChangeStatusAlert{undefined} setIsIncidentSelectorOpen{setIsIncidentSelectorOpen} /对照AlertSidebar的完整 props 定义alert-sidebar.tsxProp类型必填作用isOpenboolean是控制侧边栏显示toggleVoidFunction是关闭回调点击遮罩/关闭按钮触发alertAlertDto \| null是当前展示的告警setRunWorkflowModalAlert(alert) void可选打开“运行工作流”弹窗setDismissModalAlert(alerts[]) void可选打开“忽略Dismiss”弹窗setChangeStatusAlert(alert) void可选打开“变更状态”弹窗setIsIncidentSelectorOpen(open: boolean) void必填打开“关联事件”选择器从源码结构看事件页目前只接通了setIsIncidentSelectorOpen其余三个动作 handler 传undefined侧边栏菜单对应入口即按条件隐藏而在主告警表格alert-table.tsx中这些 props 全部接通这也是下文“功能对齐”设计的关键——同一组件在不同页面通过 props 开放不同能力。两种用户交互入口文档描述了侧边栏的两种打开方式结合源码与测试incident-alerts-sidebar.test.tsx/incidents/[id]/alerts/tests/incident-alerts-sidebar.test.tsx)核验后的真实行为如下行点击打开 AlertSidebar点击告警表格中的任意一行触发AlertsTableBody的onRowClick回调设置selectedAlert并打开侧边栏AlertsTableBody table{table} showSkeleton{false} theme{theme} onRowClick{(alert) { setSelectedAlert(alert); setIsSidebarOpen(true); }} lastViewedAlert{null} presetName{incident-alerts} /表格由 TanStack Table 构建行 ID 使用alert.fingerprint且对 API 偶发返回重复 ID 的情况做了“追加行下标”的去重兜底处理。View Details 按钮打开 ViewAlertModal行尾操作托盘IncidentAlertActionTray中的“查看详情”按钮实际打开的是ViewAlertModal源码注释// Open the ViewAlertModal when clicking the view button而非侧边栏。测试用例should open ViewAlertModal when clicking view button in action tray也明确断言了这一点点击 view 按钮后view-alert-modal可见、alert-sidebar不可见。因此严格来说事件页的侧边栏唯一入口是行点击两个组件按“行点击 vs 视图按钮”分工并存。关闭方式点击右上角关闭按钮、点击遮罩区域Dialog onClose{toggle}都会调用handleSidebarClose。测试专门覆盖了关闭后isOpenfalse且alertnull防止出现 “Cannot read properties of null (reading fingerprint)” 之类的空指针回归。AlertSidebar 核心能力与源码级讲解侧边栏本体是一个固定右侧、宽度 2/4 的抽屉面板Dialog.Panel带 300ms 滑入/淡出过渡自上而下包含标题区严重级别徽标 告警名、告警菜单AlertMenu、可配置字段区、关联事件列表、告警时间线、相关服务拓扑。告警菜单AlertMenu与动作体系侧边栏头部内嵌AlertMenualert-menu.tsxisInSidebar{true}时展示完整动作集合动作项通过item.show条件按 props 是否传入决定显隐Run Workflow回调setRunWorkflowModalAlert?.(alert)打开工作流运行弹窗Dismiss / RestoreonDismiss回调setDismissModalAlert?.([alert])Change StatussetChangeStatusAlert?.(alert)Correlate IncidentsetIsIncidentSelectorOpen?.(true)仅当传入该回调时显示查看原始 PayloadopenAlertPayloadModalProvider 方法调用openMethodModal(method)可对已安装 provider 执行自定义方法Assign 分派callAssignEndpoint()。这解释了事件页集成时为何必须新增isIncidentSelectorOpen状态——事件上下文里“关联事件”是高频操作但运行工作流/忽略/改状态等弹窗入口在事件页暂以undefined关闭形成与主告警流有差异、面向事件场景的能力子集。可配置字段渲染ALERT_SIDEBAR_FIELDS侧边栏主体按config.ALERT_SIDEBAR_FIELDS来自 useConfig渲染字段字段注册表定义在 alertSidebarFields.tsxexport type AlertSidebarFieldName | service | source | description | message | fingerprint | url | incidents | timeline | relatedServices;标准字段service、source、description、message、fingerprint、url等每个字段都带shouldRender(alert)守卫如无 URL 时不渲染 URL 行fingerprint与url支持一键复制handleCopyFingerprint/handleCopyUrl失败时通过showErrorToast提示并给出文档链接特殊字段incidents、timeline、relatedServices在字段循环外单独渲染见下文自定义字段getCustomFields解析ALERT_SIDEBAR_FIELDS中非标准字段按点分路径取值支持labels.alertname、annotations.description甚至数组下标incident_dto.0.assignee见getNestedValue实现字段名自动由 snake_case/camelCase 转成 Title Case。关联事件、时间线与相关服务拓扑Incidents当配置包含incidents且alert.incident_dto存在时渲染可折叠的CollapsibleIncidentsList展示该告警所属的事件列表Alert Timeline通过useAlerts().useAlertAudit(alert.fingerprint)拉取审计历史展示状态变更与操作记录key随审计数据长度变化以便刷新后重挂载支持手动刷新handleRefresh调用mutate()Related Services当配置包含relatedServices时渲染TopologyMap复用 拓扑地图/topology/ui/map) 组件以alert.providerId与alert.service定位相关服务拓扑帮助在事件排障时快速看清告警影响的上下游服务。测试覆盖与运行方式集成配套的测试文件为 incident-alerts-sidebar.test.tsx/incidents/[id]/alerts/tests/incident-alerts-sidebar.test.tsx)采用 Jest Testing Library通过 mock 掉next/navigation、数据 hooksuseIncidentAlerts、usePollIncidentAlerts、provider/config hooks 及AlertSidebar本身来隔离测试目标组件。覆盖点用例断言内容渲染告警列表正确展示名称、严重级别初始侧边栏关闭行点击打开点击alert-row-*后侧边栏出现且内容为对应告警关闭点击关闭按钮后侧边栏消失、状态复位无异常关闭关闭后isOpenfalse且alertnull无空指针异常告警切换从告警 A 切到告警 B侧边栏内容随selectedAlert更新空状态无告警时渲染EmptyStateCard“No alerts yet”加载状态数据拉取中渲染IncidentAlertsTableBodySkeleton骨架屏双组件共存View 按钮打开ViewAlertModal行点击打开AlertSidebar两者可同时存在运行测试文档给出的命令需在keep-ui目录下cd keep-ui npm test -- --testPathPatternincident-alerts-sidebar.test.tsx若只跑事件告警相关的全部用例可将 pattern 替换为incident-alerts.*。收益与未来扩展收益总结全应用统一的侧边栏交互事件上下文中告警动作能力与主告警流对齐单组件多页面复用显著降低 UI 维护成本对用户而言熟悉的行点击-抽屉模式降低了学习成本。未来扩展方向文档指出侧边栏已具备工作流执行、状态变更等能力当前事件页以undefined关闭这些入口后续如需在事件上下文中启用只需把对应 handler 从父组件传入AlertSidebar isOpen{isSidebarOpen} toggle{handleSidebarClose} alert{selectedAlert} setRunWorkflowModalAlert{setRunWorkflowModalAlert} // 传入后菜单项自动显示 setDismissModalAlert{setDismissModalAlert} setChangeStatusAlert{setChangeStatusAlert} setIsIncidentSelectorOpen{setIsIncidentSelectorOpen} /由于AlertMenu依据 props 是否存在控制菜单项显隐接入无需改动侧边栏本体体现了该组件面向需求演进的扩展性设计。若需进一步定制展示字段可通过后端配置ALERT_SIDEBAR_FIELDS含标准字段与点分路径自定义字段动态调整侧边栏内容实现“一套组件、多处配置”的灵活布局。【免费下载链接】keepThe open-source AIOps and alert management platform项目地址: https://gitcode.com/GitHub_Trending/kee/keep创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考