From 878eb937f3f6057431cc49449a8df0f248c8efac Mon Sep 17 00:00:00 2001 From: rcourtman Date: Fri, 12 Dec 2025 14:55:08 +0000 Subject: [PATCH] feat(ui): Add AI Insights Panel component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add collapsible panel to display AI-learned intelligence: Features: - Failure predictions with time estimates - Color-coded severity (overdue=red, <3 days=amber, etc.) - Human-readable event types and confidence percentages - Resource dependency/correlation display - Shows source → target relationships with avg delay - Expandable/collapsible design to save space Styling: - Purple gradient theme consistent with AI branding - Responsive with dark mode support - Clean card-based layout for predictions - Badge showing total insight count Ready to integrate into Alerts page or resource details. --- .../src/components/shared/AIInsightsPanel.tsx | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 frontend-modern/src/components/shared/AIInsightsPanel.tsx diff --git a/frontend-modern/src/components/shared/AIInsightsPanel.tsx b/frontend-modern/src/components/shared/AIInsightsPanel.tsx new file mode 100644 index 0000000..2aa2e12 --- /dev/null +++ b/frontend-modern/src/components/shared/AIInsightsPanel.tsx @@ -0,0 +1,197 @@ +import { Component, createSignal, createEffect, Show, For } from 'solid-js'; +import { AIAPI } from '@/api/ai'; +import type { FailurePrediction, ResourceCorrelation } from '@/types/aiIntelligence'; + +/** + * AIInsightsPanel displays AI-learned predictions and correlations + * Shows failure predictions with confidence levels and resource dependencies + */ +export const AIInsightsPanel: Component<{ resourceId?: string }> = (props) => { + const [predictions, setPredictions] = createSignal([]); + const [correlations, setCorrelations] = createSignal([]); + const [loading, setLoading] = createSignal(false); + const [expanded, setExpanded] = createSignal(false); + + const loadData = async () => { + setLoading(true); + try { + const [predResp, corrResp] = await Promise.all([ + AIAPI.getPredictions(props.resourceId), + AIAPI.getCorrelations(props.resourceId), + ]); + setPredictions(predResp.predictions || []); + setCorrelations(corrResp.correlations || []); + } catch (e) { + console.error('Failed to load AI insights:', e); + } finally { + setLoading(false); + } + }; + + createEffect(() => { + loadData(); + }); + + const totalInsights = () => predictions().length + correlations().length; + + // Format days until in a human-readable way + const formatDaysUntil = (days: number) => { + if (days < 0) return 'Overdue'; + if (days < 1) return 'Today'; + if (days < 2) return 'Tomorrow'; + return `In ${Math.round(days)} days`; + }; + + // Get severity color based on days until and confidence + const getPredictionColor = (pred: FailurePrediction) => { + if (pred.is_overdue || pred.days_until < 0) return 'text-red-600 dark:text-red-400'; + if (pred.days_until < 3) return 'text-amber-600 dark:text-amber-400'; + if (pred.days_until < 7) return 'text-yellow-600 dark:text-yellow-400'; + return 'text-blue-600 dark:text-blue-400'; + }; + + // Get event type display name + const getEventDisplayName = (eventType: string) => { + const names: Record = { + high_memory: 'High Memory', + high_cpu: 'High CPU', + disk_full: 'Disk Full', + oom: 'Out of Memory', + restart: 'Restart', + unresponsive: 'Unresponsive', + backup_failed: 'Backup Failure', + }; + return names[eventType] || eventType; + }; + + return ( + 0 || loading()}> +
+ {/* Header */} + + + {/* Content */} + +
+ {/* Loading state */} + +
+ + Loading insights... +
+
+ + {/* Predictions */} + 0}> +
+

+ + + + Failure Predictions +

+
+ + {(pred) => ( +
+
+
+
+ {getEventDisplayName(pred.event_type)} + + {formatDaysUntil(pred.days_until)} + +
+

+ {pred.basis} +

+
+
+
+ {Math.round(pred.confidence * 100)}% confidence +
+
+
+
+ )} +
+
+
+
+ + {/* Correlations */} + 0}> +
+

+ + + + Resource Dependencies +

+
+ + {(corr) => ( +
+
+ + {corr.source_name || corr.source_id} + + + + + + {corr.target_name || corr.target_id} + +
+

+ {corr.description || `${corr.event_pattern} (${corr.occurrences} observations)`} +

+
+ Avg delay: {corr.avg_delay} + Confidence: {Math.round(corr.confidence * 100)}% +
+
+ )} +
+
+
+
+ + {/* Empty state */} + +

+ No predictions or correlations detected yet. The AI will learn patterns over time. +

+
+
+
+
+
+ ); +};