| 4962 | if (!rows || !rows.length) { |
| 4963 | addConsoleMessage('Nothing to export yet — run it first', 'warning'); |
| 4964 | return; |
| 4965 | } |
| 4966 | const q = (c) => `"${String(c == null ? '' : c).replace(/"/g, '""')}"`; |
| 4967 | const csv = [header].concat(rows).map(r => r.map(q).join(',')).join('\n'); |
| 4968 | const blob = new Blob([csv], { type: 'text/csv' }); |
| 4969 | const url = URL.createObjectURL(blob); |
| 4970 | const a = document.createElement('a'); |
| 4971 | a.href = url; |
| 4972 | a.download = `ragnar_${nameBase}_${new Date().toISOString().slice(0, 10)}.csv`; |
| 4973 | a.click(); |
| 4974 | URL.revokeObjectURL(url); |
| 4975 | } |
| 4976 | |
| 4977 | function exportLldpCsv() { |
| 4978 | _ndDownloadCsv('switch_neighbors', |
| 4979 | ['Local IF', 'Protocol', 'Switch', 'Switch descr', 'Port', 'VLAN ID', 'VLAN name', 'PoE', 'Mgmt IP'], |
| 4980 | (_ndLastLldp || []).map(n => [n.local_interface, n.protocol, n.switch_name, |