fix(campaigns): make Expected Detection editable when adding a test to a campaign
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled

Was a read-only reference shown only when the template already had
content, unlike the standalone create-from-template form where it's
an editable field feeding detect_procedure on the new test. Brought
the campaign flow in line with that so leads get the same editing
capability regardless of whether the test is going into a campaign.
This commit is contained in:
kitos
2026-07-15 16:49:43 +02:00
parent 68ab6406d4
commit 8d9e25703d
@@ -89,6 +89,7 @@ export default function AddTestToCampaignModal({
const [formPlatform, setFormPlatform] = useState(""); const [formPlatform, setFormPlatform] = useState("");
const [formProcedure, setFormProcedure] = useState(""); const [formProcedure, setFormProcedure] = useState("");
const [formTool, setFormTool] = useState(""); const [formTool, setFormTool] = useState("");
const [formExpectedDetection, setFormExpectedDetection] = useState("");
// ── reset when closed ──────────────────────────────────────────── // ── reset when closed ────────────────────────────────────────────
useEffect(() => { useEffect(() => {
@@ -143,6 +144,7 @@ export default function AddTestToCampaignModal({
setFormPlatform(fullTemplate.platform || ""); setFormPlatform(fullTemplate.platform || "");
setFormProcedure(fullTemplate.attack_procedure || ""); setFormProcedure(fullTemplate.attack_procedure || "");
setFormTool(fullTemplate.tool_suggested || ""); setFormTool(fullTemplate.tool_suggested || "");
setFormExpectedDetection(fullTemplate.expected_detection || "");
} }
}, [fullTemplate]); }, [fullTemplate]);
@@ -179,6 +181,7 @@ export default function AddTestToCampaignModal({
platform: formPlatform.trim() || undefined, platform: formPlatform.trim() || undefined,
procedure_text: formProcedure.trim() || undefined, procedure_text: formProcedure.trim() || undefined,
tool_used: formTool.trim() || undefined, tool_used: formTool.trim() || undefined,
detect_procedure: formExpectedDetection.trim() || undefined,
}, },
); );
await addTestToCampaign(campaignId, { test_id: test.id }); await addTestToCampaign(campaignId, { test_id: test.id });
@@ -455,20 +458,19 @@ export default function AddTestToCampaignModal({
/> />
</div> </div>
{/* Expected detection — read-only reference */} {/* Expected Detection */}
{fullTemplate?.expected_detection && (
<div> <div>
<label className="mb-1.5 block text-sm font-medium text-gray-300"> <label className="mb-1.5 block text-sm font-medium text-gray-300">
Expected Detection Expected Detection
<span className="ml-2 text-xs text-gray-500">(reference Blue Team)</span>
</label> </label>
<div className="rounded-lg border border-gray-700 bg-gray-800/50 p-3"> <textarea
<p className="whitespace-pre-wrap font-mono text-xs text-gray-400"> value={formExpectedDetection}
{fullTemplate.expected_detection} onChange={(e) => setFormExpectedDetection(e.target.value)}
</p> rows={4}
className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 font-mono text-sm text-gray-200 placeholder-gray-500 focus:border-cyan-500 focus:outline-none"
placeholder="What the blue team should detect, and how..."
/>
</div> </div>
</div>
)}
{/* Error */} {/* Error */}
{createAndAddMutation.isError && ( {createAndAddMutation.isError && (