Make ending sessions faster #71
|
@ -3,6 +3,7 @@
|
|||
## Improved
|
||||
* game overview: improve how editions and purchases are displayed
|
||||
* add purchase: only allow choosing purchases of selected edition
|
||||
* session list: clicking the "End now?" link is not much faster
|
||||
|
||||
## 1.5.1 / 2023-11-14 21:10+01:00
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{% load django_htmx %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{% load static %}
|
||||
|
@ -12,6 +13,7 @@
|
|||
{% endblock title %}
|
||||
</title>
|
||||
<script src="{% static 'js/htmx.min.js' %}"></script>
|
||||
{% django_htmx_script %}
|
||||
<link rel="stylesheet" href="{% static 'base.css' %}" />
|
||||
</head>
|
||||
<body class="dark" hx-indicator="#indicator">
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
{% if dataset.count >= 1 %}
|
||||
<div class="mx-auto text-center my-4">
|
||||
<a id="last-session-start"
|
||||
href="{% url 'start_session_same_as_last' last.id %}"
|
||||
hx-get="{% url 'start_session_same_as_last' last.id %}"
|
||||
hx-swap="afterbegin"
|
||||
hx-target=".responsive-table tbody"
|
||||
hx-select=".responsive-table tbody tr:first-child"
|
||||
onClick="document.querySelector('#last-session-start').classList.add('invisible')"
|
||||
class="{% if last.timestamp_end == null %}invisible{% endif %}">
|
||||
href="{% url 'start_session_same_as_last' last.id %}"
|
||||
hx-get="{% url 'start_session_same_as_last' last.id %}"
|
||||
hx-swap="afterbegin"
|
||||
hx-target=".responsive-table tbody"
|
||||
hx-select=".responsive-table tbody tr:first-child"
|
||||
onClick="document.querySelector('#last-session-start').classList.add('invisible')"
|
||||
class="{% if last.timestamp_end == null %}invisible{% endif %}">
|
||||
{% include 'components/button_start.html' with text=last.purchase title="Start session of last played game" only %}
|
||||
</a>
|
||||
</div>
|
||||
|
@ -29,36 +29,37 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for data in dataset %}
|
||||
<tr>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 purchase-name truncate max-w-20char md:max-w-40char">
|
||||
<a class="underline decoration-slate-500 sm:decoration-2"
|
||||
href="{% url 'view_game' data.purchase.edition.game.id %}">
|
||||
{{ data.purchase.edition }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden sm:table-cell">
|
||||
{{ data.timestamp_start | date:"d/m/Y H:i" }}
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden lg:table-cell">
|
||||
{% if data.unfinished %}
|
||||
<a href="{% url 'update_session' data.id %}"
|
||||
hx-get="{% url 'update_session' data.id %}"
|
||||
hx-swap="outerHTML"
|
||||
hx-target=".responsive-table tbody tr:first-child"
|
||||
hx-select=".responsive-table tbody tr:first-child"
|
||||
hx-indicator="#indicator"
|
||||
onClick="document.querySelector('#last-session-start').classList.remove('invisible')">
|
||||
<span class="text-yellow-300">Finish now?</span>
|
||||
</a>
|
||||
{% elif data.duration_manual %}
|
||||
--
|
||||
{% else %}
|
||||
{{ data.timestamp_end | date:"d/m/Y H:i" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ data.duration_formatted }}</td>
|
||||
</tr>
|
||||
{% for session in dataset %}
|
||||
{% partialdef session-row inline=True %}
|
||||
<tr>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 purchase-name truncate max-w-20char md:max-w-40char">
|
||||
<a class="underline decoration-slate-500 sm:decoration-2"
|
||||
href="{% url 'view_game' session.purchase.edition.game.id %}">
|
||||
{{ session.purchase.edition }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden sm:table-cell">
|
||||
{{ session.timestamp_start | date:"d/m/Y H:i" }}
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden lg:table-cell">
|
||||
{% if session.unfinished %}
|
||||
<a href="{% url 'update_session' session.id %}"
|
||||
hx-get="{% url 'update_session' session.id %}"
|
||||
hx-target="closest tr"
|
||||
hx-swap="outerHTML"
|
||||
hx-indicator="#indicator"
|
||||
onClick="document.querySelector('#last-session-start').classList.remove('invisible')">
|
||||
<span class="text-yellow-300">Finish now?</span>
|
||||
</a>
|
||||
{% elif session.duration_manual %}
|
||||
--
|
||||
{% else %}
|
||||
{{ session.timestamp_end | date:"d/m/Y H:i" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ session.duration_formatted }}</td>
|
||||
</tr>
|
||||
{% endpartialdef %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.http import (
|
|||
from django.shortcuts import redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from common.time import format_duration
|
||||
from common.utils import safe_division
|
||||
|
@ -74,9 +75,12 @@ def add_session(request, purchase_id=None):
|
|||
|
||||
|
||||
def update_session(request, session_id=None):
|
||||
session = Session.objects.get(id=session_id)
|
||||
session = get_object_or_404(Session, id=session_id)
|
||||
session.finish_now()
|
||||
session.save()
|
||||
if request.htmx:
|
||||
context = {"session": session}
|
||||
return render(request, "list_sessions.html#session-row", context)
|
||||
return redirect("list_sessions")
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aniso8601"
|
||||
|
@ -172,6 +172,39 @@ files = [
|
|||
[package.dependencies]
|
||||
Django = ">=3.2"
|
||||
|
||||
[[package]]
|
||||
name = "django-htmx"
|
||||
version = "1.17.2"
|
||||
description = "Extensions for using Django with htmx."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "django-htmx-1.17.2.tar.gz", hash = "sha256:4089f2ed38727e9846c2f4cd1daddf6b010c7be8d834cfbcffc8c5ecf445c04e"},
|
||||
{file = "django_htmx-1.17.2-py3-none-any.whl", hash = "sha256:f4971432d2ca45dbb31d9b58add1c50ae54354afe4bf59cafd591b1711b502c0"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
asgiref = ">=3.6"
|
||||
Django = ">=3.2"
|
||||
|
||||
[[package]]
|
||||
name = "django-template-partials"
|
||||
version = "23.4"
|
||||
description = "django-template-partials"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "django-template-partials-23.4.tar.gz", hash = "sha256:f762b0b7b2222462df0845f0556792640b769eb832eae218a0e7dadd4e5606cc"},
|
||||
{file = "django_template_partials-23.4-py2.py3-none-any.whl", hash = "sha256:d83d9c2d2836be769919e9aaf394d5feb1ac86e1187083030398308070122fca"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
Django = "*"
|
||||
|
||||
[package.extras]
|
||||
docs = ["Sphinx"]
|
||||
tests = ["coverage", "django_coverage_plugin"]
|
||||
|
||||
[[package]]
|
||||
name = "djhtml"
|
||||
version = "1.5.2"
|
||||
|
@ -986,5 +1019,5 @@ watchdog = ["watchdog (>=2.3)"]
|
|||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "e864dc8abf6c84e5bb16ac2aa937c2a70561d15f3e8a1459866b9d6507e8773e"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "4662e73ad621b11cbe5b517ca08aae4cbeb350bfcc855a6c067861942e232d2a"
|
||||
|
|
|
@ -8,11 +8,13 @@ readme = "README.md"
|
|||
packages = [{include = "timetracker"}]
|
||||
|
||||
[tool.poetry.group.main.dependencies]
|
||||
python = "^3.12"
|
||||
python = "^3.11"
|
||||
django = "^4.2.0"
|
||||
gunicorn = "^20.1.0"
|
||||
uvicorn = "^0.20.0"
|
||||
graphene-django = "^3.1.5"
|
||||
django-htmx = "^1.17.2"
|
||||
django-template-partials = "^23.4"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
black = "^22.12.0"
|
||||
|
@ -27,6 +29,7 @@ isort = "^5.11.4"
|
|||
pre-commit = "^3.5.0"
|
||||
django-debug-toolbar = "^4.2.0"
|
||||
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@ INSTALLED_APPS = [
|
|||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"template_partials",
|
||||
"graphene_django",
|
||||
"django_htmx",
|
||||
]
|
||||
|
||||
GRAPHENE = {"SCHEMA": "games.schema.schema"}
|
||||
|
@ -56,6 +58,7 @@ MIDDLEWARE = [
|
|||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
"django_htmx.middleware.HtmxMiddleware",
|
||||
]
|
||||
|
||||
if DEBUG:
|
||||
|
@ -79,6 +82,7 @@ TEMPLATES = [
|
|||
"games.views.model_counts",
|
||||
"games.views.stats_dropdown_year_range",
|
||||
],
|
||||
"builtins": ["template_partials.templatetags.partials"],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue