Projektleiter-Rolle, Papierkorb, neue Login-Seite und Benutzerverwaltung
- Neue Rolle "Projektleiter": Projekte anlegen und löschen nur noch für Projektleiter und Administratoren (serverseitig in /save-week geprüft) - Papierkorb: gelöschte Projekte 30 Tage durch Admins wiederherstellbar - Benutzerverwaltung: Aktionen im Drei-Punkte-Menü mit Rückfrage im Menü, getrennte Felder für Vor- und Nachname, E-Mail-Vorschlag v.nachname@rauschenberg-ing.de, Benutzername = Anfang der E-Mail, Person-ID aus dem Kürzel - Endgültiges Löschen eines Benutzers entfernt ihn auch aus den Projekten und Aufgaben der aktuellen Sitzung; Dateien bleiben als "Gelöschter Benutzer" - Login-Seite neu (Design "Kalenderwoche") mit Logo als Wasserzeichen; Anmeldung ohne Groß-/Kleinschreibung, auch mit voller E-Mail-Adresse Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
93505e0e48
commit
f4fb3c550b
13 files changed
+1214
-116
No files matched your search
+93
-39
@@ -34,12 +34,13 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Projektübersicht</title>
|
||||
<link rel="stylesheet" href="/styles.css?v=64">
|
||||
<link rel="stylesheet" href="/styles.css?v=67">
|
||||
<link rel="stylesheet" href="/plan-styles.css?v=19">
|
||||
<!-- Fredoka/Nunito Sans: nur für die Wandtafel (js/wand/wand.js), siehe ihren
|
||||
Dateikopf — fällt ohne Internetzugang automatisch auf die System-Schrift
|
||||
zurück (font-family-Stack in styles.css), bricht also nichts offline. -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fredoka:wght@500;600;700&family=Nunito+Sans:wght@400;600;700;800&display=swap">
|
||||
Dateikopf; Outfit: nur für die Kalenderwoche der Login-Seite. Alle fallen
|
||||
ohne Internetzugang automatisch auf die System-Schrift zurück
|
||||
(font-family-Stack in styles.css), brechen also nichts offline. -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fredoka:wght@500;600;700&family=Outfit:wght@300;500&family=Nunito+Sans:wght@400;600;700;800&display=swap">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.10/pdfmake.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.10/vfs_fonts.js"></script>
|
||||
</head>
|
||||
@@ -186,7 +187,7 @@
|
||||
js/pdf.js. Damit fällt die einzige gewerkeübergreifende
|
||||
Sitzungsübersicht als PDF weg; die einzelnen Gewerke-Berichte
|
||||
im Wochenbericht bleiben die Ablage. -->
|
||||
<button class="menu-item sidebar-subitem" onclick="openNewProjWizard()">+ Neues Projekt</button>
|
||||
<button class="menu-item sidebar-subitem nur-projektleitung" onclick="openNewProjWizard()">+ Neues Projekt</button>
|
||||
<button class="menu-item sidebar-subitem" onclick="showTab('wand')">Wandtafel</button>
|
||||
</div>
|
||||
|
||||
@@ -212,6 +213,7 @@
|
||||
<button class="menu-item sidebar-subitem" data-admin-section="vorlagen" onclick="showAdminSection('vorlagen')">Aufgaben-Vorlagen</button>
|
||||
<button class="menu-item sidebar-subitem" data-admin-section="planchecker" onclick="showAdminSection('planchecker')">Plan-Checker-Merkmale</button>
|
||||
<button class="menu-item sidebar-subitem" data-admin-section="betrieb" onclick="showAdminSection('betrieb')">Betrieb & Sicherheit</button>
|
||||
<button class="menu-item sidebar-subitem" data-admin-section="papierkorb" onclick="showAdminSection('papierkorb')">Papierkorb</button>
|
||||
<button class="menu-item sidebar-subitem" data-admin-section="datenbank" onclick="showAdminSection('datenbank')">Datenbank & Sitzungen</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,7 +241,7 @@
|
||||
zusätzlich stehen, weil er dort dieselbe Maske öffnet. -->
|
||||
<div class="bericht-titelzeile">
|
||||
<div class="section-title" style="margin:0">Projekte</div>
|
||||
<button type="button" class="secondary small" onclick="openNewProjWizard()">+ Projekt</button>
|
||||
<button type="button" class="secondary small nur-projektleitung" onclick="openNewProjWizard()">+ Projekt</button>
|
||||
</div>
|
||||
<!-- Die Farbe der Kreise richtet sich nach der ROLLE (siehe
|
||||
.board-avatar.role-* in styles.css), die Füllung nach der Art der
|
||||
@@ -715,7 +717,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Benutzername</th>
|
||||
<th>Anzeigename</th>
|
||||
<th>Name</th>
|
||||
<th>E-Mail</th>
|
||||
<th>Rolle</th>
|
||||
<th>Abteilung</th>
|
||||
@@ -731,6 +733,15 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="settings-card settings-card-wide" id="adminPapierkorbCard" data-admin-section="papierkorb" style="display:none">
|
||||
<h3 class="settings-card-title">Papierkorb <span class="settings-scope">nur Administratoren</span></h3>
|
||||
<p class="hint">Aus der Projektliste gelöschte Projekte — samt Terminplan, Beteiligten und
|
||||
Leistungsphasen. Sie bleiben 30 Tage hier und lassen sich in die aktuelle Sitzung
|
||||
zurückholen; danach werden sie endgültig entfernt. Dateien und Protokolle hängen an der
|
||||
Projektnummer und sind nach dem Wiederherstellen ebenfalls wieder da.</p>
|
||||
<div id="adminPapierkorbList"><p class="hint">Wird geladen…</p></div>
|
||||
</section>
|
||||
|
||||
<section class="settings-card" id="adminDatenbankCard" data-admin-section="datenbank" style="display:none">
|
||||
<h3 class="settings-card-title">Datenbank & Sitzungen <span class="settings-scope">nur Administratoren</span></h3>
|
||||
|
||||
@@ -1536,22 +1547,30 @@
|
||||
<div class="modal-bg" id="newUserModal" style="display:none">
|
||||
<div class="modal">
|
||||
<h2>Neuer Benutzer</h2>
|
||||
<div class="form-row">
|
||||
<label>Benutzername</label>
|
||||
<input type="text" id="newUserUsername" placeholder="z. B. mmustermann" autocomplete="off">
|
||||
<div class="form-row-pair">
|
||||
<div class="form-row">
|
||||
<label for="newUserFirstName">Vorname</label>
|
||||
<input type="text" id="newUserFirstName" placeholder="z. B. Max" autocomplete="off" oninput="onNewUserNameInput()">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="newUserLastName">Nachname</label>
|
||||
<input type="text" id="newUserLastName" placeholder="z. B. Mustermann" autocomplete="off" oninput="onNewUserNameInput()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Anzeigename</label>
|
||||
<input type="text" id="newUserDisplayName" placeholder="z. B. Max Mustermann" oninput="onNewUserDisplayNameInput()">
|
||||
<label for="newUserEmail">E-Mail</label>
|
||||
<input type="email" id="newUserEmail" placeholder="v.nachname@rauschenberg-ing.de">
|
||||
<span class="hint" style="margin:4px 0 0">Der Anfang der Adresse ist zugleich der Benutzername für die Anmeldung.</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>E-Mail</label>
|
||||
<input type="email" id="newUserEmail" placeholder="max.mustermann@beispiel.de">
|
||||
<label for="newUserUsername">Benutzername</label>
|
||||
<input type="text" id="newUserUsername" placeholder="Anfang der E-Mail, z. B. m.mustermann" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Rolle</label>
|
||||
<select id="newUserRole" onchange="onUserRoleChange('new')">
|
||||
<option value="member">Mitglied</option>
|
||||
<option value="projektleiter">Projektleiter (darf Projekte anlegen und löschen)</option>
|
||||
<option value="admin">Administrator</option>
|
||||
<option value="kiosk">Kiosk (Wandtafel-Konto)</option>
|
||||
</select>
|
||||
@@ -1563,7 +1582,7 @@
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Kürzel</label>
|
||||
<input type="text" id="newUserInitials" placeholder="wird aus dem Anzeigenamen vorgeschlagen" maxlength="4">
|
||||
<input type="text" id="newUserInitials" placeholder="wird aus dem Namen vorgeschlagen" maxlength="4">
|
||||
<p class="hint">Kurzform fürs Projektboard (2-4 Zeichen), wird vorgeschlagen und kann angepasst werden.</p>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
@@ -1573,7 +1592,7 @@
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Person-ID</label>
|
||||
<input type="text" id="newUserPersonId" placeholder="wird aus dem Anzeigenamen vorgeschlagen">
|
||||
<input type="text" id="newUserPersonId" placeholder="wird aus dem Kürzel gebildet, z. B. p_mm">
|
||||
<p class="hint">Verknüpft den Account mit einem Eintrag in der Projektbeteiligten-Liste (personIdForName). Bei Kollisionen anpassen.</p>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
@@ -1601,18 +1620,25 @@
|
||||
<div class="modal">
|
||||
<h2>Benutzer bearbeiten</h2>
|
||||
<p class="hint" id="editUserUsernameLabel" style="margin-bottom:10px"></p>
|
||||
<div class="form-row">
|
||||
<label>Anzeigename</label>
|
||||
<input type="text" id="editUserDisplayName">
|
||||
<div class="form-row-pair">
|
||||
<div class="form-row">
|
||||
<label for="editUserFirstName">Vorname</label>
|
||||
<input type="text" id="editUserFirstName" oninput="onEditUserNameInput()">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="editUserLastName">Nachname</label>
|
||||
<input type="text" id="editUserLastName" oninput="onEditUserNameInput()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>E-Mail</label>
|
||||
<input type="email" id="editUserEmail">
|
||||
<input type="email" id="editUserEmail" placeholder="v.nachname@rauschenberg-ing.de">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Rolle</label>
|
||||
<select id="editUserRole" onchange="onUserRoleChange('edit')">
|
||||
<option value="member">Mitglied</option>
|
||||
<option value="projektleiter">Projektleiter (darf Projekte anlegen und löschen)</option>
|
||||
<option value="admin">Administrator</option>
|
||||
<option value="kiosk">Kiosk (Wandtafel-Konto)</option>
|
||||
</select>
|
||||
@@ -1748,41 +1774,69 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Login-Overlay: blockiert die gesamte App ohne gültige Session (siehe js/auth.js) -->
|
||||
<div id="loginOverlay" style="display:none;" class="modal-bg">
|
||||
<div class="modal">
|
||||
<h2>Anmelden</h2>
|
||||
<form id="loginForm">
|
||||
<div class="form-row"><label>Benutzername</label><input type="text" id="loginUsername" autocomplete="username" required></div>
|
||||
<div class="form-row"><label>Passwort</label><input type="password" id="loginPassword" autocomplete="current-password" required></div>
|
||||
<div id="loginError" style="color:#c00;"></div>
|
||||
<div class="toolbar"><button type="submit">Anmelden</button></div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- Login-Seite: blockiert die gesamte App ohne gültige Session (siehe
|
||||
js/auth.js). Design "Kalenderwoche" (Eriks Wahl B aus dem Vergleich der
|
||||
Login-Entwürfe): links Logo und Formular, rechts die laufende
|
||||
Kalenderwoche als große Zahl mit ihren Arbeitstagen — die App denkt in
|
||||
Sitzungen je KW. Gefüllt von renderLoginWoche(). Das Logo liegt als
|
||||
blasses Wasserzeichen über die ganze Seite (Variante E aus dem
|
||||
Logo-Vergleich), ein kleines Logo gibt es bewusst nicht. -->
|
||||
<div id="loginOverlay" class="login-seite" style="display:none;">
|
||||
<div class="login-wz-rahmen" aria-hidden="true"><img class="login-wasserzeichen" src="/logo.png" alt=""></div>
|
||||
<main class="login-raster" aria-label="Anmeldung bei der Projektübersicht">
|
||||
<section class="login-links">
|
||||
<h1 class="login-titel">Projektübersicht</h1>
|
||||
<p class="login-unter">Melde dich mit dem Anfang deiner E-Mail-Adresse an.</p>
|
||||
<form id="loginForm" class="login-form" novalidate>
|
||||
<div class="login-feld">
|
||||
<label for="loginUsername">Benutzername</label>
|
||||
<input type="text" id="loginUsername" name="username" autocomplete="username" placeholder="z. B. m.mustermann" spellcheck="false" autocapitalize="off">
|
||||
</div>
|
||||
<div class="login-feld">
|
||||
<label for="loginPassword">Passwort</label>
|
||||
<div class="login-pw">
|
||||
<input type="password" id="loginPassword" name="password" autocomplete="current-password">
|
||||
<button type="button" id="loginPwToggle" class="login-pw-toggle" aria-pressed="false" aria-controls="loginPassword">Anzeigen</button>
|
||||
</div>
|
||||
<p id="loginCaps" class="login-caps" hidden>Die Feststelltaste ist aktiv.</p>
|
||||
</div>
|
||||
<p id="loginError" class="login-fehler" role="alert" hidden></p>
|
||||
<button type="submit" id="loginSubmit" class="login-btn"><span class="login-spinner" aria-hidden="true"></span><span class="login-btn-text">Anmelden</span></button>
|
||||
</form>
|
||||
<p class="login-hilfe">Passwort vergessen? Ein Administrator setzt es dir zurück.</p>
|
||||
</section>
|
||||
<section class="login-woche" aria-label="Laufende Kalenderwoche">
|
||||
<span class="login-kw-label">Kalenderwoche</span>
|
||||
<span class="login-kw-zahl" id="loginKwZahl"></span>
|
||||
<span class="login-kw-jahr" id="loginKwJahr"></span>
|
||||
<ol class="login-tage" id="loginTage"></ol>
|
||||
<p class="login-datum"><span id="loginDatum"></span>. Die Sitzung dieser Woche ist geöffnet.</p>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="/js/globals.js?v=7"></script>
|
||||
<script src="/js/utils.js?v=18"></script>
|
||||
<script src="/js/utils.js?v=19"></script>
|
||||
<script src="/js/icons.js?v=2"></script>
|
||||
<script src="/js/ui.js?v=9"></script>
|
||||
<script src="/js/date-picker.js?v=5"></script>
|
||||
<script src="/js/server.js?v=6"></script>
|
||||
<script src="/js/auth.js?v=4"></script>
|
||||
<script src="/js/auth.js?v=6"></script>
|
||||
<script src="/js/store.js?v=10"></script>
|
||||
<script src="/js/weeks.js?v=11"></script>
|
||||
<script src="/js/board/board.js?v=30"></script>
|
||||
<script src="/js/board/board.js?v=31"></script>
|
||||
<script src="/js/wochenbericht/wochenbericht.js?v=20"></script>
|
||||
<script src="/js/people/people.js?v=7"></script>
|
||||
<script src="/js/planung/planung.js?v=1"></script>
|
||||
<script src="/js/planchecker/planchecker.js?v=1"></script>
|
||||
<script src="/js/projects/projects.js?v=7"></script>
|
||||
<script src="/js/projects/projects.js?v=8"></script>
|
||||
<script src="/js/load/load.js?v=18"></script>
|
||||
<!-- auftrag.js: Auftragsstatus und Dialog "Beauftragung". Nach load.js, weil
|
||||
der Neues-Projekt-Dialog dort die Statusauswahl mit AUFTRAGSSTATUS füllt. -->
|
||||
<script src="/js/auftrag.js?v=1"></script>
|
||||
<!-- Assistent "Neues Projekt": braucht auftrag.js (Auftragsstatus) und
|
||||
load.js (faktorFormat), steht deshalb dahinter. -->
|
||||
<script src="/js/projekt-wizard.js?v=1"></script>
|
||||
<script src="/js/projekt-wizard.js?v=2"></script>
|
||||
<script src="/js/dashboard/dashboard.js?v=5"></script>
|
||||
<!-- wand.js braucht berechneAuslastung()/loadAmpelColor()/kapazitaetsFaktor()/
|
||||
stundenFormat() (load.js), classifyProjectChange()/findPreviousWeek()
|
||||
@@ -1791,9 +1845,9 @@
|
||||
bereits vorher, die Reihenfolge hier ist also nur Zuordnung zum
|
||||
Tab-Ordner, keine neue Abhängigkeit nach vorn. -->
|
||||
<script src="/js/wand/wand.js?v=12"></script>
|
||||
<script src="/js/settings/settings.js?v=9"></script>
|
||||
<script src="/js/admin/admin.js?v=11"></script>
|
||||
<script src="/js/admin-users.js?v=4"></script>
|
||||
<script src="/js/settings/settings.js?v=10"></script>
|
||||
<script src="/js/admin/admin.js?v=12"></script>
|
||||
<script src="/js/admin-users.js?v=7"></script>
|
||||
<script src="/js/gantt.js?v=7"></script>
|
||||
<!-- Module des Projektbereichs (#plan). Sie liefen frueher nur in
|
||||
project-plan.html; seit der Projektbereich ein Bereich dieser Seite ist,
|
||||
|
||||
Reference in new issue
Block a user