Termin aus Mail, Rollen & Rechte, Abwesenheiten, Glas-Darstellung und Pi-Betrieb

- Termin aus Mail: Mailtext oder .eml per Drag & Drop/Strg+V auf Terminplan
  oder Aufgaben, KI schlägt Aufgaben vor, Prüfung im Aufgaben-Panel; neues
  Notizfeld je Aufgabe (plan_todos.notiz)
- Terminplan: Meilensteine ohne Aufgabenbezug je in eigener Zeile,
  "+ Neu"-Menü klappt neben schmaler Seitenleiste nach rechts, Leistungsphasen
- Rollen & Rechte, Abwesenheiten-Seite, Benachrichtigungen, Rundgang
- Glas-Darstellung, Logo als Favicon
- Pi-Betrieb: PDF-Arbeit im Kindprozess, Wächter, Einrichtungs- und
  Prüfskript inkl. WLAN-Wächter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
erikandClaude Opus 5.5 committed 2026-10-29 14:16:52 +01:00
1 parent f4fb3c550b
commit b7e0bd0d92
56 files changed
+12265 -2974

No files matched your search

+34 -11
View File
@@ -19,25 +19,30 @@
// zeigte „Passwortwechsel erforderlich" an, erfüllen konnte ihn niemand.
// currentUser: der aktuell angemeldete Benutzer ({id, username, displayName,
// email, role, personId, mustChangePassword}) oder null vor dem Login.
// email, role, rolleName, rechte, personId, mustChangePassword}) oder null
// vor dem Login.
let currentUser = null;
// renderUserBar: zeigt Namen + Rolle des angemeldeten Benutzers im Menueband
// an (Element #userBarInfo) und blendet den gesamten Admin-Bereich der
// Seitenleiste (#navAdminSection) nur fuer Administratoren ein. Dieser
// Bereich fuehrt zu allen Admin-Aufgaben — Benutzerverwaltung, firmenweite
// Vorgaben, Datenbank und Sitzungen. Es ist ein reines UI-Gate; die
// eigentliche Sperre sitzt serverseitig in requireRole('admin') auf den
// zugehoerigen Routen, und showTab() leitet Nicht-Administratoren zusaetzlich
// vom Bereich „Admin" weg (js/tabs-auth.js).
// Seitenleiste (#navAdminSection) nur bei mindestens einem Admin-Recht ein
// (Rollen & Rechte). Es ist ein reines UI-Gate; die eigentliche Sperre sitzt
// serverseitig in requireRecht() auf den zugehoerigen Routen, und showTab()
// leitet ohne Recht zusaetzlich vom Bereich „Admin" weg (js/tabs-auth.js).
function renderUserBar(){
const info = document.getElementById('userBarInfo');
if(info && currentUser){
const roleLabel = systemRolleText(currentUser.role);
const roleLabel = currentUser.rolleName || systemRolleText(currentUser.role);
info.textContent = (currentUser.displayName || currentUser.username) + ' (' + roleLabel + ')';
}
const navAdminSection = document.getElementById('navAdminSection');
if(navAdminSection) navAdminSection.style.display = (currentUser && currentUser.role === 'admin') ? '' : 'none';
if(navAdminSection) navAdminSection.style.display = hatAdminRecht() ? '' : 'none';
// Wandtafel-Eintrag nur mit Recht „Wandtafel anzeigen“
document.querySelectorAll('[data-tab="wand"], .nur-wandtafel-recht').forEach(el => { el.hidden = !hatRecht('wand'); });
if(typeof adminNavAbgleichen === 'function') adminNavAbgleichen();
// Allgemeines UI-Gate: Elemente mit class="nur-recht" data-recht="…"
// data-recht="a|b": eines der Rechte genügt.
document.querySelectorAll('.nur-recht[data-recht]').forEach(el => { el.hidden = !el.dataset.recht.split('|').some(r => hatRecht(r)); });
document.querySelectorAll('.nur-projektleitung').forEach(el => { el.hidden = !darfProjektlisteAendern(); });
}
@@ -50,13 +55,26 @@ function systemRolleText(role){
}
// darfProjektlisteAendern: ob das angemeldete Konto Projekte anlegen und aus
// der Projektliste löschen darf (Projektleiter und Administratoren). Reines
// der Projektliste löschen darf (Recht „Projekte anlegen und löschen“). Reines
// UI-Gate — dieselbe Regel setzt /save-week serverseitig durch
// (darfProjektlisteAendern() in server.js), dort mit 403. Knöpfe zum
// Anlegen tragen die Klasse .nur-projektleitung und werden von
// renderUserBar() ausgeblendet.
function darfProjektlisteAendern(){
return !!currentUser && (currentUser.role === 'admin' || currentUser.role === 'projektleiter');
return hatRecht('proj.anlegen');
}
// hatRecht: ob die Rolle des angemeldeten Kontos dieses Recht hat (Admin →
// Rollen & Rechte). /whoami liefert die Liste mit (currentUser.rechte).
// Reines UI-Gate — die Grenze ziehen requireRecht()/hatRecht() im Server.
function hatRecht(recht){
return !!currentUser && Array.isArray(currentUser.rechte) && currentUser.rechte.includes(recht);
}
// hatAdminRecht: mindestens ein Recht aus dem Admin-Bereich (a.*) — dann
// erscheint „Admin“ in der Seitenleiste, mit den erlaubten Abschnitten.
function hatAdminRecht(){
return !!currentUser && Array.isArray(currentUser.rechte) && currentUser.rechte.some(r => r.startsWith('a.'));
}
// logout: beendet die Server-Session und lädt die Seite neu (zeigt danach
@@ -138,6 +156,10 @@ function afterAuthenticated(onAuthenticated){
renderUserBar();
onAuthenticated();
if(currentUser && currentUser.mustChangePassword) openPasswordModal(true);
// Rundgang (js/einfuehrung.js): wartet selbst, bis die Daten geladen sind
// und kein Dialog offen ist — nach einem Pflicht-Passwortwechsel also erst
// danach.
else if(typeof einfuehrungBeiBedarf === 'function') einfuehrungBeiBedarf();
}
// ---------- Eigenes Passwort ändern (#passwordModal) ----------
@@ -218,6 +240,7 @@ async function submitPasswordChange(ev){
// Der Bereich „Einstellungen" zeigt die Kennzeichnung mit an.
if(typeof renderSettings === 'function' && typeof currentTab !== 'undefined' && currentTab === 'settings') renderSettings();
alert('Das Passwort wurde geändert.');
if(typeof einfuehrungBeiBedarf === 'function') einfuehrungBeiBedarf();
}
// checkAuthAndInit: prüft per GET /whoami, ob eine gültige Session besteht.