diff --git a/app.js b/app.js index 940e345..a033992 100644 --- a/app.js +++ b/app.js @@ -14,12 +14,13 @@ document.addEventListener('DOMContentLoaded', async () => { showAuxiliary: true, isEditMode: false, isLoading: true, - hasLoadedFromDB: false + hasLoadedFromDB: false, + currentProjektId: null, + allowedProjects: [] }; const getProjektId = () => { - const urlParams = new URLSearchParams(window.location.search); - return urlParams.get('project') || urlParams.get('projekt') || urlParams.get('projekt_id') || "BWSamern-Ohne"; + return state.currentProjektId || "BWSamern-Ohne"; }; const STATUS_MAP = { @@ -2019,16 +2020,46 @@ document.addEventListener('DOMContentLoaded', async () => { } } - // Initialize Dynamic Layers and then load data - initDynamicLayers().then(async () => { + // Dynamic projects loading and switching logic + async function switchProject(projId) { + state.currentProjektId = projId; + + // Quietly update the project URL parameter without reloading + const url = new URL(window.location); + url.searchParams.set('project', projId); + window.history.pushState({}, '', url); + + const statusEl = document.getElementById('statusInfo'); + if (statusEl) { + statusEl.innerText = `Projekt "${projId}" wird geladen...`; + } + + // 1. Clear existing turbines + state.turbines.forEach(t => { + try { + if (t.layers && t.variant && variantLayers[t.variant]) { + Object.values(t.layers).forEach(l => variantLayers[t.variant].removeLayer(l)); + } + } catch (e) { + console.error("Fehler beim Entfernen alter WEA-Layer:", e); + } + }); + state.turbines = []; + + // 2. Clear existing owner statuses + state.ownerStatuses = {}; + try { - // Erst Status laden + // 3. Load dynamic layers for new project + await initDynamicLayers(); + + // 4. Load owner statuses await loadOwnerStatusesFromDB(); - // Dann WEAs laden + // 5. Load turbines await loadTurbinesFromDB(); - // Automatisches Mapping für den Eigentümer-Layer prüfen + // 6. Automatisches Mapping für den Eigentümer-Layer prüfen const ownerLayerName = Object.keys(overlays).find(k => k.toLowerCase().includes('eigentümer')); if (ownerLayerName && overlays[ownerLayerName]) { const layer = overlays[ownerLayerName]; @@ -2047,7 +2078,7 @@ document.addEventListener('DOMContentLoaded', async () => { } } - // Auto-zoom to project parcels + // 7. Auto-zoom to project parcels if (ownerLayerName && overlays[ownerLayerName]) { const layer = overlays[ownerLayerName]; const layers = layer.getLayers(); @@ -2066,13 +2097,114 @@ document.addEventListener('DOMContentLoaded', async () => { console.log(`Auto-Zoom auf ${matchedLayers.length} Flächen des Projekts ausgeführt.`); } } + + if (statusEl) { + statusEl.innerText = `Projekt "${projId}" erfolgreich geladen.`; + } } catch (e) { - console.error("Fehler bei der Initialisierung des Planungstools:", e); + console.error("Fehler beim Umschalten des Projekts:", e); + if (statusEl) { + statusEl.innerHTML = `Fehler beim Laden des Projekts: ${e.message}`; + } + } + } + + // Initialize allowed projects and project selector + async function initializeProjects() { + const statusEl = document.getElementById('statusInfo'); + try { + if (statusEl) statusEl.innerText = "Benutzerdaten werden geprüft..."; + + const response = await fetch('/api/user/projekte'); + if (!response.ok) { + if (response.status === 401 || response.status === 403) { + throw new Error("Sie haben keine Berechtigung für dieses Planungstool."); + } + throw new Error(`HTTP Fehler ${response.status}`); + } + + const data = await response.json(); + state.allowedProjects = data.projects || []; + + if (state.allowedProjects.length === 0) { + throw new Error("Ihnen wurden in Authentik keine Projekte zugewiesen."); + } + + console.log(`Erlaubte Projekte geladen:`, state.allowedProjects); + + // Determine initial project + const urlParams = new URLSearchParams(window.location.search); + const requestedProj = urlParams.get('project') || urlParams.get('projekt') || urlParams.get('projekt_id'); + + let initialProj = null; + if (requestedProj) { + // Check if requested project name or ID is in allowed list + const matches = state.allowedProjects.find(p => + p.id.toLowerCase() === requestedProj.toLowerCase() || + p.name.toLowerCase() === requestedProj.toLowerCase() + ); + if (matches) { + initialProj = matches.id; + } + } + + // Fallback to first project if not found or not specified + if (!initialProj) { + initialProj = state.allowedProjects[0].id; + } + + // Setup project selector UI + const selectorContainer = document.getElementById('projectSelectorContainer'); + const selector = document.getElementById('projectSelector'); + + if (state.allowedProjects.length > 1) { + // Populate dropdown + selector.innerHTML = ''; + state.allowedProjects.forEach(p => { + const opt = document.createElement('option'); + opt.value = p.id; + opt.textContent = p.name; + selector.appendChild(opt); + }); + selector.value = initialProj; + + // Show dropdown container + if (selectorContainer) { + selectorContainer.style.display = 'flex'; + } + + // Handle change event + selector.addEventListener('change', async (e) => { + state.isLoading = true; + await switchProject(e.target.value); + state.isLoading = false; + }); + } else { + // Hide dropdown container if only one project is allowed + if (selectorContainer) { + selectorContainer.style.display = 'none'; + } + } + + // Perform initial load + await switchProject(initialProj); + + } catch (err) { + console.error("Initialisierungsfehler:", err); + if (statusEl) { + statusEl.innerHTML = `Zugriff verweigert: ${err.message}`; + } + // Block edit interactions + state.isEditMode = false; + const btnEdit = document.getElementById('btnToggleEditMode'); + if (btnEdit) btnEdit.disabled = true; } finally { state.isLoading = false; - console.log("Planungstool initialisiert, isLoading = false"); } - }); + } + + // Start loading process + initializeProjects(); // Project Persistence const btnSave = document.getElementById('btnSaveProject'); @@ -2190,19 +2322,19 @@ document.addEventListener('DOMContentLoaded', async () => { const dbTurbines = await response.json(); console.log(`Datenbank-Response: ${dbTurbines.length} WEAs erhalten.`); - if (dbTurbines.length > 0) { - // Clear existing turbines safely - state.turbines.forEach(t => { - try { - if (t.layers && t.variant && variantLayers[t.variant]) { - Object.values(t.layers).forEach(l => variantLayers[t.variant].removeLayer(l)); - } - } catch (e) { - console.error("Error clearing existing layers:", e); + // Clear existing turbines safely + state.turbines.forEach(t => { + try { + if (t.layers && t.variant && variantLayers[t.variant]) { + Object.values(t.layers).forEach(l => variantLayers[t.variant].removeLayer(l)); } - }); - state.turbines = []; + } catch (e) { + console.error("Error clearing existing layers:", e); + } + }); + state.turbines = []; + if (dbTurbines && dbTurbines.length > 0) { dbTurbines.forEach(t => { try { const latlng = L.latLng(t.lat, t.lng); diff --git a/index.html b/index.html index 1c4716e..7bc7187 100644 --- a/index.html +++ b/index.html @@ -25,6 +25,12 @@