fix: reuse map area display names
This commit is contained in:
parent
415a7223cd
commit
306812d692
@ -1,4 +1,8 @@
|
||||
import { DEFAULT_MAP_FILTERS, MAP_OBJECT_TYPES } from "../../lib/locationMapUtils";
|
||||
import {
|
||||
DEFAULT_MAP_FILTERS,
|
||||
MAP_OBJECT_TYPES,
|
||||
getMapObjectDisplayLabel,
|
||||
} from "../../lib/locationMapUtils";
|
||||
|
||||
function objectZoneId(object) {
|
||||
return object?.zone_id ? String(object.zone_id) : "";
|
||||
@ -48,7 +52,7 @@ export default function LocationMapBottomSheet({
|
||||
onDuplicateObject,
|
||||
onDeleteObject,
|
||||
}) {
|
||||
const selectedTitle = selectedObject?.label || selectedObject?.zone_name || "Map Area";
|
||||
const selectedTitle = getMapObjectDisplayLabel(selectedObject);
|
||||
const selectedAssignedItems = selectedObject?.zone_id
|
||||
? (mapState?.items || []).filter((item) => String(item.zone_id || "") === objectZoneId(selectedObject))
|
||||
: [];
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { useRef, useState } from "react";
|
||||
import {
|
||||
clientPointToMap,
|
||||
getMapObjectDisplayLabel,
|
||||
getObjectKey,
|
||||
itemsForZone,
|
||||
} from "../../lib/locationMapUtils";
|
||||
@ -8,12 +9,6 @@ import {
|
||||
const DRAG_CHANGE_THRESHOLD = 2;
|
||||
const NUDGE_KEYS = new Set(["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft"]);
|
||||
|
||||
function mapObjectDisplayLabel(object, fallback) {
|
||||
const label = String(object.label || "").trim();
|
||||
const zoneName = String(object.zone_name || "").trim();
|
||||
return label || zoneName || fallback;
|
||||
}
|
||||
|
||||
export default function LocationMapCanvas({
|
||||
mode,
|
||||
editorTool,
|
||||
@ -218,7 +213,7 @@ export default function LocationMapCanvas({
|
||||
};
|
||||
|
||||
const fittedLabelLines = (object, fallback) => {
|
||||
const rawLabel = mapObjectDisplayLabel(object, fallback);
|
||||
const rawLabel = getMapObjectDisplayLabel(object, fallback);
|
||||
const maxCharacters = Math.max(8, Math.floor((Number(object.width) - 28) / 13));
|
||||
const canUseTwoLines = Number(object.height) >= 92 && rawLabel.length > maxCharacters;
|
||||
if (!canUseTwoLines) return [truncateLabel(rawLabel, maxCharacters)];
|
||||
@ -301,7 +296,7 @@ export default function LocationMapCanvas({
|
||||
height={object.height}
|
||||
rx="12"
|
||||
role="button"
|
||||
aria-label={`Map area ${mapObjectDisplayLabel(object, index + 1)}`}
|
||||
aria-label={`Map area ${getMapObjectDisplayLabel(object, index + 1)}`}
|
||||
aria-pressed={isSelected}
|
||||
tabIndex={mode === "view" || canEditObjects ? 0 : -1}
|
||||
onPointerDown={(event) => startDrag(event, object, "move")}
|
||||
|
||||
@ -129,6 +129,12 @@ export function getObjectKey(object) {
|
||||
return String(object.id || object.client_id);
|
||||
}
|
||||
|
||||
export function getMapObjectDisplayLabel(object, fallback = "Map Area") {
|
||||
const label = String(object?.label || "").trim();
|
||||
const zoneName = String(object?.zone_name || "").trim();
|
||||
return label || zoneName || fallback;
|
||||
}
|
||||
|
||||
export function prepareObjectsForSave(objects) {
|
||||
return objects.map((object, index) => ({
|
||||
zone_id: object.zone_id || null,
|
||||
|
||||
@ -24,6 +24,7 @@ import {
|
||||
clampMapZoom,
|
||||
clampObjectToMap,
|
||||
createClientObject,
|
||||
getMapObjectDisplayLabel,
|
||||
getMapStatus,
|
||||
getObjectKey,
|
||||
itemsForZone,
|
||||
@ -322,11 +323,12 @@ export default function LocationMapManager() {
|
||||
const handleDuplicateObject = () => {
|
||||
if (!selectedObject) return;
|
||||
remember();
|
||||
const displayLabel = getMapObjectDisplayLabel(selectedObject, "Area");
|
||||
const nextObject = {
|
||||
...selectedObject,
|
||||
id: undefined,
|
||||
client_id: `copy-${Date.now()}`,
|
||||
label: `${selectedObject.label || "Area"} Copy`,
|
||||
label: `${displayLabel} Copy`,
|
||||
x: selectedObject.x + 28,
|
||||
y: selectedObject.y + 28,
|
||||
sort_order: objects.length + 1,
|
||||
@ -584,7 +586,7 @@ export default function LocationMapManager() {
|
||||
|
||||
<ConfirmSlideModal
|
||||
isOpen={Boolean(pendingDeleteObject)}
|
||||
title={`Delete ${pendingDeleteObject?.label || "this map area"}?`}
|
||||
title={`Delete ${getMapObjectDisplayLabel(pendingDeleteObject, "this map area")}?`}
|
||||
description="This removes the area from the draft map. Save the draft after deleting to keep the change."
|
||||
confirmLabel="Delete Area"
|
||||
onClose={() => setPendingDeleteObject(null)}
|
||||
|
||||
@ -596,7 +596,7 @@ test("admin selecting an object does not mark a draft dirty until it changes", a
|
||||
await expect(page.getByRole("button", { name: "Undo" })).toBeEnabled();
|
||||
});
|
||||
|
||||
test("admin cleared map area labels keep linked zone accessible names", async ({ page }) => {
|
||||
test("admin cleared map area labels keep linked zone action names", async ({ page }) => {
|
||||
await mockMapShell(page);
|
||||
|
||||
const mapState = draftMapState([
|
||||
@ -635,6 +635,15 @@ test("admin cleared map area labels keep linked zone accessible names", async ({
|
||||
|
||||
await expect(page.getByRole("button", { name: "Map area Bakery", exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Map area 1", exact: true })).toHaveCount(0);
|
||||
|
||||
await page.getByRole("button", { name: "Delete" }).click();
|
||||
await expect(page.getByRole("heading", { name: "Delete Bakery?" })).toBeVisible();
|
||||
await page.getByRole("button", { name: "Cancel" }).click();
|
||||
|
||||
await page.getByRole("button", { name: "Duplicate" }).click();
|
||||
await expect(page.getByRole("textbox", { name: "Label" })).toHaveValue("Bakery Copy");
|
||||
await expect(page.getByRole("button", { name: "Map area Bakery Copy" })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Map area Area Copy" })).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("admin nudges selected map areas with arrow keys", async ({ page }) => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user