Add store location map manager #20

Open
nalalangan wants to merge 206 commits from feature/location-map-manager into feature/store-selector-modal
2 changed files with 39 additions and 30 deletions
Showing only changes of commit bf34cc341a - Show all commits

View File

@ -1,9 +1,9 @@
import { useRef, useState } from "react"; import { useMemo, useRef, useState } from "react";
import { import {
clientPointToMap, clientPointToMap,
getMapObjectDisplayLabel, getMapObjectDisplayLabel,
getObjectKey, getObjectKey,
itemsForZone, itemMatchesMapFilters,
} from "../../lib/locationMapUtils"; } from "../../lib/locationMapUtils";
const DRAG_CHANGE_THRESHOLD = 2; const DRAG_CHANGE_THRESHOLD = 2;
@ -55,6 +55,24 @@ export default function LocationMapCanvas({
const objectDragHistoryCapturedRef = useRef(false); const objectDragHistoryCapturedRef = useRef(false);
const suppressPanClickRef = useRef(false); const suppressPanClickRef = useRef(false);
const [isPanning, setIsPanning] = useState(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) => { const startDrag = (event, object, type) => {
if (!canEditObjects || object.locked || !svgRef.current) return; if (!canEditObjects || object.locked || !svgRef.current) return;
@ -261,12 +279,9 @@ export default function LocationMapCanvas({
if (!object.visible || !filters.showZones) return null; if (!object.visible || !filters.showZones) return null;
const key = getObjectKey(object); const key = getObjectKey(object);
const isSelected = key === selectedObjectKey; const isSelected = key === selectedObjectKey;
const zoneItems = itemsForZone(mapItems, object.zone_id, filters, username); const zoneKey = String(object.zone_id || "");
const assignedZoneItemCount = object.zone_id const zoneItems = zoneKey ? zoneItemSummary.visibleItemsByZone.get(zoneKey) || [] : [];
? mapItems.filter( const assignedZoneItemCount = zoneKey ? zoneItemSummary.assignedCounts.get(zoneKey) || 0 : 0;
(item) => String(item.zone_id || "") === String(object.zone_id || "")
).length
: 0;
const count = zoneItems.length; const count = zoneItems.length;
const hasHiddenZoneItems = assignedZoneItemCount > count; const hasHiddenZoneItems = assignedZoneItemCount > count;
const countLabel = hasHiddenZoneItems const countLabel = hasHiddenZoneItems

View File

@ -156,9 +156,7 @@ export function prepareObjectsForSave(objects) {
})); }));
} }
export function itemsForZone(items, zoneId, filters, username) { export function itemMatchesMapFilters(item, filters, username) {
return items.filter((item) => {
if (String(item.zone_id || "") !== String(zoneId || "")) return false;
if (!filters.showCompleted && item.bought) return false; if (!filters.showCompleted && item.bought) return false;
const addedBy = Array.isArray(item.added_by_users) ? item.added_by_users : []; const addedBy = Array.isArray(item.added_by_users) ? item.added_by_users : [];
@ -167,21 +165,17 @@ export function itemsForZone(items, zoneId, filters, username) {
if (isMine && !filters.showMyItems) return false; if (isMine && !filters.showMyItems) return false;
if (!isMine && !filters.showOtherItems) return false; if (!isMine && !filters.showOtherItems) return false;
return true; 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) { export function unmappedItems(items, filters, username) {
return items.filter((item) => { return items.filter((item) => !item.zone_id && itemMatchesMapFilters(item, filters, username));
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;
});
} }
export function clientPointToMap(event, svgElement, mapSize) { export function clientPointToMap(event, svgElement, mapSize) {