Alert Detail Sidebar#
The Alert Detail Sidebar is a slide-in panel (AlertSidebar) rendered over the alert feed when a user clicks an alert row. It displays alert metadata (severity, source, description, fingerprint, linked incidents), a AlertTimeline audit history component, and a topology map for related services.
Entry point: keep-ui/features/alerts/alert-detail-sidebar/ui/alert-sidebar.tsx
useAlertAudit β SWR-based audit data refresh#
Audit events are fetched via useAlertAudit, a hook returned by the useAlerts factory . The hook is defined in keep-ui/entities/alerts/model/useAlerts.ts:
- Endpoint:
GET /alerts/{fingerprint}/audit, returningAuditEvent[] - Conditional fetch: SWR key is
null(no request) until bothapi.isReady()is true and a non-empty fingerprint is provided β preventing spurious requests when the sidebar is first mounted with no alert selected. - Default config:
revalidateOnFocus: false, so audit data is not silently re-fetched on window focus, but callers can override theSWRConfigurationoptions. - Manual refresh:
AlertSidebarexposes a refresh button that callsmutate()directly , triggering a re-fetch on demand. Themutatefunction is destructured from theuseAlertAuditreturn value.
AlertTimeline β react-chrono rendering and remount-by-key#
AlertTimeline renders audit events as a vertical timeline using react-chrono. Key implementation details:
- Scroll container: The
Chronocomponent is wrapped in a<Card>withmax-h-[500px] overflow-y-auto, so the timeline itself scrolls internally rather than relying on the sidebar's outer scroll. This is the standard mitigation for nested scroll conflicts reported in issue #4618, where the innerChronocontainer would block scrolling when the item count exceeded ~20. - Chrono config: The component uses
mode="VERTICAL",hideControls,disableToolbar,borderLessCards, andslideShow={false}. Cards are visually hidden (viaclassNames) so only the custom content children render . - Default event fallback: If
auditDatais empty, a synthetic "Alert is triggered" event is generated fromalert.lastReceived, ensuring the timeline is never blank.
Remount-by-key pattern: AlertTimeline is rendered with a computed key in AlertSidebar:
key={auditData ? auditData.length : 1}
When the audit data length changes after a refresh, React destroys and remounts the AlertTimeline component entirely. This forces react-chrono to reinitialize with the new item count, working around internal state issues where Chrono does not reliably reconcile when its items prop changes in place.
Sidebar layout and scroll#
The outer Dialog.Panel uses overflow-auto flex flex-col , enabling the panel itself to scroll for tall content (topology map, many metadata fields). The AlertTimeline card's own overflow-y-auto creates a second, independent scroll region. This two-level scroll structure is the intended fix for the UX issue in #4618, where the incident timeline panel was constrained to the height of its parent and not scrollable.
Related files#
| File | Purpose |
|---|---|
alert-sidebar.tsx | Main sidebar component; composes timeline, metadata, topology |
alert-timeline.tsx | react-chrono-based audit event renderer |
useAlerts.ts | Factory hook providing useAlertAudit |
| Issue #4618 | Bug report tracking scroll and panel-height UX problems |