fix(assets): rediriger le fil d'Ariane et retour carte des espaces verts vers la carte unifiée

This commit is contained in:
kdeterme 2026-10-10 13:49:21 +02:00
parent e201a928b8
commit 9af4f99f17
4 changed files with 25 additions and 116 deletions

View file

@ -3,7 +3,7 @@
{% block tab_actions %} {% block tab_actions %}
<li class="nav-item ms-auto"> <li class="nav-item ms-auto">
<a href="{% url 'assets:management_zones_index' %}?thematic=nature" class="btn btn-sm btn-outline-success d-inline-flex align-items-center gap-1 my-1 me-2" title="{% translate 'Gérer les zones de gestion écologique et d'entretien' %}"> <a href="{% url 'assets:management_zones_index' %}?thematic=nature" class="btn btn-sm btn-outline-success d-inline-flex align-items-center gap-1 my-1 me-2" title="{% translate "Gérer les zones de gestion écologique et d'entretien" %}">
<i class="bi bi-diagram-3"></i> <i class="bi bi-diagram-3"></i>
<span>{% translate "Zones de gestion" %}</span> <span>{% translate "Zones de gestion" %}</span>
</a> </a>

View file

@ -56,13 +56,12 @@
<div class="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2"> <div class="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2">
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb mb-0"> <ol class="breadcrumb mb-0">
<li class="breadcrumb-item"><a href="{% url 'assets:nature_index' %}" class="text-decoration-none">{% translate "Nature" %}</a></li> <li class="breadcrumb-item"><a href="{% url 'assets:index' %}?thematic=nature" class="text-decoration-none">{% translate "Nature" %}</a></li>
<li class="breadcrumb-item"><a href="{% url 'assets:nature_locations' %}" class="text-decoration-none">{% translate "Voiries" %}</a></li>
<li class="breadcrumb-item active fw-semibold" aria-current="page">{{ section.code }}</li> <li class="breadcrumb-item active fw-semibold" aria-current="page">{{ section.code }}</li>
</ol> </ol>
</nav> </nav>
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<a href="{% url 'assets:nature_index' %}" class="btn btn-sm btn-outline-secondary"> <a href="{% url 'assets:index' %}?thematic=nature" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-arrow-left me-1"></i>{% translate "Retour à la carte" %} <i class="bi bi-arrow-left me-1"></i>{% translate "Retour à la carte" %}
</a> </a>
{% if section.lon and section.lat %} {% if section.lon and section.lat %}

View file

