Fix: Benutzer-Löschen im Browser kaputt (JS), Gruppen-Rechtetabelle überarbeitet

Bugfix (von dir gemeldet, live auf Port 5000 gefunden):
- initConfirmables() in app.js rief beim bestätigten Absenden
  form.requestSubmit() OHNE den ursprünglichen Submitter auf. Laut Spec
  wird dann KEIN Submit-Button-Name/Value mitgeschickt. users.html trug
  die Benutzer-ID als name/value des Löschen-Buttons selbst (statt eines
  verstecken Inputs wie überall sonst) — dadurch kam "delete_user" nie
  im Request an, der Klick tat scheinbar nichts. Fix: e.submitter beim
  ersten Klick merken und an requestSubmit(submitter) weiterreichen
  (behebt es grundsätzlich für alle Formulare dieser Art); zusätzlich
  users.html auf das robustere hidden-input-Muster umgestellt wie
  credentials/devices/groups. Mit echtem Playwright-Browserklick
  (nicht nur curl) verifiziert.

Gruppen-Rechtetabelle, mehrere Korrekturrunden nach deinem Mockup:
- Bereichsname + Kill-Switch-Kästchen jetzt eng nebeneinander in der
  Tabellen-Kopfzeile (nicht mehr an den Rand gestellt), R/W/E/D-Spalten
  in derselben Zeile statt einer zweiten.
- Nur die von einem Bereich tatsächlich genutzten Spalten werden gezeigt
  (GROUP_ROW_TYPES) — Logs zeigt nur R, Einstellungen nur R/W/E, nur
  Geräte zeigt zusätzlich D.
- Bugfix: D-Spalte bei Geräte verschwand durch zu schmale Flex-Breite der
  Spalte im Overflow, obwohl serverseitig korrekt gerendert — behoben
  durch flex:0 0 auto statt fester Breite.
- Checkbox-Zentrierung robust per display:block+margin:auto statt sich
  auf native Checkbox-Ränder zu verlassen (waren leicht asymmetrisch).
- Unterpunkte deutlich weiter eingerückt (34px) für klare Hierarchie.
- Sichtbares Ausgrauen (nicht nur natives disabled) der Unterpunkte,
  solange der Bereich-Kill-Switch aus ist (JS setzt .permission-locked).
- Legende jetzt UNTER der Rechtetabelle statt darüber.
- Rechte lassen sich jetzt direkt beim Anlegen einer neuen Gruppe setzen
  (Modal zeigt dieselbe Rechtetabelle, add_group-Route verarbeitet
  mitgesendete permissions[] im selben Request) statt sie erst danach
  über die Gruppentabelle nachzupflegen.

