diff --git a/core/static/core/liens_libres.css b/core/static/core/liens_libres.css index 0a89fac..ccdbda0 100644 --- a/core/static/core/liens_libres.css +++ b/core/static/core/liens_libres.css @@ -1,5 +1,3 @@ .fiche-detail__liens { grid-column: span 3; - background-color: var(--fiche-detail-bloc-background-color); - padding: var(--fiche-detail-bloc-padding); } \ No newline at end of file diff --git a/sv/static/sv/common.css b/sv/static/sv/common.css new file mode 100644 index 0000000..9646179 --- /dev/null +++ b/sv/static/sv/common.css @@ -0,0 +1,14 @@ +.fiche-action { + display: flex; +} + +.fiche-action .fr-translate__btn { + line-height: 1.5rem; + min-height: 2.5rem; + padding: .5rem 1rem; +} + +.fiche-action .fr-translate .fr-translate__btn::before { + -webkit-mask-image: url(../../../static/icons/system/add-line.svg); + mask-image: url(../../../static/icons/system/add-line.svg); +} diff --git a/sv/static/sv/fichedetection_detail.css b/sv/static/sv/fichedetection_detail.css index 0723ff2..96f6918 100644 --- a/sv/static/sv/fichedetection_detail.css +++ b/sv/static/sv/fichedetection_detail.css @@ -35,21 +35,6 @@ main{ } -.fiche-action { - display: flex; -} - -.fiche-action .fr-translate__btn { - line-height: 1.5rem; - min-height: 2.5rem; - padding: .5rem 1rem; -} - -.fiche-action .fr-translate .fr-translate__btn::before { - -webkit-mask-image: url(../../../static/icons/system/add-line.svg); - mask-image: url(../../../static/icons/system/add-line.svg); -} - /* Bloc Informations */ .fiche-detail__informations{ grid-column: span 3; diff --git a/sv/static/sv/fichezone_detail.js b/sv/static/sv/fichezone_detail.js new file mode 100644 index 0000000..01f055f --- /dev/null +++ b/sv/static/sv/fichezone_detail.js @@ -0,0 +1,8 @@ +document.addEventListener('DOMContentLoaded', function() { + new Choices(document.getElementById('id_object_choice'), { + classNames: { + containerInner: 'fr-select', + }, + itemSelectText: '' + }); +}); diff --git a/sv/templates/sv/_action_navigation.html b/sv/templates/sv/_detection_action_navigation.html similarity index 100% rename from sv/templates/sv/_action_navigation.html rename to sv/templates/sv/_detection_action_navigation.html diff --git a/sv/templates/sv/_lienlibre_modal.html b/sv/templates/sv/_lienlibre_modal.html index 73f8e2a..350603d 100644 --- a/sv/templates/sv/_lienlibre_modal.html +++ b/sv/templates/sv/_lienlibre_modal.html @@ -14,7 +14,7 @@

{{ free_link_form.as_dsfr_div }} {% csrf_token %} - +
diff --git a/sv/templates/sv/_list_free_links.html b/sv/templates/sv/_list_free_links.html new file mode 100644 index 0000000..5f607a0 --- /dev/null +++ b/sv/templates/sv/_list_free_links.html @@ -0,0 +1,13 @@ +
+

Liens libres

+ {% for link in free_links_list %} + {% if link.related_object_1 == fiche and not link.related_object_2.is_deleted %} + {{ link.related_object_2 }} + {% endif %} + {% if link.related_object_2 == fiche and not link.related_object_1.is_deleted %} + {{ link.related_object_1 }} + {% endif %} + {% empty %} +

Pas de liens pour cette fiche.

+ {% endfor %} +
\ No newline at end of file diff --git a/sv/templates/sv/_zone_action_navigation.html b/sv/templates/sv/_zone_action_navigation.html new file mode 100644 index 0000000..cca728e --- /dev/null +++ b/sv/templates/sv/_zone_action_navigation.html @@ -0,0 +1,11 @@ + diff --git a/sv/templates/sv/fichedetection_detail.html b/sv/templates/sv/fichedetection_detail.html index 36534c0..6028bec 100644 --- a/sv/templates/sv/fichedetection_detail.html +++ b/sv/templates/sv/fichedetection_detail.html @@ -4,6 +4,7 @@ {% load etat_tags %} {% block extrahead %} + {% endblock %} @@ -44,8 +45,8 @@

Fiche détection n° {{ fichedetection.numero }} - {% include "sv/_action_navigation.html" %} - {% include "sv/_lienlibre_modal.html" %} + {% include "sv/_detection_action_navigation.html" %} + {% include "sv/_lienlibre_modal.html" with fiche=fichedetection %} {% include "sv/_delete_fiche_modal.html" %} {% include "sv/_fichedetection_cloturer_modal.html" %} {% if can_update_visibilite %} @@ -205,19 +206,7 @@

Mesures de gestion

-
-

Liens libres

- {% for link in free_links_list %} - {% if link.related_object_1 == fichedetection and not link.related_object_2.is_deleted %} - {{ link.related_object_2 }} - {% endif %} - {% if link.related_object_2 == fichedetection and not link.related_object_1.is_deleted %} - {{ link.related_object_1 }} - {% endif %} - {% empty %} -

Pas de liens pour cette fiche.

- {% endfor %} -
+ {% include "sv/_list_free_links.html" with fiche=fichedetection %} {% include "sv/_fichedetection_synthese.html" %} diff --git a/sv/templates/sv/fichezonedelimitee_detail.html b/sv/templates/sv/fichezonedelimitee_detail.html index bf67ea0..c000b17 100644 --- a/sv/templates/sv/fichezonedelimitee_detail.html +++ b/sv/templates/sv/fichezonedelimitee_detail.html @@ -4,9 +4,14 @@ {% load remove_trailing_zero %} {% block extrahead %} + {% endblock %} +{% block scripts %} + +{% endblock %} + {% block content %}
@@ -14,27 +19,10 @@

Fiche zone délimitée n° {{ fiche.numero }}

-
    -
  • - -
  • -
  • - -
  • -
+
+ {% include "sv/_zone_action_navigation.html" %} + {% include "sv/_lienlibre_modal.html" %} +
@@ -180,5 +168,7 @@

Zones infestées {% if zones_infestees|length %}({{ zones_infestees|length }

Aucune zone infestée

{% endif %}

+ + {% include "sv/_list_free_links.html" with classes="fr-mt-8v" %} {% endblock %} diff --git a/sv/tests/conftest.py b/sv/tests/conftest.py index 5d733fb..3d9505b 100644 --- a/sv/tests/conftest.py +++ b/sv/tests/conftest.py @@ -7,7 +7,7 @@ from playwright.sync_api import Page from model_bakery import baker from model_bakery.recipe import Recipe, foreign_key -from sv.models import Etat, FicheDetection +from sv.models import Etat, FicheDetection, FicheZoneDelimitee User = get_user_model() @@ -44,6 +44,16 @@ def add_basic_etat_objects(): Etat.objects.get_or_create(libelle="clôturé") +@pytest.fixture +def fiche_zone_bakery(db, mocked_authentification_user): + def _fiche_zone_bakery(): + return baker.make( + FicheZoneDelimitee, _fill_optional=True, createur=mocked_authentification_user.agent.structure + ) + + return _fiche_zone_bakery + + @pytest.fixture def fiche_detection_bakery(db, mocked_authentification_user): def _fiche_detection_bakery(): diff --git a/sv/tests/test_fichezone_liens.py b/sv/tests/test_fichezone_liens.py new file mode 100644 index 0000000..7fbea64 --- /dev/null +++ b/sv/tests/test_fichezone_liens.py @@ -0,0 +1,33 @@ +import pytest +from django.contrib.contenttypes.models import ContentType + +from core.models import LienLibre +from playwright.sync_api import expect + + +@pytest.mark.django_db +def test_can_add_free_link(live_server, page, fiche_zone_bakery, choice_js_fill): + fiche = fiche_zone_bakery() + other_fiche = fiche_zone_bakery() + page.goto(f"{live_server.url}{fiche.get_absolute_url()}") + + page.get_by_role("button", name="Actions").click() + page.get_by_role("link", name="Ajouter un lien libre").click() + page.wait_for_selector("#fr-modal-freelink .choices__list--single") + choice_js_fill( + page, + "#fr-modal-freelink .choices__list--single", + f"Fiche Zone Delimitee: {str(other_fiche.numero)}", + f"Fiche Zone Delimitee: {str(other_fiche.numero)}", + ) + page.get_by_test_id("submit-freelink").click() + + expect(page.get_by_text("Le lien a été créé avec succès.")).to_be_visible() + + link = LienLibre.objects.get() + assert link.content_type_1 == ContentType.objects.get_for_model(other_fiche) + assert link.content_type_2 == ContentType.objects.get_for_model(other_fiche) + assert link.object_id_1 == fiche.pk + assert link.object_id_2 == other_fiche.pk + + expect(page.get_by_role("link", name=str(other_fiche.numero))).to_be_visible() diff --git a/sv/views.py b/sv/views.py index a780a41..4279bfe 100644 --- a/sv/views.py +++ b/sv/views.py @@ -751,10 +751,15 @@ def formset_invalid(self): return self.render_to_response(self.get_context_data()) -class FicheZoneDelimiteeDetailView(DetailView): +class FicheZoneDelimiteeDetailView(WithFreeLinksListInContextMixin, DetailView): model = FicheZoneDelimitee context_object_name = "fiche" + def _get_free_link_form(self): + return FreeLinkForm( + content_type_1=ContentType.objects.get_for_model(self.get_object()).pk, object_id_1=self.get_object().pk + ) + def get_queryset(self): zone_infestee_detections_prefetch = Prefetch( "fichedetection_set", queryset=FicheDetection.objects.select_related("numero") @@ -770,6 +775,7 @@ def get_queryset(self): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) fichezonedelimitee = self.get_object() + context["free_link_form"] = self._get_free_link_form() context["detections_hors_zone_infestee"] = fichezonedelimitee.fichedetection_set.select_related("numero").all() context["zones_infestees"] = [ (zone_infestee, zone_infestee.fichedetection_set.all())