@page "/audit/log" @attribute [Authorize(Policy = AuthorizationPolicies.OperationalAudit)] @using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Audit @using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared @using ZB.MOM.WW.ScadaBridge.CentralUI.Services @using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit @using ZB.MOM.WW.ScadaBridge.Security @inject IAuditLogQueryService AuditLogQueryService Audit Log

Audit Log

@* Trends panel (M6 / K15). A best-effort collapsible Bootstrap card sitting above the audit query UI: one KpiTrendChart per AuditLog global metric over a 24h (default) / 7d window. Series are fetched independently in the code-behind — a failed fetch degrades only that chart to the unavailable placeholder and never breaks the filter bar / grid below. *@
@if (_trendsOpen) {
}
@if (_trendsOpen) {
@foreach (var (metric, title, unit) in TrendMetrics) { var series = SeriesFor(metric);
}
}
@* Filter bar (Bundle B / M7-T2). Apply hands the collapsed filter to the grid. Bundle D (M7-T10..T12) threads a query-string instance prefill through InitialInstanceSearch — UI-only because the filter contract has no instance column. *@
@* Export button (Bundle F / M7-T14). A plain link triggers the streaming CSV endpoint at /api/centralui/audit/export — chosen over a SignalR-driven download because the request can stream 100k rows directly to the response body without buffering through the Blazor circuit. The href reflects the most recently applied filter; before Apply is clicked, an unconstrained export is exposed. Bundle G (#23 M7-T15) gates the button on the AuditExport policy so an OperationalAudit-only operator (read access without bulk export) sees the page + filters but cannot trigger the CSV pull. The endpoint itself is gated separately, so a hand-crafted URL still 403s — the AuthorizeView here is the user-facing affordance, not the authoritative check. *@
Export CSV
@* Results grid (Bundle B / M7-T3). Row clicks emit OnRowSelected for Bundle C's drilldown drawer; the grid stays in "no events" mode until the user applies a filter so the page does not auto-load the full audit table on first render. *@
@* Drilldown drawer (Bundle C / M7-T4..T8). Hosted at the page level so the off-canvas overlay sits above the grid / filter bar irrespective of scroll. *@