From 006cbcf9c3c7d0d8c83f86e502dc0e67cbcbd20b Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 10 Sep 2025 20:57:07 -0600 Subject: [PATCH] Fixed spatial issues with finding map cuts data. --- map/app/controllers/cutsController.js | 12 +-- map/app/public/js/admin-cuts-main.js | 110 -------------------------- map/app/public/js/admin-email.js | 29 ++++--- map/app/public/js/admin-map.js | 6 ++ map/app/utils/spatial.js | 20 ++++- 5 files changed, 48 insertions(+), 129 deletions(-) delete mode 100644 map/app/public/js/admin-cuts-main.js diff --git a/map/app/controllers/cutsController.js b/map/app/controllers/cutsController.js index 54cdef2..64f434a 100644 --- a/map/app/controllers/cutsController.js +++ b/map/app/controllers/cutsController.js @@ -383,8 +383,8 @@ class CutsController { return res.status(404).json({ error: 'Cut not found' }); } - // Get all locations - const locationsResponse = await nocodbService.getAll(config.LOCATIONS_TABLE_ID); + // Get all locations (use paginated to get ALL records, not just first page) + const locationsResponse = await nocodbService.getAllPaginated(config.LOCATIONS_TABLE_ID); if (!locationsResponse || !locationsResponse.list) { return res.json({ locations: [], statistics: { total_locations: 0 } }); } @@ -448,8 +448,8 @@ class CutsController { return res.status(403).json({ error: 'Export is disabled for this cut' }); } - // Get all locations - const locationsResponse = await nocodbService.getAll(config.LOCATIONS_TABLE_ID); + // Get all locations (use paginated to get ALL records, not just first page) + const locationsResponse = await nocodbService.getAllPaginated(config.LOCATIONS_TABLE_ID); if (!locationsResponse || !locationsResponse.list) { return res.json({ locations: [] }); } @@ -586,8 +586,8 @@ class CutsController { return res.status(404).json({ error: 'Cut not found' }); } - // Get all locations - const locationsResponse = await nocodbService.getAll(config.LOCATIONS_TABLE_ID); + // Get all locations (use paginated to get ALL records, not just first page) + const locationsResponse = await nocodbService.getAllPaginated(config.LOCATIONS_TABLE_ID); if (!locationsResponse || !locationsResponse.list) { return res.json({ statistics: { total_locations: 0 }, diff --git a/map/app/public/js/admin-cuts-main.js b/map/app/public/js/admin-cuts-main.js deleted file mode 100644 index 5803069..0000000 --- a/map/app/public/js/admin-cuts-main.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Admin Cuts Management Module - * Main initialization file that imports and orchestrates all cut management modules - */ - -// Global admin cuts manager instance -let adminCutsManager = null; - -// Initialize the admin cuts system when DOM is ready -document.addEventListener('DOMContentLoaded', async function() { - console.log('DOM loaded, initializing admin cuts system...'); - - try { - // Wait for all module classes to be loaded - if (typeof AdminCutsManager === 'undefined') { - console.error('AdminCutsManager class not loaded'); - return; - } - - if (typeof CutDrawing === 'undefined') { - console.error('CutDrawing class not loaded'); - return; - } - - if (typeof CutLocationManager === 'undefined') { - console.error('CutLocationManager class not loaded'); - return; - } - - if (typeof CutPrintUtils === 'undefined') { - console.error('CutPrintUtils class not loaded'); - return; - } - - // Create manager instance - adminCutsManager = new AdminCutsManager(); - - // Initialize the system - await adminCutsManager.initialize(); - - console.log('Admin cuts system initialized successfully'); - - // Make manager globally accessible for debugging - window.adminCutsManager = adminCutsManager; - - } catch (error) { - console.error('Failed to initialize admin cuts system:', error); - - // Show error notification if available - if (typeof showNotification === 'function') { - showNotification('Failed to initialize cuts management system', 'error'); - } - } -}); - -// Global functions for backward compatibility -function startDrawing() { - if (adminCutsManager && adminCutsManager.cutDrawing) { - adminCutsManager.handleStartDrawing(); - } -} - -function finishDrawing() { - if (adminCutsManager && adminCutsManager.cutDrawing) { - adminCutsManager.cutDrawing.finishDrawing(); - } -} - -function cancelDrawing() { - if (adminCutsManager && adminCutsManager.cutDrawing) { - adminCutsManager.cutDrawing.cancelDrawing(); - } -} - -function resetForm() { - if (adminCutsManager) { - adminCutsManager.resetForm(); - } -} - -function exportCuts() { - if (adminCutsManager) { - adminCutsManager.exportCuts(); - } -} - -function refreshCuts() { - if (adminCutsManager) { - adminCutsManager.loadCuts(); - } -} - -// Debug functions -function debugFormState() { - if (adminCutsManager) { - adminCutsManager.debugFormState(); - } -} - -function debugOpacityState() { - if (adminCutsManager) { - adminCutsManager.debugOpacityState(); - } -} - -function forceUpdateDrawingStyle() { - if (adminCutsManager) { - adminCutsManager.forceUpdateDrawingStyle(); - } -} diff --git a/map/app/public/js/admin-email.js b/map/app/public/js/admin-email.js index 4af1d69..3d7bee9 100644 --- a/map/app/public/js/admin-email.js +++ b/map/app/public/js/admin-email.js @@ -3,8 +3,8 @@ * Handles email composition, broadcasting to all users, and progress tracking */ -// Email state -let allUsersData = []; +// Email state - use users module data instead of declaring our own +// let allUsersData = []; // Removed - use window.adminUsers.getAllUsersData() instead // Email All Users Functions async function showEmailUsersModal() { @@ -14,12 +14,15 @@ async function showEmailUsersModal() { const data = await response.json(); if (data.success && data.users) { - allUsersData = data.users; + // Use the users module to store user data + if (window.adminUsers && window.adminUsers.setAllUsersData) { + window.adminUsers.setAllUsersData(data.users); + } // Update recipients count const recipientsCount = document.getElementById('recipients-count'); if (recipientsCount) { - recipientsCount.textContent = `${allUsersData.length}`; + recipientsCount.textContent = `${data.users.length}`; } } } catch (error) { @@ -144,18 +147,19 @@ async function sendEmailToAllUsers(e) { return; } - if (allUsersData.length === 0) { + const allUsers = (window.adminUsers && window.adminUsers.getAllUsersData) ? window.adminUsers.getAllUsersData() : []; + if (allUsers.length === 0) { window.adminCore.showStatus('No users found to email', 'error'); return; } - const confirmMessage = `Send this email to all ${allUsersData.length} users?`; + const confirmMessage = `Send this email to all ${allUsers.length} users?`; if (!confirm(confirmMessage)) { return; } // Initialize progress tracking - initializeEmailProgress(allUsersData.length); + initializeEmailProgress(allUsers.length); try { const response = await fetch('/api/users/email-all', { @@ -223,7 +227,8 @@ function initializeEmailProgress(totalCount) { if (closeBtn) closeBtn.style.display = 'none'; // Add status items for each user - allUsersData.forEach(user => { + const allUsers = (window.adminUsers && window.adminUsers.getAllUsersData) ? window.adminUsers.getAllUsersData() : []; + allUsers.forEach(user => { if (statusList) { const statusItem = document.createElement('div'); statusItem.className = 'email-status-item'; @@ -389,6 +394,10 @@ window.adminEmail = { updateEmailPreview, sendEmailToAllUsers, setupEmailModalEventListeners, - getAllUsersData: () => allUsersData, - setAllUsersData: (data) => { allUsersData = data; } + getAllUsersData: () => (window.adminUsers && window.adminUsers.getAllUsersData) ? window.adminUsers.getAllUsersData() : [], + setAllUsersData: (data) => { + if (window.adminUsers && window.adminUsers.setAllUsersData) { + window.adminUsers.setAllUsersData(data); + } + } }; diff --git a/map/app/public/js/admin-map.js b/map/app/public/js/admin-map.js index aca7044..811cb38 100644 --- a/map/app/public/js/admin-map.js +++ b/map/app/public/js/admin-map.js @@ -30,6 +30,12 @@ function initializeAdminMap() { return; } + // Check if Leaflet is available + if (typeof L === 'undefined') { + console.error('Leaflet (L) is not defined. Map initialization failed.'); + return; + } + console.log('Initializing admin map...'); adminMap = L.map('admin-map').setView([53.5461, -113.4938], 11); diff --git a/map/app/utils/spatial.js b/map/app/utils/spatial.js index 92372c4..ebf9b8f 100644 --- a/map/app/utils/spatial.js +++ b/map/app/utils/spatial.js @@ -35,10 +35,18 @@ function isPointInPolygon(lat, lng, polygon) { */ function isLocationInCut(location, cutGeoJson) { // Handle different possible field names for coordinates - const lat = location.latitude || location.Latitude || location.lat; - const lng = location.longitude || location.Longitude || location.lng || location.lon; + const latRaw = location.latitude || location.Latitude || location.lat; + const lngRaw = location.longitude || location.Longitude || location.lng || location.lon; - if (!lat || !lng || !cutGeoJson) { + if (!latRaw || !lngRaw || !cutGeoJson) { + return false; + } + + // Parse coordinates as floats since they might be strings + const lat = parseFloat(latRaw); + const lng = parseFloat(lngRaw); + + if (isNaN(lat) || isNaN(lng)) { return false; } @@ -72,14 +80,20 @@ function filterLocationsInCut(locations, cut, filters = {}) { const geojsonData = cut.geojson || cut.Geojson || cut.GeoJSON || cut['GeoJSON Data'] || cut.geojson_data; if (!geojsonData) { + console.log('No geojson data found for cut:', cut.name || cut.Name || 'Unknown'); return []; } + // Debug: Log total locations being tested + console.log(`Testing ${locations.length} locations against cut boundaries`); + // First filter by geographic boundaries let filteredLocations = locations.filter(location => isLocationInCut(location, geojsonData) ); + console.log(`Filtered ${locations.length} total locations down to ${filteredLocations.length} locations within cut bounds`); + // Apply additional filters if (filters.support_level) { filteredLocations = filteredLocations.filter(location => {