Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UX/UI : Modification filtres sur la liste des salariés et PASS IAE et sur la liste des fiches salarié ASP #4083

Merged
merged 2 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions itou/static/js/htmx_dropdown_filter.js
hellodeloo marked this conversation as resolved.
Show resolved Hide resolved
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);
});
});
17 changes: 17 additions & 0 deletions itou/templates/approvals/includes/approvals_filters/expiry.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<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{% endif %}>
<label class="form-check-label" for="{{ choice.id_for_label }}">{{ choice.data.label }}</label>
</div>
</div>
</li>
{% endfor %}
</ul>
</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>

This file was deleted.

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/list_reset_filters.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/expiry.html" %}
{% include "approvals/includes/list_reset_filters.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 %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{% load list_filters %}

<div id="employee-records-list-filters"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
{% for choice, badge in form.status|zip:badges %}
<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{% endif %}>
<label class="form-check-label" for="{{ choice.id_for_label }}">
{{ choice.data.label }}
<span class="badge rounded-pill badge-xs {{ badge.1 }}">{{ badge.0 }}</span>
</label>
</div>
</div>
</li>
{% endfor %}
</div>
7 changes: 7 additions & 0 deletions itou/templates/employee_record/includes/list_counter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% load str_filters %}

{% with navigation_pages.paginator.count as counter %}
<h3 class="h4 m-0 me-auto" id="employee-record-list-count"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
{{ counter }} résultat{{ counter|pluralizefr }}
</h3>
{% endwith %}
21 changes: 0 additions & 21 deletions itou/templates/employee_record/includes/list_form_fields.html

This file was deleted.

13 changes: 13 additions & 0 deletions itou/templates/employee_record/includes/list_order.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div id="employee-record-order"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
<span class="fs-sm">Trier par :</span>
<button type="button" class="btn btn-sm btn-link dropdown-toggle p-0" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ ordered_by_label }}
</button>
<div class="dropdown-menu dropdown-menu-end" id="order-form-group">
{% for order_value, order_label in form.order.field.choices %}
<button class="dropdown-item {% if order_value == form.order.value %}active{% endif %}" type="button" value="{{ order_value }}">
{{ order_label }}
</button>
{% endfor %}
</div>
</div>
27 changes: 6 additions & 21 deletions itou/templates/employee_record/includes/list_results.html
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
{% load django_bootstrap5 %}
{% load str_filters %}

<div id="employee-records-container">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
{% with navigation_pages.paginator.count as counter %}
<h3 class="h4 m-0">{{ counter }} résultat{{ counter|pluralizefr }}</h3>
{% endwith %}
</div>
<div>
<span class="fs-sm">Trier par :</span>
<button type="button" class="btn btn-sm btn-link dropdown-toggle p-0" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ ordered_by_label }}
</button>
<div class="dropdown-menu dropdown-menu-end" id="order-form-group">
{% for order_value, order_label in form.order.field.choices %}
<button class="dropdown-item {% if order_value == form.order.value %}active{% endif %}" type="button" value="{{ order_value }}">
{{ order_label }}
</button>
{% endfor %}
</div>
</div>
</div>
{# "Real" employee records objects #}
<div class="employee-records-list">
{% if employee_records_list %}
Expand All @@ -42,7 +24,10 @@ <h3 class="h4 m-0">{{ counter }} résultat{{ counter|pluralizefr }}</h3>
{% endif %}
{% include "includes/pagination.html" with page=navigation_pages boost=True boost_target="#employee-records-container" boost_indicator="#employee-records-container" %}
</div>

{% if request.htmx %}
{% include "employee_record/includes/list_order.html" %}
{% 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" %}
{% endif %}
48 changes: 34 additions & 14 deletions 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 @@ -56,22 +57,40 @@ <h2 class="h3">Nous transférons vos fiches salarié à l'ASP afin de vous faire
</div>
</div>
<div class="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>Filtres des fiches salarié</span>
</button>
<div class="c-aside-filters__card collapse show" id="asideFiltersCollapse">
<form hx-get="{% url 'employee_record_views:list' %}" hx-trigger="change delay:.5s" hx-indicator="#employee-records-container" hx-target="#employee-records-container" hx-swap="outerHTML" hx-push-url="true">
{% 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 }}
</form>
<div class="col-12">
<form hx-get="{% url 'employee_record_views:list' %}"
hx-trigger="change delay:.5s, change from:#id_job_seekers"
hx-indicator="#employee-records-container"
hx-target="#employee-records-container"
hx-swap="outerHTML"
hx-push-url="true"
hx-include="#id_job_seekers">
<div class="btn-dropdown-filter-group mb-3 mb-md-4">
<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">
{% include "employee_record/includes/employee_record_filters/status.html" %}
</ul>
</div>
</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_order.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>
</div>
</section>
Expand All @@ -80,6 +99,7 @@ <h2 class="h3">Nous transférons vos fiches salarié à l'ASP afin de vous faire
{% block script %}
{{ block.super }}
<script src='{% static "js/htmx_compat.js" %}'></script>
<script src='{% static "js/htmx_dropdown_filter.js" %}'></script>
<!-- Needed to use Select2MultipleWidget. -->
{{ filters_form.media.js }}
<script nonce="{{ CSP_NONCE }}">
Expand Down
17 changes: 13 additions & 4 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 All @@ -54,6 +62,7 @@ class ApprovalForm(forms.Form):
choices=ApprovalExpiry.choices,
widget=forms.RadioSelect,
initial=ApprovalExpiry.ALL,
required=False,
)

def __init__(self, siae_pk, data, *args, **kwargs):
Expand Down Expand Up @@ -102,8 +111,8 @@ def get_qs_filters(self):
status_filters_list.append(Q(end_at__lt=now))
qs_filters_list.append(Q(reduce(operator.or_, status_filters_list, Q())))

if expiry := int(data.get("expiry")):
qs_filters_list.append(Q(end_at__lt=now + relativedelta(months=expiry), end_at__gte=now))
if expiry := data.get("expiry", ApprovalExpiry.ALL):
qs_filters_list.append(Q(end_at__lt=now + relativedelta(months=int(expiry)), end_at__gte=now))

return qs_filters_list

Expand Down
Loading