From 8c18dc8482f3ec04985921297e9ffb46c1528181 Mon Sep 17 00:00:00 2001 From: zvx-echo6 Date: Sun, 17 May 2026 19:52:30 -0600 Subject: [PATCH] fix(gui): region picker render + click-to-draw Bug A: Maps render blank on /setup/adapters for FIRMS and USGS because Leaflet computed zero dimensions before container layout settled. Fix: add setTimeout invalidateSize() after map creation. Bug B: No click-to-draw functionality - only drag corners. Fix: add L.Control.Draw for rectangle drawing with CREATED event handler to replace existing rectangle. Both fixes applied to: - setup_adapters.html (wizard inline JS) - _region_picker.html (standalone edit page) Co-Authored-By: Claude Opus 4.5 --- src/central/gui/templates/_region_picker.html | 53 +++++++++++++++++-- src/central/gui/templates/setup_adapters.html | 43 ++++++++++++++- 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/central/gui/templates/_region_picker.html b/src/central/gui/templates/_region_picker.html index 5c53bc9..9c9b211 100644 --- a/src/central/gui/templates/_region_picker.html +++ b/src/central/gui/templates/_region_picker.html @@ -59,6 +59,10 @@ maxZoom: 18 }).addTo(map); + // Ensure map renders correctly even if container has not + // finished laying out at init time + setTimeout(function() { map.invalidateSize(); }, 100); + // Create initial rectangle const bounds = L.latLngBounds( L.latLng(savedSouth, savedWest), @@ -69,11 +73,34 @@ map.fitBounds(bounds.pad(0.1)); // Create editable rectangle - const rectangle = L.rectangle(bounds, { + let rectangle = L.rectangle(bounds, { color: '#3388ff', weight: 2, fillOpacity: 0.2 - }).addTo(map); + }); + + // Set up Leaflet.draw for click-to-draw + const drawnItems = new L.FeatureGroup(); + drawnItems.addLayer(rectangle); + map.addLayer(drawnItems); + + const drawControl = new L.Control.Draw({ + draw: { + rectangle: { shapeOptions: { color: '#3388ff', weight: 2, + fillOpacity: 0.2 } }, + polyline: false, + polygon: false, + circle: false, + marker: false, + circlemarker: false + }, + edit: { + featureGroup: drawnItems, + edit: false, + remove: false + } + }); + map.addControl(drawControl); // Make rectangle editable rectangle.editing.enable(); @@ -96,13 +123,33 @@ // Listen for rectangle edit events rectangle.on('edit', updateInputs); + // When user draws a new rectangle, replace the existing one + map.on(L.Draw.Event.CREATED, function(e) { + drawnItems.clearLayers(); + rectangle = e.layer; + rectangle.setStyle({ color: '#3388ff', weight: 2, + fillOpacity: 0.2 }); + drawnItems.addLayer(rectangle); + rectangle.editing.enable(); + rectangle.on('edit', updateInputs); + updateInputs(); + }); + // Reset button document.getElementById('region-reset-btn').addEventListener('click', function() { const originalBounds = L.latLngBounds( L.latLng(savedSouth, savedWest), L.latLng(savedNorth, savedEast) ); - rectangle.setBounds(originalBounds); + drawnItems.clearLayers(); + rectangle = L.rectangle(originalBounds, { + color: '#3388ff', + weight: 2, + fillOpacity: 0.2 + }); + drawnItems.addLayer(rectangle); + rectangle.editing.enable(); + rectangle.on('edit', updateInputs); updateInputs(); }); diff --git a/src/central/gui/templates/setup_adapters.html b/src/central/gui/templates/setup_adapters.html index 0411e28..9ff2f50 100644 --- a/src/central/gui/templates/setup_adapters.html +++ b/src/central/gui/templates/setup_adapters.html @@ -174,17 +174,44 @@ document.addEventListener('DOMContentLoaded', function() { maxZoom: 18 }).addTo(map); + // Ensure map renders correctly even if container has not + // finished laying out at init time + setTimeout(function() { map.invalidateSize(); }, 100); + const bounds = L.latLngBounds( L.latLng(savedSouth, savedWest), L.latLng(savedNorth, savedEast) ); map.fitBounds(bounds.pad(0.1)); - const rectangle = L.rectangle(bounds, { + let rectangle = L.rectangle(bounds, { color: '#3388ff', weight: 2, fillOpacity: 0.2 - }).addTo(map); + }); + + // Set up Leaflet.draw for click-to-draw + const drawnItems = new L.FeatureGroup(); + drawnItems.addLayer(rectangle); + map.addLayer(drawnItems); + + const drawControl = new L.Control.Draw({ + draw: { + rectangle: { shapeOptions: { color: '#3388ff', weight: 2, + fillOpacity: 0.2 } }, + polyline: false, + polygon: false, + circle: false, + marker: false, + circlemarker: false + }, + edit: { + featureGroup: drawnItems, + edit: false, + remove: false + } + }); + map.addControl(drawControl); rectangle.editing.enable(); @@ -204,6 +231,18 @@ document.addEventListener('DOMContentLoaded', function() { rectangle.on('edit', updateInputs); updateInputs(); + // When user draws a new rectangle, replace the existing one + map.on(L.Draw.Event.CREATED, function(e) { + drawnItems.clearLayers(); + rectangle = e.layer; + rectangle.setStyle({ color: '#3388ff', weight: 2, + fillOpacity: 0.2 }); + drawnItems.addLayer(rectangle); + rectangle.editing.enable(); + rectangle.on('edit', updateInputs); + updateInputs(); + }); + // Fix map size when details is opened const details = container.closest('details'); if (details) {