Files
projektuebersicht/public/js/showmode.js
T

207 lines
7.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// -----------------------------
// 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/board.js/js/load/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 = '<div class="show-mode-loading">Lädt…</div>';
}
// 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();
}
});