diff --git a/frontend/src/components/maps/LocationMapCanvas.jsx b/frontend/src/components/maps/LocationMapCanvas.jsx index 9b0f167..f07523a 100644 --- a/frontend/src/components/maps/LocationMapCanvas.jsx +++ b/frontend/src/components/maps/LocationMapCanvas.jsx @@ -55,6 +55,21 @@ export default function LocationMapCanvas({ const objectDragHistoryCapturedRef = useRef(false); const suppressPanClickRef = useRef(false); const [isPanning, setIsPanning] = useState(false); + const orderedObjects = useMemo(() => { + if (!selectedObjectKey) return objects; + + const selectedObjects = []; + const remainingObjects = []; + objects.forEach((object) => { + if (getObjectKey(object) === selectedObjectKey) { + selectedObjects.push(object); + return; + } + remainingObjects.push(object); + }); + + return [...remainingObjects, ...selectedObjects]; + }, [objects, selectedObjectKey]); const zoneItemSummary = useMemo(() => { const assignedCounts = new Map(); const visibleItemsByZone = new Map(); @@ -324,13 +339,7 @@ export default function LocationMapCanvas({ {mode === "edit" ? ( ) : null} - {(selectedObjectKey - ? [ - ...objects.filter((object) => getObjectKey(object) !== selectedObjectKey), - ...objects.filter((object) => getObjectKey(object) === selectedObjectKey), - ] - : objects - ).map(renderMapObject)} + {orderedObjects.map(renderMapObject)} {emptyCanvasMessage ? (
{ await expect(page.locator(".location-map-resize-handle")).toBeVisible(); }); +test("admin selected overlapping map area renders above other areas", async ({ page }) => { + await mockMapShell(page); + + const mapState = draftMapState([ + { + id: 1311, + location_map_id: 900, + zone_id: 501, + zone_name: "Bakery", + type: "zone", + label: "Bakery", + x: 40, + y: 40, + width: 260, + height: 180, + rotation: 0, + locked: false, + visible: true, + sort_order: 1, + }, + { + id: 1312, + location_map_id: 900, + zone_id: 502, + zone_name: "Frozen Foods", + type: "zone", + label: "Frozen Foods", + x: 120, + y: 90, + width: 260, + height: 180, + rotation: 0, + locked: false, + visible: true, + sort_order: 2, + }, + ], 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(); + + const bakeryArea = page.getByRole("button", { name: "Map area Bakery" }); + await bakeryArea.focus(); + await page.keyboard.press("Enter"); + await expect(bakeryArea).toHaveAttribute("aria-pressed", "true"); + + await expect.poll(async () => + page.locator(".location-map-object").evaluateAll((nodes) => + nodes.map((node) => node.getAttribute("data-object-key")) + ) + ).toEqual(["1312", "1311"]); + await expect(page.locator('[data-object-key="1311"] .location-map-resize-handle')).toBeVisible(); +}); + test("admin cleared map area labels keep linked zone action names", async ({ page }) => { await mockMapShell(page);