From 44da80337e071d34976ff44b65502923c704bed4 Mon Sep 17 00:00:00 2001 From: Victor Andersson Date: Sun, 9 Nov 2025 10:27:43 +0100 Subject: [PATCH] Add client-side filtering for dashboard --- claims/templates/claims/dashboard.html | 109 ++++++++++++++++++++++--- claims/tests.py | 9 ++ claims/views.py | 21 ++++- 3 files changed, 122 insertions(+), 17 deletions(-) diff --git a/claims/templates/claims/dashboard.html b/claims/templates/claims/dashboard.html index ef74129..b44439c 100644 --- a/claims/templates/claims/dashboard.html +++ b/claims/templates/claims/dashboard.html @@ -66,14 +66,20 @@

{% trans "Hantera utlägg" %}

{% trans "Välj status för att fokusera listan nedan." %}

-
+ - {% if claims %} -
- {% for claim in claims %} -
+
+ {% for claim in claims %} +
@@ -231,12 +238,18 @@
- {% endfor %} -
- {% else %} -
-

{% trans "Inga utlägg ännu" %}

-

{% trans "När formuläret tas emot visas posterna automatiskt här." %}

+
+ {% empty %} +
+

{% trans "Inga utlägg ännu" %}

+

{% trans "När formuläret tas emot visas posterna automatiskt här." %}

+
+ {% endfor %} +
+ {% if has_any_claims %} +
+

{% trans "Inga utlägg matchar filtret" %}

+

{% trans "Välj en annan status för att se fler poster." %}

{% endif %}
@@ -292,4 +305,74 @@ + {% endblock %} diff --git a/claims/tests.py b/claims/tests.py index f4d9cd4..bbd0be9 100644 --- a/claims/tests.py +++ b/claims/tests.py @@ -113,3 +113,12 @@ class DashboardViewTests(TestCase): self.assertEqual(summary["pending_count"], 1) self.assertEqual(summary["approved_count"], 2) self.assertEqual(summary["ready_to_pay"], 1) + self.assertTrue(response.context["has_filtered_claims"]) + + response = self.client.get(reverse("claims:admin-list") + "?status=rejected") + self.assertTrue(response.context["has_filtered_claims"]) + + def test_has_filtered_claims_false_when_no_matching_status(self): + self._create_claim(status=Claim.Status.PENDING) + response = self.client.get(reverse("claims:admin-list") + "?status=approved") + self.assertFalse(response.context["has_filtered_claims"]) diff --git a/claims/views.py b/claims/views.py index b4eeabb..d154e42 100644 --- a/claims/views.py +++ b/claims/views.py @@ -149,11 +149,8 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView): queryset = ( Claim.objects.select_related("submitted_by", "project", "paid_by") .prefetch_related("logs__performed_by") - .all() + .order_by("-created_at") ) - status = self.request.GET.get("status") - if status in {choice[0] for choice in Claim.Status.choices}: - queryset = queryset.filter(status=status) return queryset def get_context_data(self, **kwargs): @@ -164,6 +161,8 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView): context["can_change"] = self.request.user.has_perm("claims.change_claim") context["payments_enabled"] = getattr(settings, "CLAIMS_ENABLE_INTERNAL_PAYMENTS", False) context["summary"] = self._build_summary() + context["has_any_claims"] = context["summary"]["total_claims"] > 0 + context["has_filtered_claims"] = self._has_filtered_claims(context["status_filter"], context["summary"]) context["recent_claims"] = ( Claim.objects.select_related("project") .prefetch_related("logs__performed_by") @@ -265,6 +264,20 @@ class ClaimDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView): "paid_amount": _sum(approved_qs.filter(paid_at__isnull=False)), } + @staticmethod + def _has_filtered_claims(active_filter, summary): + if active_filter == "all": + return summary["total_claims"] > 0 + key_map = { + Claim.Status.PENDING: "pending_count", + Claim.Status.APPROVED: "approved_count", + Claim.Status.REJECTED: "rejected_count", + } + key = key_map.get(active_filter) + if not key: + return summary["total_claims"] > 0 + return summary.get(key, 0) > 0 + class ClaimExportMenuView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView): template_name = "claims/export_placeholder.html"