document.addEventListener('DOMContentLoaded', function () { const CHART_COLORS = { red: 'rgba(234, 67, 53, 0.8)', orange: 'rgba(249, 171, 0, 0.8)', green: 'rgba(52, 168, 83, 0.8)', blue: 'rgba(26, 115, 232, 0.8)', }; const CHART_BORDERS = { red: 'rgb(234, 67, 53)', orange: 'rgb(249, 171, 0)', green: 'rgb(52, 168, 83)', blue: 'rgb(26, 115, 232)', }; const chartContexts = { perWarehouse: document.getElementById('alertsPerWarehouseChart')?.getContext('2d'), overTime: document.getElementById('alertsOverTimeChart')?.getContext('2d'), status: document.getElementById('alertStatusChart')?.getContext('2d') }; const charts = {}; function createOrUpdateChart(ctx, type, data, options) { const chartId = ctx.canvas.id; if (charts[chartId]) { charts[chartId].data = data; charts[chartId].options = options; charts[chartId].update(); } else { charts[chartId] = new Chart(ctx, { type, data, options }); } } function renderAlertsTable(alerts) { const tableBody = document.getElementById('alerts-table-body'); if (!tableBody) return; tableBody.innerHTML = ''; // Clear existing rows if (!alerts || alerts.length === 0) { tableBody.innerHTML = 'No active alerts found.'; return; } alerts.forEach(alert => { const statusBadge = getStatusBadge(alert.status); const row = ` ${alert.alert_id} ${new Date(alert.timestamp).toLocaleString()} ${alert.warehouse_name} ${alert.slot_name} ${alert.node_name} ${alert.metric_name} ${alert.actual_value} ${alert.threshold_value} ${alert.status} `; tableBody.insertAdjacentHTML('beforeend', row); }); } function getStatusBadge(status) { switch (status) { case 'active': return 'text-bg-danger'; case 'acknowledged': return 'text-bg-warning'; case 'resolved': return 'text-bg-success'; default: return 'text-bg-secondary'; } } function renderCharts(chartData) { // Chart 1: Alerts per Warehouse (Bar) if (chartContexts.perWarehouse && chartData.per_warehouse) { const data = { labels: chartData.per_warehouse.map(d => d.name), datasets: [{ label: 'Alerts', data: chartData.per_warehouse.map(d => d.alert_count), backgroundColor: CHART_COLORS.blue, borderColor: CHART_BORDERS.blue, borderWidth: 1 }] }; const options = { responsive: true, plugins: { legend: { display: false }, title: { display: true, text: 'Alerts per Warehouse' } }, scales: { y: { beginAtZero: true } } }; createOrUpdateChart(chartContexts.perWarehouse, 'bar', data, options); } // Chart 2: Alerts over Time (Line) if (chartContexts.overTime && chartData.over_time) { const data = { labels: chartData.over_time.map(d => d.alert_date), datasets: [{ label: 'Alerts', data: chartData.over_time.map(d => d.alert_count), borderColor: CHART_COLORS.red, backgroundColor: CHART_COLORS.red, tension: 0.1, fill: false }] }; const options = { responsive: true, plugins: { legend: { display: false }, title: { display: true, text: 'Alerts Over Last 7 Days' } }, scales: { y: { beginAtZero: true } } }; createOrUpdateChart(chartContexts.overTime, 'line', data, options); } // Chart 3: Alert Status (Pie) if (chartContexts.status && chartData.status_distribution) { const data = { labels: chartData.status_distribution.map(d => d.status), datasets: [{ label: 'Alerts', data: chartData.status_distribution.map(d => d.alert_count), backgroundColor: [CHART_COLORS.red, CHART_COLORS.orange, CHART_COLORS.green], borderColor: [CHART_BORDERS.red, CHART_BORDERS.orange, CHART_BORDERS.green], borderWidth: 1 }] }; const options = { responsive: true, plugins: { legend: { position: 'top' }, title: { display: true, text: 'Alert Status Distribution' } } }; createOrUpdateChart(chartContexts.status, 'pie', data, options); } } async function fetchData() { const tableBody = document.getElementById('alerts-table-body'); try { const response = await fetch('api/alerts-data.php'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); if (data.success) { renderAlertsTable(data.alerts); renderCharts(data.chart_data); } else { console.error('API Error:', data.error); if(tableBody) tableBody.innerHTML = `Failed to load data from API.`; } } catch (error) { console.error('Fetch Error:', error); if(tableBody) tableBody.innerHTML = `Error fetching data. Check console for details.`; } } fetchData(); // setInterval(fetchData, 30000); // Optional: Refresh every 30 seconds });