Release v2.5.0 — Client-Versions-Übersicht im Web-Editor

Jeder Client meldet beim Start seinen Status (Name, Abteilung, Plugin- und
Thunderbird-Version) als _clients/<email>.json ins Gitea-Repo — aber nur, wenn
sich tatsächlich etwas geändert hat (kein Commit-Spam pro Start).

Web-Editor: neuer Admin-Unterpunkt "User & Versionen" (Route /api/clients)
mit Tabelle je User und "veraltet"-Markierung für Clients, die nicht auf der
neuesten gemeldeten Version laufen. _clients/ ist in den Ordner-Filtern
ausgenommen, damit es nicht als Abteilung erscheint.

Nebenbei: Web-Editor-Button-Label "Abteilung" -> "Vorlage" (Templates-Tab).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PZHd9vRsBiH8cKYdQo1Yv
This commit is contained in:
Kendrick Bollens
2026-07-22 14:42:23 +02:00
parent d244273e44
commit 02776311c3
6 changed files with 177 additions and 7 deletions

View File

@@ -279,6 +279,19 @@ button { font-family: inherit; }
.list-body::-webkit-scrollbar, .html-editor::-webkit-scrollbar, .editorpane::-webkit-scrollbar { width: 10px; }
.list-body::-webkit-scrollbar-thumb, .html-editor::-webkit-scrollbar-thumb, .editorpane::-webkit-scrollbar-thumb { background: #cdd6c9; border-radius: 10px; border: 2px solid transparent; background-clip: content-box; }
/* ── User & Versionen (Clients) ── */
.cl-tablewrap { margin-top: 6px; overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.cl-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.cl-table th, .cl-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.cl-table thead th { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; background: var(--bg); }
.cl-table tbody tr:last-child td { border-bottom: none; }
.cl-table tbody tr:hover { background: var(--bg); }
.cl-table .cl-mail { color: var(--muted); font-family: var(--mono); font-size: 12.5px; }
.cl-row-old td { background: var(--danger-50); }
.cl-row-old:hover td { background: #fbe3e1; }
.cl-badge { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; font-size: 11px; font-weight: 700; vertical-align: middle; }
.cl-badge.cl-old { background: var(--danger-50); color: var(--danger); border: 1px solid #ecc4c2; }
/* ── Responsive ── */
@media (max-width: 980px) { .workspace { grid-template-columns: 250px 1fr; } .stat-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 760px) {