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:
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user