diff --git a/CHANGELOG.md b/CHANGELOG.md index 9070a1a..d664c05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,8 +33,16 @@ row per test) with double-click inline edit. - **`tasks/spec.md` amended** — §4 in-scope bullet on blue saisie now lists the 5 fields, §F6 describes the tabular UX (full-bleed, one table per scenario, double-click inline edit), §8 model bullet enumerates the new columns. Header carries a `revised: 2026-05-15` note pointing readers at the amendment. - **`tasks/todo.md` M7 section** carries a dedicated "Amendement 2026-05-15" sub-block tracking the backend (☑) and frontend (☐) items. -#### Frontend (in progress) -- Tabular layout per scenario, full screen width (escape `max-w-page` like the MITRE picker), columns `Test | Procédure | Exécution | Source de log | Commentaires | Logs SIEM | Cyber Incident`. Double-click row → inline edit gated by red/blue perms. Per-test page kept for evidence upload. +#### Frontend (shipped) +- **`MissionScenarioTable` component** (`frontend/src/pages/MissionScenarioTable.tsx`): per-scenario `
| # | -Test | -MITRE | -OPSEC | -State | -
|---|---|---|---|---|
| {t.position + 1} | -- - {t.snapshot_name} - - | -
-
- {t.mitre_tags.map((tag) => (
-
- |
- - {t.snapshot_opsec_level} - | -
- |
-
+ {test.executed_at ?? '—'}
+
+ {test.red_command && (
+
+ {truncate(test.red_command, 140)}
+
+ )}
+ + {truncate(test.blue_comment_md, 220)} +
+ )} +{test.blue_incident_at}
+ )}
+ {test.blue_incident_number && (
+ {test.blue_incident_number}
+ )}
+ {test.blue_incident_recipient_email && (
+ {test.blue_incident_recipient_email}
+ )}
+ | Test | +Procédure | +Exécution | +Source de log | +Commentaires | +Logs SIEM | +Cyber Incident | +Actions | +
|---|---|---|---|---|---|---|---|
|
+
+ {t.snapshot_name}
+
+
+ {t.mitre_tags.slice(0, 3).map((tag) => (
+
+ |
+ + {truncate( + t.snapshot_objective ?? t.snapshot_description ?? '', + 180, + )} + | +
+ |
+ + {t.blue_log_source ?? '—'} + | +
+ |
+ + {truncate(t.blue_siem_logs, 240)} + | +
+ |
+ + + open ↗ + + | +
|
+
+ {t.snapshot_name}
+
+
+ {t.mitre_tags.slice(0, 3).map((tag) => (
+
+ |
+ + {t.snapshot_objective ?? t.snapshot_description ?? ''} + | +
+
+ set('executed_at', e.target.value)}
+ disabled={!canWriteRed}
+ className="w-full rounded border border-border bg-bg-card px-1 py-1 font-mono text-3xs text-text-bright"
+ data-testid={`cell-executed-at-${t.id}`}
+ />
+
+ |
+ + set('blue_log_source', e.target.value)} + disabled={!canWriteBlue} + placeholder="EDR / Firewall / NDR …" + className="w-full rounded border border-border bg-bg-card px-1 py-1 font-mono text-3xs text-text" + data-testid={`cell-log-source-${t.id}`} + /> + | +
+
+
+
+ |
+ + | +
+
+ set('blue_incident_at', e.target.value)}
+ disabled={!canWriteBlue}
+ className="w-full rounded border border-border bg-bg-card px-1 py-1 font-mono text-3xs text-text"
+ data-testid={`cell-incident-at-${t.id}`}
+ />
+
+ set('blue_incident_number', e.target.value)
+ }
+ disabled={!canWriteBlue}
+ placeholder="INC-2026-…"
+ className="w-full rounded border border-border bg-bg-card px-1 py-1 font-mono text-3xs text-text"
+ data-testid={`cell-incident-number-${t.id}`}
+ />
+
+ set('blue_incident_recipient_email', e.target.value)
+ }
+ disabled={!canWriteBlue}
+ placeholder="soc@…"
+ className="w-full rounded border border-border bg-bg-card px-1 py-1 font-mono text-3xs text-text"
+ data-testid={`cell-incident-email-${t.id}`}
+ />
+
+ |
+
+
+
+
+ {apiErr && (
+
+ + {apiErr} + + )} + |
+
+ Double-click a row to edit · Esc to cancel · "open ↗" for the full + per-test page (evidence upload, full procedure) +
+