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>
119 lines
5.5 KiB
HTML
119 lines
5.5 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Einstellungen - Busylight{% endblock %}
|
|
|
|
{% block content %}
|
|
<h4 class="mb-4">Einstellungen</h4>
|
|
|
|
{% if request.query_params.get('saved') %}
|
|
<div class="alert alert-success alert-dismissible fade show">
|
|
<i class="bi bi-check-circle"></i> Einstellungen gespeichert.
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<form method="post" action="/api/settings">
|
|
<div class="row g-4">
|
|
<!-- Azure AD -->
|
|
<div class="col-lg-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-microsoft"></i> Azure AD / Microsoft Graph</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Client ID</label>
|
|
<input type="text" name="azure_client_id" class="form-control font-monospace"
|
|
value="{{ settings.azure_client_id }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Client Secret</label>
|
|
<input type="password" name="azure_client_secret" class="form-control font-monospace"
|
|
value="{{ settings.azure_client_secret }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Tenant ID</label>
|
|
<input type="text" name="azure_tenant_id" class="form-control font-monospace"
|
|
value="{{ settings.azure_tenant_id }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Auth Tenant</label>
|
|
<input type="text" name="azure_auth_tenant" class="form-control"
|
|
value="{{ settings.azure_auth_tenant }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Graph Scopes</label>
|
|
<input type="text" name="azure_scopes" class="form-control"
|
|
value="{{ settings.azure_scopes }}">
|
|
</div>
|
|
<div class="border rounded p-3 bg-light">
|
|
{% if authenticated %}
|
|
<i class="bi bi-check-circle text-success"></i>
|
|
<strong class="text-success">Authentifiziert</strong>
|
|
{% else %}
|
|
<i class="bi bi-x-circle text-danger"></i>
|
|
<strong class="text-danger">Nicht authentifiziert</strong>
|
|
<p class="small text-muted mt-2 mb-0">
|
|
Fuehre auf dem Server aus:<br>
|
|
<code>python app.py --auth</code>
|
|
</p>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Polling & AIDA -->
|
|
<div class="col-lg-6">
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-clock"></i> Polling</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Abfrage-Intervall (Sekunden)</label>
|
|
<input type="number" name="poll_interval" class="form-control"
|
|
value="{{ settings.poll_interval }}" min="5" max="300">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="bi bi-file-earmark-spreadsheet"></i> AIDA Zeiterfassung</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">CSV-Pfad</label>
|
|
<input type="text" name="aida_csv_path" class="form-control font-monospace"
|
|
value="{{ settings.aida_csv_path }}"
|
|
placeholder="/mnt/zeiterfassung/Status.csv">
|
|
<small class="text-muted">Auf Linux z.B. via SMB-Mount</small>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status: Anwesend</label>
|
|
<input type="text" name="aida_status_anwesend" class="form-control"
|
|
value="{{ settings.aida_status_anwesend }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status: Abwesend</label>
|
|
<input type="text" name="aida_status_abwesend" class="form-control"
|
|
value="{{ settings.aida_status_abwesend }}">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Status: Homeoffice</label>
|
|
<input type="text" name="aida_status_homeoffice" class="form-control"
|
|
value="{{ settings.aida_status_homeoffice }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="bi bi-check-lg"></i> Einstellungen speichern
|
|
</button>
|
|
</div>
|
|
</form>
|
|
{% endblock %}
|