feat(campaign-ui): review and link managed attachments

This commit is contained in:
2026-07-20 20:08:41 +02:00
parent fce6dd1138
commit 0a6064ec62
9 changed files with 921 additions and 150 deletions
@@ -39,7 +39,7 @@ export default function TemplateDataPage({ settings, campaignId }: {settings: Ap
const version = data.currentVersion;
const locked = isAuditLockedVersion(version, data.campaign?.current_version_id);
const { draft, setDraft, displayDraft, dirty, saveState, localError, patch, markDirty, saveDraft } = useCampaignDraftEditor({
const { draft, setDraft, displayDraft, dirty, saveState, localError, patch, markDirty, discardDraft, saveDraft } = useCampaignDraftEditor({
settings,
campaignId,
version,
@@ -121,6 +121,7 @@ export default function TemplateDataPage({ settings, campaignId }: {settings: Ap
const handle = window.setTimeout(() => {
void previewCampaignAttachments(settings, campaignId, version.id, {
include_unmatched: false,
include_unlinked_candidates: true,
campaign_json: campaignJsonForAttachmentPreview(displayDraft)
}).
then((response) => {
@@ -233,7 +234,7 @@ export default function TemplateDataPage({ settings, campaignId }: {settings: Ap
</div>
<div className="button-row compact-actions">
<Button disabled>i18n:govoplan-campaign.manage_templates.23688071</Button>
<Button onClick={reload} disabled={loading}>i18n:govoplan-campaign.reload.cce71553</Button>
<Button onClick={() => void discardDraft()} disabled={loading}>Discard</Button>
<Button variant="primary" onClick={() => saveDraft("manual")} disabled={!dirty || locked || !draft}>i18n:govoplan-campaign.save.efc007a3</Button>
</div>
</div>
@@ -399,45 +400,46 @@ draft: Record<string, unknown>)
: CampaignMessagePreviewAttachment[] {
if (loading) {
return [{
filename: i18nMessage("i18n:govoplan-campaign.resolving_attachment_patterns.87d7d21b"),
detail: i18nMessage("i18n:govoplan-campaign.managed_files_are_being_checked_for_this_recipie.489ecefd")
filename: "Resolving attachment patterns",
detail: "Managed files are being checked for this recipient preview."
}];
}
if (error) {
return [{ filename: i18nMessage("i18n:govoplan-campaign.attachment_preview_unavailable.62211756"), detail: error }];
return [{ filename: "Attachment preview unavailable", detail: error }];
}
return rules.flatMap((rule) => {
const zipProtection = zipProtectionForRule(rule, draft);
const detailParts = [
rule.source === "global" ? i18nMessage("i18n:govoplan-campaign.global.5f1184f7") : i18nMessage("i18n:govoplan-campaign.recipient.90343260"),
rule.source === "global" ? "Global" : "Recipient",
rule.label,
rule.required ? i18nMessage("i18n:govoplan-campaign.required.eed6bfb4") : i18nMessage("i18n:govoplan-campaign.optional.0c6c4102"),
rule.required ? "Required" : "Optional",
rule.pattern].
filter(Boolean);
const detail = detailParts.join(" · ");
const fallbackArchiveLabel = i18nMessage("i18n:govoplan-campaign.recipient_attachments_zip.79d436c7");
const fallbackArchiveLabel = "Recipient attachments ZIP";
if (rule.matches.length > 0) {
return rule.matches.map((match) => ({
filename: match.filename || match.display_path,
label: rule.label,
detail: i18nMessage("i18n:govoplan-campaign.value_value.a8618e4a", { value0: detail, value1: match.display_path ? ` · ${match.display_path}` : "" }),
detail: `${match.linked_to_campaign === false ? "Unlinked candidate" : "Linked"} · ${match.display_path ? `${detail} · ${match.display_path}` : detail}`,
contentType: match.content_type,
sizeBytes: match.size_bytes,
linkedToCampaign: match.linked_to_campaign !== false,
archiveGroup: rule.zip_included ? rule.zip_filename || "recipient-attachments.zip" : null,
archiveLabel: rule.zip_included ? rule.zip_filename || fallbackArchiveLabel : null,
protected: zipProtection.protected,
protectionNote: zipProtection.note
}));
}
const pattern = rule.pattern || i18nMessage("i18n:govoplan-campaign.attachment_pattern.3540c952");
const pattern = rule.pattern || "attachment pattern";
return [{
filename: i18nMessage("i18n:govoplan-campaign.no_file_matched_value", { value0: pattern }),
filename: `No file matched ${pattern}`,
label: rule.label,
detail: i18nMessage("i18n:govoplan-campaign.value_value.a8618e4a", { value0: detail, value1: rule.status !== "ok" ? ` · ${rule.status}` : "" }),
archiveGroup: rule.zip_included ? rule.zip_filename || "recipient-attachments.zip" : null,
archiveLabel: rule.zip_included ? rule.zip_filename || fallbackArchiveLabel : null,
protected: zipProtection.protected,
protectionNote: zipProtection.note
detail: rule.status !== "ok" ? `${detail} · ${rule.status}` : detail,
archiveGroup: null,
archiveLabel: null,
protected: false,
protectionNote: null
}];
});
}