feat(campaign-ui): configure attachment delivery behavior

This commit is contained in:
2026-07-20 20:08:53 +02:00
parent 0a6064ec62
commit c71fa3dc64
3 changed files with 45 additions and 22 deletions

View File

@@ -38,7 +38,7 @@ export default function GlobalSettingsPage({ settings, auth, campaignId, view =
const version = data.currentVersion;
const locked = isAuditLockedVersion(version, data.campaign?.current_version_id);
const { draft, displayDraft, dirty, saveState, localError, patch, markDirty, saveDraft } = useCampaignDraftEditor({
const { draft, displayDraft, dirty, saveState, localError, patch, markDirty, discardDraft, saveDraft } = useCampaignDraftEditor({
settings,
campaignId,
version,
@@ -71,6 +71,11 @@ export default function GlobalSettingsPage({ settings, auth, campaignId, view =
markDirty();
}
function patchSendWithoutAttachmentsBehavior(value: string) {
patch(["attachments", "send_without_attachments_behavior"], value);
patch(["attachments", "send_without_attachments"], value !== "block");
}
return (
<div className="content-pad workspace-data-page">
<div className="page-heading split workspace-heading">
@@ -79,7 +84,7 @@ export default function GlobalSettingsPage({ settings, auth, campaignId, view =
<VersionLine version={version} versions={data.versions} status={saveState} />
</div>
<div className="button-row compact-actions">
<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}>{dirty ? "i18n:govoplan-campaign.save_now.3989b7c0" : "i18n:govoplan-campaign.saved.c0ae8f6e"}</Button>
</div>
</div>
@@ -208,8 +213,8 @@ export default function GlobalSettingsPage({ settings, auth, campaignId, view =
effectiveClassName="campaign-policy-effective-note"
label="i18n:govoplan-campaign.send_without_attachments.ead6d030"
note="i18n:govoplan-campaign.campaign_wide_fallback_when_no_attachment_is_ava.84ffa0bc"
control={<ToggleSwitch label="i18n:govoplan-campaign.allowed.77c7b490" checked={getBool(attachments, "send_without_attachments", true)} disabled={locked} onChange={(checked) => patch(["attachments", "send_without_attachments"], checked)} />}
effective={getBool(attachments, "send_without_attachments", true) ? "i18n:govoplan-campaign.messages_may_be_sent_when_attachment_rules_allow.e6bf1aed" : "i18n:govoplan-campaign.missing_attachment_coverage_blocks_sending.05ff02a1"} />
control={<PolicySelectControl value={sendWithoutAttachmentsBehavior(attachments)} disabled={locked} onChange={patchSendWithoutAttachmentsBehavior} />}
effective={behaviorSummary(sendWithoutAttachmentsBehavior(attachments))} />
</PolicyTable>
</Card>
@@ -261,3 +266,9 @@ function behaviorSummary(value: string): string {
if (value === "warn") return "i18n:govoplan-campaign.keeps_sending_possible_with_a_warning.66c84a54";
return "i18n:govoplan-campaign.uses_the_configured_behavior.ea6e82a3";
}
function sendWithoutAttachmentsBehavior(attachments: Record<string, unknown>): string {
const configured = getText(attachments, "send_without_attachments_behavior");
if (behaviorOptions.includes(configured)) return configured;
return getBool(attachments, "send_without_attachments", true) ? "continue" : "block";
}