Alles inkl. Erstellen-mit-Rechten und Bearbeiten-Regression live per
Playwright verifiziert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 09:52:01 +02:00
co-authored by Claude Sonnet 5
parent 8e4a874943
commit 7d7239e1af
6 changed files with 172 additions and 91 deletions
+31 -33
View File
@@ -109,43 +109,41 @@ Ein Benutzer kann mehreren Gruppen angehören, die Rechte addieren sich
### Zweistufiger Rechtebaum
Der Baum hat genau zwei Ebenen, exakt gespiegelt an den drei Sidebar-Gruppen.
Pro Bereich gibt es eine kompakte Tabelle: Zeilen = der Bereich selbst
„(gesamt)“ + je ein Unterpunkt, Spalten = die Rechte **R**(ead/Lesen),
**W**(rite/Schreiben, Anlegen), **E**(dit/Ändern) nebeneinander. **„Ändern“
deckt Löschen überall mit ab** — es gibt bewusst kein eigenes
Löschen-Recht. Eine vierte Spalte **D** existiert nur bei Clients und
bedeutet dort **nicht** Löschen, sondern *PoE-Neustart über das
Dashboard-Popup auslösen* (automatische Neustarts bei Ausfall über
`poe.sh` sind davon komplett unabhängig und laufen immer). Für Zeilen/Spalten
ohne passendes Recht (z.B. „W“ beim Bereich selbst, oder „D“ bei
Switche/Zugangsdaten/Benutzer/Gruppen) wird eine ausgegraute, nicht
anklickbare Checkbox angezeigt statt die Zelle wegzulassen:
Der Baum hat genau zwei Ebenen, exakt gespiegelt an den drei Sidebar-Gruppen
(Geräte/Logs/Einstellungen). Auf der Gruppen-Seite stehen sie als drei
kompakte Spalten nebeneinander, mit einer kurzen Legende direkt darüber.
Jede Spalte ist eine kleine Tabelle: die Kopfzeile enthält in EINER Zeile
sowohl den Bereichsnamen mit seinem Kästchen (dem Kill-Switch, dicht
nebeneinander statt an den Rand gestellt) als auch die Buchstaben-Spalten
**R**(ead/Lesen), **W**(rite/Schreiben, Anlegen), **E**(dit/Ändern) — nur
die Rechte, die dieser Bereich tatsächlich nutzt. Darunter je eine
eingerückte Zeile pro Unterpunkt. **„Ändern“ deckt Löschen überall mit
ab** — es gibt bewusst kein eigenes Löschen-Recht. Eine vierte Spalte **D**
gibt es nur bei Geräte → Clients, und sie bedeutet dort **nicht** Löschen,
sondern *PoE-Neustart über das Dashboard-Popup auslösen* (automatische
Neustarts bei Ausfall über `poe.sh` sind davon komplett unabhängig und
laufen immer). Für Zeilen ohne passendes Recht (z.B. „D“ bei Switche/
Zugangsdaten/Benutzer/Gruppen) wird eine ausgegraute, nicht anklickbare
Checkbox angezeigt statt die Zelle wegzulassen:
```
Geräte (gesamt) R
├─ Clients R · W · E · D (D = PoE-Neustart über Dashboard)
├─ Switche R · W · E
└─ Zugangsdaten R · W · E
Logs (gesamt) R
├─ Live R
└─ Änderungen R
Einstellungen (gesamt) R
├─ Benutzer R · W · E
├─ Gruppen R · W · E
├─ Systemeinstellungen R · E
└─ Im-/Export R (Export) · E (Import)
Geräte R W E D ☑ Logs R W E ☑ Einstellungen R W E
Clients ☑ ☑ ☑ ☑ Live ☑ ☑ ☑ Benutzer ☑ ☑ ☑
Switche ☑ ☑ ☑ ▢ Änd. ☑ ☑ ☑ Gruppen ☑ ☑ ☑
Zugangsd. ☑ ☑ ☑ ▢ Systemeinst. ☑ ▢ ☑
Im-/Export ☑ ▢ ☑
```
Das jeweilige „Bereich an/aus“-Recht (`devices_group.view` /
`logs_group.view` / `settings_group.view`, die „(gesamt)“-Zeile) wirkt als
**Kill-Switch**: ist es für eine Gruppe nicht gesetzt, greift kein einziges
Recht darunter mehr — selbst wenn z.B. `devices.view` einzeln noch angehakt
ist. So lässt sich ein ganzer Bereich mit einem Klick sperren, ohne jedes
Unterrecht einzeln zurücknehmen zu müssen (`User.has_permission()` in
`app.py`). Auf der Gruppen-Seite sind die Unterpunkt-Zeilen einer Tabelle per
JavaScript so lange gesperrt (ausgegraut, nicht anklickbar), bis die
„(gesamt)“-Zeile angehakt ist.
Das jeweilige „Bereich sichtbar“-Recht (`devices_group.view` /
`logs_group.view` / `settings_group.view`, das Kästchen in der Kopfzeile
einer Spalte) wirkt als **Kill-Switch**: ist es für eine Gruppe nicht
gesetzt, greift kein einziges Recht darunter mehr — selbst wenn z.B.
`devices.view` einzeln noch angehakt ist. So lässt sich ein ganzer Bereich
mit einem Klick sperren, ohne jedes Unterrecht einzeln zurücknehmen zu
müssen (`User.has_permission()` in `app.py`). Auf der Gruppen-Seite sind
die Unterpunkt-Zeilen einer Spalte per JavaScript so lange gesperrt UND
sichtbar ausgegraut (nicht nur das dezente native disabled-Styling), bis
das Kopfzeilen-Kästchen angehakt ist.
### Systemgruppen