Compare commits

..

2 commits

Author SHA1 Message Date
c1b905f49d Merge branch 'chore/admin-panel-restrict-template'
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Admin web build (push) Waiting to run
CI / Grammy store bot (push) Waiting to run
CI / Docker main topology smoke (push) Waiting to run
2026-09-16 14:13:31 +01:00
ec00aa32ae admin panel: add restrict-account decision template
The moderation case decision dropdown had no way to apply the new
restrict_account/unrestrict_account sanction; add it alongside freeze,
including the appeal-remedy auto-detection. Rebuilds web/dist so the
embedded panel binary picks up the change.
2026-09-16 14:13:27 +01:00
3 changed files with 19 additions and 4 deletions

View file

@ -23,7 +23,7 @@
})(); })();
</script> </script>
<script type="module" crossorigin src="/assets/index-BFJUBZwA.js"></script> <script type="module" crossorigin src="/assets/index-D2R4fOVC.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-P_k7ini0.css"> <link rel="stylesheet" crossorigin href="/assets/index-P_k7ini0.css">
</head> </head>
<body> <body>

View file

@ -12,7 +12,7 @@ import {
moderationTargetLabel moderationTargetLabel
} from "./ModerationCasesPage"; } from "./ModerationCasesPage";
type DecisionPreset = "no_violation" | "scam" | "fake" | "freeze" | "scam_freeze" | "fake_freeze" | "delete_messages" | "delete_account"; type DecisionPreset = "no_violation" | "scam" | "fake" | "freeze" | "restrict" | "scam_freeze" | "fake_freeze" | "delete_messages" | "delete_account";
export function ModerationCaseDetailPage({ id, navigate }: { id: number; navigate: Navigate }) { export function ModerationCaseDetailPage({ id, navigate }: { id: number; navigate: Navigate }) {
const [detail, setDetail] = useState<ModerationCaseDetail | null>(null); const [detail, setDetail] = useState<ModerationCaseDetail | null>(null);
@ -241,6 +241,7 @@ export function ModerationCaseDetailPage({ id, navigate }: { id: number; navigat
<option value="scam">{"Mark as SCAM"}</option> <option value="scam">{"Mark as SCAM"}</option>
<option value="fake">{"Mark as FAKE"}</option> <option value="fake">{"Mark as FAKE"}</option>
<option value="freeze">{"Freeze account"}</option> <option value="freeze">{"Freeze account"}</option>
<option value="restrict">{"Restrict account (spam)"}</option>
<option value="scam_freeze">{"SCAM + freeze"}</option> <option value="scam_freeze">{"SCAM + freeze"}</option>
<option value="fake_freeze">{"FAKE + freeze"}</option> <option value="fake_freeze">{"FAKE + freeze"}</option>
<option value="delete_messages">{"Delete messages covered by evidence"}</option> <option value="delete_messages">{"Delete messages covered by evidence"}</option>
@ -314,6 +315,8 @@ function actionsForPreset(
return [{ kind: "mark_fake", payload: {} }]; return [{ kind: "mark_fake", payload: {} }];
case "freeze": case "freeze":
return [{ kind: "freeze_account", payload: {} }]; return [{ kind: "freeze_account", payload: {} }];
case "restrict":
return [{ kind: "restrict_account", payload: {} }];
case "scam_freeze": case "scam_freeze":
return [{ kind: "mark_scam", payload: {} }, { kind: "freeze_account", payload: {} }]; return [{ kind: "mark_scam", payload: {} }, { kind: "freeze_account", payload: {} }];
case "fake_freeze": case "fake_freeze":
@ -350,6 +353,7 @@ function requiredAppealRemedy(detail: ModerationCaseDetail): {
} { } {
let flagsActive = false; let flagsActive = false;
let freezeActive = false; let freezeActive = false;
let restrictActive = false;
let irreversible = false; let irreversible = false;
for (const action of [...detail.Actions].sort((left, right) => left.ID - right.ID)) { for (const action of [...detail.Actions].sort((left, right) => left.ID - right.ID)) {
if (action.Status !== "succeeded") continue; if (action.Status !== "succeeded") continue;
@ -367,6 +371,12 @@ function requiredAppealRemedy(detail: ModerationCaseDetail): {
case "unfreeze_account": case "unfreeze_account":
freezeActive = false; freezeActive = false;
break; break;
case "restrict_account":
restrictActive = true;
break;
case "unrestrict_account":
restrictActive = false;
break;
case "delete_private_message": case "delete_private_message":
case "delete_channel_message": case "delete_channel_message":
case "delete_account": case "delete_account":
@ -384,6 +394,10 @@ function requiredAppealRemedy(detail: ModerationCaseDetail): {
actions.push({ kind: "unfreeze_account", payload: {} }); actions.push({ kind: "unfreeze_account", payload: {} });
labels.push("Unfreeze account"); labels.push("Unfreeze account");
} }
if (restrictActive) {
actions.push({ kind: "unrestrict_account", payload: {} });
labels.push("Unrestrict account");
}
return { actions, label: labels.join(" + ") || "No recovery action needed", blocked: irreversible }; return { actions, label: labels.join(" + ") || "No recovery action needed", blocked: irreversible };
} }
@ -393,6 +407,7 @@ function decisionPresetLabel(preset: DecisionPreset): string {
scam: "Mark as SCAM", scam: "Mark as SCAM",
fake: "Mark as FAKE", fake: "Mark as FAKE",
freeze: "Freeze account", freeze: "Freeze account",
restrict: "Restrict account (spam)",
scam_freeze: "SCAM + freeze", scam_freeze: "SCAM + freeze",
fake_freeze: "FAKE + freeze", fake_freeze: "FAKE + freeze",
delete_messages: "Delete messages covered by evidence", delete_messages: "Delete messages covered by evidence",