Dashboard: Verbindungen insgesamt getrennt von eindeutigen Geräten, Geräte-Übersicht ergänzt

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8BG6rcfV94au1CrMNQq9E
main
Samuel Zielke 3 weeks ago
parent 357ec010d4
commit 4f9f357f9c

@ -42,30 +42,39 @@
</div>
<div class="row g-3 mb-3">
<div class="col-6 col-md-3">
<div class="col-6 col-md-6">
<div class="stat-card text-center">
<div class="stat-value">{{ total_connections }}</div>
<div class="stat-label">Verbindungen insgesamt <small class="text-muted">(alle Pings)</small></div>
</div>
</div>
<div class="col-6 col-md-6">
<div class="stat-card text-center">
<div class="stat-value">{{ unique_devices_total }}</div>
<div class="stat-label">Geräte insgesamt <small class="text-muted">(eindeutig)</small></div>
</div>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-6 col-md-4">
<div class="stat-card text-center">
<div class="stat-value">{{ devices_today }}</div>
<div class="stat-label">Geräte heute</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="col-6 col-md-4">
<div class="stat-card text-center">
<div class="stat-value">{{ devices_7d }}</div>
<div class="stat-label">Geräte (7 Tage)</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="col-6 col-md-4">
<div class="stat-card text-center">
<div class="stat-value">{{ devices_30d }}</div>
<div class="stat-label">Geräte (30 Tage)</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card text-center">
<div class="stat-value">{{ unique_devices_total }}</div>
<div class="stat-label">Geräte insgesamt</div>
</div>
</div>
</div>
<div class="row g-3 mb-3">
@ -107,8 +116,38 @@
</p>
</div>
<div class="stat-card mb-3">
<h5 class="mb-2">Geräte-Übersicht <small class="text-muted">(ein Eintrag pro Gerät, nicht pro Ping)</small></h5>
<div style="overflow-x: auto;">
<table class="table table-sm table-striped mb-0">
<thead>
<tr>
<th>Gerät</th>
<th>Pings</th>
<th>Erster Kontakt</th>
<th>Letzter Kontakt</th>
<th>Standalone</th>
</tr>
</thead>
<tbody>
{% for device in device_summary %}
<tr>
<td><code>{{ device.device_id|slice:":8" }}…</code></td>
<td>{{ device.ping_count }}</td>
<td>{{ device.first_seen|date:"d.m.Y H:i" }}</td>
<td>{{ device.last_seen|date:"d.m.Y H:i" }}</td>
<td>{{ device.standalone_any|yesno:"Ja,Nein" }}</td>
</tr>
{% empty %}
<tr><td colspan="5" class="text-muted">Noch keine Daten</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="stat-card">
<h5 class="mb-2">Letzte Signale</h5>
<h5 class="mb-2">Letzte Signale <small class="text-muted">(roher Ping-Log, ein Gerät kann hier mehrfach auftauchen)</small></h5>
<div style="overflow-x: auto;">
<table class="table table-sm table-striped mb-0">
<thead>

@ -1,7 +1,7 @@
import json
from django.contrib.admin.views.decorators import staff_member_required
from django.db.models import Count
from django.db.models import Count, Max, Min
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse, redirect
from django.utils import timezone
@ -102,6 +102,7 @@ def usage_dashboard(request):
events = UsageEvent.objects.all()
context = {
"total_connections": events.count(),
"unique_devices_total": events.values("device_id").distinct().count(),
"devices_today": events.filter(created_at__gte=today_start).values("device_id").distinct().count(),
"devices_7d": events.filter(created_at__gte=now - timedelta(days=7)).values("device_id").distinct().count(),
@ -109,6 +110,16 @@ def usage_dashboard(request):
"standalone_count": events.filter(is_standalone=True).values("device_id").distinct().count(),
"by_platform": events.values("platform").annotate(count=Count("device_id", distinct=True)).order_by("-count"),
"by_browser": events.values("browser").annotate(count=Count("device_id", distinct=True)).order_by("-count"),
"device_summary": (
events.values("device_id")
.annotate(
ping_count=Count("id"),
first_seen=Min("created_at"),
last_seen=Max("created_at"),
standalone_any=Max("is_standalone"),
)
.order_by("-last_seen")
),
"recent_events": events[:30],
}
return render(request, "app/dashboard.html", context)

Loading…
Cancel
Save

Powered by TurnKey Linux.