fix: memoize map manager derived data

This commit is contained in:
Nico 2026-06-04 03:48:47 -07:00
parent 2a3e028281
commit 9390bfdf53

View File

@ -1,4 +1,4 @@
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
import { useBeforeUnload, useLocation, useNavigate, useParams } from "react-router-dom";
import {
createBlankLocationMap,
@ -38,6 +38,8 @@ import {
} from "../lib/locationMapUtils";
import "../styles/pages/LocationMapManager.css";
const EMPTY_MAP_ITEMS = [];
export default function LocationMapManager() {
const { storeId, locationId } = useParams();
const navigate = useNavigate();
@ -77,16 +79,44 @@ export default function LocationMapManager() {
const location = mapState?.location || stores.find((store) => String(store.id) === String(locationId));
const canManage = Boolean(mapState?.can_manage ?? ["owner", "admin"].includes(activeHousehold?.role));
const activeMap = mapForMode(mapState, mode, previewDraft);
const selectedObject = objects.find((object) => getObjectKey(object) === selectedObjectKey) || null;
const selectedZoneItems = selectedObject?.zone_id
? itemsForZone(mapState?.items || [], selectedObject.zone_id, filters, username)
: [];
const visibleUnmappedItems = unmappedItems(mapState?.items || [], filters, username);
const visibleAssignedItemCount = (mapState?.items || []).filter((item) => (
item.zone_id && itemMatchesMapFilters(item, filters, username)
)).length;
const unmappedItemCount = (mapState?.items || []).filter((item) => !item.zone_id).length;
const hiddenAreaCount = objects.filter((object) => object.visible === false).length;
const mapItems = mapState?.items || EMPTY_MAP_ITEMS;
const selectedObject = useMemo(
() => objects.find((object) => getObjectKey(object) === selectedObjectKey) || null,
[objects, selectedObjectKey]
);
const selectedZoneItems = useMemo(
() => selectedObject?.zone_id
? itemsForZone(mapItems, selectedObject.zone_id, filters, username)
: EMPTY_MAP_ITEMS,
[filters, mapItems, selectedObject?.zone_id, username]
);
const visibleUnmappedItems = useMemo(
() => unmappedItems(mapItems, filters, username),
[filters, mapItems, username]
);
const { visibleAssignedItemCount, unmappedItemCount } = useMemo(() => {
let nextVisibleAssignedItemCount = 0;
let nextUnmappedItemCount = 0;
mapItems.forEach((item) => {
if (!item.zone_id) {
nextUnmappedItemCount += 1;
return;
}
if (itemMatchesMapFilters(item, filters, username)) {
nextVisibleAssignedItemCount += 1;
}
});
return {
visibleAssignedItemCount: nextVisibleAssignedItemCount,
unmappedItemCount: nextUnmappedItemCount,
};
}, [filters, mapItems, username]);
const hiddenAreaCount = useMemo(
() => objects.filter((object) => object.visible === false).length,
[objects]
);
const shouldGuardLeave = canManage && hasUnsavedChanges;
const mapSize = {
@ -584,7 +614,7 @@ export default function LocationMapManager() {
mapSize={mapSize}
zoom={zoom}
selectedObjectKey={selectedObjectKey}
mapItems={mapState?.items || []}
mapItems={mapItems}
username={username}
svgRef={svgRef}
dragState={dragState}