From 30051938d583f1a0f164a618709eebe9b58cc038 Mon Sep 17 00:00:00 2001 From: kdeterme Date: Mon, 12 Oct 2026 13:42:21 +0200 Subject: [PATCH] feat: add dynamic active tab management and URL query param support for warehouse index view --- .../templates/stock/warehouses_index.html | 39 ++++++++++++------- loko/stock/tests.py | 20 ++++++++++ loko/stock/views.py | 9 +++++ 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/loko/stock/templates/stock/warehouses_index.html b/loko/stock/templates/stock/warehouses_index.html index 60853e8..725d23a 100644 --- a/loko/stock/templates/stock/warehouses_index.html +++ b/loko/stock/templates/stock/warehouses_index.html @@ -96,21 +96,21 @@
-
+
@@ -126,7 +126,7 @@
-
+
-
+
{% if can_manage_products %}
@@ -274,7 +274,7 @@ {#
...
#} -
+
{% if can_manage_products %}
@@ -284,7 +284,7 @@ {% endif %}
- +
@@ -446,14 +446,27 @@ document.querySelectorAll('#tablesTab button[data-bs-toggle="tab"]').forEach(function(btn) { btn.addEventListener('shown.bs.tab', function() { const tabName = btn.id.replace('-table-tab', ''); - history.replaceState(null, '', '?tab=' + tabName); + const currentUrl = new URL(window.location.href); + if (currentUrl.searchParams.get('tab') !== tabName) { + if (tabName === 'serialized-items') { + currentUrl.searchParams.set('tab', tabName); + } else { + currentUrl.search = '?tab=' + tabName; + } + history.replaceState(null, '', currentUrl.pathname + currentUrl.search); + } }); }); // Activer l'onglet indiqué par ?tab= au chargement de la page - const tab = new URLSearchParams(window.location.search).get('tab'); + const urlParams = new URLSearchParams(window.location.search); + let tab = urlParams.get('tab'); + if (!tab && (urlParams.get('si_q') || urlParams.get('si_product') || urlParams.get('si_status'))) { + tab = 'serialized-items'; + } if (tab) { - const tabBtn = document.getElementById(tab + '-table-tab'); + const normalizedTab = tab.replace(/-table$/, ''); + const tabBtn = document.getElementById(normalizedTab + '-table-tab') || document.getElementById(tab + '-table-tab'); if (tabBtn) { tabBtn.click(); tabBtn.blur(); diff --git a/loko/stock/tests.py b/loko/stock/tests.py index 4fddad9..9c71da9 100644 --- a/loko/stock/tests.py +++ b/loko/stock/tests.py @@ -1162,6 +1162,26 @@ class ProductLocationsTests(TestCase): self.assertContains(response, "SN-MOB-TEST") self.assertContains(response, "editItemMobileModal") + def test_warehouses_index_serialized_items_tab_active(self): + response = self.client.get(reverse("stock:warehouses") + "?tab=serialized-items") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["active_tab"], "serialized-items") + + def test_warehouses_index_serialized_items_table_legacy_tab_active(self): + response = self.client.get(reverse("stock:warehouses") + "?tab=serialized-items-table") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["active_tab"], "serialized-items") + + def test_warehouses_index_filter_by_query_activates_serialized_items_tab(self): + response = self.client.get(reverse("stock:warehouses") + "?si_q=makita") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["active_tab"], "serialized-items") + + def test_warehouses_index_default_tab_is_warehouses(self): + response = self.client.get(reverse("stock:warehouses")) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context["active_tab"], "warehouses") + class AssociateStockLocationsCommandTests(TestCase): def setUp(self): diff --git a/loko/stock/views.py b/loko/stock/views.py index fc7a66c..5d52a1c 100644 --- a/loko/stock/views.py +++ b/loko/stock/views.py @@ -100,6 +100,14 @@ def warehouses_index(request): si_query = request.GET.get("si_q", "").strip() si_product_id = request.GET.get("si_product", "").strip() si_status = request.GET.get("si_status", "").strip() + tab_param = request.GET.get("tab", "").strip() + + if tab_param in ("serialized-items", "serialized-items-table") or (not tab_param and (si_query or si_product_id or si_status)): + active_tab = "serialized-items" + elif tab_param in ("products", "warehouse-locations", "warehouses"): + active_tab = tab_param + else: + active_tab = "warehouses" serialized_items_qs = SerializedItem.objects.select_related( "product", "current_location__warehouse", "current_holder" @@ -129,6 +137,7 @@ def warehouses_index(request): "si_product_id": si_product_id, "si_status": si_status, "si_status_choices": SerializedItem.STATUS_CHOICES, + "active_tab": active_tab, } return render(request, "stock/warehouses_index.html", context)