UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

1,016 lines 36 kB
"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