const LIVE_LOG_COLUMNS: &[&str] = &[ "time", "request", "host", "source_ip", "vhost", "backend", "status", "duration", "cache", "outcome", "transport", "websocket", "upstream_error", ]; const FILE_LOG_COLUMN_MAX: usize = 64; const BACKEND_TABLE_COLUMNS: &[&str] = &[ "vhost", "backend", "status", "active", "requests", "errors", "latency", "traffic", "generation", "generationRequests", "generationAge", "rotations", "lastFailure", "lastRecovery", ]; const VHOST_LIST_SORT_COLUMNS: &[&str] = &[ "id", "hostname", "status", "listeners", "certificate", "backends", ]; const DOCKER_VHOST_SORT_COLUMNS: &[&str] = &[ "service", "hostname", "status", "backend", "scheme", "published", ]; const REDIRECT_LIST_SORT_COLUMNS: &[&str] = &[ "id", "name", "hostname", "status", "target", "rules", "listeners", "certificate", ]; const NOTFOUND_LIST_SORT_COLUMNS: &[&str] = &[ "id", "name", "hostname", "status", "mode", "listeners", "certificate", ]; const STREAM_LIST_SORT_COLUMNS: &[&str] = &[ "name", "id", "protocol", "listen", "upstream", "status", "maxConnections", "idleTimeout", ]; #[derive(serde::Deserialize)] struct DashboardWidgetDefinition { id: String, default_hidden: bool, display_type: String, } static DASHBOARD_WIDGETS: std::sync::LazyLock> = std::sync::LazyLock::new(|| { serde_json::from_str(include_str!("web/dashboard-widgets.json")) .expect("invalid bundled Overview Cards registry") }); #[derive(serde::Deserialize)] #[serde(deny_unknown_fields)] struct DashboardDefaultPreset { dashboard_widgets: Vec, dashboard_hidden_widgets: Vec, dashboard_density: String, overview_samples: u16, } static DASHBOARD_DEFAULT_PRESET: std::sync::LazyLock = std::sync::LazyLock::new(|| { let preset: DashboardDefaultPreset = serde_json::from_str(include_str!("web/dashboard-defaults.json")) .expect("invalid factory Overview layout preset"); let registry = DASHBOARD_WIDGETS .iter() .map(|w| w.id.as_str()) .collect::>(); let order = preset .dashboard_widgets .iter() .map(String::as_str) .collect::>(); let hidden = preset .dashboard_hidden_widgets .iter() .map(String::as_str) .collect::>(); assert_eq!( order.len(), preset.dashboard_widgets.len(), "duplicate factory widget ID" ); assert_eq!( hidden.len(), preset.dashboard_hidden_widgets.len(), "duplicate hidden factory widget ID" ); assert!( order.is_subset(®istry) && hidden.is_subset(&order), "unknown widget in factory layout" ); assert!( matches!( preset.dashboard_density.as_str(), "normal" | "compact" | "ultra" ), "invalid factory density" ); assert!( matches!(preset.overview_samples, 60 | 120 | 300 | 600), "invalid factory sample count" ); preset }); fn valid_dashboard_span(display_type: &str, span: u8) -> bool { match display_type { "table" => matches!(span, 6 | 12), "panel" => matches!(span, 4 | 6 | 12), "chart" => matches!(span, 3 | 4 | 6 | 12), _ => matches!(span, 2 | 3 | 4 | 6 | 12), } } fn valid_dashboard_sizes(sizes: &Option>) -> bool { sizes.as_ref().is_none_or(|sizes| { sizes.len() <= DASHBOARD_WIDGETS.len() && sizes.iter().all(|(id, span)| { DASHBOARD_WIDGETS.iter().any(|widget| { widget.id == *id && valid_dashboard_span(&widget.display_type, *span) }) }) }) } fn default_hidden_dashboard_widgets() -> Vec { let mut hidden = DASHBOARD_DEFAULT_PRESET.dashboard_hidden_widgets.clone(); for widget in DASHBOARD_WIDGETS.iter() { if !DASHBOARD_DEFAULT_PRESET .dashboard_widgets .contains(&widget.id) && widget.default_hidden { hidden.push(widget.id.clone()); } } hidden } fn default_admin_dashboard_widgets() -> Vec { let mut order = DASHBOARD_DEFAULT_PRESET.dashboard_widgets.clone(); for widget in DASHBOARD_WIDGETS.iter() { if !order.contains(&widget.id) { order.push(widget.id.clone()); } } order }