diff --git a/frontend/src/components/test-detail/TeamTabs.tsx b/frontend/src/components/test-detail/TeamTabs.tsx index 4b25291..ca2b4f6 100644 --- a/frontend/src/components/test-detail/TeamTabs.tsx +++ b/frontend/src/components/test-detail/TeamTabs.tsx @@ -118,18 +118,46 @@ export default function TeamTabs({ enabled: !!test.technique_mitre_id, }); + // Leads and admins can edit during both draft and executing phases. + // Operators (red_tech) may only edit once execution has started — + // the timer must be running before they can document the attack. const canEditRed = - RED_EDITABLE_STATES.includes(test.state) && - (role === "red_tech" || role === "red_lead" || role === "admin"); + (test.state === "red_executing" && + (role === "red_tech" || role === "red_lead" || role === "admin")) || + (test.state === "draft" && (role === "red_lead" || role === "admin")); + // Blue operators may only edit after they explicitly pick up the test + // (Start Evaluation pressed → blue_work_started_at is set). + // Blue leads and admins can edit at any point during blue_evaluating. const canEditBlue = BLUE_EDITABLE_STATES.includes(test.state) && - (role === "blue_tech" || role === "blue_lead" || role === "admin"); + ((role === "blue_lead" || role === "admin") || + (role === "blue_tech" && !!test.blue_work_started_at)); + + // Hint messages shown to operators when editing is locked + const redLockedHint = + test.state === "draft" && role === "red_tech" + ? "Press Start Execution to begin editing — the timer must be running first." + : null; + + const blueLockedHint = + BLUE_EDITABLE_STATES.includes(test.state) && + role === "blue_tech" && + !test.blue_work_started_at + ? "Press Start Evaluation to begin editing — pick up the test first." + : null; // ── Red Team Tab ───────────────────────────────────────────────── const renderRedTab = () => (
+ {/* Locked hint for red_tech in draft state */} + {redLockedHint && ( +
+ + {redLockedHint} +
+ )} {/* Procedure */}