36209-vm/assets/js/alerts.js
Flatlogic Bot bc7bcad072 2
2025-11-24 14:56:59 +00:00

165 lines
6.6 KiB
JavaScript

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 = '<tr><td colspan="10" class="text-center text-muted">No active alerts found.</td></tr>';
return;
}
alerts.forEach(alert => {
const statusBadge = getStatusBadge(alert.status);
const row = `
<tr>
<td><span class="fw-bold">${alert.alert_id}</span></td>
<td>${new Date(alert.timestamp).toLocaleString()}</td>
<td>${alert.warehouse_name}</td>
<td>${alert.slot_name}</td>
<td>${alert.node_name}</td>
<td>${alert.metric_name}</td>
<td><span class="fw-bold text-danger">${alert.actual_value}</span></td>
<td>${alert.threshold_value}</td>
<td><span class="badge ${statusBadge}">${alert.status}</span></td>
<td>
<button class="btn btn-sm btn-outline-secondary" title="Acknowledge"><i class="bi bi-check-circle"></i></button>
<button class="btn btn-sm btn-outline-secondary" title="Resolve"><i class="bi bi-patch-check"></i></button>
</td>
</tr>
`;
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 = `<tr><td colspan="10" class="text-center text-danger">Failed to load data from API.</td></tr>`;
}
} catch (error) {
console.error('Fetch Error:', error);
if(tableBody) tableBody.innerHTML = `<tr><td colspan="10" class="text-center text-danger">Error fetching data. Check console for details.</td></tr>`;
}
}
fetchData();
// setInterval(fetchData, 30000); // Optional: Refresh every 30 seconds
});