@ -5665,9 +5665,23 @@ class NatureLocationDetailViewTest(TestCase):
self.assertContains(response, "TR-001") self.assertContains(response, "TR-001")
self.assertContains(response, "SHR-001") self.assertContains(response, "SHR-001")
self.assertContains(response, "BNC-001") self.assertContains(response, "BNC-001")
self.assertContains(response, "Quercus robur")
self.assertContains(response, "layer-switcher-control.js")
self.assertContains(response, "nature_location_detail.js") self.assertContains(response, "nature_location_detail.js")
unified_nature_url = f'{reverse("assets:index")}?thematic=nature'
self.assertContains(response, f'href="{unified_nature_url}"')
self.assertNotContains(response, f'href="{reverse("assets:nature_index")}"')
self.assertNotContains(response, f'href="{reverse("assets:nature_locations")}"')
def test_nature_index_redirects_to_unified_index(self):
self.client.force_login(self.user)
response = self.client.get(reverse('assets:nature_index'))
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'{reverse("assets:index")}?thematic=nature')
def test_nature_locations_redirects_to_unified_index(self):
self.client.force_login(self.user)
response = self.client.get(reverse('assets:nature_locations'))
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'{reverse("assets:index")}?thematic=nature')
def test_nature_locations_detail_view_empty(self): def test_nature_locations_detail_view_empty(self):
empty_loc = NatureLocation.objects.create( empty_loc = NatureLocation.objects.create(

View file

@ -1,4 +1,4 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404, redirect
from django.http import JsonResponse, Http404 from django.http import JsonResponse, Http404
from django.contrib.gis.db.models.functions import Transform from django.contrib.gis.db.models.functions import Transform
from django.contrib.gis.geos import GEOSGeometry, Point, MultiPolygon from django.contrib.gis.geos import GEOSGeometry, Point, MultiPolygon
@ -28,119 +28,15 @@ from interventions.views.drafts import InterventionDraftManager
@check_thematic_access('nature') @check_thematic_access('nature')
def nature_index(request): def nature_index(request):
thematic = 'nature' query_params = request.GET.copy()
lang = get_language() if 'thematic' not in query_params:
query_params['thematic'] = 'nature'
# Get filters from URL return redirect(f"{reverse('assets:index')}?{query_params.urlencode()}")
statuses = request.GET.getlist('status')
highway = request.GET.get('highway') == "1"
selected_categories = request.GET.getlist('category')
selected_models = request.GET.getlist('model')
selected_location_type = request.GET.get('location_type', '')
# Get preventive draft ID (if any) for selecting assets
preventive_draft_id = request.GET.get('preventive_draft_id')
if preventive_draft_id:
drafts = InterventionDraftManager(request.session)
draft_data = drafts.get(preventive_draft_id)
form_data = draft_data.get('form_data', {})
preventive_element_type = form_data.get('type_of_selected_elements')
if preventive_element_type == 'assets':
selected_assets = draft_data.get('assets', []) or []
else:
selected_locations_ids = draft_data.get('locations', [])
thematic_choices_qs = (
UserThematics.objects
.filter(user_config=request.user.config, can_view_assets=True)
.select_related('thematic')
.order_by(f'thematic__{"name_nl" if lang == "nl" else "name_fr"}')
)
thematics = [tc.thematic for tc in thematic_choices_qs]
selected_thematic = {
"code": thematic,
"name": next((t.name for t in thematics if t.code == thematic), None),
"icon": next((t.icon for t in thematics if t.code == thematic), None),
}
categories = list(AssetCategory.objects.filter(thematic__code = 'nature'))
categories.sort(key=lambda m: m.get_name().lower())
category_choices = [(m.id, m.get_name()) for m in categories]
selected_management_types = request.GET.getlist('management_type')
from assets.permissions import get_user_accessible_municipalities
_munis = list(get_user_accessible_municipalities(request.user))
if len(_munis) == 1:
_sm = _munis[0]
_code = str(getattr(_sm, 'niscode', '') or '').strip()
_is_wal = _code[:2] in ('25', '51', '52', '53', '55', '56', '57', '61', '62', '63', '81', '82', '83', '84', '85', '91', '92', '93') or (_code and _code[0] in ('5', '6', '8', '9')) or 'court-saint' in (_sm.name_fr or '').lower()
_is_vlg = (_code and _code[0] in ('1', '3', '4', '7')) or _code[:2] in ('23', '24')
if _is_wal:
_reg_lbl = _("Régional (Région wallonne)")
elif _is_vlg:
_reg_lbl = _("Régional (Région flamande)")
else:
_reg_lbl = _("Régional (Bruxelles Mobilité)")
management_type_choices = [
('municipal', _("Communal (%(name)s)") % {'name': _sm.name}),
('regional', _reg_lbl),
('community', _("Intercommunal / Communautaire")),
('private', _("Privé / Conventionné")),
]
else:
management_type_choices = [
('municipal', _("Communal (Commune)")),
('regional', _("Régional (Région / Bruxelles Mobilité)")),
('community', _("Intercommunal / Communautaire")),
('private', _("Privé / Conventionné")),
]
models = list(NatureAssetModel.objects.all())
models.sort(key=lambda m: (m.get_name() or "").lower())
model_choices = [(m.id, m.get_name()) for m in models]
category_model_map = defaultdict(list)
models = NatureAssetModel.objects.all()
for model in models:
if model.category:
display_name = model.get_name()
category_model_map[str(model.category_id)].append({
"key": str(model.id),
"label": display_name,
})
context = {
'thematics': thematics,
'category_choices': category_choices,
'model_choices': model_choices,
'category_model_map': dict(category_model_map),
'selected_thematic': selected_thematic,
'management_type_choices': management_type_choices,
'selected_management_types': selected_management_types,
'selected_statuses': statuses,
'selected_categories': selected_categories,
'selected_models': selected_models,
'highway': highway,
'selected_location_type': selected_location_type,
'preventive_draft_id': preventive_draft_id,
'preventive_element_type': preventive_element_type if 'preventive_element_type' in locals() else '',
'selected_locations_ids': selected_locations_ids if 'selected_locations_ids' in locals() else [],
"selected_assets_json": json.dumps(selected_assets) if 'selected_assets' in locals() else [],
'locations_tab_title': _("Voiries"),
'locations_assets_title': "Assets",
}
return render(request, "assets/nature_index.html", context)
def nature_locations(request): def nature_locations(request):
pass return redirect(f"{reverse('assets:index')}?thematic=nature")
@check_thematic_access('nature') @check_thematic_access('nature')