diff --git a/djangorota/djangorota/templates/rota/partials/leave_form_modal.html b/djangorota/djangorota/templates/rota/partials/leave_form_modal.html new file mode 100644 index 0000000..c22bec0 --- /dev/null +++ b/djangorota/djangorota/templates/rota/partials/leave_form_modal.html @@ -0,0 +1,22 @@ +{% load crispy_forms_tags %} + diff --git a/djangorota/djangorota/templates/rota/partials/worker_form_modal.html b/djangorota/djangorota/templates/rota/partials/worker_form_modal.html index 2005314..abd0496 100644 --- a/djangorota/djangorota/templates/rota/partials/worker_form_modal.html +++ b/djangorota/djangorota/templates/rota/partials/worker_form_modal.html @@ -20,6 +20,19 @@ {% include 'rota/partials/worker_token_area.html' with worker=worker token_link=token_link %} {% endif %} + {% if worker %} +
+

Leaves

+
+ {% include 'rota/partials/leave_list.html' with leaves=worker.leaves.all token=None %} +
+
+ Open full page + +
+
+ {% endif %} +

Non-working days

diff --git a/djangorota/djangorota/templates/rota/partials/worker_list.html b/djangorota/djangorota/templates/rota/partials/worker_list.html index 0bfdd34..e12c1ed 100644 --- a/djangorota/djangorota/templates/rota/partials/worker_list.html +++ b/djangorota/djangorota/templates/rota/partials/worker_list.html @@ -6,7 +6,7 @@
  • - {{ w.name }} + {{ w.name }} — {{ w.site }}{% if w.grade %} · grade {{ w.grade }}{% endif %} · FTE {{ w.fte }} {# show non-working days stored in options.nwds if present; render JSON safely and let JS format it #} {% if w.options.nwds %} @@ -38,9 +38,10 @@
    {% endif %}
    -
    - - +
    + + Leave +
  • diff --git a/djangorota/djangorota/templates/rota/partials/worker_overview_modal.html b/djangorota/djangorota/templates/rota/partials/worker_overview_modal.html new file mode 100644 index 0000000..4b55a30 --- /dev/null +++ b/djangorota/djangorota/templates/rota/partials/worker_overview_modal.html @@ -0,0 +1,58 @@ +{% load crispy_forms_tags %} + diff --git a/djangorota/rota/urls.py b/djangorota/rota/urls.py index 3e83254..3255787 100644 --- a/djangorota/rota/urls.py +++ b/djangorota/rota/urls.py @@ -14,7 +14,9 @@ urlpatterns = [ path("rota//edit/", views.rota_edit, name="rota_edit"), path("worker/add/", views.worker_create, name="worker_add"), path("worker///edit/", views.worker_edit, name="worker_edit"), + path("worker///overview/", views.worker_overview, name="worker_overview"), path("worker///delete/", views.worker_delete, name="worker_delete"), + path("worker//leave/add/", views.worker_leave_add, name="worker_leave_add"), path("worker//", views.worker_detail, name="worker_detail"), path("worker//leaves.json", views.leaves_json, name="worker_leaves_json"), path("leave/request/", views.request_leave, name="request_leave"), diff --git a/djangorota/rota/views.py b/djangorota/rota/views.py index 607786e..19afde7 100644 --- a/djangorota/rota/views.py +++ b/djangorota/rota/views.py @@ -14,6 +14,7 @@ from django.http import JsonResponse from django.views.decorators.http import require_POST from django.shortcuts import HttpResponseRedirect import traceback + def _get_constraint_description(key: str): @@ -345,6 +346,58 @@ def worker_detail(request, worker_id): return render(request, "rota/worker_detail.html", {"worker": worker, "form": form, "leaves": leaves, "leaves_json": leaves_json}) +@require_http_methods(["GET", "POST"]) +def worker_leave_add(request, worker_id): + """HTMX endpoint: show a leave form modal for a worker, or create the leave on POST.""" + worker = get_object_or_404(Worker, pk=worker_id) + is_hx = request.headers.get("HX-Request", "false").lower() == "true" + + if request.method == "POST": + form = LeaveForm(request.POST) + if form.is_valid(): + leave = form.save(commit=False) + leave.worker = worker + leave.save() + if is_hx: + # Close modal and optionally trigger an update; leave list can be refreshed separately + response = HttpResponse("") + response["HX-Trigger"] = "closeModal" + return response + return redirect("rota:worker_detail", worker_id=worker.id) + + + + # invalid: return modal with errors + if is_hx: + modal_html = render_to_string("rota/partials/leave_form_modal.html", {"form": form, "worker": worker, "form_action": request.path}, request=request) + return HttpResponse(modal_html) + # non-HTMX fallthrough + # GET: render modal partial + form = LeaveForm() + if is_hx: + modal_html = render_to_string("rota/partials/leave_form_modal.html", {"form": form, "worker": worker, "form_action": request.path}, request=request) + return HttpResponse(modal_html) + return redirect("rota:worker_detail", worker_id=worker.id) + + +@require_http_methods(["GET"]) +def worker_overview(request, rota_id, worker_id): + """Return a read-only modal overview of the worker (HTMX GET).""" + rota = get_object_or_404(RotaSchedule, pk=rota_id) + worker = get_object_or_404(Worker, pk=worker_id) + try: + pretty_options = json.dumps(worker.options or {}, indent=2, default=str) + except Exception: + pretty_options = str(worker.options or {}) + + modal_html = render_to_string( + "rota/partials/worker_overview_modal.html", + {"worker": worker, "rota": rota, "pretty_options": pretty_options}, + request=request, + ) + return HttpResponse(modal_html) + + @require_http_methods(["GET", "POST"]) def worker_edit(request, rota_id, worker_id): rota = get_object_or_404(RotaSchedule, pk=rota_id)