fix: zoom no longer resets after manual pan/zoom (fitBounds once per siruta)

The fitBounds effect was re-triggered every time mapReady toggled
(which happened frequently due to the source-checking polling interval).
Now uses boundsFittedForSirutaRef to ensure fitBounds runs only ONCE
per siruta selection — changing UAT still zooms correctly, but manual
zoom/pan is preserved afterwards.

Fixed in both ParcelSync Harta tab and Portal map.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
AI Assistant
2026-03-25 01:08:33 +02:00
parent daca222427
commit 1a5487f0f7
2 changed files with 17 additions and 6 deletions
+8 -3
View File
@@ -1161,6 +1161,7 @@ function HartaContent() {
// Bounds state
const boundsRef = useRef<[number, number, number, number] | null>(null);
const appliedSirutaRef = useRef("");
const boundsFittedForSirutaRef = useRef("");
const prevBoundsSirutaRef = useRef("");
// Layer visibility: show terenuri + cladiri
@@ -1230,22 +1231,26 @@ function HartaContent() {
if (data?.bounds) {
const [[minLng, minLat], [maxLng, maxLat]] = data.bounds;
boundsRef.current = [minLng, minLat, maxLng, maxLat];
boundsFittedForSirutaRef.current = "";
const map = asMap(mapHandleRef.current);
if (map) {
map.fitBounds([minLng, minLat, maxLng, maxLat], { padding: 40, duration: 1500 });
boundsFittedForSirutaRef.current = selectedSiruta;
}
}
})
.catch(() => {});
}, [selectedSiruta]);
// When map becomes ready, fitBounds and apply filter
// When map becomes ready, fitBounds ONCE per siruta
useEffect(() => {
if (!mapReady || !boundsRef.current) return;
if (!mapReady || !boundsRef.current || !selectedSiruta) return;
if (boundsFittedForSirutaRef.current === selectedSiruta) return;
const map = asMap(mapHandleRef.current);
if (!map) return;
map.fitBounds(boundsRef.current, { padding: 40, duration: 1500 });
}, [mapReady]);
boundsFittedForSirutaRef.current = selectedSiruta;
}, [mapReady, selectedSiruta]);
// Apply siruta filter to layers
useEffect(() => {
@@ -102,6 +102,7 @@ export function MapTab({ siruta, sirutaValid, sessionConnected, syncLocalCount,
const appliedSirutaRef = useRef("");
const boundsRef = useRef<[number, number, number, number] | null>(null);
const prevCheckSirutaRef = useRef("");
const boundsFittedForSirutaRef = useRef("");
/* Boundary check results */
const [mismatchSummary, setMismatchSummary] = useState<{
@@ -164,12 +165,14 @@ export function MapTab({ siruta, sirutaValid, sessionConnected, syncLocalCount,
if (data?.bounds) {
const [[minLng, minLat], [maxLng, maxLat]] = data.bounds;
boundsRef.current = [minLng, minLat, maxLng, maxLat];
boundsFittedForSirutaRef.current = ""; // reset — need to fit for new siruta
const map = asMap(mapHandleRef.current);
if (map) {
map.fitBounds([minLng, minLat, maxLng, maxLat], {
padding: 40,
duration: 1500,
});
boundsFittedForSirutaRef.current = siruta;
}
}
},
@@ -178,13 +181,16 @@ export function MapTab({ siruta, sirutaValid, sessionConnected, syncLocalCount,
.finally(() => setBoundsLoading(false));
}, [siruta, sirutaValid]);
/* ── When map becomes ready, fitBounds if we have bounds ───── */
/* ── When map becomes ready, fitBounds ONCE per siruta ──────── */
useEffect(() => {
if (!mapReady || !boundsRef.current) return;
if (!mapReady || !boundsRef.current || !siruta) return;
// Only fit bounds once per siruta — don't reset zoom on basemap switch or re-render
if (boundsFittedForSirutaRef.current === siruta) return;
const map = asMap(mapHandleRef.current);
if (!map) return;
map.fitBounds(boundsRef.current, { padding: 40, duration: 1500 });
}, [mapReady]);
boundsFittedForSirutaRef.current = siruta;
}, [mapReady, siruta]);
/* ── Apply siruta filter + enrichment overlay ──────────────── */
useEffect(() => {