polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
1,016 lines • 36 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.AlertPanel = void 0;
const blessed = __importStar(require("blessed"));
const base_component_1 = require("./base.component");
let screen = null;
let screenRefCount = 0;
const getScreen = () => {
if (!screen) {
try {
screen = blessed.screen({
smartCSR: true,
dockBorders: true,
});
}
catch (error) {
screen = {
render: () => { },
destroy: () => { },
};
}
}
screenRefCount++;
return screen;
};
const releaseScreen = () => {
screenRefCount--;
if (screenRefCount <= 0 && screen && screen.destroy) {
try {
screen.destroy();
}
catch {
}
screen = null;
screenRefCount = 0;
}
};
class AlertPanel extends base_component_1.BaseComponent {
constructor(config, eventBus) {
super(config, eventBus);
this.alerts = [];
this.filteredAlerts = [];
this.selectedAlertIndex = 0;
this.currentFilter = {};
this.showDetailsPane = false;
this.showFilterPane = false;
this.showStatisticsPane = false;
this.levelIcons = {
info: 'ⓘ',
warning: '⚠',
error: '✗',
critical: '🔴'
};
this.typeIcons = {
system: '⚙',
stream: '📹',
channel: '📺',
network: '🌐'
};
this.panelConfig = {
maxDisplayItems: 50,
autoScroll: true,
showTimestamps: true,
showSources: true,
showIds: false,
timeFormat: 'relative',
colorCoding: true,
compactMode: false,
...config.config['panelConfig'],
...config.config['alertPanel']
};
this.setupAlertEventListeners();
}
setupAlertEventListeners() {
this.subscribe('alert:new', this.handleNewAlert.bind(this));
this.subscribe('alert:acknowledged', this.handleAlertAcknowledged.bind(this));
this.subscribe('alert:resolved', this.handleAlertResolved.bind(this));
this.subscribe('alert:updated', this.handleAlertUpdated.bind(this));
this.subscribe('alert:filter', this.handleFilterChanged.bind(this));
this.subscribe('alert:clear', this.handleClearAlerts.bind(this));
}
createWidget() {
try {
this.widget = blessed.box({
parent: getScreen(),
top: this.config.position.y || 0,
left: this.config.position.x || 0,
width: this.config.position.width || '100%',
height: this.config.position.height || '100%',
label: ' Alert Center ',
border: { type: 'line' },
style: {
border: { fg: 'blue' },
label: { fg: 'white' },
},
keys: true,
mouse: true,
scrollable: true,
});
this.container = this.widget;
this.createAlertList();
this.createDetailsBox();
this.createFilterBox();
this.createStatisticsBox();
this.createActionBar();
this.actionBar.setContent(this.generateActionBarContent());
this.updateLayout();
this.bindKeyboardEvents();
this.bindMouseEvents();
}
catch (error) {
this.handleError(error instanceof Error ? error : new Error('Widget creation failed'));
}
}
createAlertList() {
this.alertList = blessed.list({
parent: this.container,
top: 1,
left: 0,
width: this.showDetailsPane ? '60%' : '100%',
height: this.showFilterPane || this.showStatisticsPane ? '70%' : '85%',
label: ' Alerts ',
border: { type: 'line' },
style: {
border: { fg: 'cyan' },
selected: { bg: 'blue', fg: 'white' },
item: { fg: 'white' },
},
keys: true,
mouse: true,
scrollable: true,
alwaysScroll: true,
scrollbar: {
ch: ' ',
track: {
bg: 'gray',
},
style: {
inverse: true,
},
},
});
}
createDetailsBox() {
this.detailsBox = blessed.box({
parent: this.container,
top: 1,
left: '60%',
width: '40%',
height: this.showFilterPane || this.showStatisticsPane ? '70%' : '85%',
label: ' Alert Details ',
border: { type: 'line' },
style: {
border: { fg: 'green' },
label: { fg: 'white' },
},
hidden: !this.showDetailsPane,
scrollable: true,
alwaysScroll: true,
keys: true,
mouse: true,
});
}
createFilterBox() {
this.filterBox = blessed.box({
parent: this.container,
top: '71%',
left: 0,
width: this.showDetailsPane ? '60%' : '100%',
height: '14%',
label: ' Filter & Search ',
border: { type: 'line' },
style: {
border: { fg: 'yellow' },
label: { fg: 'white' },
},
hidden: !this.showFilterPane,
scrollable: true,
content: this.generateFilterContent(),
});
}
createStatisticsBox() {
this.statisticsBox = blessed.box({
parent: this.container,
top: '71%',
left: this.showDetailsPane ? '60%' : (this.showFilterPane ? '0%' : '0%'),
width: this.showDetailsPane ? '40%' : '100%',
height: '14%',
label: ' Alert Statistics ',
border: { type: 'line' },
style: {
border: { fg: 'magenta' },
label: { fg: 'white' },
},
hidden: !this.showStatisticsPane,
content: 'Loading statistics...',
});
}
createActionBar() {
this.actionBar = blessed.box({
parent: this.container,
top: '86%',
left: 0,
width: '100%',
height: '14%',
label: ' Actions ',
border: { type: 'line' },
style: {
border: { fg: 'white' },
label: { fg: 'white' },
},
content: this.generateActionBarContent(),
});
}
updateLayout() {
if (!this.alertList || !this.detailsBox || !this.filterBox || !this.statisticsBox)
return;
this.alertList.width = this.showDetailsPane ? '60%' : '100%';
this.alertList.height = (this.showFilterPane || this.showStatisticsPane) ? '70%' : '85%';
this.detailsBox.hidden = !this.showDetailsPane;
this.detailsBox.height = (this.showFilterPane || this.showStatisticsPane) ? '70%' : '85%';
this.filterBox.hidden = !this.showFilterPane;
this.filterBox.width = this.showDetailsPane ? '60%' : '100%';
this.statisticsBox.hidden = !this.showStatisticsPane;
if (this.showStatisticsPane) {
if (this.showDetailsPane) {
this.statisticsBox.left = '60%';
this.statisticsBox.width = '40%';
}
else if (this.showFilterPane) {
this.statisticsBox.left = '0%';
this.statisticsBox.top = '71%';
this.statisticsBox.width = '100%';
}
else {
this.statisticsBox.left = '0%';
this.statisticsBox.width = '100%';
}
}
}
bindKeyboardEvents() {
if (!this.alertList)
return;
this.alertList.on('select', (_item, index) => {
this.selectedAlertIndex = index;
this.updateDetailsPane();
});
this.alertList.key(['up', 'k'], () => {
this.alertList.up(1);
this.selectedAlertIndex = Math.max(0, this.selectedAlertIndex - 1);
this.updateDetailsPane();
});
this.alertList.key(['down', 'j'], () => {
this.alertList.down(1);
this.selectedAlertIndex = Math.min(this.filteredAlerts.length - 1, this.selectedAlertIndex + 1);
this.updateDetailsPane();
});
}
bindMouseEvents() {
if (!this.alertList)
return;
this.alertList.on('click', () => {
this.updateDetailsPane();
});
}
handleCustomKeyboard(event) {
switch (event.key) {
case 'a':
this.acknowledgeSelectedAlert();
return true;
case 'r':
this.resolveSelectedAlert();
return true;
case 'i':
this.ignoreSelectedAlert();
return true;
case 'n':
this.addNotesToSelected();
return true;
case 'A':
this.acknowledgeAllFiltered();
return true;
case 'S':
this.resolveAllFiltered();
return true;
case 'd':
this.toggleDetailsPane();
return true;
case 'f':
this.toggleFilterPane();
return true;
case 's':
this.toggleStatisticsPane();
return true;
case 'c':
this.clearAllAlerts();
return true;
case 'x':
this.deleteSelectedAlert();
return true;
case 'R':
this.refreshAlerts();
return true;
case '1':
case '2':
case '3':
case '4':
case '5':
this.jumpToAlert(parseInt(event.key) - 1);
return true;
default:
return false;
}
}
generateActionBarContent() {
return [
'{bold}Alert Actions:{/bold}',
'[a]ck [r]esolve [i]gnore [n]otes [d]etails [f]ilter',
'[A]ck All [S]olve All [c]lear [x]delete [R]efresh',
'1-5: Jump to alert [s]tats [Esc]Close',
].join('\n');
}
generateFilterContent() {
const activeFilters = [];
if (this.currentFilter.levels?.length) {
activeFilters.push(`Levels: ${this.currentFilter.levels.join(', ')}`);
}
if (this.currentFilter.types?.length) {
activeFilters.push(`Types: ${this.currentFilter.types.join(', ')}`);
}
if (this.currentFilter.statuses?.length) {
activeFilters.push(`Status: ${this.currentFilter.statuses.join(', ')}`);
}
if (this.currentFilter.searchText) {
activeFilters.push(`Search: "${this.currentFilter.searchText}"`);
}
return activeFilters.length > 0
? `Active Filters:\n${activeFilters.join('\n')}`
: 'No active filters';
}
formatAlertForList(alert, index) {
const icon = this.levelIcons[alert.level];
const typeIcon = this.typeIcons[alert.type];
const timestamp = this.formatTimestamp(alert.timestamp);
const ackStatus = alert.acknowledged ? '✓' : ' ';
if (this.panelConfig.compactMode) {
return `${icon} ${alert.title} (${alert.source})`;
}
const parts = [];
if (this.panelConfig.showIds) {
parts.push(`[${index + 1}]`);
}
parts.push(`${icon}${typeIcon}`);
parts.push(ackStatus);
if (this.panelConfig.showTimestamps) {
parts.push(`[${timestamp}]`);
}
parts.push(alert.title);
if (this.panelConfig.showSources) {
parts.push(`(${alert.source})`);
}
return parts.join(' ');
}
formatTimestamp(timestamp) {
const date = new Date(timestamp);
if (this.panelConfig.timeFormat === 'relative') {
const now = Date.now();
const diff = now - timestamp;
if (diff < 60000) {
return `${Math.floor(diff / 1000)}s ago`;
}
else if (diff < 3600000) {
return `${Math.floor(diff / 60000)}m ago`;
}
else if (diff < 86400000) {
return `${Math.floor(diff / 3600000)}h ago`;
}
else {
return `${Math.floor(diff / 86400000)}d ago`;
}
}
else {
return date.toLocaleTimeString();
}
}
updateAlertList() {
if (!this.alertList)
return;
const items = this.filteredAlerts.map((alert, index) => this.formatAlertForList(alert, index));
this.alertList.setItems(items);
if (this.panelConfig.autoScroll && items.length > 0) {
this.alertList.select(items.length - 1);
this.selectedAlertIndex = items.length - 1;
}
const totalCount = this.alerts.length;
const filteredCount = this.filteredAlerts.length;
const label = totalCount === filteredCount
? ` Alerts (${totalCount}) `
: ` Alerts (${filteredCount}/${totalCount}) `;
this.alertList.setLabel(label);
}
updateDetailsPane() {
if (!this.detailsBox || !this.showDetailsPane)
return;
const selectedAlert = this.filteredAlerts[this.selectedAlertIndex];
if (!selectedAlert) {
this.detailsBox.setContent('No alert selected');
return;
}
const content = this.formatAlertDetails(selectedAlert);
this.detailsBox.setContent(content);
}
formatAlertDetails(alert) {
const lines = [];
lines.push(`{bold}Alert Details{/bold}`);
lines.push('');
lines.push(`ID: ${alert.id}`);
lines.push(`Level: ${this.levelIcons[alert.level]} ${alert.level.toUpperCase()}`);
lines.push(`Type: ${this.typeIcons[alert.type]} ${alert.type.toUpperCase()}`);
lines.push(`Status: ${alert.status.toUpperCase()}`);
lines.push('');
lines.push(`{bold}Title:{/bold} ${alert.title}`);
lines.push('');
lines.push(`{bold}Message:{/bold}`);
lines.push(alert.message);
lines.push('');
lines.push(`{bold}Source:{/bold} ${alert.source}`);
if (alert.channelId) {
lines.push(`{bold}Channel:{/bold} ${alert.channelId}`);
}
lines.push('');
lines.push(`{bold}Created:{/bold} ${new Date(alert.timestamp).toLocaleString()}`);
if (alert.acknowledged) {
lines.push(`{bold}Acknowledged:{/bold} ${alert.acknowledgedAt ? new Date(alert.acknowledgedAt).toLocaleString() : 'Yes'}`);
if (alert.acknowledgedBy) {
lines.push(`{bold}Acknowledged By:{/bold} ${alert.acknowledgedBy}`);
}
}
if (alert.resolvedAt) {
lines.push(`{bold}Resolved:{/bold} ${new Date(alert.resolvedAt).toLocaleString()}`);
}
if (alert.notes) {
lines.push('');
lines.push(`{bold}Notes:{/bold}`);
lines.push(alert.notes);
}
if (alert.metadata && Object.keys(alert.metadata).length > 0) {
lines.push('');
lines.push(`{bold}Metadata:{/bold}`);
Object.entries(alert.metadata).forEach(([key, value]) => {
lines.push(` ${key}: ${JSON.stringify(value)}`);
});
}
return lines.join('\n');
}
applyFilter() {
this.filteredAlerts = this.alerts.filter(alert => {
if (this.currentFilter.levels?.length && !this.currentFilter.levels.includes(alert.level)) {
return false;
}
if (this.currentFilter.types?.length && !this.currentFilter.types.includes(alert.type)) {
return false;
}
if (this.currentFilter.statuses?.length && !this.currentFilter.statuses.includes(alert.status)) {
return false;
}
if (this.currentFilter.sources?.length && !this.currentFilter.sources.includes(alert.source)) {
return false;
}
if (this.currentFilter.channelIds?.length && !this.currentFilter.channelIds.includes(alert.channelId || '')) {
return false;
}
if (this.currentFilter.timeRange) {
if (alert.timestamp < this.currentFilter.timeRange.start ||
alert.timestamp > this.currentFilter.timeRange.end) {
return false;
}
}
if (this.currentFilter.searchText) {
const searchText = this.currentFilter.searchText.toLowerCase();
return alert.title.toLowerCase().includes(searchText) ||
alert.message.toLowerCase().includes(searchText) ||
alert.source.toLowerCase().includes(searchText);
}
if (this.currentFilter.acknowledgedOnly && !alert.acknowledged) {
return false;
}
if (this.currentFilter.unacknowledgedOnly && alert.acknowledged) {
return false;
}
return true;
});
if (this.currentGrouping) {
this.applyGrouping();
}
this.filteredAlerts.sort((a, b) => b.timestamp - a.timestamp);
}
applyGrouping() {
if (!this.currentGrouping)
return;
const groups = new Map();
this.filteredAlerts.forEach(alert => {
const groupKey = alert[this.currentGrouping.field];
if (!groups.has(groupKey)) {
groups.set(groupKey, []);
}
groups.get(groupKey).push(alert);
});
this.filteredAlerts = [];
Array.from(groups.entries()).forEach(([, groupAlerts]) => {
groupAlerts.sort((a, b) => {
const aVal = a[this.currentGrouping.field];
const bVal = b[this.currentGrouping.field];
if (aVal === undefined && bVal === undefined)
return 0;
if (aVal === undefined)
return 1;
if (bVal === undefined)
return -1;
return this.currentGrouping.sortOrder === 'asc' ?
(aVal < bVal ? -1 : 1) : (aVal > bVal ? -1 : 1);
});
const limitedGroup = this.currentGrouping.maxPerGroup
? groupAlerts.slice(0, this.currentGrouping.maxPerGroup)
: groupAlerts;
this.filteredAlerts.push(...limitedGroup);
});
}
toggleDetailsPane() {
this.showDetailsPane = !this.showDetailsPane;
this.updateLayout();
this.updateDetailsPane();
this.throttledRender();
}
toggleFilterPane() {
this.showFilterPane = !this.showFilterPane;
this.updateLayout();
if (this.filterBox) {
this.filterBox.setContent(this.generateFilterContent());
}
this.throttledRender();
}
toggleStatisticsPane() {
this.showStatisticsPane = !this.showStatisticsPane;
this.updateLayout();
this.updateStatistics();
this.throttledRender();
}
updateStatistics() {
if (!this.statisticsBox || !this.showStatisticsPane)
return;
const stats = this.calculateStatistics();
const content = this.formatStatistics(stats);
this.statisticsBox.setContent(content);
}
calculateStatistics() {
const stats = {
total: this.alerts.length,
byLevel: { info: 0, warning: 0, error: 0, critical: 0 },
byType: { system: 0, stream: 0, channel: 0, network: 0 },
byStatus: { active: 0, acknowledged: 0, resolved: 0, ignored: 0 },
bySource: {},
last24Hours: 0,
mostFrequentType: 'system',
};
const now = Date.now();
const last24Hours = now - (24 * 60 * 60 * 1000);
const ackTimes = [];
const resolveTimes = [];
this.alerts.forEach(alert => {
stats.byLevel[alert.level]++;
stats.byType[alert.type]++;
stats.byStatus[alert.status]++;
stats.bySource[alert.source] = (stats.bySource[alert.source] || 0) + 1;
if (alert.timestamp >= last24Hours) {
stats.last24Hours++;
}
if (alert.acknowledged && alert.acknowledgedAt) {
ackTimes.push(alert.acknowledgedAt - alert.timestamp);
}
if (alert.resolvedAt) {
resolveTimes.push(alert.resolvedAt - alert.timestamp);
}
});
const typeEntries = Object.entries(stats.byType);
stats.mostFrequentType = typeEntries.reduce((a, b) => a[1] > b[1] ? a : b)[0];
if (ackTimes.length > 0) {
stats.avgTimeToAck = ackTimes.reduce((a, b) => a + b, 0) / ackTimes.length;
}
if (resolveTimes.length > 0) {
stats.avgTimeToResolve = resolveTimes.reduce((a, b) => a + b, 0) / resolveTimes.length;
}
return stats;
}
formatStatistics(stats) {
const lines = [];
lines.push(`{bold}Alert Statistics{/bold}`);
lines.push('');
lines.push(`Total Alerts: ${stats.total}`);
lines.push(`Last 24h: ${stats.last24Hours}`);
lines.push('');
lines.push(`{bold}By Level:{/bold}`);
Object.entries(stats.byLevel).forEach(([level, count]) => {
if (count > 0) {
const icon = this.levelIcons[level];
lines.push(` ${icon} ${level}: ${count}`);
}
});
lines.push('');
lines.push(`{bold}By Type:{/bold}`);
Object.entries(stats.byType).forEach(([type, count]) => {
if (count > 0) {
const icon = this.typeIcons[type];
lines.push(` ${icon} ${type}: ${count}`);
}
});
lines.push('');
lines.push(`{bold}By Status:{/bold}`);
Object.entries(stats.byStatus).forEach(([status, count]) => {
if (count > 0) {
lines.push(` ${status}: ${count}`);
}
});
if (stats.avgTimeToAck) {
lines.push('');
lines.push(`Avg Ack Time: ${Math.round(stats.avgTimeToAck / 1000)}s`);
}
if (stats.avgTimeToResolve) {
lines.push(`Avg Resolve Time: ${Math.round(stats.avgTimeToResolve / 60000)}m`);
}
return lines.join('\n');
}
acknowledgeSelectedAlert() {
const alert = this.filteredAlerts[this.selectedAlertIndex];
if (!alert || alert.acknowledged)
return;
this.acknowledgeAlert(alert.id);
}
ignoreSelectedAlert() {
const alert = this.filteredAlerts[this.selectedAlertIndex];
if (!alert)
return;
this.ignoreAlert(alert.id);
}
addNotesToSelected() {
const alert = this.filteredAlerts[this.selectedAlertIndex];
if (!alert)
return;
this.emit('alert:request-notes', { alertId: alert.id, alert });
}
jumpToAlert(index) {
if (index >= 0 && index < this.filteredAlerts.length) {
this.selectAlert(index);
}
}
resolveSelectedAlert() {
const alert = this.filteredAlerts[this.selectedAlertIndex];
if (!alert)
return;
this.resolveAlert(alert.id);
}
deleteSelectedAlert() {
const alert = this.filteredAlerts[this.selectedAlertIndex];
if (!alert)
return;
this.deleteAlert(alert.id);
}
clearAllAlerts() {
this.alerts = [];
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:cleared', { timestamp: Date.now() });
}
refreshAlerts() {
this.emit('alert:refresh', { timestamp: Date.now() });
}
addAlert(alert) {
this.alerts.unshift(alert);
if (this.alerts.length > this.panelConfig.maxDisplayItems) {
this.alerts = this.alerts.slice(0, this.panelConfig.maxDisplayItems);
}
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
}
deleteAlert(alertId) {
const index = this.alerts.findIndex(a => a.id === alertId);
if (index === -1)
return false;
this.alerts.splice(index, 1);
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:deleted', { alertId, timestamp: Date.now() });
return true;
}
setFilter(filter) {
this.currentFilter = { ...filter };
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
if (this.filterBox) {
this.filterBox.setContent(this.generateFilterContent());
}
this.throttledRender();
}
setGrouping(grouping) {
this.currentGrouping = grouping;
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.throttledRender();
}
getAlerts() {
return [...this.alerts];
}
getFilteredAlerts() {
return [...this.filteredAlerts];
}
getStatistics() {
return this.calculateStatistics();
}
acknowledgeCurrentAlert(user) {
const alert = this.getSelectedAlert();
if (!alert)
return false;
return this.acknowledgeAlert(alert.id, user);
}
acknowledgeAlert(alertId, user) {
return this.acknowledgeAlertInternal(alertId, user, true);
}
resolveCurrentAlert(user) {
const alert = this.getSelectedAlert();
if (!alert)
return false;
return this.resolveAlert(alert.id, user);
}
resolveAlert(alertId, user) {
return this.resolveAlertInternal(alertId, user, true);
}
ignoreCurrentAlert(user) {
const alert = this.getSelectedAlert();
if (!alert)
return false;
return this.ignoreAlert(alert.id, user);
}
ignoreAlert(alertId, user) {
const alert = this.alerts.find(a => a.id === alertId);
if (!alert || alert.status === 'ignored')
return false;
alert.status = 'ignored';
alert.acknowledgedAt = Date.now();
if (user) {
alert.acknowledgedBy = user;
}
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:ignored', { alertId, alert, user });
return true;
}
acknowledgeBatch(alertIds, user) {
const result = { success: [], failed: [] };
alertIds.forEach(alertId => {
if (this.acknowledgeAlertInternal(alertId, user, false)) {
result.success.push(alertId);
}
else {
result.failed.push(alertId);
}
});
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:batch-acknowledged', { success: result.success, failed: result.failed, user });
return result;
}
resolveBatch(alertIds, user) {
const result = { success: [], failed: [] };
alertIds.forEach(alertId => {
if (this.resolveAlertInternal(alertId, user, false)) {
result.success.push(alertId);
}
else {
result.failed.push(alertId);
}
});
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:batch-resolved', { success: result.success, failed: result.failed, user });
return result;
}
acknowledgeAllFiltered(user) {
const alertIds = this.filteredAlerts
.filter(alert => !alert.acknowledged)
.map(alert => alert.id);
const result = this.acknowledgeBatch(alertIds, user);
return result.success.length;
}
resolveAllFiltered(user) {
const alertIds = this.filteredAlerts
.filter(alert => alert.status === 'active' || alert.status === 'acknowledged')
.map(alert => alert.id);
const result = this.resolveBatch(alertIds, user);
return result.success.length;
}
addAlertNotes(alertId, notes, user) {
const alert = this.alerts.find(a => a.id === alertId);
if (!alert)
return false;
const timestamp = new Date().toISOString();
const noteEntry = user ? `[${timestamp}] ${user}: ${notes}` : `[${timestamp}] ${notes}`;
if (alert.notes) {
alert.notes += '\n' + noteEntry;
}
else {
alert.notes = noteEntry;
}
this.updateDetailsPane();
this.throttledRender();
this.emit('alert:notes-added', { alertId, alert, notes, user });
return true;
}
getSelectedAlert() {
if (this.selectedAlertIndex >= 0 && this.selectedAlertIndex < this.filteredAlerts.length) {
return this.filteredAlerts[this.selectedAlertIndex] || null;
}
return null;
}
selectAlert(index) {
if (index >= 0 && index < this.filteredAlerts.length) {
this.selectedAlertIndex = index;
if (this.alertList) {
this.alertList.select(index);
}
this.updateDetailsPane();
this.throttledRender();
return true;
}
return false;
}
selectAlertById(alertId) {
const index = this.filteredAlerts.findIndex(alert => alert.id === alertId);
if (index !== -1) {
return this.selectAlert(index);
}
return false;
}
acknowledgeAlertInternal(alertId, user, shouldUpdate = true) {
const alert = this.alerts.find(a => a.id === alertId);
if (!alert || alert.acknowledged)
return false;
alert.acknowledged = true;
alert.acknowledgedAt = Date.now();
if (user) {
alert.acknowledgedBy = user;
}
if (alert.status === 'active') {
alert.status = 'acknowledged';
}
if (shouldUpdate) {
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:acknowledged', { alertId, alert, user });
}
return true;
}
resolveAlertInternal(alertId, user, shouldUpdate = true) {
const alert = this.alerts.find(a => a.id === alertId);
if (!alert || alert.status === 'resolved')
return false;
alert.status = 'resolved';
alert.resolvedAt = Date.now();
if (!alert.acknowledged) {
alert.acknowledged = true;
alert.acknowledgedAt = Date.now();
if (user) {
alert.acknowledgedBy = user;
}
}
if (shouldUpdate) {
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
this.emit('alert:resolved', { alertId, alert, user });
}
return true;
}
handleNewAlert(data) {
this.addAlert(data.alert);
}
handleAlertAcknowledged(data) {
this.acknowledgeAlertInternal(data.alertId, data.user, false);
}
handleAlertResolved(data) {
this.resolveAlertInternal(data.alertId, undefined, false);
}
handleAlertUpdated(data) {
const index = this.alerts.findIndex(a => a.id === data.alert.id);
if (index !== -1) {
this.alerts[index] = data.alert;
this.applyFilter();
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
this.throttledRender();
}
}
handleFilterChanged(data) {
this.setFilter(data.filter);
}
handleClearAlerts() {
this.clearAllAlerts();
}
render() {
if (this.isDestroyed)
return;
try {
this.updateAlertList();
this.updateDetailsPane();
this.updateStatistics();
const currentScreen = getScreen();
if (currentScreen && currentScreen.render) {
currentScreen.render();
}
}
catch (error) {
this.handleError(error instanceof Error ? error : new Error('Render failed'));
}
}
update(data) {
if (this.isDestroyed)
return;
try {
if (data === null || data === undefined) {
return;
}
if (data.alerts && Array.isArray(data.alerts)) {
this.alerts = data.alerts;
this.applyFilter();
}
if (data.filter && typeof data.filter === 'object') {
this.setFilter(data.filter);
}
if (data.grouping) {
this.setGrouping(data.grouping);
}
this.updateState({ data, lastUpdate: new Date() });
this.throttledRender();
}
catch (error) {
this.handleError(error instanceof Error ? error : new Error('Update failed'));
}
}
destroy() {
this.alerts = [];
this.filteredAlerts = [];
super.destroy();
releaseScreen();
}
}
exports.AlertPanel = AlertPanel;
//# sourceMappingURL=alert.panel.js.map