(message, type = 'info')
| 12022 | <p>No files collected for this network yet.</p> |
| 12023 | </div>`; |
| 12024 | return; |
| 12025 | } |
| 12026 | |
| 12027 | // Group by category |
| 12028 | const grouped = {}; |
| 12029 | files.forEach(f => { |
| 12030 | if (!grouped[f.category]) grouped[f.category] = []; |
| 12031 | grouped[f.category].push(f); |
| 12032 | }); |
| 12033 | |
| 12034 | let html = ''; |
| 12035 | const categoryOrder = ['data_stolen', 'credentials', 'vulnerabilities', 'scan_results']; |
| 12036 | |
| 12037 | categoryOrder.forEach(cat => { |
| 12038 | if (!grouped[cat] || grouped[cat].length === 0) return; |
| 12039 | const meta = NETWORK_FILE_CATEGORY_LABELS[cat] || { label: cat, color: 'text-gray-300' }; |
| 12040 | |
| 12041 | html += ` |
| 12042 | <div class="mb-6"> |
| 12043 | <h4 class="text-sm font-semibold uppercase tracking-wider ${meta.color} mb-3">${meta.label} (${grouped[cat].length})</h4> |
| 12044 | <div class="space-y-2">`; |
| 12045 | |
| 12046 | grouped[cat].forEach(file => { |
| 12047 | const fname = escapeHtml(file.filename); |
| 12048 | const size = escapeHtml(file.size || ''); |
| 12049 | const mod = escapeHtml(file.modified || ''); |
| 12050 | const vpath = file.virtual_path ? encodeURIComponent(file.virtual_path) : ''; |
| 12051 | const clickable = !!vpath; |
| 12052 |
no test coverage detected