import { useState } from 'react'; import { PREDEFINED_TAGS } from '../utils/classifications'; interface BulkClassificationProps { selectedIPs: string[]; onClose: () => void; onSuccess: () => void; } export function BulkClassification({ selectedIPs, onClose, onSuccess }: BulkClassificationProps) { const [selectedLabel, setSelectedLabel] = useState('suspicious'); const [selectedTags, setSelectedTags] = useState([]); const [comment, setComment] = useState(''); const [confidence, setConfidence] = useState(0.7); const [processing, setProcessing] = useState(false); const [progress, setProgress] = useState({ current: 0, total: selectedIPs.length }); const toggleTag = (tag: string) => { setSelectedTags(prev => prev.includes(tag) ? prev.filter(t => t !== tag) : [...prev, tag] ); }; const handleBulkClassify = async () => { setProcessing(true); try { // Process in batches of 10 const batchSize = 10; for (let i = 0; i < selectedIPs.length; i += batchSize) { const batch = selectedIPs.slice(i, i + batchSize); await Promise.all( batch.map(ip => fetch('/api/analysis/classifications', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ip, label: selectedLabel, tags: selectedTags, comment: `${comment} (Classification en masse - ${selectedIPs.length} IPs)`, confidence, analyst: 'soc_user', bulk_operation: true, bulk_id: `bulk-${Date.now()}` }) }) ) ); setProgress({ current: Math.min(i + batchSize, selectedIPs.length), total: selectedIPs.length }); } // Log the bulk operation await fetch('/api/audit/logs', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'BULK_CLASSIFICATION', entity_type: 'ip', entity_count: selectedIPs.length, details: { label: selectedLabel, tags: selectedTags, confidence } }) }); onSuccess(); } catch (error) { console.error('Bulk classification error:', error); alert('Erreur lors de la classification en masse'); } finally { setProcessing(false); } }; const handleExportCSV = () => { const csv = selectedIPs.map(ip => `${ip},${selectedLabel},"${selectedTags.join(';')}",${confidence},"${comment}"` ).join('\n'); const header = 'ip,label,tags,confidence,comment\n'; const blob = new Blob([header + csv], { type: 'text/csv' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `bulk_classification_${Date.now()}.csv`; document.body.appendChild(a); a.click(); document.body.removeChild(a); }; return (
{/* Header */}

🏷️ Classification en Masse

{selectedIPs.length} IPs sélectionnées

{/* Progress Bar */} {processing && (
Progression {progress.current} / {progress.total}
)} {/* Classification Label */}
{/* Tags */}
{PREDEFINED_TAGS.map(tag => ( ))}
{selectedTags.length > 0 && (
{selectedTags.length} tag(s) sélectionné(s)
)}
{/* Confidence Slider */}
setConfidence(parseFloat(e.target.value))} disabled={processing} className="w-full h-2 bg-background-card rounded-lg appearance-none cursor-pointer" />
0% 50% 100%
{/* Comment */}