Skip to content

Commit

Permalink
feat: update approvals list filters ui
Browse files Browse the repository at this point in the history
  • Loading branch information
hellodeloo committed May 24, 2024
1 parent 29e89f2 commit 78ddb28
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 55 deletions.
10 changes: 10 additions & 0 deletions itou/static/js/htmx_dropdown_filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
htmx.onLoad((target) => {
function toggleHasSelectedItem() {
const dropdown = this.closest('.dropdown');
this.classList.toggle('has-selected-item', dropdown.querySelector('input:checked:not([value=""])'));
}
target.querySelectorAll('.btn-dropdown-filter.dropdown-toggle').forEach((dropdownFilter) => {
dropdownFilter.addEventListener('hide.bs.dropdown', toggleHasSelectedItem);
toggleHasSelectedItem.call(dropdownFilter);
});
});
12 changes: 12 additions & 0 deletions itou/templates/approvals/includes/approvals_filters/reset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% load str_filters %}

<div class="ms-md-auto" id="approvals-list-filter-counter"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
{% if filters_counter > 0 %}
<a href="{% url 'approvals:list' %}"
class="btn btn-ico btn-dropdown-filter"
aria-label="Réinitialiser le{{ filters_counter|pluralizefr }} filtre{{ filters_counter|pluralizefr }} actif{{ filters_counter|pluralizefr }}">
<i class="ri-eraser-line font-weight-bold" aria-hidden="true"></i>
<span>Effacer tout</span>
</a>
{% endif %}
</div>
18 changes: 10 additions & 8 deletions itou/templates/approvals/includes/approvals_filters/status.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{% load django_bootstrap5 %}

<fieldset>
<legend>Statut du PASS IAE</legend>
<ul class="list-unstyled">
<li>{% bootstrap_field filters_form.status_valid wrapper_class="" %}</li>
<li>{% bootstrap_field filters_form.status_suspended wrapper_class="" %}</li>
<li>{% bootstrap_field filters_form.status_future wrapper_class="" %}</li>
<li>{% bootstrap_field filters_form.status_expired wrapper_class="" %}</li>
<div class="dropdown">
<button type="button" class="btn btn-dropdown-filter dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
Statut
</button>
<ul class="dropdown-menu">
<li>{% bootstrap_field filters_form.status_valid wrapper_class="dropdown-item" %}</li>
<li>{% bootstrap_field filters_form.status_suspended wrapper_class="dropdown-item" %}</li>
<li>{% bootstrap_field filters_form.status_future wrapper_class="dropdown-item" %}</li>
<li>{% bootstrap_field filters_form.status_expired wrapper_class="dropdown-item" %}</li>
</ul>
</fieldset>
</div>
23 changes: 17 additions & 6 deletions itou/templates/approvals/includes/approvals_filters/users.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
{% load django_bootstrap5 %}

<fieldset>
<legend>Nom du salarié</legend>
{% bootstrap_field filters_form.users layout="inline" %}
</fieldset>
<div class="dropdown">
<button type="button" class="btn btn-dropdown-filter dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
Fin du parcours en IAE
</button>
<ul class="dropdown-menu">
{% for choice in filters_form.expiry %}
<li>
<div class="dropdown-item">
<div class="form-check">
<input class="form-check-input" type="radio" name="{{ choice.data.name }}" id="{{ choice.id_for_label }}" value="{{ choice.data.value }}"{% if choice.data.selected %} checked="checked"{% endif %}>
<label class="form-check-label" for="{{ choice.id_for_label }}">{{ choice.data.label }}</label>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
5 changes: 5 additions & 0 deletions itou/templates/approvals/includes/list_counter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% load str_filters %}

<h3 class="h4 mb-0" id="approvals-list-count"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
{% with paginator.count as counter %}<strong>{{ counter }} résultat{{ counter|pluralizefr }}</strong>{% endwith %}
</h3>
12 changes: 12 additions & 0 deletions itou/templates/approvals/includes/list_reset_filters.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% load str_filters %}

