Locking refinement; Review/Send improvement

This commit is contained in:
2026-06-13 22:06:32 +02:00
parent c72df498e7
commit e97af1cf91
18 changed files with 569 additions and 371 deletions

View File

@@ -10,7 +10,7 @@ import VersionLine from "./components/VersionLine";
import ToggleSwitch from "../../components/ToggleSwitch";
import EmailAddressInput from "../../components/email/EmailAddressInput";
import DismissibleAlert from "../../components/DismissibleAlert";
import DataGrid, { DataGridRowActions, type DataGridColumn } from "../../components/table/DataGrid";
import DataGrid, { DataGridEmptyAction, DataGridRowActions, type DataGridColumn } from "../../components/table/DataGrid";
import { useCampaignWorkspaceData } from "./hooks/useCampaignWorkspaceData";
import { useCampaignDraftEditor } from "./hooks/useCampaignDraftEditor";
import { asArray, asRecord, isAuditLockedVersion } from "./utils/campaignView";
@@ -42,7 +42,7 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
const { data, loading, error, reload, setError } = useCampaignWorkspaceData(settings, campaignId);
const version = data.currentVersion;
const locked = isAuditLockedVersion(version);
const locked = isAuditLockedVersion(version, data.campaign?.current_version_id);
const { draft, displayDraft, dirty, saveState, localError, patch, saveDraft } = useCampaignDraftEditor({
settings,
campaignId,
@@ -144,7 +144,7 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
{error && <DismissibleAlert tone="danger" resetKey={error} floating>{error}</DismissibleAlert>}
{localError && <DismissibleAlert tone="danger" resetKey={localError} floating>{localError}</DismissibleAlert>}
{locked && <LockedVersionNotice settings={settings} campaignId={campaignId} version={version} reload={reload} message="Create an editable copy before changing sender or recipient profiles." />}
{locked && <LockedVersionNotice settings={settings} campaignId={campaignId} version={version} currentVersionId={data.campaign?.current_version_id} reload={reload} message="This page is read-only for the selected version." />}
<LoadingFrame loading={loading || !draft} label="Loading campaign draft…">
<>
@@ -239,7 +239,8 @@ export default function RecipientDataPage({ settings, campaignId }: { settings:
rows={inlineEntries.slice(0, 100)}
columns={recipientProfileColumns({ locked, entries: inlineEntries, entryAddressColumns, addressSuggestions, updateEntryAddressList, updateEntry, addRecipient, moveEntry, removeEntry })}
getRowKey={(entry, index) => String(entry.id || index)}
emptyText={<div className="data-grid-empty-action"><span>No recipient profiles are stored in the current version yet.</span><Button variant="primary" onClick={() => addRecipient(-1)} disabled={locked}>Add recipient</Button></div>}
emptyText="No recipient profiles are stored in the current version yet."
emptyAction={<DataGridEmptyAction onAdd={() => addRecipient(-1)} disabled={locked} label="Add first recipient" />}
className="recipient-table-wrap recipient-address-table"
/>
)}
@@ -293,7 +294,7 @@ function recipientProfileColumns({ locked, entries, entryAddressColumns, address
{
id: "actions",
header: "Actions",
width: 150,
width: 180,
sticky: "end",
render: (_entry, index) => (
<DataGridRowActions