diff --git a/loko/assets/static/assets/asset_add_modal.js b/loko/assets/static/assets/asset_add_modal.js
index f201b11..3be3477 100644
--- a/loko/assets/static/assets/asset_add_modal.js
+++ b/loko/assets/static/assets/asset_add_modal.js
@@ -20,6 +20,18 @@
const categoriesCache = {};
+ function populateCategorySelectIfEmpty(select, categories) {
+ if (!select || select.options.length > 1 || !categories || categories.length === 0) {
+ return;
+ }
+ categories.forEach(cat => {
+ const option = document.createElement('option');
+ option.value = cat.id;
+ option.textContent = cat.name;
+ select.appendChild(option);
+ });
+ }
+
function initializeForm(form, modalId) {
const thematicCode = form.dataset.thematic;
const categorySelect = form.querySelector('.asset-category-select');
@@ -31,17 +43,22 @@
const submitBtn = form.querySelector(`#${modalId}Submit`);
// Fetch and cache categories for this thematic
- if (thematicCode && !categoriesCache[thematicCode]) {
- fetch(`/assets/${thematicCode}/categories/`)
- .then(response => response.json())
- .then(data => {
- if (data.categories) {
- categoriesCache[thematicCode] = data.categories;
- }
- })
- .catch(error => {
- console.error('Error prefetching categories:', error);
- });
+ if (thematicCode) {
+ if (categoriesCache[thematicCode]) {
+ populateCategorySelectIfEmpty(categorySelect, categoriesCache[thematicCode]);
+ } else {
+ fetch(`/assets/${thematicCode}/categories/`)
+ .then(response => response.json())
+ .then(data => {
+ if (data.categories) {
+ categoriesCache[thematicCode] = data.categories;
+ populateCategorySelectIfEmpty(categorySelect, data.categories);
+ }
+ })
+ .catch(error => {
+ console.error('Error prefetching categories:', error);
+ });
+ }
}
async function onCategoryChange() {
diff --git a/loko/assets/templates/assets/components/add_asset_modal.html b/loko/assets/templates/assets/components/add_asset_modal.html
index 2479f99..b40b4a9 100644
--- a/loko/assets/templates/assets/components/add_asset_modal.html
+++ b/loko/assets/templates/assets/components/add_asset_modal.html
@@ -23,6 +23,12 @@
{% if intervention_id %}
{% endif %}
+ {% if location %}
+
+ {% endif %}
+ {% if structure %}
+
+ {% endif %}
diff --git a/loko/assets/templates/assets/structures_location_detail.html b/loko/assets/templates/assets/structures_location_detail.html
index 17583e0..ecb7e53 100644
--- a/loko/assets/templates/assets/structures_location_detail.html
+++ b/loko/assets/templates/assets/structures_location_detail.html
@@ -382,7 +382,7 @@
{% if can_create_assets %}
-{% include "assets/components/add_asset_modal.html" with modal_id="addAssetLocationModal" thematic_code="structures" location=location %}
+{% include "assets/components/add_asset_modal.html" with modal_id="addAssetLocationModal" thematic_code="structures" location=location categories=categories %}
{% endif %}
{% endblock content%}
diff --git a/loko/assets/tests.py b/loko/assets/tests.py
index 8095d6b..853b0f9 100644
--- a/loko/assets/tests.py
+++ b/loko/assets/tests.py
@@ -374,6 +374,65 @@ class CategoryAllowedModelTest(TestCase):
self.assertFalse(accessory_model["is_model_required"])
+class StructuresLocationDetailAddAssetModalTest(TestCase):
+ def setUp(self):
+ from common.models import Role
+ from assets.models.structures import Structure, StructureLocation
+ from django.contrib.gis.geos import Point
+
+ self.user = User.objects.create_superuser(username="admin_struct", password="password123")
+ self.config = UserConfig.objects.create(user=self.user, is_intern=True)
+ admin_role, _ = Role.objects.get_or_create(name="admin")
+ self.config.roles.add(admin_role)
+
+ self.thematic, _ = Thematic.objects.get_or_create(
+ code="structures",
+ defaults={"name_fr": "Ouvrages d'art", "name_nl": "Kunstwerken"}
+ )
+ UserThematics.objects.create(
+ user_config=self.config,
+ thematic=self.thematic,
+ can_view_assets=True,
+ can_edit_assets=True
+ )
+
+ self.category, _ = AssetCategory.objects.get_or_create(
+ code="TU_BAL_TEST",
+ defaults={
+ "name_fr": "Balisage Test",
+ "name_nl": "Balisage Test NL",
+ "thematic": self.thematic
+ }
+ )
+
+ from django.contrib.gis.geos import MultiPolygon, Polygon
+ poly = Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0)))
+ mpoly = MultiPolygon(poly, srid=3812)
+
+ self.structure = Structure.objects.create(
+ code="OA_TEST_01",
+ name_fr="Pont Test",
+ structure_type="bridge"
+ )
+ self.location = StructureLocation.objects.create(
+ code="LOC_TEST_01",
+ name_fr="Localisation Test",
+ structure=self.structure,
+ geom=mpoly
+ )
+
+ def test_structures_location_detail_contains_categories(self):
+ self.client.force_login(self.user)
+ response = self.client.get(reverse("assets:structures_locations_detail", args=[self.location.id]))
+ self.assertEqual(response.status_code, 200)
+ self.assertIn("categories", response.context)
+ categories_in_context = response.context["categories"]
+ self.assertTrue(any(c.id == self.category.id for c in categories_in_context))
+ self.assertContains(response, "Balisage Test")
+ self.assertContains(response, f'name="location_id" value="{self.location.id}"')
+
+
+
from assets.views.trafficlights import parse_dxf_poles
@tag('slow', 'dxf')
diff --git a/loko/assets/views/structures.py b/loko/assets/views/structures.py
index cc02bdf..a7465c7 100644
--- a/loko/assets/views/structures.py
+++ b/loko/assets/views/structures.py
@@ -621,10 +621,15 @@ def structures_locations_detail(request, location_id):
geom = json.loads(location_geom_4326.geojson) if location_geom_4326 else None
+ # Récupérer les catégories d'assets pour la thématique "structures"
+ categories = list(AssetCategory.objects.filter(thematic__code='structures'))
+ categories.sort(key=lambda m: m.get_name().lower())
+
return render(request, "assets/structures_location_detail.html", {
"location": location,
"interventions": interventions, # toutes les interventions de l'arbre
"assets": assets,
+ "categories": categories,
"main_documents": main_documents,
"other_documents": other_docs,
"add_document_form": StructureDocumentForm(),