diff --git a/itou/templates/employee_record/includes/list_form_fields.html b/itou/templates/employee_record/includes/list_form_fields.html new file mode 100644 index 0000000000..d3a49719b2 --- /dev/null +++ b/itou/templates/employee_record/includes/list_form_fields.html @@ -0,0 +1,21 @@ +{% load django_bootstrap5 %} +{% load list_filters %} +
+
+ Statut +
+ {% for status, badge in form.status|zip:badges %} +
+
{{ status }}
+
+ {{ badge.0 }} +
+
+ {% endfor %} +
+
+
+ Par candidat + {% bootstrap_field filters_form.job_seekers show_label=False %} +
+
diff --git a/itou/templates/employee_record/includes/list_results.html b/itou/templates/employee_record/includes/list_results.html new file mode 100644 index 0000000000..0fb6837839 --- /dev/null +++ b/itou/templates/employee_record/includes/list_results.html @@ -0,0 +1,48 @@ +{% load str_filters %} +
+
+
+ {% with navigation_pages.paginator.count as counter %} +

{{ counter }} résultat{{ counter|pluralizefr }}

+ {% endwith %} +
+
+ Trier par : + + +
+
+ {# "Real" employee records objects #} +
+ {% if employee_records_list %} + {% for employee_record in navigation_pages %} + {% include "employee_record/includes/list_item.html" with employee_record=employee_record item=employee_record.job_application current_url=request.get_full_path only %} + {% endfor %} + {# New employee records i.e. job applications #} + {% else %} + {% for job_application in navigation_pages %} + {% include "employee_record/includes/list_item.html" with employee_record=None item=job_application only %} + {% endfor %} + {% endif %} +
+ {% if not navigation_pages %} +
+
+

Aucune fiche salarié avec le statut selectionné.

+
+
+ {% endif %} + {% include "includes/pagination.html" with page=navigation_pages boost=True boost_target="#employee-records-container" boost_indicator="#employee-records-container" %} +
+{% if request.htmx %} + {% include "employee_record/includes/list_status_help.html" with request=request status=form.status.value only %} + {% include "employee_record/includes/list_form_fields.html" %} +{% endif %} diff --git a/itou/templates/employee_record/includes/list_status_help.html b/itou/templates/employee_record/includes/list_status_help.html new file mode 100644 index 0000000000..d7d3d27c29 --- /dev/null +++ b/itou/templates/employee_record/includes/list_status_help.html @@ -0,0 +1,41 @@ +
+ {% if status == "NEW" %} +

+ Vous trouverez ici les candidatures validées à partir desquelles vous devez créer de nouvelles fiches salarié. +

+ {% elif status == "READY" %} +

+ Vous trouverez ici les fiches salarié complétées + en attente d’envoi à l’ASP, qui a lieu automatiquement à intervalles réguliers. +

+

+ À ce stade, seule la visualisation des informations de la fiche est + possible. +

+

Merci de votre patience.

+ {% elif status == "SENT" %} +

Vous trouverez ici les fiches salarié complétées et envoyées à l'ASP.

+

+ À ce stade, et en attendant un retour de l'ASP, seule la visualisation des informations de + la fiche est possible. +

+ {% elif status == "REJECTED" %} +

+ Vous trouverez ici les fiches salarié envoyées à l'ASP et retournées avec une + erreur. +

+

Vous pouvez modifier les fiches en erreur et les envoyer à nouveau.

+ {% elif status == "PROCESSED" %} +

Vous trouverez ici les fiches salarié envoyées et validées par l'ASP.

+

+ Aucune action ultérieure n'est possible à ce stade, mais vous pouvez consulter le détail de + la fiche salarié. +

+ {% elif status == "DISABLED" %} +

Vous trouverez ici les fiches salarié que vous avez désactivées.

+

+ En cas de besoin vous pouvez réactiver une fiche, elle sera transférée dans la catégorie + "Nouvelle". +

+ {% endif %} +
diff --git a/itou/templates/employee_record/list.html b/itou/templates/employee_record/list.html index 4cc6393788..2593206993 100644 --- a/itou/templates/employee_record/list.html +++ b/itou/templates/employee_record/list.html @@ -1,8 +1,5 @@ {% extends "layout/base.html" %} {% load static %} -{% load str_filters %} -{% load list_filters %} -{% load django_bootstrap5 %} {% block title %}Fiches salarié ASP - {{ request.current_organization.display_name }} {{ block.super }}{% endblock %} @@ -44,45 +41,7 @@

Nous transférons vos fiches salarié à l'ASP afin de vous faire
  • La visualisation dans l’Extranet IAE 2.0 interviendra dans les 2 heures suivant l’envoi.
  • - {% if form.status.value == "NEW" %} -

    - Vous trouverez ici les candidatures validées à partir desquelles vous devez créer de nouvelles fiches salarié. -

    - {% elif form.status.value == "READY" %} -

    - Vous trouverez ici les fiches salarié complétées - en attente d’envoi à l’ASP, qui a lieu automatiquement à intervalles réguliers. -

    -

    - À ce stade, seule la visualisation des informations de la fiche est - possible. -

    -

    Merci de votre patience.

    - {% elif form.status.value == "SENT" %} -

    Vous trouverez ici les fiches salarié complétées et envoyées à l'ASP.

    -

    - À ce stade, et en attendant un retour de l'ASP, seule la visualisation des informations de - la fiche est possible. -

    - {% elif form.status.value == "REJECTED" %} -

    - Vous trouverez ici les fiches salarié envoyées à l'ASP et retournées avec une - erreur. -

    -

    Vous pouvez modifier les fiches en erreur et les envoyer à nouveau.

    - {% elif form.status.value == "PROCESSED" %} -

    Vous trouverez ici les fiches salarié envoyées et validées par l'ASP.

    -

    - Aucune action ultérieure n'est possible à ce stade, mais vous pouvez consulter le détail de - la fiche salarié. -

    - {% elif form.status.value == "DISABLED" %} -

    Vous trouverez ici les fiches salarié que vous avez désactivées.

    -

    - En cas de besoin vous pouvez réactiver une fiche, elle sera transférée dans la catégorie - "Nouvelle". -

    - {% endif %} + {% include "employee_record/includes/list_status_help.html" with request=request status=form.status.value only %} {% endblock %} {% block content %} @@ -104,79 +63,15 @@

    Nous transférons vos fiches salarié à l'ASP afin de vous faire Filtres des fiches salarié
    -
    -
    -
    - Statut -
    - {% for status, badge in form.status|zip:badges %} -
    -
    {{ status }}
    -
    - {{ badge.0 }} -
    -
    - {% endfor %} -
    -
    - {# Job seeker filter #} -
    - Par candidat - {% bootstrap_field filters_form.job_seekers show_label=False %} -
    -
    - {# Filled via jQuery #} + + {% include "employee_record/includes/list_form_fields.html" %} + {# Filled via jQuery. Does not need reloading with HTMX, its content is static. #} {{ form.order.as_hidden }}
    - -
    -
    -
    - {% with navigation_pages.paginator.count as counter %} -

    {{ counter }} résultat{{ counter|pluralizefr }}

    - {% endwith %} -
    -
    - Trier par : - - -
    -
    - - {# "Real" employee records objects #} -
    - {% if employee_records_list %} - {% for employee_record in navigation_pages %} - {% include "employee_record/includes/list_item.html" with employee_record=employee_record item=employee_record.job_application current_url=request.get_full_path only %} - {% endfor %} - {# New employee records i.e. job applications #} - {% else %} - {% for job_application in navigation_pages %} - {% include "employee_record/includes/list_item.html" with employee_record=None item=job_application only %} - {% endfor %} - {% endif %} -
    - - {% if not navigation_pages %} -
    -
    -

    Aucune fiche salarié avec le statut selectionné.

    -
    -
    - {% endif %} - {% include "includes/pagination.html" with page=navigation_pages %} -
    +
    {% include "employee_record/includes/list_results.html" %}
    @@ -184,16 +79,21 @@

    {{ counter }} résultat{{ counter|pluralizefr }}

    {% block script %} {{ block.super }} + {{ filters_form.media.js }} {% endblock %} diff --git a/itou/www/employee_record_views/views.py b/itou/www/employee_record_views/views.py index 3f45583b98..e9bb624f55 100644 --- a/itou/www/employee_record_views/views.py +++ b/itou/www/employee_record_views/views.py @@ -254,7 +254,7 @@ def list_employee_records(request, template_name="employee_record/list.html"): "back_url": reverse("dashboard:index"), } - return render(request, template_name, context) + return render(request, "employee_record/includes/list_results.html" if request.htmx else template_name, context) @login_required diff --git a/tests/www/employee_record_views/test_list.py b/tests/www/employee_record_views/test_list.py index 1df9d4cc18..f7b27334d7 100644 --- a/tests/www/employee_record_views/test_list.py +++ b/tests/www/employee_record_views/test_list.py @@ -20,6 +20,7 @@ from tests.employee_record import factories as employee_record_factories from tests.employee_record.factories import EmployeeRecordFactory from tests.job_applications.factories import JobApplicationWithApprovalNotCancellableFactory +from tests.utils.htmx.test import assertSoupEqual, update_page_with_htmx from tests.utils.test import BASE_NUM_QUERIES, TestCase, assert_previous_step, parse_response_to_soup @@ -488,6 +489,42 @@ def test_display_result_count(self): response = self.client.get(self.URL + "?status=READY") self.assertContains(response, "0 résultat") + def test_htmx(self): + self.client.force_login(self.user) + response = self.client.get(self.URL, {"status": "NEW"}) + simulated_page = parse_response_to_soup(response) + + [new_status] = simulated_page.find_all("input", attrs={"name": "status", "value": "NEW"}) + del new_status["checked"] + [ready_status] = simulated_page.find_all("input", attrs={"name": "status", "value": "READY"}) + ready_status["checked"] = "" + + response = self.client.get(self.URL, {"status": "READY"}, headers={"HX-Request": "true"}) + update_page_with_htmx(simulated_page, f"form[hx-get='{self.URL}']", response) + + response = self.client.get(self.URL + "?status=READY") + fresh_page = parse_response_to_soup(response) + assertSoupEqual(simulated_page, fresh_page) + + def test_htmx_new_employee_record_updates_badge_count(self): + self.client.force_login(self.user) + response = self.client.get(self.URL, {"status": "NEW"}) + simulated_page = parse_response_to_soup(response) + # This new application should update the counter badge on NEW. + JobApplicationWithApprovalNotCancellableFactory(to_company=self.company) + + [new_status] = simulated_page.find_all("input", attrs={"name": "status", "value": "NEW"}) + del new_status["checked"] + [ready_status] = simulated_page.find_all("input", attrs={"name": "status", "value": "READY"}) + ready_status["checked"] = "" + + response = self.client.get(self.URL, {"status": "READY"}, headers={"HX-Request": "true"}) + update_page_with_htmx(simulated_page, f"form[hx-get='{self.URL}']", response) + + response = self.client.get(self.URL + "?status=READY") + fresh_page = parse_response_to_soup(response) + assertSoupEqual(simulated_page, fresh_page) + def test_an_active_siae_without_convention_can_not_access_the_view(client): siae = CompanyFactory(