refactor(webui): select Mail-owned profiles for campaigns

This commit is contained in:
2026-07-21 17:13:22 +02:00
parent 2c5519908a
commit 701c0fe184
13 changed files with 210 additions and 561 deletions

View File

@@ -136,12 +136,7 @@ export default function ReviewSendPage({ settings, campaignId }: {settings: ApiS
const version = data.currentVersion;
const campaignJson = useMemo(() => getCampaignJson(version), [version]);
const server = asRecord(campaignJson.server);
const smtpServer = asRecord(server.smtp);
const imapServer = asRecord(server.imap);
const serverCredentials = asRecord(server.credentials);
const smtpCredentials = asRecord(serverCredentials.smtp);
const imapCredentials = asRecord(serverCredentials.imap);
const selectedMailProfileId = getText(server, "mail_profile_id", getText(server, "profile_id"));
const selectedMailProfileId = getText(server, "mail_profile_id");
const inlineEntries = useMemo(
() => asArray(asRecord(campaignJson.entries).inline).map(asRecord),
[campaignJson]
@@ -398,7 +393,9 @@ export default function ReviewSendPage({ settings, campaignId }: {settings: ApiS
const imapAppendResultRows = asArray(imapAppendResult?.results).map(asRecord);
const imapDiagnosticRows = imapDiagnostics.jobs.map(asRecord);
const imapDiagnosticsPending = imapDiagnosticRows.filter((job) => String(job.imap_status ?? "").toLowerCase() === "pending").length;
const imapDiagnosticsFailed = imapDiagnosticRows.filter((job) => String(job.imap_status ?? "").toLowerCase() === "failed").length;
const imapDiagnosticsFailed = imapDiagnosticRows.filter((job) =>
["failed", "outcome_unknown"].includes(String(job.imap_status ?? "").toLowerCase()),
).length;
const imapPendingForDisplay = Math.max(imapPending, imapDiagnosticsPending);
const imapFailedForDisplay = Math.max(imapFailed, imapDiagnosticsFailed);
const canAppendPendingImap = Boolean(imapAppend.enabled) && imapPendingForDisplay > 0 && !historicalVersion && !userLockedVersion;
@@ -1032,13 +1029,12 @@ export default function ReviewSendPage({ settings, campaignId }: {settings: ApiS
const ambiguousAttachments = numberFrom(attachmentSummary, ["ambiguous_configs"]);
const messagesPerMinute = numberFrom(rateLimit, ["messages_per_minute"]);
const estimatedMinutes = messagesPerMinute > 0 && jobsTotal > 0 ? Math.ceil(jobsTotal / messagesPerMinute) : null;
const smtpConfigured = Boolean(selectedMailProfileId || getText(smtpServer, "host") || getText(smtpCredentials, "username"));
const imapConfigured = Boolean(selectedMailProfileId || getText(imapServer, "host") || getText(imapCredentials, "username"));
const mailProfileSelected = Boolean(selectedMailProfileId);
const deliverabilityPreflightItems: DeliverabilityPreflightItem[] = [
{
label: "Transport",
detail: smtpConfigured ? selectedMailProfileId ? "Reusable mail profile selected." : "Inline SMTP settings are present." : "Select a reusable mail profile or configure SMTP before live delivery.",
state: smtpConfigured ? "ready" : "blocked"
detail: mailProfileSelected ? "i18n:govoplan-campaign.mail_owned_delivery_profile_selected.4f44778e" : "i18n:govoplan-campaign.select_an_authorized_mail_profile_before_live_de.45c80a42",
state: mailProfileSelected ? "ready" : "blocked"
},
{
label: "Policy",
@@ -1062,8 +1058,8 @@ export default function ReviewSendPage({ settings, campaignId }: {settings: ApiS
},
{
label: "Sent copy",
detail: Boolean(imapAppend.enabled) ? imapConfigured ? `IMAP append enabled for ${String(imapAppend.folder ?? "auto")}.` : "IMAP append is enabled, but no IMAP server/profile is visible." : "IMAP append is disabled for this campaign.",
state: Boolean(imapAppend.enabled) ? imapConfigured ? "ready" : "blocked" : "info"
detail: Boolean(imapAppend.enabled) ? mailProfileSelected ? i18nMessage("i18n:govoplan-campaign.imap_append_requested_for_value0_validation_chec.51527a20", { value0: String(imapAppend.folder ?? "auto") }) : "i18n:govoplan-campaign.imap_append_is_enabled_but_no_mail_profile_is_se.cf50419e" : "i18n:govoplan-campaign.imap_append_is_disabled_for_this_campaign.7757f7f1",
state: Boolean(imapAppend.enabled) ? mailProfileSelected ? "ready" : "blocked" : "info"
}];
const canCompleteInspection = blockingReviewCount === 0 &&
reviewRequiredCount > 0 &&