- useEffect pointerdown + Escape listeners when dropdown open (NIT 1)
- empty state now renders NewSimulationDropdown instead of plain Link (NIT 2)
- 3 new Vitest: close-on-outside, close-on-Escape, empty-state has dropdown
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MitreTechniquesField test: rewrite dedup test to actually exercise picker
selection path — types query, waits for option, fires pointerDown,
asserts no PATCH sent (dedup guard in handleSelect now truly covered)
- MitreMatrixModal: Apply button disabled only when totalSelected === 0
AND initialSelection.length === 0 (no-op case); when totalSelected === 0
but initialSelection was non-empty, shows "Clear all" and stays enabled
so user can explicitly wipe the list
- MitreMatrixModal tests: update disabled test to match "Clear all" label,
add "Clear all" enabled + onApply([]) path test
- SimulationList: stopPropagation on Name <Link> to prevent double-navigate
with row onClick handler
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Translate all remaining French strings to English (toasts, buttons, banner)
- Fix UsersAdminPage create-form grid alignment: items-start + self-end on button wrapper
- Change execution_result from TextInput to TextArea (5 rows, multiline)
- Replace split Save RT / Save SOC footers + workflow div with a single sticky
action bar (Save Red Team | Save SOC | Mark for review | Close | Delete)
- Update Vitest assertions to use English button labels
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MitreTechniquePicker: guard sync effect while dropdown open to prevent
mid-stroke wipe when onChange(null,null) propagates back as null props
- SimulationList: replace window.location.href with navigate() to keep
TanStack Query cache intact on row click
- SimulationFormPage: simplify redundant ternary on SOC form onSubmit
- SimulationFormPage: remove dead .replace(' ','T') on executed_at
(backend already returns ISO 8601 with T separator)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>