<div class="ms-md-auto" id="approvals-list-filter-counter"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
{% if filters_counter > 0 %}
<a href="{% url 'approvals:list' %}"
class="btn btn-ico btn-dropdown-filter"
aria-label="Réinitialiser le{{ filters_counter|pluralizefr }} filtre{{ filters_counter|pluralizefr }} actif{{ filters_counter|pluralizefr }}">
<i class="ri-eraser-line font-weight-bold" aria-hidden="true"></i>
<span>Effacer tout</span>
</a>
{% endif %}
</div>
20 changes: 7 additions & 13 deletions itou/templates/approvals/includes/list_results.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
{% load str_filters %}
{% load django_bootstrap5 %}

<div id="approvals-list">
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-md-between mb-3 mb-md-4">
<h3 class="h4 mb-0">
{% with paginator.count as counter %}<strong>{{ counter }} résultat{{ counter|pluralizefr }}</strong>{% endwith %}
</h3>
{% if filters_counter > 0 %}
<div class="flex-column flex-md-row btn-group btn-group-sm btn-group-action" role="group" aria-label="Actions sur les filtres de PASS IAE">
<a href="{% url 'approvals:list' %}" class="btn btn-secondary btn-ico">
<i class="ri-arrow-go-back-line" aria-hidden="true"></i>
<span>Réinitialiser les filtres ({{ filters_counter }})</span>
</a>
</div>
{% endif %}
</div>
{% if not approval_list %}
<div class="c-box c-box--results my-3 my-md-4">
<div class="c-box--results__body">
Expand All @@ -26,3 +15,8 @@ <h3 class="h4 mb-0">
{% include "includes/pagination.html" with page=page_obj boost=True boost_target="#approvals-list" boost_indicator="#approvals-list" %}
{% endif %}
</div>

{% if request.htmx %}
{% include "approvals/includes/list_counter.html" %}
{% include "approvals/includes/approvals_filters/reset.html" %}
{% endif %}
44 changes: 23 additions & 21 deletions itou/templates/approvals/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,30 @@
<section class="s-section">
<div class="s-section__container container">
<div class="s-section__row row">
<div class="col-12 col-md-4 mb-3 mb-md-5">
<aside class="c-aside-filters">
<button class="c-aside-filters__btn__collapse" data-bs-toggle="collapse" data-bs-target="#asideFiltersCollapse" aria-expanded="true" aria-controls="asideFiltersCollapse">
<i class="ri-filter-line" aria-hidden="true"></i>
<span>Filtrer les résultats</span>
</button>
<div class="c-aside-filters__card collapse show" id="asideFiltersCollapse">
<form hx-get="{% url 'approvals:list' %}" hx-trigger="change delay:.5s" hx-indicator="#approvals-list" hx-target="#approvals-list" hx-swap="outerHTML" hx-push-url="true">
<div class="c-aside-filters__card__body">
{% include "approvals/includes/approvals_filters/users.html" %}
<hr>
{% include "approvals/includes/approvals_filters/status.html" %}
<hr>
<fieldset>
<legend>Fin du parcours en IAE</legend>
{% bootstrap_field filters_form.expiry layout="inline" %}
</fieldset>
</div>
</form>
<div class="col-12">
<form hx-get="{% url 'approvals:list' %}"
hx-trigger="change delay:.5s, change from:#id_users"
hx-indicator="#approvals-list"
hx-target="#approvals-list"
hx-swap="outerHTML"
hx-push-url="true"
hx-include="#id_users">
<div class="btn-dropdown-filter-group mb-3 mb-md-4">
{% include "approvals/includes/approvals_filters/status.html" %}
{% include "approvals/includes/approvals_filters/users.html" %}
{% include "approvals/includes/approvals_filters/reset.html" %}
</div>
</aside>
</form>
</div>
</div>
<div class="s-section__row row">
<div class="col-12">
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-md-between mb-3 mb-md-4">
{% include "approvals/includes/list_counter.html" %}
<div class="flex-column flex-md-row mt-3 mt-md-0">{% bootstrap_field filters_form.users layout="inline" %}</div>
</div>
{% include "approvals/includes/list_results.html" %}
</div>
<div class="col-12 col-md-8">{% include "approvals/includes/list_results.html" %}</div>
</div>
</div>
</section>
Expand All @@ -45,6 +46,7 @@
{% block script %}
{{ block.super }}
<script src='{% static "js/htmx_compat.js" %}'></script>
<script src='{% static "js/htmx_dropdown_filter.js" %}'></script>
<!-- Needed to use the Select2MultipleWidget JS widget. -->
{{ filters_form.media.js }}
{% endblock %}
4 changes: 3 additions & 1 deletion itou/templates/employee_record/includes/list_results.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,7 @@ <h3 class="h4 m-0">{{ counter }} résultat{{ counter|pluralizefr }}</h3>
</div>
{% 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" %}
{% include "employee_record/includes/list_counter.html" %}
{% include "employee_record/includes/employee_record_filters/status.html" %}
{% include "employee_record/includes/employee_record_filters/reset.html" %}
{% endif %}
17 changes: 16 additions & 1 deletion itou/templates/employee_record/list.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% extends "layout/base.html" %}
{% load django_bootstrap5 %}
{% load static %}

