fix(alerts): limit alerts to 500 per type in SQL + frontend pagination with 'Ver más' + summary bar

This commit is contained in:
2026-05-26 09:12:09 +00:00
parent 3009ffa1b0
commit 61bf84b2dc
4 changed files with 109 additions and 54 deletions

View File

@@ -686,6 +686,7 @@
apiFetch(API + '/alerts').then(function (data) {
if (!data) return;
var alerts = data.data || [];
var counts = data.counts || {};
if (!container) return;
if (!alerts.length) {
@@ -697,45 +698,56 @@
return;
}
var html = '';
// Summary bar
var html = '<div style="display:flex;gap:var(--space-3);flex-wrap:wrap;margin-bottom:var(--space-6);padding:var(--space-4);background:var(--color-surface-2);border-radius:var(--radius-lg);">' +
'<div style="font-size:var(--text-sm);font-weight:700;">Resumen de alertas</div>' +
(counts.critical ? '<span class="badge badge--low">' + counts.critical + ' crítica' + (counts.critical !== 1 ? 's' : '') + '</span>' : '') +
(counts.warning ? '<span class="badge badge--over">' + counts.warning + ' advertencia' + (counts.warning !== 1 ? 's' : '') + '</span>' : '') +
(counts.info ? '<span class="badge badge--ok">' + counts.info + ' informativa' + (counts.info !== 1 ? 's' : '') + '</span>' : '') +
'</div>';
// Group by severity
var critical = alerts.filter(function (a) { return a.severity === 'critical'; });
var warning = alerts.filter(function (a) { return a.severity === 'warning'; });
var info = alerts.filter(function (a) { return a.severity !== 'critical' && a.severity !== 'warning'; });
if (critical.length) {
html += '<div class="section-heading"><span class="section-heading__title">Criticas</span><div class="section-heading__line"></div><span class="badge badge--low">' + critical.length + '</span></div>';
html += '<div class="alerts-grid" style="margin-bottom:var(--space-6);">';
critical.forEach(function (a) {
var icon = a.type === 'zero' ? 'AGOTADO' : (a.type === 'low' ? 'BAJO' : a.type.toUpperCase());
html += buildAlertCard(a, icon, 'critical');
});
html += '</div>';
}
if (warning.length) {
html += '<div class="section-heading"><span class="section-heading__title">Advertencias</span><div class="section-heading__line"></div><span class="badge badge--over">' + warning.length + '</span></div>';
html += '<div class="alerts-grid" style="margin-bottom:var(--space-6);">';
warning.forEach(function (a) {
html += buildAlertCard(a, 'EXCESO', 'warning');
});
html += '</div>';
}
if (info.length) {
html += '<div class="section-heading"><span class="section-heading__title">Informativas</span><div class="section-heading__line"></div><span class="badge badge--ok">' + info.length + '</span></div>';
html += '<div class="alerts-grid" style="margin-bottom:var(--space-6);">';
info.forEach(function (a) {
html += buildAlertCard(a, 'INFO', 'info');
});
html += '</div>';
}
html += renderAlertSection('Criticas', critical, 'critical', 'badge--low');
html += renderAlertSection('Advertencias', warning, 'warning', 'badge--over');
html += renderAlertSection('Informativas', info, 'info', 'badge--ok');
container.innerHTML = html;
});
}
function renderAlertSection(title, alerts, level, badgeClass) {
if (!alerts.length) return '';
var initialLimit = 30;
var showAll = window._alertsShowAll && window._alertsShowAll[level];
var display = showAll ? alerts : alerts.slice(0, initialLimit);
var remaining = alerts.length - display.length;
var html = '<div class="section-heading"><span class="section-heading__title">' + title + '</span><div class="section-heading__line"></div><span class="badge ' + badgeClass + '">' + alerts.length + '</span></div>';
html += '<div class="alerts-grid" style="margin-bottom:var(--space-6);">';
display.forEach(function (a) {
var icon = a.type === 'zero' ? 'AGOTADO' : (a.type === 'low' ? 'BAJO' : a.type.toUpperCase());
html += buildAlertCard(a, icon, level);
});
html += '</div>';
if (remaining > 0) {
html += '<div style="text-align:center;margin-bottom:var(--space-6);">' +
'<button class="btn btn--ghost btn--sm" onclick="window._showMoreAlerts(\'' + level + '\')">Ver ' + remaining + ' más</button>' +
'</div>';
}
return html;
}
window._showMoreAlerts = function(level) {
window._alertsShowAll = window._alertsShowAll || {};
window._alertsShowAll[level] = true;
loadAlerts();
};
function buildAlertCard(a, icon, level) {
var cls = level === 'critical' ? 'alert-card--critical' : (level === 'warning' ? 'alert-card--warning' : 'alert-card--info');
return '<div class="alert-card ' + cls + '">' +