fix: expand map while dragging areas
This commit is contained in:
parent
dedfc30998
commit
1c50c67410
@ -10,11 +10,40 @@ import LocationMapObject from "./LocationMapObject";
|
|||||||
const DRAG_CHANGE_THRESHOLD = 2;
|
const DRAG_CHANGE_THRESHOLD = 2;
|
||||||
const NUDGE_KEYS = new Set(["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft"]);
|
const NUDGE_KEYS = new Set(["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft"]);
|
||||||
const SELECTED_OBJECT_SCROLL_PADDING = 24;
|
const SELECTED_OBJECT_SCROLL_PADDING = 24;
|
||||||
|
const EDGE_PAN_ZONE = 56;
|
||||||
|
const MAX_EDGE_PAN_STEP = 18;
|
||||||
|
|
||||||
function clampScrollPosition(value, maxValue) {
|
function clampScrollPosition(value, maxValue) {
|
||||||
return Math.min(Math.max(0, value), Math.max(0, maxValue));
|
return Math.min(Math.max(0, value), Math.max(0, maxValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEdgePanStep(pointerPosition, start, end) {
|
||||||
|
if (pointerPosition < start + EDGE_PAN_ZONE) {
|
||||||
|
const intensity = (start + EDGE_PAN_ZONE - pointerPosition) / EDGE_PAN_ZONE;
|
||||||
|
return -Math.ceil(MAX_EDGE_PAN_STEP * intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointerPosition > end - EDGE_PAN_ZONE) {
|
||||||
|
const intensity = (pointerPosition - (end - EDGE_PAN_ZONE)) / EDGE_PAN_ZONE;
|
||||||
|
return Math.ceil(MAX_EDGE_PAN_STEP * intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function panScrollElement(scrollElement, deltaX, deltaY) {
|
||||||
|
if (!scrollElement || (!deltaX && !deltaY)) return;
|
||||||
|
|
||||||
|
scrollElement.scrollLeft = clampScrollPosition(
|
||||||
|
scrollElement.scrollLeft + deltaX,
|
||||||
|
scrollElement.scrollWidth - scrollElement.clientWidth
|
||||||
|
);
|
||||||
|
scrollElement.scrollTop = clampScrollPosition(
|
||||||
|
scrollElement.scrollTop + deltaY,
|
||||||
|
scrollElement.scrollHeight - scrollElement.clientHeight
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function getSelectedObjectScrollKey(object, selectedObjectKey, zoom) {
|
function getSelectedObjectScrollKey(object, selectedObjectKey, zoom) {
|
||||||
return [
|
return [
|
||||||
selectedObjectKey,
|
selectedObjectKey,
|
||||||
@ -38,6 +67,22 @@ function clampResizedObjectToMap(object, mapSize) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDraggedObjectCandidate(object, dragState, deltaX, deltaY) {
|
||||||
|
if (dragState.type === "resize") {
|
||||||
|
return {
|
||||||
|
...object,
|
||||||
|
width: Math.max(40, dragState.startObject.width + deltaX),
|
||||||
|
height: Math.max(40, dragState.startObject.height + deltaY),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...object,
|
||||||
|
x: Math.max(0, dragState.startObject.x + deltaX),
|
||||||
|
y: Math.max(0, dragState.startObject.y + deltaY),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function hasObjectBoundsChanged(object, nextObject) {
|
function hasObjectBoundsChanged(object, nextObject) {
|
||||||
return (
|
return (
|
||||||
object.x !== nextObject.x ||
|
object.x !== nextObject.x ||
|
||||||
@ -47,22 +92,6 @@ function hasObjectBoundsChanged(object, nextObject) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDraggedObjectUpdate(object, dragState, deltaX, deltaY, mapSize) {
|
|
||||||
if (dragState.type === "resize") {
|
|
||||||
return clampResizedObjectToMap({
|
|
||||||
...object,
|
|
||||||
width: Math.max(40, dragState.startObject.width + deltaX),
|
|
||||||
height: Math.max(40, dragState.startObject.height + deltaY),
|
|
||||||
}, mapSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return clampObjectToMap({
|
|
||||||
...object,
|
|
||||||
x: dragState.startObject.x + deltaX,
|
|
||||||
y: dragState.startObject.y + deltaY,
|
|
||||||
}, mapSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function LocationMapCanvas({
|
export default function LocationMapCanvas({
|
||||||
mode,
|
mode,
|
||||||
objects,
|
objects,
|
||||||
@ -83,12 +112,13 @@ export default function LocationMapCanvas({
|
|||||||
setSelectedObjectKey,
|
setSelectedObjectKey,
|
||||||
remember,
|
remember,
|
||||||
updateObjects,
|
updateObjects,
|
||||||
|
expandMapToFitObject,
|
||||||
}) {
|
}) {
|
||||||
const canEditObjects = !editingLocked && mode === "edit";
|
const canEditObjects = !editingLocked && mode === "edit";
|
||||||
const canDragPan = mode === "view" || mode === "edit";
|
const canDragPan = mode === "view" || mode === "edit";
|
||||||
const hiddenByZonesLayer = objects.length > 0 && !filters.showZones;
|
const hiddenByZonesLayer = objects.length > 0 && !filters.showZones;
|
||||||
const visibleObjectCount = filters.showZones
|
const visibleObjectCount = filters.showZones
|
||||||
? objects.filter((object) => object.visible).length
|
? objects.filter((object) => object.visible !== false).length
|
||||||
: 0;
|
: 0;
|
||||||
const hasNoVisibleObjects = objects.length > 0 && filters.showZones && visibleObjectCount === 0;
|
const hasNoVisibleObjects = objects.length > 0 && filters.showZones && visibleObjectCount === 0;
|
||||||
const canAddFirstArea =
|
const canAddFirstArea =
|
||||||
@ -215,6 +245,16 @@ export default function LocationMapCanvas({
|
|||||||
const handlePointerMove = (event) => {
|
const handlePointerMove = (event) => {
|
||||||
if (!dragState || !svgRef.current) return;
|
if (!dragState || !svgRef.current) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
const scrollElement = scrollRef.current;
|
||||||
|
if (scrollElement) {
|
||||||
|
const scrollBounds = scrollElement.getBoundingClientRect();
|
||||||
|
panScrollElement(
|
||||||
|
scrollElement,
|
||||||
|
getEdgePanStep(event.clientX, scrollBounds.left, scrollBounds.right),
|
||||||
|
getEdgePanStep(event.clientY, scrollBounds.top, scrollBounds.bottom)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const point = clientPointToMap(event, svgRef.current, mapSize);
|
const point = clientPointToMap(event, svgRef.current, mapSize);
|
||||||
const deltaX = point.x - dragState.startPoint.x;
|
const deltaX = point.x - dragState.startPoint.x;
|
||||||
const deltaY = point.y - dragState.startPoint.y;
|
const deltaY = point.y - dragState.startPoint.y;
|
||||||
@ -225,7 +265,11 @@ export default function LocationMapCanvas({
|
|||||||
if (!hasMeaningfulChange) return;
|
if (!hasMeaningfulChange) return;
|
||||||
const draggedObject = objects.find((object) => getObjectKey(object) === dragState.key);
|
const draggedObject = objects.find((object) => getObjectKey(object) === dragState.key);
|
||||||
if (!draggedObject) return;
|
if (!draggedObject) return;
|
||||||
const nextDraggedObject = getDraggedObjectUpdate(draggedObject, dragState, deltaX, deltaY, mapSize);
|
const nextDraggedObjectCandidate = getDraggedObjectCandidate(draggedObject, dragState, deltaX, deltaY);
|
||||||
|
const nextMapSize = expandMapToFitObject?.(nextDraggedObjectCandidate) || mapSize;
|
||||||
|
const nextDraggedObject = dragState.type === "resize"
|
||||||
|
? clampResizedObjectToMap(nextDraggedObjectCandidate, nextMapSize)
|
||||||
|
: clampObjectToMap(nextDraggedObjectCandidate, nextMapSize);
|
||||||
if (!hasObjectBoundsChanged(draggedObject, nextDraggedObject)) return;
|
if (!hasObjectBoundsChanged(draggedObject, nextDraggedObject)) return;
|
||||||
|
|
||||||
if (!objectDragHistoryCapturedRef.current) {
|
if (!objectDragHistoryCapturedRef.current) {
|
||||||
@ -233,11 +277,15 @@ export default function LocationMapCanvas({
|
|||||||
objectDragHistoryCapturedRef.current = true;
|
objectDragHistoryCapturedRef.current = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateObjects((currentObjects) =>
|
updateObjects(
|
||||||
currentObjects.map((object) => {
|
(currentObjects) => currentObjects.map((object) => {
|
||||||
if (getObjectKey(object) !== dragState.key) return object;
|
if (getObjectKey(object) !== dragState.key) return object;
|
||||||
return getDraggedObjectUpdate(object, dragState, deltaX, deltaY, mapSize);
|
const candidate = getDraggedObjectCandidate(object, dragState, deltaX, deltaY);
|
||||||
})
|
return dragState.type === "resize"
|
||||||
|
? clampResizedObjectToMap(candidate, nextMapSize)
|
||||||
|
: clampObjectToMap(candidate, nextMapSize);
|
||||||
|
}),
|
||||||
|
nextMapSize
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -283,22 +331,25 @@ export default function LocationMapCanvas({
|
|||||||
const nudgeAmount = event.shiftKey ? 25 : 10;
|
const nudgeAmount = event.shiftKey ? 25 : 10;
|
||||||
const deltaX = event.key === "ArrowLeft" ? -nudgeAmount : event.key === "ArrowRight" ? nudgeAmount : 0;
|
const deltaX = event.key === "ArrowLeft" ? -nudgeAmount : event.key === "ArrowRight" ? nudgeAmount : 0;
|
||||||
const deltaY = event.key === "ArrowUp" ? -nudgeAmount : event.key === "ArrowDown" ? nudgeAmount : 0;
|
const deltaY = event.key === "ArrowUp" ? -nudgeAmount : event.key === "ArrowDown" ? nudgeAmount : 0;
|
||||||
const nextObject = clampObjectToMap({
|
const nextObjectCandidate = {
|
||||||
...object,
|
...object,
|
||||||
x: object.x + deltaX,
|
x: Math.max(0, object.x + deltaX),
|
||||||
y: object.y + deltaY,
|
y: Math.max(0, object.y + deltaY),
|
||||||
}, mapSize);
|
};
|
||||||
|
const nextMapSize = expandMapToFitObject?.(nextObjectCandidate) || mapSize;
|
||||||
|
const nextObject = clampObjectToMap(nextObjectCandidate, nextMapSize);
|
||||||
|
|
||||||
setSelectedObjectKey(getObjectKey(object));
|
setSelectedObjectKey(getObjectKey(object));
|
||||||
if (!hasObjectBoundsChanged(object, nextObject)) return;
|
if (!hasObjectBoundsChanged(object, nextObject)) return;
|
||||||
|
|
||||||
remember(undefined, getObjectKey(object));
|
remember(undefined, getObjectKey(object));
|
||||||
updateObjects((currentObjects) =>
|
updateObjects(
|
||||||
currentObjects.map((candidate) =>
|
(currentObjects) => currentObjects.map((candidate) =>
|
||||||
getObjectKey(candidate) === getObjectKey(object)
|
getObjectKey(candidate) === getObjectKey(object)
|
||||||
? nextObject
|
? nextObject
|
||||||
: candidate
|
: candidate
|
||||||
)
|
),
|
||||||
|
nextMapSize
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -353,8 +404,14 @@ export default function LocationMapCanvas({
|
|||||||
panDragRef.current.moved = true;
|
panDragRef.current.moved = true;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
scrollRef.current.scrollLeft = panDragRef.current.scrollLeft - deltaX;
|
scrollRef.current.scrollLeft = clampScrollPosition(
|
||||||
scrollRef.current.scrollTop = panDragRef.current.scrollTop - deltaY;
|
panDragRef.current.scrollLeft - deltaX,
|
||||||
|
scrollRef.current.scrollWidth - scrollRef.current.clientWidth
|
||||||
|
);
|
||||||
|
scrollRef.current.scrollTop = clampScrollPosition(
|
||||||
|
panDragRef.current.scrollTop - deltaY,
|
||||||
|
scrollRef.current.scrollHeight - scrollRef.current.clientHeight
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const endPan = (event) => {
|
const endPan = (event) => {
|
||||||
|
|||||||
@ -50,7 +50,7 @@ export default function LocationMapObject({
|
|||||||
onObjectClick,
|
onObjectClick,
|
||||||
onObjectKeyDown,
|
onObjectKeyDown,
|
||||||
}) {
|
}) {
|
||||||
if (!object.visible || !filters.showZones) return null;
|
if (object.visible === false || !filters.showZones) return null;
|
||||||
|
|
||||||
const key = getObjectKey(object);
|
const key = getObjectKey(object);
|
||||||
const displayLabel = getMapObjectDisplayLabel(object, index + 1);
|
const displayLabel = getMapObjectDisplayLabel(object, index + 1);
|
||||||
|
|||||||
@ -129,6 +129,6 @@ export default function useLocationMapDraftState({
|
|||||||
loadError, loadMap, loading, mapDraft, mapState, mode, objects, previewDraft, saving,
|
loadError, loadMap, loading, mapDraft, mapState, mode, objects, previewDraft, saving,
|
||||||
savingAction, selectedObjectKey, setDragState, setFilters, setFuture,
|
savingAction, selectedObjectKey, setDragState, setFilters, setFuture,
|
||||||
setHasUnsavedChanges, setHistory, setLayersOpen, setMapState, setMode, setObjects,
|
setHasUnsavedChanges, setHistory, setLayersOpen, setMapState, setMode, setObjects,
|
||||||
setPreviewDraft, setSelectedObjectKey, setZoom, syncMapDraftFromState, zoom,
|
setMapDraft, setPreviewDraft, setSelectedObjectKey, setZoom, syncMapDraftFromState, zoom,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import {
|
|||||||
} from "../lib/locationMapUtils";
|
} from "../lib/locationMapUtils";
|
||||||
|
|
||||||
const EMPTY_ZONES = [];
|
const EMPTY_ZONES = [];
|
||||||
|
const MAP_EDGE_GROW_PADDING = 360;
|
||||||
|
|
||||||
function createHistorySnapshot(objects, selectedObjectKey) {
|
function createHistorySnapshot(objects, selectedObjectKey) {
|
||||||
return {
|
return {
|
||||||
@ -27,6 +28,7 @@ export default function useLocationMapObjectActions({
|
|||||||
setFuture,
|
setFuture,
|
||||||
setHasUnsavedChanges,
|
setHasUnsavedChanges,
|
||||||
setHistory,
|
setHistory,
|
||||||
|
setMapDraft,
|
||||||
setObjects,
|
setObjects,
|
||||||
setSelectedObjectKey,
|
setSelectedObjectKey,
|
||||||
toast,
|
toast,
|
||||||
@ -42,13 +44,39 @@ export default function useLocationMapObjectActions({
|
|||||||
setFuture([]);
|
setFuture([]);
|
||||||
}, [objects, selectedObjectKey, setFuture, setHistory]);
|
}, [objects, selectedObjectKey, setFuture, setHistory]);
|
||||||
|
|
||||||
const updateObjects = useCallback((updater) => {
|
const updateObjects = useCallback((updater, bounds = mapSize) => {
|
||||||
setHasUnsavedChanges(true);
|
setHasUnsavedChanges(true);
|
||||||
setObjects((currentObjects) =>
|
setObjects((currentObjects) =>
|
||||||
updater(currentObjects).map((object) => clampObjectToMap(object, mapSize))
|
updater(currentObjects).map((object) => clampObjectToMap(object, bounds))
|
||||||
);
|
);
|
||||||
}, [mapSize, setHasUnsavedChanges, setObjects]);
|
}, [mapSize, setHasUnsavedChanges, setObjects]);
|
||||||
|
|
||||||
|
const expandMapToFitObject = useCallback((object) => {
|
||||||
|
const nextWidth = Math.max(
|
||||||
|
mapSize.width,
|
||||||
|
Math.ceil(Number(object.x || 0) + Number(object.width || 0) + MAP_EDGE_GROW_PADDING)
|
||||||
|
);
|
||||||
|
const nextHeight = Math.max(
|
||||||
|
mapSize.height,
|
||||||
|
Math.ceil(Number(object.y || 0) + Number(object.height || 0) + MAP_EDGE_GROW_PADDING)
|
||||||
|
);
|
||||||
|
const nextMapSize = {
|
||||||
|
width: nextWidth,
|
||||||
|
height: nextHeight,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (nextWidth > mapSize.width || nextHeight > mapSize.height) {
|
||||||
|
setMapDraft((currentDraft) => ({
|
||||||
|
...currentDraft,
|
||||||
|
width: Math.max(Number(currentDraft.width || 0), nextWidth),
|
||||||
|
height: Math.max(Number(currentDraft.height || 0), nextHeight),
|
||||||
|
}));
|
||||||
|
setHasUnsavedChanges(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextMapSize;
|
||||||
|
}, [mapSize.height, mapSize.width, setHasUnsavedChanges, setMapDraft]);
|
||||||
|
|
||||||
const handleAddObject = useCallback(() => {
|
const handleAddObject = useCallback(() => {
|
||||||
if (!canManage) return;
|
if (!canManage) return;
|
||||||
remember();
|
remember();
|
||||||
@ -148,6 +176,7 @@ export default function useLocationMapObjectActions({
|
|||||||
handleObjectField,
|
handleObjectField,
|
||||||
handleShowHiddenAreas,
|
handleShowHiddenAreas,
|
||||||
handleZoneLinkChange,
|
handleZoneLinkChange,
|
||||||
|
expandMapToFitObject,
|
||||||
pendingDeleteObject,
|
pendingDeleteObject,
|
||||||
remember,
|
remember,
|
||||||
requestDeleteObject,
|
requestDeleteObject,
|
||||||
|
|||||||
@ -64,6 +64,7 @@ export default function LocationMapManager() {
|
|||||||
setHasUnsavedChanges,
|
setHasUnsavedChanges,
|
||||||
setHistory,
|
setHistory,
|
||||||
setLayersOpen,
|
setLayersOpen,
|
||||||
|
setMapDraft,
|
||||||
setMapState,
|
setMapState,
|
||||||
setMode,
|
setMode,
|
||||||
setObjects,
|
setObjects,
|
||||||
@ -155,6 +156,7 @@ export default function LocationMapManager() {
|
|||||||
handleObjectField,
|
handleObjectField,
|
||||||
handleShowHiddenAreas,
|
handleShowHiddenAreas,
|
||||||
handleZoneLinkChange,
|
handleZoneLinkChange,
|
||||||
|
expandMapToFitObject,
|
||||||
pendingDeleteObject,
|
pendingDeleteObject,
|
||||||
remember,
|
remember,
|
||||||
requestDeleteObject,
|
requestDeleteObject,
|
||||||
@ -171,6 +173,7 @@ export default function LocationMapManager() {
|
|||||||
setFuture,
|
setFuture,
|
||||||
setHasUnsavedChanges,
|
setHasUnsavedChanges,
|
||||||
setHistory,
|
setHistory,
|
||||||
|
setMapDraft,
|
||||||
setObjects,
|
setObjects,
|
||||||
setSelectedObjectKey,
|
setSelectedObjectKey,
|
||||||
toast,
|
toast,
|
||||||
@ -420,6 +423,7 @@ export default function LocationMapManager() {
|
|||||||
setSelectedObjectKey={setSelectedObjectKey}
|
setSelectedObjectKey={setSelectedObjectKey}
|
||||||
remember={remember}
|
remember={remember}
|
||||||
updateObjects={updateObjects}
|
updateObjects={updateObjects}
|
||||||
|
expandMapToFitObject={expandMapToFitObject}
|
||||||
onShowZones={() =>
|
onShowZones={() =>
|
||||||
setFilters((current) => ({
|
setFilters((current) => ({
|
||||||
...current,
|
...current,
|
||||||
|
|||||||
@ -2082,6 +2082,84 @@ test("admin locked map areas hide resize affordances", async ({ page }) => {
|
|||||||
await expect(page.getByRole("button", { name: "Map area Bakery, locked", exact: true })).toHaveCount(0);
|
await expect(page.getByRole("button", { name: "Map area Bakery, locked", exact: true })).toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("admin can drag map areas beyond the current right edge", async ({ page }) => {
|
||||||
|
await page.setViewportSize({ width: 398, height: 617 });
|
||||||
|
await mockMapShell(page);
|
||||||
|
|
||||||
|
const baseState = draftMapState([
|
||||||
|
{
|
||||||
|
id: 1321,
|
||||||
|
location_map_id: 900,
|
||||||
|
zone_id: 501,
|
||||||
|
zone_name: "Bakery",
|
||||||
|
type: "zone",
|
||||||
|
label: "Bakery",
|
||||||
|
x: 420,
|
||||||
|
y: 80,
|
||||||
|
width: 220,
|
||||||
|
height: 140,
|
||||||
|
rotation: 0,
|
||||||
|
locked: false,
|
||||||
|
visible: true,
|
||||||
|
sort_order: 1,
|
||||||
|
},
|
||||||
|
], true);
|
||||||
|
const mapState = {
|
||||||
|
...baseState,
|
||||||
|
map: { ...baseState.map, width: 700, height: 420 },
|
||||||
|
draft_map: { ...baseState.draft_map, width: 700, height: 420 },
|
||||||
|
};
|
||||||
|
let savedPayload: { map?: { width?: number; height?: number }; objects?: Array<Record<string, unknown>> } | null = null;
|
||||||
|
|
||||||
|
await page.route("**/households/1/locations/10/map", async (route) => {
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: "application/json",
|
||||||
|
body: JSON.stringify(mapState),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.route("**/households/1/locations/10/map/draft", async (route) => {
|
||||||
|
savedPayload = await route.request().postDataJSON();
|
||||||
|
const savedState = draftMapState(savedPayload?.objects || [], true);
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: "application/json",
|
||||||
|
body: JSON.stringify({
|
||||||
|
...savedState,
|
||||||
|
map: { ...savedState.map, width: savedPayload?.map?.width, height: savedPayload?.map?.height },
|
||||||
|
draft_map: { ...savedState.draft_map, width: savedPayload?.map?.width, height: savedPayload?.map?.height },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto("/stores/100/locations/10/map");
|
||||||
|
await page.getByRole("button", { name: "Continue Editing" }).click();
|
||||||
|
const scroll = page.locator(".location-map-scroll");
|
||||||
|
const bakeryArea = page.getByRole("button", { name: "Map area Bakery" });
|
||||||
|
await bakeryArea.click();
|
||||||
|
|
||||||
|
const areaBox = await bakeryArea.boundingBox();
|
||||||
|
expect(areaBox).not.toBeNull();
|
||||||
|
if (!areaBox) throw new Error("Bakery map area was not measurable");
|
||||||
|
await page.mouse.move(areaBox.x + areaBox.width / 2, areaBox.y + areaBox.height / 2);
|
||||||
|
await page.mouse.down();
|
||||||
|
await page.mouse.move(areaBox.x + areaBox.width + 180, areaBox.y + areaBox.height / 2, { steps: 12 });
|
||||||
|
await page.mouse.up();
|
||||||
|
|
||||||
|
await expect.poll(async () => scroll.evaluate((element) => element.scrollLeft)).toBeGreaterThan(0);
|
||||||
|
await page.getByRole("button", { name: "Save Draft" }).click();
|
||||||
|
|
||||||
|
await expect.poll(() => savedPayload?.map?.width || 0).toBeGreaterThan(700);
|
||||||
|
expect(savedPayload?.objects?.[0]).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
label: "Bakery",
|
||||||
|
x: expect.any(Number),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(Number(savedPayload?.objects?.[0]?.x)).toBeGreaterThan(420);
|
||||||
|
});
|
||||||
|
|
||||||
test("admin selected overlapping map area renders above other areas", async ({ page }) => {
|
test("admin selected overlapping map area renders above other areas", async ({ page }) => {
|
||||||
await mockMapShell(page);
|
await mockMapShell(page);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user