{% block title %}Fiches salarié ASP - {{ request.current_organization.display_name }} {{ block.super }}{% endblock %}
Expand Down Expand Up @@ -69,7 +70,21 @@ <h2 class="h3">Nous transférons vos fiches salarié à l'ASP afin de vous faire
{{ form.order.as_hidden }}
</form>
</div>
</aside>
{# Filled via jQuery. Does not need reloading with HTMX, its content is static. #}
{{ form.order.as_hidden }}
</form>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="d-flex flex-column flex-md-row align-items-md-center mb-3 mb-md-4">
{% include "employee_record/includes/list_counter.html" %}
{% include "employee_record/includes/list_sort.html" %}
<div class="flex-column flex-md-row mt-3 mt-md-0 ms-md-3">
{% bootstrap_field filters_form.job_seekers layout="inline" %}
</div>
</div>
{% include "employee_record/includes/list_results.html" %}
</div>
<div class="col-12 col-md-8">{% include "employee_record/includes/list_results.html" %}</div>
</div>
Expand Down
12 changes: 10 additions & 2 deletions itou/www/approvals_views/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,19 @@ class ApprovalExpiry(TextChoices):
LESS_THAN_1_MONTH = "1", "Moins d'1 mois"
LESS_THAN_3_MONTHS = "3", "Moins de 3 mois"
LESS_THAN_7_MONTHS = "7", "Moins de 7 mois"
ALL = "0", "Tous"
ALL = "", "Tous"


class ApprovalForm(forms.Form):
users = forms.MultipleChoiceField(required=False, label="Nom", widget=Select2MultipleWidget)
users = forms.MultipleChoiceField(
required=False,
label="Nom",
widget=Select2MultipleWidget(
attrs={
"data-placeholder": "Nom du candidat",
}
),
)
status_valid = forms.BooleanField(label="PASS IAE valide", required=False)
status_suspended = forms.BooleanField(label="PASS IAE valide (suspendu)", required=False)
status_future = forms.BooleanField(label="PASS IAE valide (non démarré)", required=False)
Expand Down
6 changes: 3 additions & 3 deletions tests/www/approvals_views/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,11 @@ def test_approval_expiry_filter_default(self, client):
response = client.get(list_url)
# Check that the default "Fin du parcours en IAE" value "Tous" is selected
expiry_all_input = parse_response_to_soup(response, "input[name='expiry'][value='0']")
assert expiry_all_input.get("checked")
assert expiry_all_input.has_attr("checked")
response = client.get(f"{list_url}?page=2")
# Check that the default "Fin du parcours en IAE" value "Tous" is selected
expiry_all_input = parse_response_to_soup(response, "input[name='expiry'][value='0']")
assert expiry_all_input.get("checked")
assert expiry_all_input.has_attr("checked")

def test_update_with_htmx(self, client):
now = timezone.localdate()
Expand Down Expand Up @@ -357,7 +357,7 @@ def test_update_with_htmx(self, client):
[less_than_3_months] = simulated_page.find_all("input", attrs={"name": "expiry", "value": "3"})
del less_than_3_months["checked"]
[less_than_1_month] = simulated_page.find_all("input", attrs={"name": "expiry", "value": "1"})
less_than_1_month["checked"] = "checked"
less_than_1_month["checked"] = ""

response = client.get(url, {"expiry": "1"}, headers={"HX-Request": "true"})
update_page_with_htmx(simulated_page, f"form[hx-get='{url}']", response)
Expand Down

0 comments on commit 78ddb28

Please sign in to comment.