Dashboard-Reihenfolge, Drei-Punkte-Menü, Mehrrollen-Kürzel, Login-Rechte

- Meine Aufgaben: Projekte in der Reihenfolge der Projektliste, je Konto
  per Ziehen umsortierbar (users.dashboard_reihenfolge)
- Projektliste: Öffnen/Löschen hinter einem "⋯"-Menü
- Avatare je Person statt je Rolle; mehrere Rollen als senkrechte
  Farbstreifen; Titelleiste zieht Rollenänderungen sofort nach
- Nach dem Anmelden vollständiges Konto über /whoami laden (Seitenleiste
  zeigte sonst erst nach Neuladen alle Einträge)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
erikandClaude Opus 5.5 committed 2026-10-29 15:21:29 +01:00
1 parent b7e0bd0d92
commit a2266662ad
11 files changed
+358 -36

No files matched your search

+24 -2
View File
@@ -3035,6 +3035,13 @@ function migrateUsersDepartment(){
db.exec("ALTER TABLE users ADD COLUMN einfuehrung_am TEXT NOT NULL DEFAULT ''");
console.log('Benutzer-Tabelle um einfuehrung_am ergänzt.');
}
// dashboard_reihenfolge: eigene Reihenfolge der Projekte auf "Meine
// Aufgaben" (JSON-Liste von Projekt-Schlüsseln, meist project_uid); leer =
// wie in der Projektliste. Je Konto, damit sie auf jedem Gerät gilt.
if(!cols.includes('dashboard_reihenfolge')){
db.exec("ALTER TABLE users ADD COLUMN dashboard_reihenfolge TEXT NOT NULL DEFAULT ''");
console.log('Benutzer-Tabelle um dashboard_reihenfolge ergänzt.');
}
if(!cols.includes('department')){
db.exec("ALTER TABLE users ADD COLUMN department TEXT NOT NULL DEFAULT ''");
console.log('Benutzer-Tabelle um department ergänzt.');
@@ -3652,7 +3659,7 @@ function attachUser(req, res, next){
u.display_name AS display_name, u.email AS email, u.role AS role,
u.person_id AS person_id, u.active AS active,
u.must_change_password AS must_change_password, u.department AS department,
u.einfuehrung_am AS einfuehrung_am
u.einfuehrung_am AS einfuehrung_am, u.dashboard_reihenfolge AS dashboard_reihenfolge
FROM user_sessions s JOIN users u ON u.id = s.user_id
WHERE s.token = ?
`).get(token);
@@ -3670,7 +3677,9 @@ function attachUser(req, res, next){
// jedes Mal manuell das eigene Gewerk wählen muss.
department: row.department || '',
// einfuehrungFaellig: Rundgang noch nicht abgeschlossen (js/einfuehrung.js)
einfuehrungFaellig: !row.einfuehrung_am
einfuehrungFaellig: !row.einfuehrung_am,
// dashboardReihenfolge: eigene Projektreihenfolge auf "Meine Aufgaben"
dashboardReihenfolge: (() => { try { const a = JSON.parse(row.dashboard_reihenfolge || '[]'); return Array.isArray(a) ? a : []; } catch(e){ return []; } })()
};
// last_seen_at höchstens einmal je Minute und Sitzung schreiben. Vorher
// schrieb JEDE Anfrage — auch jede der rund 60 JS/CSS-Dateien eines
@@ -3849,6 +3858,19 @@ app.post('/einfuehrung', requireAuth, (req, res) => {
} catch(err){ console.error('Einführung speichern fehlgeschlagen:', err); res.status(500).json({ ok: false, error: String(err) }); }
});
// POST /dashboard-reihenfolge {reihenfolge:[schlüssel]} — eigene Reihenfolge
// der Projekte auf "Meine Aufgaben"; leere Liste = wie in der Projektliste.
// Nur das eigene Konto.
app.post('/dashboard-reihenfolge', requireAuth, (req, res) => {
try {
const liste = (req.body || {}).reihenfolge;
if(!Array.isArray(liste)) return res.status(400).json({ ok: false, error: 'reihenfolge muss eine Liste sein.' });
const sauber = [...new Set(liste.map(x => String(x || '').slice(0, 100)).filter(Boolean))].slice(0, 500);
db.prepare('UPDATE users SET dashboard_reihenfolge = ? WHERE id = ?').run(sauber.length ? JSON.stringify(sauber) : '', req.user.id);
res.json({ ok: true, reihenfolge: sauber });
} catch(err){ console.error('Dashboard-Reihenfolge speichern fehlgeschlagen:', err); res.status(500).json({ ok: false, error: String(err) }); }
});
// ---------- Rollen & Rechte: Routen ----------
// GET liefert Katalog und Rollen (mit Anzahl Konten) — jedes angemeldete
// Konto mit Grundzugang, weil die Benutzerverwaltung die Liste für ihre