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 +1 @@
1.1.111 1.1.112

View File

@@ -60,7 +60,7 @@ import (
usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users"
) )
var version = "1.1.111" var version = "1.1.112"
func main() { func main() {
addr := os.Getenv("EDGEGUARD_API_ADDR") addr := os.Getenv("EDGEGUARD_API_ADDR")

View File

@@ -11,7 +11,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup"
) )
var version = "1.1.111" var version = "1.1.112"
const usage = `edgeguard-ctl — EdgeGuard CLI const usage = `edgeguard-ctl — EdgeGuard CLI

View File

@@ -41,7 +41,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts"
) )
var version = "1.1.111" var version = "1.1.112"
const ( const (
// renewTickInterval — how often we re-evaluate expiring certs. // renewTickInterval — how often we re-evaluate expiring certs.

View File

@@ -1,4 +1,4 @@
import { useState } from 'react' import { useMemo, useState } from 'react'
import { import {
Alert, Button, Card, Form, Input, InputNumber, Modal, Popconfirm, Select, Space, Switch, Table, Tabs, Tag, Tooltip, Typography, message, Alert, Button, Card, Form, Input, InputNumber, Modal, Popconfirm, Select, Space, Switch, Table, Tabs, Tag, Tooltip, Typography, message,
} from 'antd' } from 'antd'
@@ -88,6 +88,20 @@ export default function AlertsPage() {
const [edit, setEdit] = useState<Channel | null>(null) const [edit, setEdit] = useState<Channel | null>(null)
const [creating, setCreating] = useState(false) const [creating, setCreating] = useState(false)
const [form] = Form.useForm<ChannelFormValues>() 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 { function buildPayload(v: ChannelFormValues): Channel {
const settings: Record<string, unknown> = {} const settings: Record<string, unknown> = {}
@@ -325,8 +339,32 @@ export default function AlertsPage() {
label: t('alerts.tabs.events'), label: t('alerts.tabs.events'),
children: ( children: (
<Card size="small"> <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} <Table size="small" rowKey="id" loading={events.isFetching}
dataSource={events.data ?? []} columns={evColumns} dataSource={filteredEvents} columns={evColumns}
pagination={{ pageSize: 25 }} pagination={{ pageSize: 25 }}
locale={{ emptyText: ( locale={{ emptyText: (
<EmptyState <EmptyState