Route kebab Customize through the prefilled policy wizard so existing methods and values can be renamed, reordered, and kept in that field order on the card after Finalize.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -53,20 +53,20 @@ import type { CommunicationMethodDetailEntry } from "../../types";
|
||||
import CustomMethodCardModalBody from "../../components/CustomMethodCardModalBody";
|
||||
import { buildCustomRuleModalKebabMenu } from "../../components/customRuleModalKebabMenu";
|
||||
import { methodCardMetaWithCustomizeHeader } from "../../../../../lib/create/methodCardCustomizeMetaPatch";
|
||||
import { buildMethodCardWizardInitialValues } from "../../../../../lib/create/methodCardWizardPrefill";
|
||||
import type { MethodCardWizardInitialValues } from "../../../../../lib/create/methodCardWizardPrefill";
|
||||
import {
|
||||
captureMethodCardCustomizeSnapshot,
|
||||
type MethodCardCustomizeSnapshot,
|
||||
type MethodCardHeaderDraft,
|
||||
} from "../../../../../lib/create/methodCardCustomizeSession";
|
||||
import MethodCardCustomizeModalHeader from "../../components/MethodCardCustomizeModalHeader";
|
||||
|
||||
export function CommunicationMethodsScreen() {
|
||||
const m = useMessages();
|
||||
const comm = m.create.customRule.communication;
|
||||
const modalKebabMenu = m.create.customRule.modalKebabMenu;
|
||||
const mdUp = useCreateFlowMdUp();
|
||||
const { confirmDiscard, confirmDirtyCustomizeCancel, confirmDialog } =
|
||||
useDiscardCustomizeConfirm();
|
||||
const { confirmDiscard, confirmDialog } = useDiscardCustomizeConfirm();
|
||||
const { state, updateState, replaceState, markCreateFlowInteraction } =
|
||||
useCreateFlow();
|
||||
const pendingEphemeralDuplicateIdRef = useRef<string | null>(null);
|
||||
@@ -79,12 +79,14 @@ export function CommunicationMethodsScreen() {
|
||||
const [pendingDraft, setPendingDraft] =
|
||||
useState<CommunicationMethodDetailEntry | null>(null);
|
||||
const [addCustomWizardOpen, setAddCustomWizardOpen] = useState(false);
|
||||
const [modalEditUnlocked, setModalEditUnlocked] = useState(false);
|
||||
const [wizardCustomizeCardId, setWizardCustomizeCardId] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
const [wizardInitialValues, setWizardInitialValues] =
|
||||
useState<MethodCardWizardInitialValues | null>(null);
|
||||
const [draftFieldBlocks, setDraftFieldBlocks] = useState<
|
||||
CustomMethodCardFieldBlock[] | null
|
||||
>(null);
|
||||
const [customizeHeaderDraft, setCustomizeHeaderDraft] =
|
||||
useState<MethodCardHeaderDraft | null>(null);
|
||||
|
||||
const selectedIds = state.selectedCommunicationMethodIds ?? [];
|
||||
|
||||
@@ -107,6 +109,8 @@ export function CommunicationMethodsScreen() {
|
||||
|
||||
const handleOpenAddWizard = useCallback(() => {
|
||||
markCreateFlowInteraction();
|
||||
setWizardCustomizeCardId(null);
|
||||
setWizardInitialValues(null);
|
||||
setAddCustomWizardOpen(true);
|
||||
}, [markCreateFlowInteraction]);
|
||||
|
||||
@@ -144,15 +148,40 @@ export function CommunicationMethodsScreen() {
|
||||
const handleCardClick = useCallback(
|
||||
(id: string) => {
|
||||
markCreateFlowInteraction();
|
||||
customizeSnapshotRef.current = null;
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
const draft = seedDraft(id);
|
||||
const persistedBlocks = state.customMethodCardFieldBlocksById?.[id];
|
||||
const initialBlocks =
|
||||
Array.isArray(persistedBlocks) && persistedBlocks.length > 0
|
||||
? structuredClone(persistedBlocks)
|
||||
: null;
|
||||
const method = methodById.get(id);
|
||||
const meta = state.customMethodCardMetaById?.[id];
|
||||
const headerDraft: MethodCardHeaderDraft = {
|
||||
title: meta?.label ?? method?.label ?? comm.confirmModal.title,
|
||||
description:
|
||||
meta?.supportText ??
|
||||
method?.supportText ??
|
||||
comm.confirmModal.description,
|
||||
};
|
||||
customizeSnapshotRef.current = captureMethodCardCustomizeSnapshot(
|
||||
draft,
|
||||
initialBlocks,
|
||||
headerDraft,
|
||||
);
|
||||
setPendingCardId(id);
|
||||
setPendingDraft(seedDraft(id));
|
||||
setPendingDraft(draft);
|
||||
setDraftFieldBlocks(initialBlocks);
|
||||
setCreateModalOpen(true);
|
||||
},
|
||||
[markCreateFlowInteraction, seedDraft],
|
||||
[
|
||||
comm.confirmModal.description,
|
||||
comm.confirmModal.title,
|
||||
markCreateFlowInteraction,
|
||||
methodById,
|
||||
seedDraft,
|
||||
state.customMethodCardFieldBlocksById,
|
||||
state.customMethodCardMetaById,
|
||||
],
|
||||
);
|
||||
|
||||
const handleDraftChange = useCallback(
|
||||
@@ -165,9 +194,7 @@ export function CommunicationMethodsScreen() {
|
||||
|
||||
const isSelectedCardModal =
|
||||
pendingCardId !== null && selectedIds.includes(pendingCardId);
|
||||
const fieldsLocked = !modalEditUnlocked;
|
||||
|
||||
const showMethodModalPrimary = !isSelectedCardModal || modalEditUnlocked;
|
||||
const showMethodModalPrimary = true;
|
||||
|
||||
const customFacetDetailsMatchPreset = useMemo(() => {
|
||||
if (!pendingCardId || !pendingDraft) return false;
|
||||
@@ -189,7 +216,7 @@ export function CommunicationMethodsScreen() {
|
||||
methodId: pendingCardId,
|
||||
meta: state.customMethodCardMetaById,
|
||||
fieldBlocksById: state.customMethodCardFieldBlocksById,
|
||||
modalEditUnlocked,
|
||||
modalEditUnlocked: false,
|
||||
draftFieldBlocks,
|
||||
customFacetDetailsMatchPreset,
|
||||
}),
|
||||
@@ -197,7 +224,6 @@ export function CommunicationMethodsScreen() {
|
||||
[
|
||||
customFacetDetailsMatchPreset,
|
||||
draftFieldBlocks,
|
||||
modalEditUnlocked,
|
||||
pendingCardId,
|
||||
state.customMethodCardFieldBlocksById,
|
||||
state.customMethodCardMetaById,
|
||||
@@ -207,11 +233,11 @@ export function CommunicationMethodsScreen() {
|
||||
const handleCreateModalClose = useCallback(async () => {
|
||||
if (
|
||||
!(await confirmDiscard(
|
||||
modalEditUnlocked,
|
||||
true,
|
||||
customizeSnapshotRef.current,
|
||||
pendingDraft,
|
||||
draftFieldBlocks,
|
||||
customizeHeaderDraft,
|
||||
customizeSnapshotRef.current?.headerDraft ?? null,
|
||||
))
|
||||
) {
|
||||
return;
|
||||
@@ -239,53 +265,14 @@ export function CommunicationMethodsScreen() {
|
||||
setCreateModalOpen(false);
|
||||
setPendingCardId(null);
|
||||
setPendingDraft(null);
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
}, [
|
||||
confirmDiscard,
|
||||
customizeHeaderDraft,
|
||||
draftFieldBlocks,
|
||||
modalEditUnlocked,
|
||||
pendingDraft,
|
||||
replaceState,
|
||||
]);
|
||||
|
||||
const handleCancelCustomize = useCallback(async () => {
|
||||
if (!modalEditUnlocked) {
|
||||
return;
|
||||
}
|
||||
const snap = customizeSnapshotRef.current;
|
||||
if (!snap) {
|
||||
customizeSnapshotRef.current = null;
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!(await confirmDirtyCustomizeCancel(
|
||||
snap,
|
||||
pendingDraft,
|
||||
draftFieldBlocks,
|
||||
customizeHeaderDraft,
|
||||
))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
setPendingDraft(structuredClone(snap.pendingDraft));
|
||||
setDraftFieldBlocks(null);
|
||||
setModalEditUnlocked(false);
|
||||
customizeSnapshotRef.current = null;
|
||||
setCustomizeHeaderDraft(null);
|
||||
}, [
|
||||
confirmDirtyCustomizeCancel,
|
||||
customizeHeaderDraft,
|
||||
draftFieldBlocks,
|
||||
modalEditUnlocked,
|
||||
pendingDraft,
|
||||
]);
|
||||
|
||||
const handleRemoveSelectedFromModal = useCallback(async () => {
|
||||
if (!pendingCardId || !selectedIds.includes(pendingCardId)) {
|
||||
return;
|
||||
@@ -293,11 +280,11 @@ export function CommunicationMethodsScreen() {
|
||||
markCreateFlowInteraction();
|
||||
if (
|
||||
!(await confirmDiscard(
|
||||
modalEditUnlocked,
|
||||
true,
|
||||
customizeSnapshotRef.current,
|
||||
pendingDraft,
|
||||
draftFieldBlocks,
|
||||
customizeHeaderDraft,
|
||||
customizeSnapshotRef.current?.headerDraft ?? null,
|
||||
))
|
||||
) {
|
||||
return;
|
||||
@@ -313,11 +300,9 @@ export function CommunicationMethodsScreen() {
|
||||
await handleCreateModalClose();
|
||||
}, [
|
||||
confirmDiscard,
|
||||
customizeHeaderDraft,
|
||||
draftFieldBlocks,
|
||||
handleCreateModalClose,
|
||||
markCreateFlowInteraction,
|
||||
modalEditUnlocked,
|
||||
pendingDraft,
|
||||
pendingCardId,
|
||||
selectedIds,
|
||||
@@ -327,37 +312,36 @@ export function CommunicationMethodsScreen() {
|
||||
|
||||
const handleCustomize = useCallback(() => {
|
||||
markCreateFlowInteraction();
|
||||
if (!pendingDraft || !pendingCardId) {
|
||||
if (!pendingCardId) {
|
||||
return;
|
||||
}
|
||||
const persistedBlocks =
|
||||
state.customMethodCardFieldBlocksById?.[pendingCardId] ?? [];
|
||||
const initialFieldBlocks =
|
||||
persistedBlocks.length > 0
|
||||
? structuredClone(persistedBlocks)
|
||||
: isCustomMethodCardId(pendingCardId, state.customMethodCardMetaById)
|
||||
? []
|
||||
: null;
|
||||
const method = methodById.get(pendingCardId);
|
||||
const meta = state.customMethodCardMetaById?.[pendingCardId];
|
||||
const headerDraft: MethodCardHeaderDraft = {
|
||||
title: meta?.label ?? method?.label ?? comm.confirmModal.title,
|
||||
description:
|
||||
meta?.supportText ??
|
||||
method?.supportText ??
|
||||
comm.confirmModal.description,
|
||||
};
|
||||
setCustomizeHeaderDraft(headerDraft);
|
||||
customizeSnapshotRef.current = captureMethodCardCustomizeSnapshot(
|
||||
pendingDraft,
|
||||
initialFieldBlocks,
|
||||
headerDraft,
|
||||
setWizardInitialValues(
|
||||
buildMethodCardWizardInitialValues({
|
||||
cardId: pendingCardId,
|
||||
fallbackTitle: method?.label ?? comm.confirmModal.title,
|
||||
fallbackDescription:
|
||||
method?.supportText ?? comm.confirmModal.description,
|
||||
meta: state.customMethodCardMetaById,
|
||||
persistedBlocks: state.customMethodCardFieldBlocksById,
|
||||
draftFieldBlocks,
|
||||
facetPrefill: pendingDraft
|
||||
? {
|
||||
group: "communication",
|
||||
draft: pendingDraft,
|
||||
headings: comm.sectionHeadings,
|
||||
}
|
||||
: undefined,
|
||||
}),
|
||||
);
|
||||
setDraftFieldBlocks(initialFieldBlocks);
|
||||
setModalEditUnlocked(true);
|
||||
setWizardCustomizeCardId(pendingCardId);
|
||||
setCreateModalOpen(false);
|
||||
setAddCustomWizardOpen(true);
|
||||
}, [
|
||||
comm.confirmModal.description,
|
||||
comm.confirmModal.title,
|
||||
comm.sectionHeadings,
|
||||
draftFieldBlocks,
|
||||
markCreateFlowInteraction,
|
||||
methodById,
|
||||
pendingCardId,
|
||||
@@ -382,9 +366,7 @@ export function CommunicationMethodsScreen() {
|
||||
() => communicationPresetFor(newId),
|
||||
);
|
||||
const blocksClone = structuredClone(
|
||||
modalEditUnlocked &&
|
||||
draftFieldBlocks !== null &&
|
||||
isCustomMethodCardId(pendingCardId, state.customMethodCardMetaById)
|
||||
draftFieldBlocks !== null
|
||||
? draftFieldBlocks
|
||||
: cloneMethodCardBlocksForDuplicate(
|
||||
state.customMethodCardFieldBlocksById,
|
||||
@@ -414,16 +396,15 @@ export function CommunicationMethodsScreen() {
|
||||
customizeSnapshotRef.current = null;
|
||||
setPendingCardId(newId);
|
||||
setPendingDraft(structuredClone(detailsClone));
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
setDraftFieldBlocks(
|
||||
blocksClone.length > 0 ? structuredClone(blocksClone) : null,
|
||||
);
|
||||
}, [
|
||||
markCreateFlowInteraction,
|
||||
modalKebabMenu.duplicateTitleSuffix,
|
||||
pendingCardId,
|
||||
pendingDraft,
|
||||
draftFieldBlocks,
|
||||
modalEditUnlocked,
|
||||
state.communicationMethodDetailsById,
|
||||
state.customMethodCardFieldBlocksById,
|
||||
state.customMethodCardMetaById,
|
||||
@@ -449,9 +430,7 @@ export function CommunicationMethodsScreen() {
|
||||
() => communicationPresetFor(newId),
|
||||
);
|
||||
const blocksClone = structuredClone(
|
||||
modalEditUnlocked &&
|
||||
draftFieldBlocks !== null &&
|
||||
isCustomMethodCardId(pendingCardId, state.customMethodCardMetaById)
|
||||
draftFieldBlocks !== null
|
||||
? draftFieldBlocks
|
||||
: cloneMethodCardBlocksForDuplicate(
|
||||
state.customMethodCardFieldBlocksById,
|
||||
@@ -481,14 +460,13 @@ export function CommunicationMethodsScreen() {
|
||||
customizeSnapshotRef.current = null;
|
||||
setPendingCardId(newId);
|
||||
setPendingDraft(structuredClone(detailsClone));
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
setDraftFieldBlocks(
|
||||
blocksClone.length > 0 ? structuredClone(blocksClone) : null,
|
||||
);
|
||||
}, [
|
||||
draftFieldBlocks,
|
||||
markCreateFlowInteraction,
|
||||
methodById,
|
||||
modalEditUnlocked,
|
||||
modalKebabMenu.duplicateTitleSuffix,
|
||||
pendingCardId,
|
||||
pendingDraft,
|
||||
@@ -501,7 +479,7 @@ export function CommunicationMethodsScreen() {
|
||||
const kebabMenuItems = useMemo(
|
||||
() =>
|
||||
buildCustomRuleModalKebabMenu(modalKebabMenu, {
|
||||
showCustomize: !modalEditUnlocked,
|
||||
showCustomize: true,
|
||||
onCustomize: handleCustomize,
|
||||
onDuplicate:
|
||||
(state.editingPublishedRuleId?.trim() ?? "") !== "" || !pendingCardId
|
||||
@@ -521,7 +499,6 @@ export function CommunicationMethodsScreen() {
|
||||
handleDuplicatePrefabCard,
|
||||
handleRemoveSelectedFromModal,
|
||||
isSelectedCardModal,
|
||||
modalEditUnlocked,
|
||||
modalKebabMenu,
|
||||
pendingCardId,
|
||||
state.customMethodCardMetaById,
|
||||
@@ -540,7 +517,7 @@ export function CommunicationMethodsScreen() {
|
||||
meta?.supportText ??
|
||||
method?.supportText ??
|
||||
comm.confirmModal.description,
|
||||
nextButtonText: modalEditUnlocked
|
||||
nextButtonText: isSelectedCardModal
|
||||
? saveLabel
|
||||
: comm.addPlatform.nextButtonText,
|
||||
};
|
||||
@@ -552,8 +529,14 @@ export function CommunicationMethodsScreen() {
|
||||
};
|
||||
|
||||
const handleCloseAddWizard = useCallback(() => {
|
||||
const resumeCardId = wizardCustomizeCardId;
|
||||
setAddCustomWizardOpen(false);
|
||||
}, []);
|
||||
setWizardCustomizeCardId(null);
|
||||
setWizardInitialValues(null);
|
||||
if (resumeCardId && pendingCardId === resumeCardId) {
|
||||
setCreateModalOpen(true);
|
||||
}
|
||||
}, [pendingCardId, wizardCustomizeCardId]);
|
||||
|
||||
const handleFinalizeCustomCard = useCallback(
|
||||
({
|
||||
@@ -566,6 +549,42 @@ export function CommunicationMethodsScreen() {
|
||||
fieldBlocks: CustomMethodCardFieldBlock[];
|
||||
}) => {
|
||||
markCreateFlowInteraction();
|
||||
const existingId = wizardCustomizeCardId;
|
||||
if (existingId) {
|
||||
updateState({
|
||||
selectedCommunicationMethodIds: moveFacetSelectionIdToFront(
|
||||
selectedIds,
|
||||
existingId,
|
||||
),
|
||||
customMethodCardMetaById: methodCardMetaWithCustomizeHeader(
|
||||
state.customMethodCardMetaById,
|
||||
existingId,
|
||||
{ title, description },
|
||||
),
|
||||
...(pendingDraft
|
||||
? {
|
||||
communicationMethodDetailsById: {
|
||||
...(state.communicationMethodDetailsById ?? {}),
|
||||
[existingId]: pendingDraft,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
customMethodCardFieldBlocksById: {
|
||||
...(state.customMethodCardFieldBlocksById ?? {}),
|
||||
[existingId]: fieldBlocks,
|
||||
},
|
||||
});
|
||||
if (pendingDraft) {
|
||||
customizeSnapshotRef.current = captureMethodCardCustomizeSnapshot(
|
||||
pendingDraft,
|
||||
fieldBlocks,
|
||||
{ title, description },
|
||||
);
|
||||
}
|
||||
setDraftFieldBlocks(structuredClone(fieldBlocks));
|
||||
setAddCustomWizardOpen(false);
|
||||
return;
|
||||
}
|
||||
const id = crypto.randomUUID();
|
||||
updateState({
|
||||
selectedCommunicationMethodIds: moveFacetSelectionIdToFront(
|
||||
@@ -588,91 +607,29 @@ export function CommunicationMethodsScreen() {
|
||||
},
|
||||
[
|
||||
markCreateFlowInteraction,
|
||||
pendingDraft,
|
||||
selectedIds,
|
||||
state.communicationMethodDetailsById,
|
||||
state.customMethodCardFieldBlocksById,
|
||||
state.customMethodCardMetaById,
|
||||
updateState,
|
||||
wizardCustomizeCardId,
|
||||
],
|
||||
);
|
||||
|
||||
const handleCreateModalPrimary = useCallback(() => {
|
||||
if (!pendingCardId) {
|
||||
handleCreateModalClose();
|
||||
void handleCreateModalClose();
|
||||
return;
|
||||
}
|
||||
markCreateFlowInteraction();
|
||||
|
||||
if (selectedIds.includes(pendingCardId)) {
|
||||
if (modalEditUnlocked) {
|
||||
if (!customizeHeaderDraft) {
|
||||
return;
|
||||
}
|
||||
const nextMeta = methodCardMetaWithCustomizeHeader(
|
||||
state.customMethodCardMetaById,
|
||||
pendingCardId,
|
||||
customizeHeaderDraft,
|
||||
);
|
||||
if (
|
||||
pendingCardId &&
|
||||
isCustomMethodCardId(pendingCardId, state.customMethodCardMetaById) &&
|
||||
usesWizardFieldBlocksModalBody({
|
||||
methodId: pendingCardId,
|
||||
meta: state.customMethodCardMetaById,
|
||||
fieldBlocksById: state.customMethodCardFieldBlocksById,
|
||||
modalEditUnlocked,
|
||||
draftFieldBlocks,
|
||||
customFacetDetailsMatchPreset,
|
||||
})
|
||||
) {
|
||||
updateState({
|
||||
customMethodCardMetaById: nextMeta,
|
||||
customMethodCardFieldBlocksById: {
|
||||
...(state.customMethodCardFieldBlocksById ?? {}),
|
||||
[pendingCardId]: structuredClone(draftFieldBlocks ?? []),
|
||||
},
|
||||
});
|
||||
} else if (pendingDraft) {
|
||||
updateState({
|
||||
customMethodCardMetaById: nextMeta,
|
||||
communicationMethodDetailsById: {
|
||||
...(state.communicationMethodDetailsById ?? {}),
|
||||
[pendingCardId]: pendingDraft,
|
||||
},
|
||||
});
|
||||
}
|
||||
customizeSnapshotRef.current = null;
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const persistWizardBlocks =
|
||||
modalUsesWizardFieldBlocksBody && draftFieldBlocks !== null;
|
||||
|
||||
if (modalEditUnlocked) {
|
||||
if (!customizeHeaderDraft) {
|
||||
return;
|
||||
}
|
||||
const nextMeta = methodCardMetaWithCustomizeHeader(
|
||||
state.customMethodCardMetaById,
|
||||
pendingCardId,
|
||||
customizeHeaderDraft,
|
||||
);
|
||||
if (
|
||||
pendingCardId &&
|
||||
isCustomMethodCardId(pendingCardId, state.customMethodCardMetaById) &&
|
||||
usesWizardFieldBlocksModalBody({
|
||||
methodId: pendingCardId,
|
||||
meta: state.customMethodCardMetaById,
|
||||
fieldBlocksById: state.customMethodCardFieldBlocksById,
|
||||
modalEditUnlocked,
|
||||
draftFieldBlocks,
|
||||
customFacetDetailsMatchPreset,
|
||||
})
|
||||
) {
|
||||
if (selectedIds.includes(pendingCardId)) {
|
||||
if (persistWizardBlocks) {
|
||||
updateState({
|
||||
customMethodCardMetaById: nextMeta,
|
||||
customMethodCardFieldBlocksById: {
|
||||
...(state.customMethodCardFieldBlocksById ?? {}),
|
||||
[pendingCardId]: structuredClone(draftFieldBlocks ?? []),
|
||||
@@ -680,22 +637,27 @@ export function CommunicationMethodsScreen() {
|
||||
});
|
||||
} else if (pendingDraft) {
|
||||
updateState({
|
||||
customMethodCardMetaById: nextMeta,
|
||||
communicationMethodDetailsById: {
|
||||
...(state.communicationMethodDetailsById ?? {}),
|
||||
[pendingCardId]: pendingDraft,
|
||||
},
|
||||
});
|
||||
}
|
||||
customizeSnapshotRef.current = null;
|
||||
setModalEditUnlocked(false);
|
||||
setDraftFieldBlocks(null);
|
||||
setCustomizeHeaderDraft(null);
|
||||
if (pendingDraft) {
|
||||
customizeSnapshotRef.current = captureMethodCardCustomizeSnapshot(
|
||||
pendingDraft,
|
||||
persistWizardBlocks ? draftFieldBlocks : null,
|
||||
customizeSnapshotRef.current?.headerDraft ?? {
|
||||
title: "",
|
||||
description: "",
|
||||
},
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pendingDraft) {
|
||||
handleCreateModalClose();
|
||||
void handleCreateModalClose();
|
||||
return;
|
||||
}
|
||||
updateState({
|
||||
@@ -707,15 +669,23 @@ export function CommunicationMethodsScreen() {
|
||||
...(state.communicationMethodDetailsById ?? {}),
|
||||
[pendingCardId]: pendingDraft,
|
||||
},
|
||||
...(persistWizardBlocks
|
||||
? {
|
||||
customMethodCardFieldBlocksById: {
|
||||
...(state.customMethodCardFieldBlocksById ?? {}),
|
||||
[pendingCardId]: structuredClone(draftFieldBlocks ?? []),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
pendingEphemeralDuplicateIdRef.current = null;
|
||||
handleCreateModalClose();
|
||||
customizeSnapshotRef.current = null;
|
||||
void handleCreateModalClose();
|
||||
}, [
|
||||
customizeHeaderDraft,
|
||||
draftFieldBlocks,
|
||||
handleCreateModalClose,
|
||||
markCreateFlowInteraction,
|
||||
modalEditUnlocked,
|
||||
modalUsesWizardFieldBlocksBody,
|
||||
pendingCardId,
|
||||
pendingDraft,
|
||||
selectedIds,
|
||||
@@ -766,33 +736,10 @@ export function CommunicationMethodsScreen() {
|
||||
<Create
|
||||
isOpen={createModalOpen}
|
||||
onClose={handleCreateModalClose}
|
||||
headerContent={
|
||||
modalEditUnlocked && customizeHeaderDraft ? (
|
||||
<MethodCardCustomizeModalHeader
|
||||
titleLabel={modalKebabMenu.customizePolicyTitleLabel}
|
||||
descriptionLabel={modalKebabMenu.customizePolicyDescriptionLabel}
|
||||
titleValue={customizeHeaderDraft.title}
|
||||
descriptionValue={customizeHeaderDraft.description}
|
||||
onTitleChange={(title) =>
|
||||
setCustomizeHeaderDraft((prev) =>
|
||||
prev ? { ...prev, title } : null,
|
||||
)
|
||||
}
|
||||
onDescriptionChange={(description) =>
|
||||
setCustomizeHeaderDraft((prev) =>
|
||||
prev ? { ...prev, description } : null,
|
||||
)
|
||||
}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
onNext={handleCreateModalPrimary}
|
||||
title={modalConfig.title}
|
||||
description={modalConfig.description}
|
||||
nextButtonText={modalConfig.nextButtonText}
|
||||
showBackButton={modalEditUnlocked}
|
||||
onBack={handleCancelCustomize}
|
||||
backButtonText={modalKebabMenu.cancelCustomize}
|
||||
showNextButton={showMethodModalPrimary}
|
||||
backdropVariant="blurredYellow"
|
||||
kebabTriggerAriaLabel={modalKebabMenu.triggerAriaLabel}
|
||||
@@ -805,14 +752,14 @@ export function CommunicationMethodsScreen() {
|
||||
cardId={pendingCardId}
|
||||
blocksById={state.customMethodCardFieldBlocksById}
|
||||
blocksOverride={
|
||||
modalEditUnlocked && draftFieldBlocks !== null
|
||||
? draftFieldBlocks
|
||||
: undefined
|
||||
draftFieldBlocks !== null ? draftFieldBlocks : undefined
|
||||
}
|
||||
policyMeta={state.customMethodCardMetaById?.[pendingCardId]}
|
||||
showPolicyContentLockupWhenNoBlocks={!modalEditUnlocked}
|
||||
showPolicyContentLockupWhenNoBlocks={
|
||||
draftFieldBlocks === null || draftFieldBlocks.length === 0
|
||||
}
|
||||
onFieldBlocksChange={
|
||||
fieldsLocked
|
||||
draftFieldBlocks === null
|
||||
? undefined
|
||||
: (next) => setDraftFieldBlocks(next)
|
||||
}
|
||||
@@ -821,7 +768,6 @@ export function CommunicationMethodsScreen() {
|
||||
<CommunicationMethodEditFields
|
||||
value={pendingDraft}
|
||||
onChange={handleDraftChange}
|
||||
readOnly={fieldsLocked}
|
||||
/>
|
||||
)
|
||||
) : null}
|
||||
@@ -830,6 +776,7 @@ export function CommunicationMethodsScreen() {
|
||||
<CustomMethodCardWizard
|
||||
isOpen={addCustomWizardOpen}
|
||||
onClose={handleCloseAddWizard}
|
||||
initialValues={wizardInitialValues}
|
||||
onFinalize={handleFinalizeCustomCard}
|
||||
onPersistCustomUploadFile={(file) =>
|
||||
uploadCreateFlowFile(file, "customMethodAttachment")
|
||||
|
||||
Reference in New Issue
Block a user