// ----------------------------- // Projektübersicht — Init / Start // ----------------------------- // Einstiegsmodul der Hauptseite: wird als letztes Skript ausschließlich von // Test.html geladen und startet direkt beim Laden den Initialisierungsablauf // (automatische Ausführung unten in der Datei, nur wenn ein 'board'-Element // existiert). Es stellt renderAll(), // initUiState() und syncRangeDisplay() bereit und nutzt loadUiState()/ // loadTheme()/loadHeaderState()/loadSidebarCollapseState() aus js/ui.js, load() aus js/store.js, // showTab()/TAB_PANELS aus js/tabs-auth.js sowie die Render-Funktionen // renderBoard()/renderWochenbericht()/renderLoad()/renderProjects()/renderPeople() // aus js/board/board.js, js/wochenbericht/wochenbericht.js, js/load/load.js, // js/projects/projects.js, js/people/people.js. // renderAll: Convenience um UI-Elemente zu initialisieren function renderAll(){ renderBoard(); const activeTab = document.querySelector('.tab.active')?.dataset.tab || currentTab; if(activeTab === 'wochenbericht') renderWochenbericht(); else if(activeTab === 'load') renderLoad(); else if(activeTab === 'people') renderPeople(); else if(activeTab === 'dashboard') renderDashboard(); else if(activeTab === 'settings') renderSettings(); else if(activeTab === 'admin') renderAdminArea(); // Der Projektbereich rendert nicht hier, sondern in showTab('plan') — // load() ruft direkt im Anschluss showTab(currentTab) auf, und erst dort // ist der Bereich sichtbar (das GANTT braucht die Containerbreite). } // initUiState: stellt beim Start den UI-Zustand her (LocalStorage-UI-State, // Theme, Header-Status), setzt den Seitentitel und zeigt den ersten Tab an. // Eine Deep-Link-URL (z. B. "/Auslastung") aus applyUrlRoute() übersteuert // dabei den Tab. Kein Rückgabewert. function initUiState(){ loadUiState(); const route = applyUrlRoute(); if(route){ currentTab = route.tab; // Deep-Link auf den Projektbereich ("/Projektplan/?weekLabel=…"): // Ziel merken, damit showTab('plan') es rendern kann. Beim ersten Aufruf // ist db.weeks noch leer — load() ruft showTab(currentTab) erneut auf, // sobald die Sitzungen da sind. Ein Sandbox-Plan der Planung trägt statt // projNr ein planId (siehe updateRouteUrl(), js/ui.js) — PlanApp.sandboxPlanId // wird deshalb nach setPlanTarget() gesetzt, das es sonst zurücksetzt. if(route.tab === 'plan'){ setPlanTarget(route.weekLabel, route.projNr, route.projName); if(route.weekLabel === SANDBOX_WEEK_LABEL) window.PlanApp.sandboxPlanId = route.planId || ''; } } loadTheme(); loadHeaderState(); loadSidebarCollapseState(); document.title = 'Projektübersicht'; const titleEl = document.getElementById('pageTitle'); if(titleEl) titleEl.textContent = 'Projektübersicht'; const tab = TAB_PANELS.includes(currentTab) ? currentTab : DEFAULT_TAB; showTab(tab); } // syncRangeDisplay: schreibt den aus zwei Datumsfeldern (startId/endId) // berechneten Zeitraum als deutschen Text (z. B. "05.04.2026 – 11.04.2026") // in das Anzeigefeld displayId. Parameter: die drei Element-IDs; kein Rückgabewert. function syncRangeDisplay(displayId, startId, endId){ const disp = document.getElementById(displayId); if(!disp) return; const sEl = document.getElementById(startId); const eEl = document.getElementById(endId); const s = sEl ? parseDateISO(sEl.value) : null; const e = eEl ? parseDateISO(eEl.value) : null; const from = s ? formatDateDE(s) : ''; const to = e ? formatDateDE(e) : from; disp.value = from ? (from + ' – ' + to) : ''; } // Automatische Initialisierung der Hauptseite — seit Projektbereich und // Benutzerverwaltung eigene Bereiche sind, ist sie die einzige Seite. Der eigentliche // Start läuft erst nach erfolgreicher Anmeldung (checkAuthAndInit(), js/auth.js) — // ohne gültige Session zeigt das Login-Overlay und blockiert die App. if(document.getElementById('board')){ checkAuthAndInit(() => { initUiState(); load(); }); }