fix: precompute map zone item counts
This commit is contained in:
parent
59b82650a6
commit
bf34cc341a
@ -1,9 +1,9 @@
|
||||
import { useRef, useState } from "react";
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
clientPointToMap,
|
||||
getMapObjectDisplayLabel,
|
||||
getObjectKey,
|
||||
itemsForZone,
|
||||
itemMatchesMapFilters,
|
||||
} from "../../lib/locationMapUtils";
|
||||
|
||||
const DRAG_CHANGE_THRESHOLD = 2;
|
||||
@ -55,6 +55,24 @@ export default function LocationMapCanvas({
|
||||
const objectDragHistoryCapturedRef = useRef(false);
|
||||
const suppressPanClickRef = useRef(false);
|
||||
const [isPanning, setIsPanning] = useState(false);
|
||||
const zoneItemSummary = useMemo(() => {
|
||||
const assignedCounts = new Map();
|
||||
const visibleItemsByZone = new Map();
|
||||
|
||||
(mapItems || []).forEach((item) => {
|
||||
const zoneKey = String(item.zone_id || "");
|
||||
if (!zoneKey) return;
|
||||
|
||||
assignedCounts.set(zoneKey, (assignedCounts.get(zoneKey) || 0) + 1);
|
||||
if (!itemMatchesMapFilters(item, filters, username)) return;
|
||||
|
||||
const existingItems = visibleItemsByZone.get(zoneKey) || [];
|
||||
existingItems.push(item);
|
||||
visibleItemsByZone.set(zoneKey, existingItems);
|
||||
});
|
||||
|
||||
return { assignedCounts, visibleItemsByZone };
|
||||
}, [filters, mapItems, username]);
|
||||
|
||||
const startDrag = (event, object, type) => {
|
||||
if (!canEditObjects || object.locked || !svgRef.current) return;
|
||||
@ -261,12 +279,9 @@ export default function LocationMapCanvas({
|
||||
if (!object.visible || !filters.showZones) return null;
|
||||
const key = getObjectKey(object);
|
||||
const isSelected = key === selectedObjectKey;
|
||||
const zoneItems = itemsForZone(mapItems, object.zone_id, filters, username);
|
||||
const assignedZoneItemCount = object.zone_id
|
||||
? mapItems.filter(
|
||||
(item) => String(item.zone_id || "") === String(object.zone_id || "")
|
||||
).length
|
||||
: 0;
|
||||
const zoneKey = String(object.zone_id || "");
|
||||
const zoneItems = zoneKey ? zoneItemSummary.visibleItemsByZone.get(zoneKey) || [] : [];
|
||||
const assignedZoneItemCount = zoneKey ? zoneItemSummary.assignedCounts.get(zoneKey) || 0 : 0;
|
||||
const count = zoneItems.length;
|
||||
const hasHiddenZoneItems = assignedZoneItemCount > count;
|
||||
const countLabel = hasHiddenZoneItems
|
||||
|
||||
@ -156,32 +156,26 @@ export function prepareObjectsForSave(objects) {
|
||||
}));
|
||||
}
|
||||
|
||||
export function itemsForZone(items, zoneId, filters, username) {
|
||||
return items.filter((item) => {
|
||||
if (String(item.zone_id || "") !== String(zoneId || "")) return false;
|
||||
if (!filters.showCompleted && item.bought) return false;
|
||||
export function itemMatchesMapFilters(item, filters, username) {
|
||||
if (!filters.showCompleted && item.bought) return false;
|
||||
|
||||
const addedBy = Array.isArray(item.added_by_users) ? item.added_by_users : [];
|
||||
const hasOwnershipData = addedBy.length > 0 && username;
|
||||
const isMine = hasOwnershipData ? addedBy.includes(username) : true;
|
||||
if (isMine && !filters.showMyItems) return false;
|
||||
if (!isMine && !filters.showOtherItems) return false;
|
||||
return true;
|
||||
});
|
||||
const addedBy = Array.isArray(item.added_by_users) ? item.added_by_users : [];
|
||||
const hasOwnershipData = addedBy.length > 0 && username;
|
||||
const isMine = hasOwnershipData ? addedBy.includes(username) : true;
|
||||
if (isMine && !filters.showMyItems) return false;
|
||||
if (!isMine && !filters.showOtherItems) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
export function itemsForZone(items, zoneId, filters, username) {
|
||||
return items.filter((item) => (
|
||||
String(item.zone_id || "") === String(zoneId || "") &&
|
||||
itemMatchesMapFilters(item, filters, username)
|
||||
));
|
||||
}
|
||||
|
||||
export function unmappedItems(items, filters, username) {
|
||||
return items.filter((item) => {
|
||||
if (item.zone_id) return false;
|
||||
if (!filters.showCompleted && item.bought) return false;
|
||||
|
||||
const addedBy = Array.isArray(item.added_by_users) ? item.added_by_users : [];
|
||||
const hasOwnershipData = addedBy.length > 0 && username;
|
||||
const isMine = hasOwnershipData ? addedBy.includes(username) : true;
|
||||
if (isMine && !filters.showMyItems) return false;
|
||||
if (!isMine && !filters.showOtherItems) return false;
|
||||
return true;
|
||||
});
|
||||
return items.filter((item) => !item.zone_id && itemMatchesMapFilters(item, filters, username));
|
||||
}
|
||||
|
||||
export function clientPointToMap(event, svgElement, mapSize) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user