import { useEffect, useState } from "react"; import type { ApiSettings } from "@govoplan/core-webui"; import { fetchGroups, fetchUsers, runRetentionPolicy, type PrivacyRetentionPolicyScope, type RetentionRunResponse } from "../../api/admin"; import { Button } from "@govoplan/core-webui"; import { Card } from "@govoplan/core-webui"; import { ConfirmDialog } from "@govoplan/core-webui"; import { RetentionPolicyScopeManager, type RetentionPolicyTargetOption } from "@govoplan/core-webui"; import { AdminPageLayout, adminErrorMessage } from "@govoplan/core-webui"; type Props = { settings: ApiSettings; scopeType: Extract; canWrite: boolean; }; const copy: Record = { system: { title: "System retention", description: "Instance-wide privacy retention policy and lower-level override permissions.", policyTitle: "System retention policy", policyDescription: "Set concrete system retention values. The Allow override toggles decide which fields tenants, owners and campaigns may override." }, tenant: { title: "Tenant retention", description: "Tenant-level privacy and retention limits for the active tenant.", policyTitle: "Tenant retention policy", policyDescription: "Tenant limits may only narrow the system policy. The Allow override toggles decide which fields users, groups and campaigns may override." }, user: { title: "User retention", description: "User-scoped retention limits for campaigns owned by users in the active tenant.", targetLabel: "User", policyTitle: "User retention policy", policyDescription: "User limits may only narrow inherited system and tenant policy. The Allow override toggles decide which fields user-owned campaigns may override." }, group: { title: "Group retention", description: "Group-scoped retention limits for group-owned campaigns in the active tenant.", targetLabel: "Group", policyTitle: "Group retention policy", policyDescription: "Group limits may only narrow inherited system and tenant policy. The Allow override toggles decide which fields group-owned campaigns may override." } }; export default function RetentionPoliciesPanel({ settings, scopeType, canWrite }: Props) { const [targets, setTargets] = useState([]); const [loadingTargets, setLoadingTargets] = useState(scopeType === "user" || scopeType === "group"); const [targetError, setTargetError] = useState(""); const [busy, setBusy] = useState(false); const [success, setSuccess] = useState(""); const [runError, setRunError] = useState(""); const [confirmRetentionRun, setConfirmRetentionRun] = useState(false); const [retentionResult, setRetentionResult] = useState(null); useEffect(() => { void loadTargets(); }, [settings.accessToken, settings.apiBaseUrl, settings.apiKey, scopeType]); async function loadTargets() { if (scopeType !== "user" && scopeType !== "group") { setTargets([]); setLoadingTargets(false); setTargetError(""); return; } setLoadingTargets(true); setTargetError(""); try { if (scopeType === "user") { const users = await fetchUsers(settings); setTargets(users.map((user) => ({ id: user.id, label: user.display_name || user.email, secondary: user.display_name ? user.email : null }))); } else { const groups = await fetchGroups(settings); setTargets(groups.map((group) => ({ id: group.id, label: group.name, secondary: group.slug }))); } } catch (err) { setTargets([]); setTargetError(adminErrorMessage(err)); } finally { setLoadingTargets(false); } } async function runRetention(dryRun: boolean) { setBusy(true); setRunError(""); setSuccess(""); try { const response = await runRetentionPolicy(settings, dryRun); setRetentionResult(response); setSuccess(dryRun ? "Retention dry run completed." : "Retention policy applied."); setConfirmRetentionRun(false); } catch (err) { setRunError(adminErrorMessage(err)); } finally { setBusy(false); } } const labels = copy[scopeType]; return ( <> {scopeType === "system" && (

Run the saved effective retention policy against stored raw JSON, generated EML, report detail, mock mailbox content and audit detail.

{retentionResult &&
{JSON.stringify(retentionResult.result, null, 2)}
}
)}
setConfirmRetentionRun(false)} onConfirm={() => void runRetention(false)} /> ); }