Rework of campaign structure; locking
This commit is contained in:
@@ -5,11 +5,13 @@ import Card from "../../components/Card";
|
||||
import FormField from "../../components/FormField";
|
||||
import PageTitle from "../../components/PageTitle";
|
||||
import LoadingFrame from "../../components/LoadingFrame";
|
||||
import LockedVersionNotice from "./components/LockedVersionNotice";
|
||||
import VersionLine from "./components/VersionLine";
|
||||
import ToggleSwitch from "../../components/ToggleSwitch";
|
||||
import EmailAddressInput from "../../components/email/EmailAddressInput";
|
||||
import { useCampaignWorkspaceData } from "./hooks/useCampaignWorkspaceData";
|
||||
import { useCampaignDraftEditor } from "./hooks/useCampaignDraftEditor";
|
||||
import { asArray, asRecord, isAuditLockedVersion, versionLockReason } from "./utils/campaignView";
|
||||
import { asArray, asRecord, isAuditLockedVersion } from "./utils/campaignView";
|
||||
import { getBool } from "./utils/draftEditor";
|
||||
import {
|
||||
addressesFromValue,
|
||||
@@ -54,6 +56,8 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
|
||||
const inlineEntries = asArray(entries.inline).map(asRecord);
|
||||
const source = asRecord(entries.source);
|
||||
const addressSuggestions = useMemo(() => collectCampaignAddressSuggestions(displayDraft), [displayDraft]);
|
||||
const defaultFrom = addressesFromValue(recipientsSection.from);
|
||||
const globalReplyTo = addressesFromValue(recipientsSection.reply_to);
|
||||
const globalRecipientValues: Record<string, MailboxAddress[]> = {
|
||||
to: addressesFromValue(recipientsSection.to),
|
||||
cc: addressesFromValue(recipientsSection.cc),
|
||||
@@ -121,8 +125,8 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
|
||||
<div className="content-pad workspace-data-page">
|
||||
<div className="page-heading split workspace-heading">
|
||||
<div>
|
||||
<PageTitle loading={loading}>Recipients</PageTitle>
|
||||
<p className="mono-small">Version {version ? `#${version.version_number}` : "—"} · {saveState}</p>
|
||||
<PageTitle loading={loading}>Sender & Recipients</PageTitle>
|
||||
<VersionLine version={version} versions={data.versions} status={saveState} />
|
||||
</div>
|
||||
<div className="button-row compact-actions">
|
||||
<Button onClick={reload} disabled={loading}>Reload</Button>
|
||||
@@ -132,10 +136,60 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
|
||||
|
||||
{error && <div className="alert danger">{error}</div>}
|
||||
{localError && <div className="alert danger">{localError}</div>}
|
||||
{locked && <div className="alert info">This version is read-only. {versionLockReason(version)}</div>}
|
||||
{locked && <LockedVersionNotice settings={settings} campaignId={campaignId} version={version} reload={reload} message="Create an editable copy before changing sender or recipient profiles." />}
|
||||
|
||||
<LoadingFrame loading={loading || !draft} label="Loading campaign draft…">
|
||||
<>
|
||||
<Card title="Campaign sender">
|
||||
<div className="campaign-header-stack">
|
||||
<div className="campaign-header-grid">
|
||||
<FormField label="Default From address">
|
||||
<EmailAddressInput
|
||||
value={defaultFrom}
|
||||
suggestions={addressSuggestions}
|
||||
allowMultiple={false}
|
||||
showAddButton={false}
|
||||
disabled={locked}
|
||||
addLabel={defaultFrom.length ? "Replace" : "Add sender"}
|
||||
emptyText="No default sender configured."
|
||||
onChange={(addresses: MailboxAddress[]) => patch(["recipients", "from"], addresses[0] ?? { name: "", email: "" })}
|
||||
/>
|
||||
</FormField>
|
||||
<div className="campaign-header-toggle">
|
||||
<ToggleSwitch
|
||||
label="Allow individual senders"
|
||||
checked={getBool(recipientsSection, "allow_individual_from")}
|
||||
disabled={locked}
|
||||
onChange={(checked) => patch(["recipients", "allow_individual_from"], checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="campaign-header-grid">
|
||||
<FormField label="Global Reply-To address">
|
||||
<EmailAddressInput
|
||||
value={globalReplyTo.slice(0, 1)}
|
||||
suggestions={addressSuggestions}
|
||||
allowMultiple={false}
|
||||
showAddButton={false}
|
||||
disabled={locked}
|
||||
addLabel={globalReplyTo.length ? "Replace" : "Add Reply-To"}
|
||||
emptyText="No Reply-To address configured."
|
||||
onChange={(addresses: MailboxAddress[]) => patch(["recipients", "reply_to"], addresses.slice(0, 1))}
|
||||
/>
|
||||
</FormField>
|
||||
<div className="campaign-header-toggle">
|
||||
<ToggleSwitch
|
||||
label="Allow individual Reply-To"
|
||||
checked={getBool(recipientsSection, "allow_individual_reply_to")}
|
||||
disabled={locked}
|
||||
onChange={(checked) => patch(["recipients", "allow_individual_reply_to"], checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card title="Global recipient headers">
|
||||
<div className="campaign-header-stack">
|
||||
{recipientHeaderRows.map((row) => (
|
||||
|
||||
Reference in New Issue
Block a user