diff --git a/frontend/src/views/admin/ops/OpsDashboard.vue b/frontend/src/views/admin/ops/OpsDashboard.vue index ff2a434d..d33f0f64 100644 --- a/frontend/src/views/admin/ops/OpsDashboard.vue +++ b/frontend/src/views/admin/ops/OpsDashboard.vue @@ -693,8 +693,8 @@ onMounted(async () => { async function loadThresholds() { try { - const settings = await opsAPI.getAlertRuntimeSettings() - metricThresholds.value = settings.thresholds || null + const thresholds = await opsAPI.getMetricThresholds() + metricThresholds.value = thresholds || null } catch (err) { console.warn('[OpsDashboard] Failed to load thresholds', err) metricThresholds.value = null diff --git a/frontend/src/views/admin/ops/components/OpsDashboardHeader.vue b/frontend/src/views/admin/ops/components/OpsDashboardHeader.vue index 2d52b6e8..8e868bba 100644 --- a/frontend/src/views/admin/ops/components/OpsDashboardHeader.vue +++ b/frontend/src/views/admin/ops/components/OpsDashboardHeader.vue @@ -169,42 +169,54 @@ const updatedAtLabel = computed(() => { return props.lastUpdated.toLocaleTimeString() }) -// --- Color coding for TTFT --- -function getTTFTColor(ms: number | null | undefined): string { - if (ms == null) return 'text-gray-900 dark:text-white' - if (ms < 500) return 'text-green-600 dark:text-green-400' - if (ms < 1000) return 'text-yellow-600 dark:text-yellow-400' - if (ms < 2000) return 'text-orange-600 dark:text-orange-400' - return 'text-red-600 dark:text-red-400' -} - // --- Threshold checking helpers --- -function isSLABelowThreshold(slaPercent: number | null): boolean { - if (slaPercent == null) return false +type ThresholdLevel = 'normal' | 'warning' | 'critical' + +function getSLAThresholdLevel(slaPercent: number | null): ThresholdLevel { + if (slaPercent == null) return 'normal' const threshold = props.thresholds?.sla_percent_min - if (threshold == null) return false - return slaPercent < threshold + if (threshold == null) return 'normal' + if (slaPercent < threshold) return 'critical' + if (slaPercent < threshold / 0.8) return 'warning' + return 'normal' } -function isTTFTAboveThreshold(ttftP99Ms: number | null): boolean { - if (ttftP99Ms == null) return false +function getTTFTThresholdLevel(ttftMs: number | null): ThresholdLevel { + if (ttftMs == null) return 'normal' const threshold = props.thresholds?.ttft_p99_ms_max - if (threshold == null) return false - return ttftP99Ms > threshold + if (threshold == null) return 'normal' + if (ttftMs >= threshold) return 'critical' + if (ttftMs >= threshold * 0.8) return 'warning' + return 'normal' } -function isRequestErrorRateAboveThreshold(errorRatePercent: number | null): boolean { - if (errorRatePercent == null) return false +function getRequestErrorRateThresholdLevel(errorRatePercent: number | null): ThresholdLevel { + if (errorRatePercent == null) return 'normal' const threshold = props.thresholds?.request_error_rate_percent_max - if (threshold == null) return false - return errorRatePercent > threshold + if (threshold == null) return 'normal' + if (errorRatePercent >= threshold) return 'critical' + if (errorRatePercent >= threshold * 0.8) return 'warning' + return 'normal' } -function isUpstreamErrorRateAboveThreshold(upstreamErrorRatePercent: number | null): boolean { - if (upstreamErrorRatePercent == null) return false +function getUpstreamErrorRateThresholdLevel(upstreamErrorRatePercent: number | null): ThresholdLevel { + if (upstreamErrorRatePercent == null) return 'normal' const threshold = props.thresholds?.upstream_error_rate_percent_max - if (threshold == null) return false - return upstreamErrorRatePercent > threshold + if (threshold == null) return 'normal' + if (upstreamErrorRatePercent >= threshold) return 'critical' + if (upstreamErrorRatePercent >= threshold * 0.8) return 'warning' + return 'normal' +} + +function getThresholdColorClass(level: ThresholdLevel): string { + switch (level) { + case 'critical': + return 'text-red-600 dark:text-red-400' + case 'warning': + return 'text-yellow-600 dark:text-yellow-400' + default: + return 'text-green-600 dark:text-green-400' + } } // --- Realtime / Overview labels --- @@ -1197,7 +1209,7 @@ function handleToolbarRefresh() {