// ----------------------------- // Projektübersicht — Show Mode // ----------------------------- // Präsentationsmodus für die Hauptseite (nur von Test.html geladen, nach // js/gantt.js, vor js/tabs-auth.js). Er durchläuft automatisch die in // SHOW_MODE_SEQUENCE hinterlegten Abteilungs-/Ansichts-Kombinationen (Board // und Auslastung) und zeigt sie in einem Vollbild-Overlay. Genutzt werden // showTab() aus js/tabs-auth.js, switchDepartment() aus js/store.js, // setHeaderCollapsed() aus js/ui.js sowie renderBoard()/renderLoad() aus // js/board.js/js/load.js. Der gesamte Lauf-Zustand liegt in den // Modulvariablen am Dateikopf. // showModeActive: true, solange der Show Mode läuft let showModeActive = false; // showModeTimer: Timer-Handle für den Wechsel zur nächsten Folie let showModeTimer = null; // showModeResumeTimer: Timer-Handle für die automatische Fortsetzung nach einer Pause let showModeResumeTimer = null; // showModePaused: true, wenn der Durchlauf gerade pausiert ist let showModePaused = false; // showModeOriginal: Abteilung und Tab vor dem Start, wird beim Beenden wiederhergestellt let showModeOriginal = { department: DEFAULT_DEPARTMENT, tab: DEFAULT_TAB }; const SHOW_MODE_SLIDE_DURATION = 10000; // 10 Sekunden pro Slide const SHOW_MODE_PAUSE_DURATION = 60000; // 1 Minute Pause // SHOW_MODE_SEQUENCE: Reihenfolge der Slides (Abteilung + Ansicht), die // zyklisch durchlaufen wird const SHOW_MODE_SEQUENCE = [ { dept: 'ELT', view: 'board' }, { dept: 'ELT', view: 'load' }, { dept: 'HLS', view: 'board' }, { dept: 'HLS', view: 'load' }, { dept: 'ARCH', view: 'board' }, { dept: 'ARCH', view: 'load' } ]; // showModeIndex: Position innerhalb der SHOW_MODE_SEQUENCE let showModeIndex = 0; // startShowMode: startet den Präsentationsmodus (falls nicht schon aktiv): // merkt sich Abteilung/Tab, zeigt das Overlay, kollabiert das Menü und beginnt // den Slide-Durchlauf. Kein Rückgabewert. function startShowMode(){ if(showModeActive) return; showModeActive = true; showModePaused = false; showModeOriginal = { department: currentDepartment, tab: currentTab }; showModeIndex = 0; const overlay = document.getElementById('showModeOverlay'); if(overlay) overlay.style.display = 'flex'; // Menü schließen, falls offen setHeaderCollapsed(true, false); showModeNextSlide(); } // stopShowMode: beendet den Präsentationsmodus: stoppt alle Timer, verbirgt // das Overlay und stellt Abteilung und Tab des ursprünglichen Zustands wieder // her (renderAll danach). Kein Rückgabewert. function stopShowMode(){ showModeActive = false; showModePaused = false; clearTimeout(showModeTimer); clearTimeout(showModeResumeTimer); const overlay = document.getElementById('showModeOverlay'); if(overlay) overlay.style.display = 'none'; // Ursprünglichen Zustand wiederherstellen currentTab = showModeOriginal.tab; if(currentDepartment !== showModeOriginal.department){ switchDepartment(showModeOriginal.department); } else { showTab(currentTab, true); renderAll(); } } // pauseShowMode: pausiert den Durchlauf (Anzeige "Pausiert") und startet die // automatische Fortsetzung nach SHOW_MODE_PAUSE_DURATION; bei erneutem Aufruf // im pausierten Zustand wird sofort fortgesetzt. Kein Rückgabewert. function pauseShowMode(){ if(!showModeActive) return; if(showModePaused){ // bereits pausiert -> sofort fortsetzen resumeShowMode(); return; } showModePaused = true; clearTimeout(showModeTimer); clearTimeout(showModeResumeTimer); const pausedEl = document.getElementById('showModePaused'); if(pausedEl) pausedEl.style.display = 'block'; showModeResumeTimer = setTimeout(() => { if(showModeActive && showModePaused) resumeShowMode(); }, SHOW_MODE_PAUSE_DURATION); } // resumeShowMode: setzt einen pausierten Durchlauf fort (Timer aufräumen, // Hinweis ausblenden) und zeigt die nächste Folie. Kein Rückgabewert. function resumeShowMode(){ if(!showModeActive) return; showModePaused = false; clearTimeout(showModeResumeTimer); const pausedEl = document.getElementById('showModePaused'); if(pausedEl) pausedEl.style.display = 'none'; showModeNextSlide(); } // showModeNextSlide: stellt die nächste Folie der SHOW_MODE_SEQUENCE dar: // setzt Titel und Ladehinweis, wechselt ggf. per switchDepartment die Abteilung // (mit waitForLoadThenRender) und kopiert danach die aktuelle Ansicht ins // Overlay. Kein Rückgabewert. function showModeNextSlide(){ if(!showModeActive || showModePaused) return; const slide = SHOW_MODE_SEQUENCE[showModeIndex % SHOW_MODE_SEQUENCE.length]; showModeIndex++; const titleEl = document.getElementById('showModeTitle'); if(titleEl){ const deptLabel = DEPARTMENTS[slide.dept] ? DEPARTMENTS[slide.dept].label : slide.dept; titleEl.textContent = `${deptLabel} – ${slide.view === 'load' ? 'Auslastung' : 'Projektboard'}`; } // Ladehinweis anzeigen, damit der alte Inhalt nicht kurz sichtbar flackert const content = document.getElementById('showModeContent'); if(content){ content.innerHTML = '
Lädt…
'; } // Wechsle Department und View in der Hauptansicht, dann kopiere ins Overlay. // Da switchDepartment asynchron lädt, müssen wir auf den Abschluss warten. if(currentDepartment !== slide.dept){ // Temporär currentTab setzen, damit nach dem Laden der richtige Tab aktiv ist. currentTab = slide.view; switchDepartment(slide.dept); // Warte bis Daten geladen sind, dann rendern und kopieren waitForLoadThenRender(slide.view); } else { showTab(slide.view, true); renderAll(); requestAnimationFrame(() => { requestAnimationFrame(() => { copyCurrentViewToShowMode(); scheduleNextShowModeSlide(); }); }); } } // waitForLoadThenRender: wartet nach dem asynchronen Abteilungswechsel, bis // Wochen geladen sind (Polling alle 200 ms, Abbruch nach 30 Versuchen), und // rendert dann die gewünschte Ansicht, kopiert sie ins Show-Mode-Overlay und // plant die nächste Folie. Parameter: view = 'board' oder 'load'. function waitForLoadThenRender(view){ let attempts = 0; const check = setInterval(() => { attempts++; // Wenn Wochen geladen sind oder nach Seed gefallen ist if(db.weeks.length > 0 || attempts > 30){ clearInterval(check); showTab(view, true); renderAll(); // Kurze Verzögerung, damit das DOM aktualisiert ist, bevor kopiert wird requestAnimationFrame(() => { requestAnimationFrame(() => { copyCurrentViewToShowMode(); scheduleNextShowModeSlide(); }); }); } }, 200); } // scheduleNextShowModeSlide: plant den Wechsel zur nächsten Folie nach // SHOW_MODE_SLIDE_DURATION (außer im pausierten/inaktiven Zustand). function scheduleNextShowModeSlide(){ if(!showModeActive || showModePaused) return; clearTimeout(showModeTimer); showModeTimer = setTimeout(() => { showModeNextSlide(); }, SHOW_MODE_SLIDE_DURATION); } // copyCurrentViewToShowMode: kopiert das gerenderte HTML des aktuellen Tabs // (Board oder Auslastung) in das Show-Mode-Overlay; in der Auslastungs-Ansicht // werden dabei Titel und Toolbar ausgeblendet. Kein Rückgabewert. function copyCurrentViewToShowMode(){ const content = document.getElementById('showModeContent'); const sourceId = currentTab === 'load' ? 'load' : 'board'; const source = document.getElementById(sourceId); if(content && source){ content.innerHTML = source.innerHTML; // Im Show Mode sollen in der Auslastung Überschrift und Steuerelemente ausgeblendet werden if(currentTab === 'load'){ content.querySelectorAll('.section-title, .toolbar').forEach(el => el.remove()); } } } // ESC-Taste beendet den Show Mode (globaler Keydown-Listener). document.addEventListener('keydown', function(e){ if(showModeActive && e.key === 'Escape'){ stopShowMode(); } });