From e416f379409e21cd12b1acff2f4041020e0650e7 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 21 Aug 2026 16:41:03 -0600 Subject: [PATCH] Treat review-page value modals as unchanged when field blocks match the open snapshot so close does not ask to discard a view-only visit. Co-authored-by: Cursor --- .../components/FinalReviewChipEditModal.tsx | 11 ++- tests/components/FinalReviewPage.test.tsx | 80 +++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/app/(app)/create/components/FinalReviewChipEditModal.tsx b/app/(app)/create/components/FinalReviewChipEditModal.tsx index 36363e0..266f739 100644 --- a/app/(app)/create/components/FinalReviewChipEditModal.tsx +++ b/app/(app)/create/components/FinalReviewChipEditModal.tsx @@ -422,7 +422,7 @@ export function FinalReviewChipEditModal({ true, coreCustomizeSnapshotRef.current, draft?.groupKey === "coreValues" ? draft.value : null, - null, + draftFieldBlocks, customizeHeaderDraft, )) ) { @@ -605,7 +605,7 @@ export function FinalReviewChipEditModal({ true, coreCustomizeSnapshotRef.current, draft?.groupKey === "coreValues" ? draft.value : null, - null, + draftFieldBlocks, customizeHeaderDraft, )) ) { @@ -622,6 +622,7 @@ export function FinalReviewChipEditModal({ confirmDiscard, customizeHeaderDraft, draft, + draftFieldBlocks, finalizeModalClose, onInteract, replaceState, @@ -647,7 +648,7 @@ export function FinalReviewChipEditModal({ true, coreCustomizeSnapshotRef.current, draft.value, - null, + draftFieldBlocks, customizeHeaderDraft, )) ) { @@ -696,6 +697,7 @@ export function FinalReviewChipEditModal({ confirmDiscard, customizeHeaderDraft, draft, + draftFieldBlocks, modalKebabMenu.duplicateTitleSuffix, onEditTargetChange, onInteract, @@ -790,7 +792,7 @@ export function FinalReviewChipEditModal({ }); coreCustomizeSnapshotRef.current = captureMethodCardCustomizeSnapshot( draft.value, - null, + draftFieldBlocks, customizeHeaderDraft ?? { title: target.chipLabel, description: "", @@ -802,6 +804,7 @@ export function FinalReviewChipEditModal({ coreCustomizeSaveDisabled, customizeHeaderDraft, draft, + draftFieldBlocks, onInteract, onSave, state.customMethodCardFieldBlocksById, diff --git a/tests/components/FinalReviewPage.test.tsx b/tests/components/FinalReviewPage.test.tsx index 1c26570..090ea2c 100644 --- a/tests/components/FinalReviewPage.test.tsx +++ b/tests/components/FinalReviewPage.test.tsx @@ -438,6 +438,86 @@ describe("FinalReviewScreen — chip detail modal", () => { ).toBeInTheDocument(); }); + it("closes a values chip without discard when nothing changed", async () => { + render( + { + /* noop */ + }} + initial={{ + selectedCoreValueIds: ["1"], + coreValuesChipsSnapshot: [ + { id: "1", label: "Accessibility", state: "selected" }, + ], + coreValueDetailsByChipId: { + "1": { + meaning: "Everyone can participate.", + signals: "Captions and ramps.", + }, + }, + customMethodCardFieldBlocksById: { + "1": [ + { + kind: "text", + id: "facet-meaning", + blockTitle: "What this value means", + placeholderText: "Everyone can participate.", + }, + { + kind: "text", + id: "facet-signals", + blockTitle: "Signals", + placeholderText: "Captions and ramps.", + }, + ], + }, + }} + />, + ); + + fireEvent.click( + await screen.findByRole("button", { name: "Accessibility" }), + ); + const valuesDialog = await screen.findByRole("dialog"); + expect(within(valuesDialog).getAllByRole("textbox").length).toBeGreaterThan( + 0, + ); + fireEvent.keyDown(document, { key: "Escape" }); + await waitFor(() => { + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + expect( + screen.queryByRole("button", { name: "Keep editing" }), + ).not.toBeInTheDocument(); + }); + + it("closes a method chip without discard when nothing changed", async () => { + render( + { + /* noop */ + }} + initial={{ + title: "Oak Park Commons", + selectedCommunicationMethodIds: ["signal"], + }} + />, + ); + + fireEvent.click(await screen.findByRole("button", { name: "Signal" })); + const methodDialog = await screen.findByRole("dialog"); + expect(within(methodDialog).getAllByRole("textbox").length).toBeGreaterThan( + 0, + ); + fireEvent.keyDown(document, { key: "Escape" }); + await waitFor(() => { + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + expect( + screen.queryByRole("button", { name: "Keep editing" }), + ).not.toBeInTheDocument(); + }); + }); /**