Files
projektuebersicht/public/js/tabs-auth.js

101 lines
5.0 KiB
JavaScript

// -----------------------------
// Projektübersicht — Tabs (Navigation)
// -----------------------------
// Modul für die Tab-Navigation der Hauptseite (nur von Test.html geladen, nach
// js/showmode.js, vor js/pdf.js). showTab() wechselt zwischen Board,
// Wochenbericht, Auslastung, Projekte, Projektbeteiligte, Meine Aufgaben,
// Einstellungen, Admin und dem Projektbereich eines einzelnen Projekts
// ('plan', siehe TAB_PANELS).
// Einstellungen und Admin sind keine eigenen Tabs mehr, sondern aufklappbare
// Bereiche direkt in der Seitenleiste (siehe toggleSidebarAccordion() in
// js/ui.js). Gerendert werden beim Tab-Wechsel renderBoard()/
// renderWochenbericht()/renderLoad()/renderProjects()/renderPeople()/
// renderDashboard() aus js/board/board.js, js/wochenbericht/wochenbericht.js,
// js/load/load.js, js/projects/projects.js, js/people/people.js,
// js/dashboard/dashboard.js. Der frühere clientseitige Passwortschutz für die
// Tabs 'projects'/'people' wurde entfernt — der Zugriffsschutz läuft jetzt
// serverseitig über die Session (siehe js/auth.js, server.js).
//
// TAB_PANELS: alle Bereiche der Hauptseite. 'plan' ist der Projektbereich
// EINES Projekts (#plan) — früher die eigenständige Seite project-plan.html,
// die in einem eigenen Dokument geöffnet wurde. Seit dem Umbau ist er ein
// Bereich wie jeder andere: Menüband und Seitenleiste bleiben stehen, der
// Wechsel dorthin läuft über denselben showTab()-Weg wie der Wechsel vom
// Dashboard ins Projektboard.
const TAB_PANELS = ['board','wochenbericht','load','people','planung','dashboard','settings','admin','plan'];
function showTab(t){
// Der Bereich „Admin" steht nur Administratoren offen. Ohne diese Weiche
// zeigte ein weitergereichter Deep-Link „/Admin" einem Mitglied eine leere
// Seite — die Karten darin rendert renderAdminArea() für Nicht-Admins gar
// nicht erst. (Ein UI-Gate, mehr nicht: Die Routen dahinter sind
// serverseitig mit requireRole('admin') abgesichert.)
if(t === 'admin' && !(currentUser && currentUser.role === 'admin')) t = DEFAULT_TAB;
if(t !== currentTab) previousTab = currentTab;
currentTab = t;
saveUiState();
updateRouteUrl(t);
TAB_PANELS.forEach(x=>{
const el = document.getElementById(x);
if(el) el.style.display=(x===t?'block':'none');
});
// Der Projektbereich steht als einziger Bereich AUSSERHALB von .container
// (er bringt eigene Kopfzeile und Innenabstände mit). Der leere Container
// hinterließe sonst seinen Innenabstand als blinden Streifen über der
// Kopfzeile des Projektbereichs.
const containerEl = document.querySelector('.app-main > .container');
if(containerEl) containerEl.style.display = (t === 'plan') ? 'none' : '';
document.querySelectorAll('.tab').forEach(el=>el.classList.toggle('active',el.dataset.tab===t));
if(t==='board' && currentWeek()) renderBoard();
if(t==='wochenbericht') renderWochenbericht();
if(t==='load') renderLoad();
if(t==='people') renderPeople();
if(t==='planung') renderPlanung();
if(t==='dashboard') renderDashboard();
if(t==='settings') renderSettings();
if(t==='admin') renderAdminArea();
syncAdminNavState(t);
// Der Projektbereich wird erst NACH dem Einblenden gerendert: das GANTT
// rechnet mit der Containerbreite, die in einem ausgeblendeten Bereich 0
// wäre. Das Ziel (Sitzung + Projekt) steht vorher über setPlanTarget().
if(t==='plan') openPlanView();
syncPlanNavItem();
}
// syncAdminNavState: „Admin" ist in der Seitenleiste kein .tab-Knopf,
// sondern der Kopf einer aufklappbaren Gruppe — die allgemeine
// .tab-Hervorhebung oben greift dort also nicht. Diese Funktion markiert ihn
// stattdessen, solange der Bereich offen ist, und klappt die Gruppe dabei
// auf, damit der gewählte Abschnitt sichtbar wird.
// Parameter: t (aktiver Bereich). Keine Rückgabe.
function syncAdminNavState(t){
const toggle = document.getElementById('adminAccordionToggle');
const subnav = document.getElementById('adminSubnav');
if(!toggle || !subnav) return;
const aktiv = (t === 'admin');
toggle.classList.toggle('active', aktiv);
if(aktiv && !subnav.classList.contains('open')){
subnav.classList.add('open');
toggle.classList.add('expanded');
toggle.setAttribute('aria-expanded', 'true');
}
}
// syncPlanNavItem: hält den Eintrag des Projektbereichs in der Seitenleiste
// aktuell. Er ist der einzige Navigationspunkt, der nicht immer da ist — er
// erscheint erst, wenn ein Projekt geöffnet wurde, und trägt dann dessen
// Bezeichnung. Damit zeigt die Seitenleiste auch im Projektbereich, wo man
// gerade ist, statt (wie es ohne ihn wäre) gar keinen Punkt hervorzuheben.
// Keine Parameter, keine Rückgabe.
function syncPlanNavItem(){
const item = document.getElementById('planNavItem');
if(!item) return;
const app = window.PlanApp;
const name = app && app.projName ? app.projName : '';
item.style.display = name ? '' : 'none';
const label = document.getElementById('planNavItemLabel');
if(label) label.textContent = name || 'Projektbereich';
item.title = name ? ('Projektbereich: ' + name) : 'Projektbereich';
}