fix: Map tab initialization (H1, H2)
- Added global let map/heatLayer/heatVisible declarations - Leaflet map initializes on first visit to Map tab (OSM tiles) - Implemented loadAssetPins() - fetches assets with coords from API, creates Leaflet markers with popups, auto-fits bounds - Guard toggleHeatmap() with proper declared globals - Closes #31 H1, #32 H2 Also confirmed M1 (empty asset list) is not a bug: API returns [] because DB has no assets yet. Empty state renders correctly.
This commit is contained in:
+53
-3
@@ -1595,10 +1595,22 @@
|
|||||||
|
|
||||||
// Map tab lifecycle
|
// Map tab lifecycle
|
||||||
if (tabId === 'tabMap') {
|
if (tabId === 'tabMap') {
|
||||||
if (map) {
|
if (!map) {
|
||||||
setTimeout(() => map.invalidateSize(), 150);
|
const tileUrl = document.querySelector('meta[name="map-tile-url"]')?.content
|
||||||
loadAssetPins(); // Refresh pins on every tab visit
|
|| 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||||
|
const tileAttr = document.querySelector('meta[name="map-tile-attribution"]')?.content
|
||||||
|
|| '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>';
|
||||||
|
map = L.map('mapContainer', {
|
||||||
|
center: [39.8283, -98.5795],
|
||||||
|
zoom: 4,
|
||||||
|
zoomControl: true,
|
||||||
|
});
|
||||||
|
L.tileLayer(tileUrl, { attribution: tileAttr, maxZoom: 19 }).addTo(map);
|
||||||
|
// Restore heatmap layer if it was active
|
||||||
|
if (heatVisible) setTimeout(() => loadHeatmapData(), 300);
|
||||||
}
|
}
|
||||||
|
setTimeout(() => map.invalidateSize(), 150);
|
||||||
|
loadAssetPins(); // Refresh pins on every tab visit
|
||||||
startVisitTracking();
|
startVisitTracking();
|
||||||
} else {
|
} else {
|
||||||
stopVisitTracking();
|
stopVisitTracking();
|
||||||
@@ -1681,6 +1693,9 @@
|
|||||||
let manualPhotoBlob = null;
|
let manualPhotoBlob = null;
|
||||||
let manKeysCounter = 0;
|
let manKeysCounter = 0;
|
||||||
let settingsCache = {};
|
let settingsCache = {};
|
||||||
|
let map = null;
|
||||||
|
let heatLayer = null;
|
||||||
|
let heatVisible = false;
|
||||||
|
|
||||||
// ── Mode Switching ──────────────────────────────────────────────────────
|
// ── Mode Switching ──────────────────────────────────────────────────────
|
||||||
function setAddAssetMode(mode) {
|
function setAddAssetMode(mode) {
|
||||||
@@ -3405,6 +3420,41 @@
|
|||||||
showToast('Import complete: ' + created + ' created, ' + skipped + ' skipped, ' + errors.length + ' errors');
|
showToast('Import complete: ' + created + ' created, ' + skipped + ' skipped, ' + errors.length + ' errors');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
|
// MAP PINS
|
||||||
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
async function loadAssetPins() {
|
||||||
|
// Store markers on a namespace so we can clear them
|
||||||
|
if (!window._assetPins) window._assetPins = [];
|
||||||
|
// Clear existing markers
|
||||||
|
window._assetPins.forEach(function(m) { if (map) map.removeLayer(m); });
|
||||||
|
window._assetPins = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const assets = await api('/api/assets?limit=1000');
|
||||||
|
assets.forEach(function(a) {
|
||||||
|
if (a.latitude != null && a.longitude != null) {
|
||||||
|
var icon = catIcon(a.category);
|
||||||
|
var popupHtml = '<b>' + esc(a.name) + '</b><br>' + esc(a.machine_id || '') +
|
||||||
|
'<br><button class="btn btn-outline btn-sm" style="margin-top:6px;" ' +
|
||||||
|
'onclick="switchTab(\'tabAssets\');viewAsset(' + a.id + ');">View Details</button>';
|
||||||
|
var marker = L.marker([a.latitude, a.longitude])
|
||||||
|
.addTo(map)
|
||||||
|
.bindPopup(popupHtml);
|
||||||
|
window._assetPins.push(marker);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// If we have assets with coords, zoom to fit them
|
||||||
|
if (window._assetPins.length > 0) {
|
||||||
|
var group = L.featureGroup(window._assetPins);
|
||||||
|
map.fitBounds(group.getBounds().pad(0.1));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to load asset pins:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
// HEATMAP
|
// HEATMAP
|
||||||
// ═══════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
Reference in New Issue
Block a user