Compare commits

...

2 Commits

Author SHA1 Message Date
Lukáš Kucharczyk 0cf3411f63
Make ending session from session list faster
Django CI/CD / test (push) Successful in 1m16s Details
Django CI/CD / build-and-push (push) Successful in 1m40s Details
2024-01-10 15:12:45 +01:00
Lukáš Kucharczyk aa669710e1
Change update_session to template partial
Django CI/CD / test (push) Failing after 1m3s Details
Django CI/CD / build-and-push (push) Has been skipped Details
2024-01-10 14:10:13 +01:00
7 changed files with 90 additions and 42 deletions

View File

@ -3,6 +3,7 @@
## Improved ## Improved
* game overview: improve how editions and purchases are displayed * game overview: improve how editions and purchases are displayed
* add purchase: only allow choosing purchases of selected edition * 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.5.1 / 2023-11-14 21:10+01:00

View File

@ -1,3 +1,4 @@
{% load django_htmx %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
{% load static %} {% load static %}
@ -12,6 +13,7 @@
{% endblock title %} {% endblock title %}
</title> </title>
<script src="{% static 'js/htmx.min.js' %}"></script> <script src="{% static 'js/htmx.min.js' %}"></script>
{% django_htmx_script %}
<link rel="stylesheet" href="{% static 'base.css' %}" /> <link rel="stylesheet" href="{% static 'base.css' %}" />
</head> </head>
<body class="dark" hx-indicator="#indicator"> <body class="dark" hx-indicator="#indicator">

View File

@ -7,13 +7,13 @@
{% if dataset.count >= 1 %} {% if dataset.count >= 1 %}
<div class="mx-auto text-center my-4"> <div class="mx-auto text-center my-4">
<a id="last-session-start" <a id="last-session-start"
href="{% url 'start_session_same_as_last' last.id %}" href="{% url 'start_session_same_as_last' last.id %}"
hx-get="{% url 'start_session_same_as_last' last.id %}" hx-get="{% url 'start_session_same_as_last' last.id %}"
hx-swap="afterbegin" hx-swap="afterbegin"
hx-target=".responsive-table tbody" hx-target=".responsive-table tbody"
hx-select=".responsive-table tbody tr:first-child" hx-select=".responsive-table tbody tr:first-child"
onClick="document.querySelector('#last-session-start').classList.add('invisible')" onClick="document.querySelector('#last-session-start').classList.add('invisible')"
class="{% if last.timestamp_end == null %}invisible{% endif %}"> 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 %} {% include 'components/button_start.html' with text=last.purchase title="Start session of last played game" only %}
</a> </a>
</div> </div>
@ -29,36 +29,37 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for data in dataset %} {% for session in dataset %}
<tr> {% partialdef session-row inline=True %}
<td class="px-2 sm:px-4 md:px-6 md:py-2 purchase-name truncate max-w-20char md:max-w-40char"> <tr>
<a class="underline decoration-slate-500 sm:decoration-2" <td class="px-2 sm:px-4 md:px-6 md:py-2 purchase-name truncate max-w-20char md:max-w-40char">
href="{% url 'view_game' data.purchase.edition.game.id %}"> <a class="underline decoration-slate-500 sm:decoration-2"
{{ data.purchase.edition }} href="{% url 'view_game' session.purchase.edition.game.id %}">
</a> {{ session.purchase.edition }}
</td> </a>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden sm:table-cell"> </td>
{{ data.timestamp_start | date:"d/m/Y H:i" }} <td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden sm:table-cell">
</td> {{ session.timestamp_start | date:"d/m/Y H:i" }}
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden lg:table-cell"> </td>
{% if data.unfinished %} <td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono hidden lg:table-cell">
<a href="{% url 'update_session' data.id %}" {% if session.unfinished %}
hx-get="{% url 'update_session' data.id %}" <a href="{% url 'update_session' session.id %}"
hx-swap="outerHTML" hx-get="{% url 'update_session' session.id %}"
hx-target=".responsive-table tbody tr:first-child" hx-target="closest tr"
hx-select=".responsive-table tbody tr:first-child" hx-swap="outerHTML"
hx-indicator="#indicator" hx-indicator="#indicator"
onClick="document.querySelector('#last-session-start').classList.remove('invisible')"> onClick="document.querySelector('#last-session-start').classList.remove('invisible')">
<span class="text-yellow-300">Finish now?</span> <span class="text-yellow-300">Finish now?</span>
</a> </a>
{% elif data.duration_manual %} {% elif session.duration_manual %}
-- --
{% else %} {% else %}
{{ data.timestamp_end | date:"d/m/Y H:i" }} {{ session.timestamp_end | date:"d/m/Y H:i" }}
{% endif %} {% endif %}
</td> </td>
<td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ data.duration_formatted }}</td> <td class="px-2 sm:px-4 md:px-6 md:py-2 font-mono">{{ session.duration_formatted }}</td>
</tr> </tr>
{% endpartialdef %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>

View File

@ -13,6 +13,7 @@ from django.http import (
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.shortcuts import get_object_or_404
from common.time import format_duration from common.time import format_duration
from common.utils import safe_division from common.utils import safe_division
@ -74,9 +75,12 @@ def add_session(request, purchase_id=None):
def update_session(request, session_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.finish_now()
session.save() session.save()
if request.htmx:
context = {"session": session}
return render(request, "list_sessions.html#session-row", context)
return redirect("list_sessions") return redirect("list_sessions")

39
poetry.lock generated
View File

@ -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]] [[package]]
name = "aniso8601" name = "aniso8601"
@ -172,6 +172,39 @@ files = [
[package.dependencies] [package.dependencies]
Django = ">=3.2" 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]] [[package]]
name = "djhtml" name = "djhtml"
version = "1.5.2" version = "1.5.2"
@ -986,5 +1019,5 @@ watchdog = ["watchdog (>=2.3)"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.12" python-versions = "^3.11"
content-hash = "e864dc8abf6c84e5bb16ac2aa937c2a70561d15f3e8a1459866b9d6507e8773e" content-hash = "4662e73ad621b11cbe5b517ca08aae4cbeb350bfcc855a6c067861942e232d2a"

View File

@ -8,11 +8,13 @@ readme = "README.md"
packages = [{include = "timetracker"}] packages = [{include = "timetracker"}]
[tool.poetry.group.main.dependencies] [tool.poetry.group.main.dependencies]
python = "^3.12" python = "^3.11"
django = "^4.2.0" django = "^4.2.0"
gunicorn = "^20.1.0" gunicorn = "^20.1.0"
uvicorn = "^0.20.0" uvicorn = "^0.20.0"
graphene-django = "^3.1.5" graphene-django = "^3.1.5"
django-htmx = "^1.17.2"
django-template-partials = "^23.4"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
black = "^22.12.0" black = "^22.12.0"
@ -27,6 +29,7 @@ isort = "^5.11.4"
pre-commit = "^3.5.0" pre-commit = "^3.5.0"
django-debug-toolbar = "^4.2.0" django-debug-toolbar = "^4.2.0"
[tool.isort] [tool.isort]
profile = "black" profile = "black"

View File

@ -38,7 +38,9 @@ INSTALLED_APPS = [
"django.contrib.sessions", "django.contrib.sessions",
"django.contrib.messages", "django.contrib.messages",
"django.contrib.staticfiles", "django.contrib.staticfiles",
"template_partials",
"graphene_django", "graphene_django",
"django_htmx",
] ]
GRAPHENE = {"SCHEMA": "games.schema.schema"} GRAPHENE = {"SCHEMA": "games.schema.schema"}
@ -56,6 +58,7 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware", "django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware",
"django_htmx.middleware.HtmxMiddleware",
] ]
if DEBUG: if DEBUG:
@ -79,6 +82,7 @@ TEMPLATES = [
"games.views.model_counts", "games.views.model_counts",
"games.views.stats_dropdown_year_range", "games.views.stats_dropdown_year_range",
], ],
"builtins": ["template_partials.templatetags.partials"],
}, },
}, },
] ]