Start Add value in the empty custom-policy wizard so Finalize can save a selected chip named from the title.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,6 +25,8 @@ import {
|
||||
MAX_SELECTED_CORE_VALUES,
|
||||
removeCoreValueChipFromDraft,
|
||||
} from "../../../../../lib/create/coreValueChipFacet";
|
||||
import { methodCardMetaWithCustomizeHeader } from "../../../../../lib/create/methodCardCustomizeMetaPatch";
|
||||
import { moveFacetSelectionIdToFront } from "../../../../../lib/create/methodCardSelectionOrder";
|
||||
import {
|
||||
buildMethodCardWizardInitialValues,
|
||||
coreValueDetailsFromWizardFieldBlocks,
|
||||
@@ -41,11 +43,13 @@ const MAX_CORE_VALUES = MAX_SELECTED_CORE_VALUES;
|
||||
*
|
||||
* - `pending` — preset chip just selected; modal opened to capture
|
||||
* meaning/signals. Close (X) confirms, then unselects the chip.
|
||||
* - `customPending` — brand-new custom chip just created via the Add
|
||||
* value flow; modal opened with empty fields. Dismiss = drop the
|
||||
* chip entirely (it was never confirmed via the Add Value button).
|
||||
* - `customPending` — leftover inline custom-chip drafts (older sessions).
|
||||
* Dismiss = drop the chip entirely.
|
||||
* - `editing` — chip already exists & is selected; modal reopened to
|
||||
* tweak meaning/signals. Dismiss = no-op (chip stays as-is).
|
||||
*
|
||||
* **Add value** (and the header "add" link) opens an empty custom-policy
|
||||
* wizard. Finalize writes a selected chip named from the wizard title.
|
||||
*/
|
||||
type ModalSession = "pending" | "customPending" | "editing";
|
||||
|
||||
@@ -489,12 +493,57 @@ export function CoreValuesSelectScreen() {
|
||||
description: string;
|
||||
fieldBlocks: CustomMethodCardFieldBlock[];
|
||||
}) => {
|
||||
const chipId = wizardCustomizeChipId ?? activeModalChipId;
|
||||
if (!chipId) return;
|
||||
markCreateFlowInteraction();
|
||||
pendingEphemeralCoreDuplicateRef.current = null;
|
||||
const trimmedTitle = title.trim();
|
||||
const trimmedDescription = description.trim();
|
||||
if (!trimmedTitle) return;
|
||||
markCreateFlowInteraction();
|
||||
pendingEphemeralCoreDuplicateRef.current = null;
|
||||
|
||||
const existingId = wizardCustomizeChipId;
|
||||
if (!existingId) {
|
||||
const id = crypto.randomUUID();
|
||||
const nextDetails = {
|
||||
...coreValueDetailsFromWizardFieldBlocks(fieldBlocks, EMPTY_DETAIL),
|
||||
...(trimmedDescription.length > 0
|
||||
? { supportText: trimmedDescription }
|
||||
: {}),
|
||||
};
|
||||
replaceState((prev) => {
|
||||
const sel = prev.selectedCoreValueIds ?? [];
|
||||
if (sel.length >= MAX_CORE_VALUES) {
|
||||
return prev;
|
||||
}
|
||||
const snap = [...(prev.coreValuesChipsSnapshot ?? [])];
|
||||
snap.push({
|
||||
id,
|
||||
label: trimmedTitle,
|
||||
state: "selected",
|
||||
});
|
||||
return {
|
||||
...prev,
|
||||
selectedCoreValueIds: moveFacetSelectionIdToFront(sel, id),
|
||||
coreValuesChipsSnapshot: snap,
|
||||
coreValueDetailsByChipId: {
|
||||
...(prev.coreValueDetailsByChipId ?? {}),
|
||||
[id]: nextDetails,
|
||||
},
|
||||
customMethodCardFieldBlocksById: {
|
||||
...(prev.customMethodCardFieldBlocksById ?? {}),
|
||||
[id]: structuredClone(fieldBlocks),
|
||||
},
|
||||
customMethodCardMetaById: methodCardMetaWithCustomizeHeader(
|
||||
prev.customMethodCardMetaById,
|
||||
id,
|
||||
{ title: trimmedTitle, description: trimmedDescription },
|
||||
),
|
||||
};
|
||||
});
|
||||
setAddCustomWizardOpen(false);
|
||||
setWizardCustomizeChipId(null);
|
||||
setWizardInitialValues(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const nextDetails = {
|
||||
...coreValueDetailsFromWizardFieldBlocks(fieldBlocks, draft),
|
||||
...(trimmedDescription.length > 0
|
||||
@@ -503,8 +552,8 @@ export function CoreValuesSelectScreen() {
|
||||
};
|
||||
replaceState((prev) => {
|
||||
const snap = [...(prev.coreValuesChipsSnapshot ?? [])];
|
||||
const i = snap.findIndex((r) => r.id === chipId);
|
||||
if (i >= 0 && trimmedTitle.length > 0) {
|
||||
const i = snap.findIndex((r) => r.id === existingId);
|
||||
if (i >= 0) {
|
||||
snap[i] = { ...snap[i], label: trimmedTitle };
|
||||
}
|
||||
return {
|
||||
@@ -512,11 +561,11 @@ export function CoreValuesSelectScreen() {
|
||||
coreValuesChipsSnapshot: snap,
|
||||
coreValueDetailsByChipId: {
|
||||
...(prev.coreValueDetailsByChipId ?? {}),
|
||||
[chipId]: nextDetails,
|
||||
[existingId]: nextDetails,
|
||||
},
|
||||
customMethodCardFieldBlocksById: {
|
||||
...(prev.customMethodCardFieldBlocksById ?? {}),
|
||||
[chipId]: structuredClone(fieldBlocks),
|
||||
[existingId]: structuredClone(fieldBlocks),
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -526,13 +575,7 @@ export function CoreValuesSelectScreen() {
|
||||
setWizardCustomizeChipId(null);
|
||||
setWizardInitialValues(null);
|
||||
},
|
||||
[
|
||||
activeModalChipId,
|
||||
draft,
|
||||
markCreateFlowInteraction,
|
||||
replaceState,
|
||||
wizardCustomizeChipId,
|
||||
],
|
||||
[draft, markCreateFlowInteraction, replaceState, wizardCustomizeChipId],
|
||||
);
|
||||
|
||||
const kebabMenuItems = useMemo(() => {
|
||||
@@ -587,15 +630,14 @@ export function CoreValuesSelectScreen() {
|
||||
|
||||
const addHandlers = {
|
||||
onAddClick: () => {
|
||||
const selectedCount = coreValueOptions.filter(
|
||||
(o) => o.state === "selected",
|
||||
).length;
|
||||
if (selectedCount >= MAX_CORE_VALUES) return;
|
||||
markCreateFlowInteraction();
|
||||
setCoreValueOptions((prev) => {
|
||||
const next: ChipOption[] = [
|
||||
...prev,
|
||||
{ id: crypto.randomUUID(), label: "", state: "custom" },
|
||||
];
|
||||
queueMicrotask(() => syncCoreValuesToDraft(next));
|
||||
return next;
|
||||
});
|
||||
setWizardCustomizeChipId(null);
|
||||
setWizardInitialValues(null);
|
||||
setAddCustomWizardOpen(true);
|
||||
},
|
||||
onCustomChipConfirm: (chipId: string, value: string) => {
|
||||
markCreateFlowInteraction();
|
||||
|
||||
Reference in New Issue
Block a user