diff --git a/frontend/src/components/maps/LocationMapBottomSheetSections.jsx b/frontend/src/components/maps/LocationMapBottomSheetSections.jsx index eb832cb..a7460e1 100644 --- a/frontend/src/components/maps/LocationMapBottomSheetSections.jsx +++ b/frontend/src/components/maps/LocationMapBottomSheetSections.jsx @@ -37,12 +37,11 @@ function MapItemActionRow({ item, onSelectItem }) { function MapItemActionList({ items, onSelectItem, itemGroupLabel }) { const [showAllItems, setShowAllItems] = useState(false); + const itemListKey = items.map((item) => item.id).join(":"); useEffect(() => { - if (items.length <= MAP_ITEM_PREVIEW_LIMIT) { - setShowAllItems(false); - } - }, [items.length]); + setShowAllItems(false); + }, [itemListKey]); const visibleItems = showAllItems ? items : items.slice(0, MAP_ITEM_PREVIEW_LIMIT); const overflowItemCount = items.length - visibleItems.length; diff --git a/frontend/tests/location-map-manager.spec.ts b/frontend/tests/location-map-manager.spec.ts index be81044..8bf1c1a 100644 --- a/frontend/tests/location-map-manager.spec.ts +++ b/frontend/tests/location-map-manager.spec.ts @@ -3968,6 +3968,93 @@ test("viewer handles empty and many-item zone panels without default pins", asyn await expect(page.locator(".location-map-pin")).toHaveCount(0); }); +test("viewer collapses expanded zone items after selecting another zone", async ({ page }) => { + await mockMapShell(page); + + const bakeryItems = Array.from({ length: 11 }, (_, index) => ({ + id: 5100 + index, + item_name: `bakery item ${index + 1}`, + quantity: 1, + bought: false, + zone_id: 501, + zone: "Bakery", + added_by_users: ["map-user"], + })); + const frozenItems = Array.from({ length: 10 }, (_, index) => ({ + id: 5200 + index, + item_name: `frozen item ${index + 1}`, + quantity: 1, + bought: false, + zone_id: 502, + zone: "Frozen Foods", + added_by_users: ["map-user"], + })); + const mapState = { + ...publishedMapState([ + { + id: 1563, + location_map_id: 901, + 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, + }, + { + id: 1564, + location_map_id: 901, + zone_id: 502, + zone_name: "Frozen Foods", + type: "zone", + label: "Frozen Foods", + x: 340, + y: 40, + width: 260, + height: 160, + rotation: 0, + locked: false, + visible: true, + sort_order: 2, + }, + ], true), + items: [...bakeryItems, ...frozenItems], + unmapped_count: 0, + }; + + 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.locator('[data-object-key="1563"]').locator("rect").first().click(); + await expect(page.locator(".location-map-zone-items .location-map-item-row")).toHaveCount(8); + await page.getByRole("button", { name: "Show 3 more zone items" }).click(); + await expect(page.locator(".location-map-zone-items .location-map-item-row")).toHaveCount(11); + await expect(page.getByText("bakery item 11")).toBeVisible(); + + await page.locator('[data-object-key="1564"]').locator("rect").first().click(); + + await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Frozen Foods"); + await expect(page.locator(".location-map-zone-items .location-map-item-row")).toHaveCount(8); + await expect(page.getByText("frozen item 8")).toBeVisible(); + await expect(page.getByText("frozen item 9")).toHaveCount(0); + await expect(page.getByText("bakery item 11")).toHaveCount(0); + await expect(page.getByRole("button", { name: "Show 2 more zone items" })).toHaveText("+2 more"); + await expect(page.getByRole("button", { name: "Show fewer zone items" })).toHaveCount(0); +}); + test("viewer map areas are keyboard selectable", async ({ page }) => { await mockMapShell(page);