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);