feat(alerts): severity + kind filter selects on Events tab

Operators can now narrow the history table by severity (INFO/WARNING/
ERROR/CRITICAL) and by alert kind (dynamically derived from loaded
events, searchable). Filtering is client-side — no extra API calls.
v1.1.112.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-26 20:07:50 +02:00
parent 326f79cf00
commit da554e9e82
5 changed files with 44 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useMemo, useState } from 'react'
import {
Alert, Button, Card, Form, Input, InputNumber, Modal, Popconfirm, Select, Space, Switch, Table, Tabs, Tag, Tooltip, Typography, message,
} from 'antd'
@@ -88,6 +88,20 @@ export default function AlertsPage() {
const [edit, setEdit] = useState<Channel | null>(null)
const [creating, setCreating] = useState(false)
const [form] = Form.useForm<ChannelFormValues>()
const [filterSev, setFilterSev] = useState<string | undefined>()
const [filterKind, setFilterKind] = useState<string | undefined>()
const kindOptions = useMemo(() => {
const kinds = [...new Set((events.data ?? []).map(e => e.kind))].sort()
return kinds.map(k => ({ value: k, label: k }))
}, [events.data])
const filteredEvents = useMemo(() =>
(events.data ?? []).filter(e =>
(!filterSev || e.severity === filterSev) &&
(!filterKind || e.kind === filterKind)
),
[events.data, filterSev, filterKind])
function buildPayload(v: ChannelFormValues): Channel {
const settings: Record<string, unknown> = {}
@@ -325,8 +339,32 @@ export default function AlertsPage() {
label: t('alerts.tabs.events'),
children: (
<Card size="small">
<Space className="mb-8">
<Select
allowClear
placeholder={t('alerts.col.severity')}
style={{ width: 150 }}
value={filterSev}
onChange={setFilterSev}
options={[
{ value: 'info', label: <Tag color="blue">INFO</Tag> },
{ value: 'warning', label: <Tag color="orange">WARNING</Tag> },
{ value: 'error', label: <Tag color="red">ERROR</Tag> },
{ value: 'critical', label: <Tag color="magenta">CRITICAL</Tag> },
]}
/>
<Select
allowClear
showSearch
placeholder={t('alerts.col.kind')}
style={{ width: 220 }}
value={filterKind}
onChange={setFilterKind}
options={kindOptions}
/>
</Space>
<Table size="small" rowKey="id" loading={events.isFetching}
dataSource={events.data ?? []} columns={evColumns}
dataSource={filteredEvents} columns={evColumns}
pagination={{ pageSize: 25 }}
locale={{ emptyText: (
<EmptyState