Replace the standalone Python script + config.cfg with a full web application featuring: - FastAPI backend with REST API - SQLite database (config, state, activity log separated) - Bootstrap 5 web interface for configuration - Pages: Dashboard, Users, Devices, Assignments, Color Rules, Settings, Log - APScheduler background polling for Teams presence + AIDA status - systemd service file for Linux deployment - Migration script to import existing config.cfg data Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
95 lines
4.2 KiB
HTML
95 lines
4.2 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Benutzer - Busylight{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h4 class="mb-0">Benutzer</h4>
|
|
<form method="post" action="/api/users/sync">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="bi bi-cloud-download"></i> Aus Azure synchronisieren
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
{% if request.query_params.get('synced') %}
|
|
<div class="alert alert-success alert-dismissible fade show">
|
|
<i class="bi bi-check-circle"></i> {{ request.query_params.get('synced') }} neue Benutzer synchronisiert.
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if request.query_params.get('error') == 'not_authenticated' %}
|
|
<div class="alert alert-danger alert-dismissible fade show">
|
|
<i class="bi bi-x-circle"></i> Azure nicht verbunden. Bitte zuerst authentifizieren.
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="card">
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Status</th>
|
|
<th>Name</th>
|
|
<th>E-Mail</th>
|
|
<th>Personal-Nr (AIDA)</th>
|
|
<th>Zuordnung</th>
|
|
<th>Aktionen</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for user in users %}
|
|
<tr class="{% if not user.active %}table-light text-muted{% endif %}">
|
|
<td>
|
|
{% if user.active %}
|
|
<span class="badge bg-success">Aktiv</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary">Inaktiv</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ user.display_name }}</td>
|
|
<td><small>{{ user.email or '-' }}</small></td>
|
|
<td>
|
|
<form method="post" action="/api/users/{{ user.azure_id }}/update" class="d-flex gap-1">
|
|
<input type="text" name="personal_nr" value="{{ user.personal_nr or '' }}"
|
|
class="form-control form-control-sm" style="width: 120px;"
|
|
placeholder="~~00000~~">
|
|
<input type="hidden" name="active" value="{{ '1' if user.active else '0' }}">
|
|
<button type="submit" class="btn btn-sm btn-outline-secondary">
|
|
<i class="bi bi-check"></i>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
<td>
|
|
{% if user.assignment_id %}
|
|
<span class="badge bg-info"><i class="bi bi-link-45deg"></i> Zugeordnet</span>
|
|
{% else %}
|
|
<span class="text-muted">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<form method="post" action="/api/users/{{ user.azure_id }}/toggle" class="d-inline">
|
|
<button type="submit" class="btn btn-sm {% if user.active %}btn-outline-warning{% else %}btn-outline-success{% endif %}">
|
|
{% if user.active %}
|
|
<i class="bi bi-pause-circle"></i>
|
|
{% else %}
|
|
<i class="bi bi-play-circle"></i>
|
|
{% endif %}
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-3 text-muted">
|
|
<small>{{ users|length }} Benutzer insgesamt</small>
|
|
</div>
|
|
{% endblock %}
|