feat: hide event types from SAC UI via Settings checkbox (0.20.23)

Per-type «Показывать в событиях» in severity settings; filters lists, dashboard, hosts, and problems.
This commit is contained in:
PTah
2026-06-21 20:13:40 +10:00
parent 87ac1e09b0
commit bf7c83c408
15 changed files with 313 additions and 60 deletions
@@ -1,4 +1,4 @@
"""Per event-type severity overrides (admin Settings UI)."""
"""Per event-type severity overrides (admin Settings UI)."""
from __future__ import annotations
@@ -9,6 +9,7 @@ from sqlalchemy.orm import Session
from app.constants.event_types import DEFAULT_EVENT_SEVERITIES
from app.models.event_severity_override import EventSeverityOverride
from app.services.event_type_visibility import get_visibility_map
from app.services.notification_settings import VALID_SEVERITIES
SOURCE_DB = "db"
@@ -19,6 +20,7 @@ class EventSeverityOverrideItem:
event_type: str
default_severity: str
override_severity: str | None
show_in_events: bool = True
def get_override_map(db: Session) -> dict[str, str]:
@@ -48,7 +50,8 @@ def apply_severity_override(payload: dict, db: Session) -> dict:
def list_severity_override_items(db: Session) -> list[EventSeverityOverrideItem]:
override_map = get_override_map(db)
types = set(DEFAULT_EVENT_SEVERITIES) | set(override_map)
visibility_map = get_visibility_map(db)
types = set(DEFAULT_EVENT_SEVERITIES) | set(override_map) | set(visibility_map)
items: list[EventSeverityOverrideItem] = []
for event_type in sorted(types):
default = DEFAULT_EVENT_SEVERITIES.get(event_type, "info")
@@ -57,6 +60,7 @@ def list_severity_override_items(db: Session) -> list[EventSeverityOverrideItem]
event_type=event_type,
default_severity=default,
override_severity=override_map.get(event_type),
show_in_events=visibility_map.get(event_type, True),
)
)
return items
@@ -0,0 +1,58 @@
"""Hide selected event types from SAC UI/API event lists."""
from __future__ import annotations
from sqlalchemy import delete, select
from sqlalchemy.orm import Session
from sqlalchemy.sql import ColumnElement
from app.models.event import Event
from app.models.event_type_visibility import EventTypeVisibility
def get_hidden_event_types(db: Session) -> frozenset[str]:
rows = db.scalars(
select(EventTypeVisibility.event_type).where(EventTypeVisibility.show_in_events.is_(False))
).all()
return frozenset(rows)
def get_visibility_map(db: Session) -> dict[str, bool]:
rows = db.scalars(select(EventTypeVisibility)).all()
return {row.event_type: row.show_in_events for row in rows}
def show_in_events_for(event_type: str, *, hidden: frozenset[str]) -> bool:
return event_type not in hidden
def visibility_type_filter(hidden: frozenset[str]) -> ColumnElement[bool] | None:
if not hidden:
return None
return Event.type.not_in(tuple(sorted(hidden)))
def replace_event_visibility(db: Session, visibility: dict[str, bool | None]) -> dict[str, bool]:
stored = get_visibility_map(db)
for event_type, show in visibility.items():
normalized_type = event_type.strip()
if not normalized_type:
raise ValueError("event_type is required")
if show is None or show is True:
db.execute(
delete(EventTypeVisibility).where(EventTypeVisibility.event_type == normalized_type)
)
stored.pop(normalized_type, None)
continue
if show is False:
row = db.get(EventTypeVisibility, normalized_type)
if row is None:
row = EventTypeVisibility(event_type=normalized_type, show_in_events=False)
db.add(row)
else:
row.show_in_events = False
stored[normalized_type] = False
else:
raise ValueError("show_in_events must be true, false, or null")
db.flush()
return stored