refactor(campaign): split review and recipient boundaries
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { asArray, asRecord } from "../utils/campaignView";
|
||||
|
||||
export function formatAddressList(value: unknown): string {
|
||||
return asArray(value).map(asRecord).map(formatSingleAddress).filter(Boolean).join(", ");
|
||||
}
|
||||
|
||||
export function formatSingleAddress(value: unknown): string {
|
||||
const address = asRecord(value);
|
||||
const email = String(address.email ?? "").trim();
|
||||
const name = String(address.name ?? "").trim();
|
||||
if (name && email) return `${name} <${email}>`;
|
||||
return email || name;
|
||||
}
|
||||
|
||||
export function countResolvedAttachments(value: unknown): number {
|
||||
const archives = new Set<string>();
|
||||
let directCount = 0;
|
||||
for (const item of asArray(value)) {
|
||||
const attachment = asRecord(item);
|
||||
const zipFilename = String(attachment.zip_filename ?? "").trim();
|
||||
const managedCount = asArray(attachment.managed_matches).length;
|
||||
const matchCount = asArray(attachment.matches).length;
|
||||
if (zipFilename && (managedCount > 0 || matchCount > 0)) {
|
||||
archives.add(zipFilename);
|
||||
continue;
|
||||
}
|
||||
if (managedCount > 0) {
|
||||
directCount += managedCount;
|
||||
continue;
|
||||
}
|
||||
directCount += matchCount;
|
||||
}
|
||||
return directCount + archives.size;
|
||||
}
|
||||
|
||||
export function numberFrom(record: Record<string, unknown>, keys: string[]): number {
|
||||
for (const key of keys) {
|
||||
const value = record[key];
|
||||
if (typeof value === "number" && Number.isFinite(value)) return value;
|
||||
if (
|
||||
typeof value === "string" &&
|
||||
value.trim() &&
|
||||
Number.isFinite(Number(value))
|
||||
) {
|
||||
return Number(value);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function numberOrUndefined(value: unknown): number | undefined {
|
||||
if (typeof value === "number" && Number.isFinite(value)) return value;
|
||||
if (
|
||||
typeof value === "string" &&
|
||||
value.trim() &&
|
||||
Number.isFinite(Number(value))
|
||||
) {
|
||||
return Number(value);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function stringOrUndefined(value: unknown): string | undefined {
|
||||
if (typeof value !== "string") return undefined;
|
||||
return value.trim() || undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user