Initial commit: PoE Manager modern UI rebuild
- Neues, eigenständiges Frontend (Sidebar, zentriertes Logo in der Topbar, Dark/Light-Theme, Karten-Dashboard, Toasts/Modals statt Bootstrap) - Oeffentliches Kurz-Dashboard ohne Login (Status-Uebersicht) - Browser-SSH-Terminal (paramiko, plattformunabhaengig) zum Testen von Switch-Zugangsdaten inkl. interaktiver Host-Key-Bestaetigung - Granulares Rechtesystem mit Gruppen (Devices/Switches-Berechtigungen) - Aufgeraeumtes Backend mit konfigurierbaren Pfaden, auto-generierten Secrets statt hart codierter Werte im Original Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
{% extends "base.html" %}
|
||||
{% set active_page = "groups" %}
|
||||
{% block page_title %}Gruppen{% endblock %}
|
||||
{% block page_sub %}<div class="topbar-sub">{{ groups|length }} Gruppen · Rechteverwaltung</div>{% endblock %}
|
||||
{% block topbar_right %}
|
||||
<button type="button" class="btn btn-primary" data-open-modal="addGroupModal">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></svg>
|
||||
Neue Gruppe
|
||||
</button>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<p class="text-faint" style="font-size:12.5px; margin-bottom:18px; max-width:720px;">
|
||||
Admins dürfen immer alles. Über Gruppen lassen sich einzelne Verwaltungsrechte für
|
||||
Devices und Switches gezielt an normale Benutzer vergeben, ohne sie zu Admins zu machen.
|
||||
Ein Benutzer kann mehreren Gruppen angehören — die Rechte addieren sich.
|
||||
</p>
|
||||
|
||||
{% if groups %}
|
||||
<div style="display:flex; flex-direction:column; gap:16px;">
|
||||
{% for g in groups %}
|
||||
<div class="card card-pad">
|
||||
<form method="post">
|
||||
<input type="hidden" name="save_group" value="1">
|
||||
<input type="hidden" name="group_id" value="{{ g.id }}">
|
||||
|
||||
<div class="section-head">
|
||||
<div class="field" style="margin-bottom:0; max-width:280px; flex:1;">
|
||||
<label>Gruppenname</label>
|
||||
<input type="text" name="name" value="{{ g.name }}" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
|
||||
Speichern
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); gap:24px; margin-top:8px;">
|
||||
{% for cat_key, cat in permission_catalog.items() %}
|
||||
<div>
|
||||
<div class="permission-group-title">{{ cat['label'] }}</div>
|
||||
<div class="check-list">
|
||||
{% for key, label in cat['items'].items() %}
|
||||
<label class="check-row">
|
||||
<input type="checkbox" name="permissions" value="{{ key }}" {% if key in g.permissions %}checked{% endif %}>
|
||||
{{ label }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div>
|
||||
<div class="permission-group-title">Mitglieder</div>
|
||||
<div class="check-list" style="max-height:180px; overflow-y:auto; padding-right:4px;">
|
||||
{% for u in all_users %}
|
||||
<label class="check-row">
|
||||
<input type="checkbox" name="members" value="{{ u['id'] }}" {% if u['id'] in g.members %}checked{% endif %}>
|
||||
{{ u['username'] }}
|
||||
</label>
|
||||
{% else %}
|
||||
<p class="text-faint" style="font-size:12px;">Keine Nicht-Admin-Benutzer vorhanden.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="flex" style="justify-content:space-between; align-items:center; margin-top:16px; padding-top:14px; border-top:1px solid var(--border-soft);">
|
||||
<span class="text-faint" style="font-size:12px;">
|
||||
{% if g.member_names %}Mitglieder: {{ g.member_names|join(', ') }}{% else %}Keine Mitglieder{% endif %}
|
||||
</span>
|
||||
<form method="post" data-confirm="Gruppe „{{ g.name }}“ wirklich löschen? Mitglieder verlieren die zugehörigen Rechte.">
|
||||
<input type="hidden" name="delete_group" value="{{ g.id }}">
|
||||
<button type="submit" class="btn btn-sm btn-danger">Gruppe löschen</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="card card-pad" style="text-align:center; color:var(--text-faint);">
|
||||
Noch keine Gruppen angelegt.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Modal: Neue Gruppe -->
|
||||
<div class="modal-overlay" id="addGroupModal">
|
||||
<div class="modal" style="max-width:380px;">
|
||||
<form method="post">
|
||||
<div class="modal-header">
|
||||
<h3>Neue Gruppe</h3>
|
||||
<button type="button" class="modal-close" data-close-modal>×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="add_group" value="1">
|
||||
<div class="field">
|
||||
<label>Name</label>
|
||||
<input type="text" name="name" required placeholder="z.B. Facility-Team">
|
||||
<div class="field-hint">Rechte und Mitglieder werden danach auf der Gruppenkarte eingestellt.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-close-modal>Abbrechen</button>
|
||||
<button type="submit" class="btn btn-primary">Anlegen</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user