diff --git a/extensions/Servers/Proxmox/views/firewall.blade.php b/extensions/Servers/Proxmox/views/firewall.blade.php index 663eea513..a22dde9dc 100644 --- a/extensions/Servers/Proxmox/views/firewall.blade.php +++ b/extensions/Servers/Proxmox/views/firewall.blade.php @@ -1107,6 +1107,44 @@ this.error = 'Failed to load connection data'; this.loading = false; }); + }, + exportToCsv() { + if (!this.connectionData || !this.connectionData.connections || this.connectionData.connections.length === 0) { + return; + } + + const headers = ['Protocol', 'Source IP', 'Source Port', 'Destination IP', 'Destination Port', 'Direction', 'State', 'Interface', 'Bytes', 'Packets']; + const rows = this.connectionData.connections.map(conn => [ + conn.protocol || '', + conn.source || '', + conn.source_port || '', + conn.destination || '', + conn.destination_port || '', + conn.direction || '', + conn.state || '', + conn.interface || '', + conn.bytes || 0, + conn.packets || 0 + ]); + + let csvContent = headers.join(',') + '\n'; + rows.forEach(row => { + csvContent += row.map(cell => { + const str = String(cell); + if (str.includes(',') || str.includes('"') || str.includes('\n')) { + return '"' + str.replace(/"/g, '""') + '"'; + } + return str; + }).join(',') + '\n'; + }); + + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); + const link = document.createElement('a'); + const timestamp = new Date().toISOString().slice(0, 19).replace(/[T:]/g, '-'); + link.href = URL.createObjectURL(blob); + link.download = `network-analysis-${this.sourceIP}-${timestamp}.csv`; + link.click(); + URL.revokeObjectURL(link.href); } }" x-cloak> @@ -1282,10 +1320,18 @@
Data from Core Router network state tracking
- +