diff --git a/frontend/src/hooks/useUnsavedMapLeaveGuard.js b/frontend/src/hooks/useUnsavedMapLeaveGuard.js index 46beba4..820dee9 100644 --- a/frontend/src/hooks/useUnsavedMapLeaveGuard.js +++ b/frontend/src/hooks/useUnsavedMapLeaveGuard.js @@ -24,6 +24,9 @@ export default function useUnsavedMapLeaveGuard({ useEffect(() => { if (!shouldGuardLeave) { + if (historyGuardActiveRef.current && guardedUrlRef.current === window.location.href) { + window.history.back(); + } setPendingLeaveTarget(null); guardedClickTargetRef.current = null; confirmedLeaveRef.current = false; diff --git a/frontend/tests/location-map-manager.spec.ts b/frontend/tests/location-map-manager.spec.ts index 352bbab..8b2e1a4 100644 --- a/frontend/tests/location-map-manager.spec.ts +++ b/frontend/tests/location-map-manager.spec.ts @@ -2723,6 +2723,57 @@ test("admin browser back warns when draft edits are unsaved", async ({ page }) = await expect(page).toHaveURL(/\/$/); }); +test("admin browser back leaves after draft edits are undone clean", async ({ page }) => { + await mockMapShell(page); + + const mapState = draftMapState([ + { + id: 1376, + 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.evaluate(() => { + window.history.replaceState(window.history.state, "", "/"); + window.history.pushState({}, "", "/stores/100/locations/10/map"); + }); + await expect(page).toHaveURL(/\/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 page.getByRole("button", { name: "Undo" }).click(); + await expect(page.locator(".location-map-status")).toHaveText("Draft"); + await expect(page.getByRole("heading", { name: "Leave with unsaved changes?" })).toHaveCount(0); + + await page.evaluate(() => window.history.back()); + await expect(page).toHaveURL(/\/$/); + await expect(page.getByRole("heading", { name: "Leave with unsaved changes?" })).toHaveCount(0); +}); + test("admin logout warns when draft edits are unsaved", async ({ page }) => { await mockMapShell(page);