refactor(fwlog): Live-Log als Child-Route /firewall/live statt Firewall-Tab

User-Feedback: Tab fühlt sich falsch an, will eine eigene Page mit
URL-Pfad unter /firewall.

UI:
- pages/Firewall/LiveLog.tsx → pages/FirewallLive/index.tsx
- FirewallPage entfernt den live-Tab aus tabs[]
- App.tsx routet /firewall/live → FirewallLivePage
- Sidebar: neuer Eintrag „Firewall-Log" eingerückt direkt unter
  „Firewall" in der Security-Section (child: true Flag → CSS-Klasse
  sidebar-menu-item--child mit padding-left 28px + dünnem vertikalem
  Trenn-Stab links). Sibling-Active-Logik exklusiv: /firewall matched
  NICHT mehr wenn /firewall/live aktiv ist.
- AppLayout PAGE_TITLES bekommt /firewall/live VOR /firewall damit
  der Title-Lookup den spezifischeren Pfad zuerst trifft.

Keine Backend-Änderungen.

Bekanntes Verhalten zu erklären: Im Live-Log sehen User aktuell nur
Smoke-Test-Events (oob.prefix=edgeguard:smoke / edgeguard:42, src/dst
127.0.0.1) — das sind die manuell-injizierten nft-Rules vom End-to-
End-Test der Pipeline. Reale Pakete fließen erst durch, wenn der
Operator auf einer firewall_rule den Log-Switch aktiviert (Firewall
→ Regeln → bearbeiten → Logging an). Aktuell hat keine einzige Rule
log=true.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-13 07:04:19 +02:00
parent b031725dfe
commit 24c40bc776
10 changed files with 55 additions and 14 deletions

View File

@@ -10,7 +10,6 @@ import ServiceGroupsTab from './ServiceGroups'
import RulesTab from './Rules'
import NATRulesTab from './NATRules'
import ZonesTab from './Zones'
import LiveLogTab from './LiveLog'
export default function FirewallPage() {
const { t } = useTranslation()
@@ -18,7 +17,6 @@ export default function FirewallPage() {
const tabs = [
{ key: 'rules', label: t('fw.tabs.rules'), children: <RulesTab /> },
{ key: 'nat', label: t('fw.tabs.nat'), children: <NATRulesTab /> },
{ key: 'live', label: t('fw.tabs.live'), children: <LiveLogTab /> },
{ key: 'zones', label: t('fw.tabs.zones'), children: <ZonesTab /> },
{ key: 'addrObj', label: t('fw.tabs.addrObj'), children: <AddressObjectsTab /> },
{ key: 'addrGrp', label: t('fw.tabs.addrGrp'), children: <AddressGroupsTab /> },

View File

@@ -7,12 +7,15 @@ import {
AlertOutlined,
ClearOutlined,
DownloadOutlined,
EyeOutlined,
PauseCircleOutlined,
PlayCircleOutlined,
PoweroffOutlined,
} from '@ant-design/icons'
import { useTranslation } from 'react-i18next'
import PageHeader from '../../components/PageHeader'
const { Text } = Typography
interface Entry {
@@ -105,7 +108,7 @@ function toCSV(rows: Entry[]): string {
// DISCONNECTED — der WebSocket wird erst beim Klick auf „Start"
// aufgebaut. Stop schließt explizit, Filter-Änderungen reconnecten
// nur wenn aktiv.
export default function LiveLogTab() {
export default function FirewallLivePage() {
const { t } = useTranslation()
const [active, setActive] = useState(false) // Start/Stop master switch
@@ -287,6 +290,11 @@ export default function LiveLogTab() {
return (
<div>
<PageHeader
icon={<EyeOutlined />}
title={t('fwlog.title')}
subtitle={t('fwlog.intro')}
/>
{!active ? (
<Card style={{ textAlign: 'center', padding: '32px 16px' }}>
<Empty