feat: tooltips universels sur l'ensemble du site

- CampaignsView: Score menace, JA4, ASN, Tendance, Score, Détections, Confiance
- FingerprintsView: colonnes avec tooltips via DataTable
- JA4InvestigationView: IPs Uniques, JA4, ASN, Score
- SubnetInvestigation: colonnes clés avec tooltips
- CorrelationGraph: légende et badges
- EntityInvestigationView: sections headers, JA4, ASN
- IncidentsView: stat cards, sévérité, ASN, Score de risque
- Fix: suppression des imports dupliqués dans CampaignsView

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
SOC Analyst
2026-03-19 12:24:53 +01:00
parent b0999ee83a
commit da6fef87fd
11 changed files with 70 additions and 44 deletions

View File

@ -1,5 +1,7 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { InfoTip } from './ui/Tooltip';
import { TIPS } from './ui/tooltips';
interface IncidentCluster {
id: string;
@ -147,10 +149,10 @@ export function IncidentsView() {
{baseline && (
<div className="grid grid-cols-3 gap-3">
{([
{ key: 'total_detections', label: 'Détections 24h', icon: '📊' },
{ key: 'unique_ips', label: 'IPs uniques', icon: '🖥️' },
{ key: 'critical_alerts', label: 'Alertes CRITICAL', icon: '🔴' },
] as { key: keyof BaselineData; label: string; icon: string }[]).map(({ key, label, icon }) => {
{ key: 'total_detections', label: 'Détections 24h', icon: '📊', tip: TIPS.total_detections_stat },
{ key: 'unique_ips', label: 'IPs uniques', icon: '🖥️', tip: TIPS.unique_ips_stat },
{ key: 'critical_alerts', label: 'Alertes CRITICAL', icon: '🔴', tip: TIPS.risk_critical },
] as { key: keyof BaselineData; label: string; icon: string; tip: string }[]).map(({ key, label, icon, tip }) => {
const m = baseline[key];
const up = m.pct_change > 0;
const neutral = m.pct_change === 0;
@ -158,7 +160,7 @@ export function IncidentsView() {
<div key={key} className="bg-background-card border border-border rounded-lg px-4 py-3 flex items-center gap-3">
<span className="text-xl">{icon}</span>
<div className="flex-1 min-w-0">
<div className="text-xs text-text-disabled uppercase tracking-wide">{label}</div>
<div className="text-xs text-text-disabled uppercase tracking-wide flex items-center gap-1">{label}<InfoTip content={tip} /></div>
<div className="text-xl font-bold text-text-primary">{m.today.toLocaleString('fr-FR')}</div>
<div className="text-xs text-text-secondary">hier: {m.yesterday.toLocaleString('fr-FR')}</div>
</div>
@ -292,7 +294,7 @@ export function IncidentsView() {
<div className="flex-1">
<div className="flex items-start justify-between mb-3">
<div className="flex items-center gap-3">
<span className={`px-2 py-1 rounded text-xs font-bold ${getSeverityBadgeColor(cluster.severity)}`}>
<span title={cluster.severity === 'CRITICAL' ? TIPS.risk_critical : cluster.severity === 'HIGH' ? TIPS.risk_high : cluster.severity === 'MEDIUM' ? TIPS.risk_medium : TIPS.risk_low} className={`px-2 py-1 rounded text-xs font-bold ${getSeverityBadgeColor(cluster.severity)}`}>
{cluster.severity}
</span>
<span className="text-lg font-bold text-text-primary">{cluster.id}</span>
@ -302,7 +304,7 @@ export function IncidentsView() {
<div className="flex items-center gap-4">
<div className="text-right">
<div className="text-2xl font-bold text-text-primary">{cluster.score}/100</div>
<div className="text-xs text-text-secondary">Score de risque</div>
<div className="text-xs text-text-secondary flex items-center gap-1">Score de risque<InfoTip content={TIPS.risk_score_inv} /></div>
</div>
</div>
</div>
@ -327,11 +329,11 @@ export function IncidentsView() {
</div>
</div>
<div>
<div className="text-xs text-text-secondary mb-1">ASN</div>
<div className="text-xs text-text-secondary mb-1 flex items-center gap-1">ASN<InfoTip content={TIPS.asn} /></div>
<div className="text-text-primary">AS{cluster.asn || '?'}</div>
</div>
<div>
<div className="text-xs text-text-secondary mb-1">Tendance</div>
<div className="text-xs text-text-secondary mb-1 flex items-center gap-1">Tendance<InfoTip content={TIPS.tendance} /></div>
<div className={`font-bold ${
cluster.trend === 'up' ? 'text-red-500' :
cluster.trend === 'down' ? 'text-green-500' :
@ -344,7 +346,7 @@ export function IncidentsView() {
{cluster.ja4 && (
<div className="mb-3 p-2 bg-background-card rounded">
<div className="text-xs text-text-secondary mb-1">JA4 Principal</div>
<div className="text-xs text-text-secondary mb-1 flex items-center gap-1">JA4 Principal<InfoTip content={TIPS.ja4} /></div>
<div className="font-mono text-xs text-text-primary break-all">{cluster.ja4}</div>
</div>
)}