From 984b55a4da9f40edd5ce5bf9b139ec2ef9652c68 Mon Sep 17 00:00:00 2001 From: Nico Date: Mon, 15 Jun 2026 15:27:30 -0700 Subject: [PATCH] fix: clear clean map undo state --- .../src/hooks/useLocationMapViewControls.js | 2 +- frontend/tests/location-map-manager.spec.ts | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/frontend/src/hooks/useLocationMapViewControls.js b/frontend/src/hooks/useLocationMapViewControls.js index f15f06c..60321ad 100644 --- a/frontend/src/hooks/useLocationMapViewControls.js +++ b/frontend/src/hooks/useLocationMapViewControls.js @@ -77,7 +77,7 @@ export default function useLocationMapViewControls({ ]); setObjects(priorSnapshot.objects); setSelectedObjectKey(priorSnapshot.selectedObjectKey); - setHasUnsavedChanges(true); + setHasUnsavedChanges(previous.length > 1); return previous.slice(0, -1); }); }, [ diff --git a/frontend/tests/location-map-manager.spec.ts b/frontend/tests/location-map-manager.spec.ts index 39ceffe..5854e3b 100644 --- a/frontend/tests/location-map-manager.spec.ts +++ b/frontend/tests/location-map-manager.spec.ts @@ -1742,6 +1742,58 @@ test("admin selecting an object does not mark a draft dirty until it changes", a await expect(page.getByRole("button", { name: "Undo" })).toBeEnabled(); }); +test("admin undoing the only draft change clears unsaved state", async ({ page }) => { + await mockMapShell(page); + + const mapState = draftMapState([ + { + id: 1356, + location_map_id: 900, + zone_id: 501, + zone_name: "Bakery", + type: "zone", + label: "Bakery", + x: 40, + y: 40, + width: 260, + height: 160, + rotation: 0, + locked: false, + visible: true, + sort_order: 1, + }, + ], true); + + await page.route("**/households/1/locations/10/map", async (route) => { + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(mapState), + }); + }); + + await page.goto("/stores/100/locations/10/map"); + + await page.getByRole("button", { name: "Continue Editing" }).click(); + await page.getByRole("button", { name: "Map area Bakery" }).click(); + + await page.getByLabel("Linked zone").selectOption(""); + await expect(page.locator(".location-map-status")).toHaveText("Unsaved Draft"); + await expect(page.getByRole("button", { name: "Save Draft" })).toBeEnabled(); + await expect(page.getByRole("button", { name: "Undo" })).toBeEnabled(); + + await page.getByRole("button", { name: "Undo" }).click(); + await expect(page.locator(".location-map-status")).toHaveText("Draft"); + await expect(page.getByRole("button", { name: "Save Draft" })).toHaveCount(0); + await expect(page.getByLabel("Linked zone")).toHaveValue("501"); + await expect(page.getByRole("button", { name: "Redo" })).toBeEnabled(); + + await page.getByRole("button", { name: "Redo" }).click(); + await expect(page.locator(".location-map-status")).toHaveText("Unsaved Draft"); + await expect(page.getByRole("button", { name: "Save Draft" })).toBeEnabled(); + await expect(page.getByLabel("Linked zone")).toHaveValue(""); +}); + test("admin can recover hidden map areas from the empty canvas", async ({ page }) => { await mockMapShell(page);