Skip to content

Commit

Permalink
feat(dashboard): add time period statistics to dashboard view
Browse files Browse the repository at this point in the history
  • Loading branch information
zyv committed Nov 3, 2023
1 parent c445099 commit 1beda39
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 22 deletions.
55 changes: 46 additions & 9 deletions logbook/templates/logbook/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,64 @@ <h2>Currency status</h2>
</tbody>
</table>

<h2>Aircraft totals</h2>
<h2>Statistics</h2>

<div class="table-responsive">
<table class="table table-striped table-sm table-hover text-center">
<thead>
<tr>
<th rowspan="2">Class</th>
{% for label in period_labels %}
<th colspan="2">{{ label }}</th>
{% endfor %}
</tr>
<tr>
{% for label in period_labels %}
<th><abbr title="Time">⏱️</abbr></th>
<th><abbr title="Landings">🛬</abbr></th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for aircraft_type, type_totals in totals_per_type.items %}
<tr>
<th>{{ aircraft_type }}</th>
{% for totals in type_totals.per_period %}
<td>
<abbr title="{% include "logbook/per_function_item.html" with items=totals.per_function.items only %}">{{ totals.grand.time | duration:"%{h}h %{m}m" }}</abbr>
</td>
<td>
<abbr title="{% include "logbook/per_function_item.html" with items=totals.per_function.items landings=True only %}">{{ totals.grand.landings }}</abbr>
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>

<h2>Totals</h2>

<div class="table-responsive">
<table class="table table-striped table-sm table-hover">
<thead>
<tr>
<th>Type / Registration</th>
<th class="text-end">Total Time</th>
<th class="text-end">Total Landings</th>
<th class="text-end"><abbr title="Total Time">⏱️</abbr></th>
<th class="text-end"><abbr title="Total Landings">🛬</abbr></th>
</tr>
</thead>
<tbody>
{% for aircraft_type, type_totals in totals_per_type.items %}
<tr>
<th>{{ aircraft_type.value }}</th>
<th class="text-end">
<abbr title="{% for key, value in type_totals.per_function.items %}{{ key }}: {{ value.time | duration:"%{h}h %{m}m" }} {% if not forloop.last %} | {% endif %}{% endfor %}">
{{ type_totals.grand.time | duration:"%{h}h %{m}m" }}
<abbr title="{% include "logbook/per_function_item.html" with items=type_totals.per_function.items only %}">
{{ type_totals.grand.time | duration:"%{h}h %{m}m" }}
</abbr>
</th>
<th class="text-end">
<abbr title="{% for key, value in type_totals.per_function.items %}{{ key }}: {{ value.landings }} {% if not forloop.last %} | {% endif %}{% endfor %}">
<abbr title="{% include "logbook/per_function_item.html" with items=type_totals.per_function.items landings=True only %}">
{{ type_totals.grand.landings }}
</abbr>
</th>
Expand All @@ -63,15 +99,16 @@ <h2>Aircraft totals</h2>
<td>
<abbr title="{{ aircraft.maker }} {{ aircraft.model }} ({{ aircraft.icao_designator }})">
{{ aircraft.registration }}
</abbr>{% if aircraft.currency_required %}&nbsp;{% include "logbook/currency_status.html" with currency=aircraft.currency_status %}{% endif %}
</abbr>{% if aircraft.currency_required %}&nbsp;
{% include "logbook/currency_status.html" with currency=aircraft.currency_status %}{% endif %}
</td>
<td class="text-end">
<abbr title="{% for key, value in aircraft_per_function.items %}{{ key }}: {{ value.time | duration:"%{h}h %{m}m" }} {% if not forloop.last %} | {% endif %}{% endfor %}">
<abbr title="{% include "logbook/per_function_item.html" with items=aircraft_per_function.items only %}">
{{ aircraft_totals.time | duration:"%{h}h %{m}m" }}
</abbr>
</td>
<td class="text-end">
<abbr title="{% for key, value in aircraft_per_function.items %}{{ key }}: {{ value.landings }} {% if not forloop.last %} | {% endif %}{% endfor %}">
<abbr title="{% include "logbook/per_function_item.html" with items=aircraft_per_function.items landings=True only %}">
{{ aircraft_totals.landings }}
</abbr>
</td>
Expand Down
5 changes: 5 additions & 0 deletions logbook/templates/logbook/per_function_item.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% spaceless %}
{% load logbook_utils %}

{% for key, value in items %}{{ key }}: {% if landings %}{{ value.landings }}{% else %}{{ value.time | duration:"%{h}h %{m}m" }}{% endif %}{% if not forloop.last %} | {% endif %}{% endfor %}
{% endspaceless %}
51 changes: 38 additions & 13 deletions logbook/views/dashboard.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import UTC, datetime, timedelta

from django.db.models import QuerySet

from ..models import Aircraft, AircraftType, FunctionType, LogEntry
Expand All @@ -20,6 +22,13 @@ def get_context_data(self, *args, **kwargs):
def totals_per_function(log_entries: QuerySet[LogEntry]):
return {function: compute_totals(log_entries.filter(time_function=function)) for function in FunctionType}

now = datetime.now(tz=UTC)
periods = {
"3M": timedelta(days=90),
"6M": timedelta(days=180),
"1Y": timedelta(days=365),
"2Y": timedelta(days=365 * 2),
}
return super().get_context_data(*args, **kwargs) | {
"passenger_currency": {
"sep": {
Expand Down Expand Up @@ -57,20 +66,36 @@ def totals_per_function(log_entries: QuerySet[LogEntry]):
},
"totals_per_type": {
aircraft_type: {
"grand": compute_totals(LogEntry.objects.filter(aircraft__type=aircraft_type.name)),
**{"per_function": totals_per_function(LogEntry.objects.filter(aircraft__type=aircraft_type.name))},
**{
"per_aircraft": [
(
aircraft,
totals_per_function(LogEntry.objects.filter(aircraft=aircraft)),
compute_totals(LogEntry.objects.filter(aircraft=aircraft)),
)
for aircraft in Aircraft.objects.filter(type=aircraft_type.name)
],
},
"grand": compute_totals(LogEntry.objects.filter(aircraft__type=aircraft_type)),
"per_function": totals_per_function(LogEntry.objects.filter(aircraft__type=aircraft_type)),
"per_aircraft": [
(
aircraft,
totals_per_function(LogEntry.objects.filter(aircraft=aircraft)),
compute_totals(LogEntry.objects.filter(aircraft=aircraft)),
)
for aircraft in Aircraft.objects.filter(type=aircraft_type)
],
"per_period": [
{
"per_function": totals_per_function(
LogEntry.objects.filter(
aircraft__type=aircraft_type,
departure_time__gt=now - period_delta,
),
),
"grand": compute_totals(
LogEntry.objects.filter(
aircraft__type=aircraft_type,
departure_time__gt=now - period_delta,
),
),
}
for period_delta in periods.values()
],
}
for aircraft_type in AircraftType
for aircraft_type in reversed(AircraftType)
},
"grand_total": compute_totals(LogEntry.objects.all()),
"period_labels": list(periods.keys()),
}

0 comments on commit 1beda39

Please sign in to comment.