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 des filtres sur la liste de candidatures [GEN-216] #4199

Merged
merged 1 commit into from
Jun 27, 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: 5 additions & 5 deletions itou/static/css/itou.css
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,6 @@
margin-left: 2px;
}

.c-aside-filters .select2-container--bootstrap-5 {
width: auto !important;
display: block !important;
}

/*
Force the display of `.invalid-feedback` for Duet Date Picker with Bootstrap 4.
See also `duet_date_picker.html`.
Expand Down Expand Up @@ -466,3 +461,8 @@ an input field being invalid, generating an uncontrolled red box-shadow. */
border-top-left-radius: 0.5rem;
border-top-right-radius: 0.5rem;
}

/* Fix for form.company and form.job_seeker width */
.w-lg-400px .select2-selection__rendered {
white-space: nowrap !important;
}
53 changes: 46 additions & 7 deletions itou/static/js/htmx_dropdown_filter.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,49 @@
htmx.onLoad((target) => {
(function() {
const filtersContentId = "offcanvasApplyFiltersContent";
const filtersContent = document.getElementById(filtersContentId);
const filtersCount = document.getElementById("all-filters-btn");

function fieldHasValue(container) {
return (
container.querySelector('input:checked:not([value=""])')
|| container.querySelector('input[value]:not([type=checkbox]):not([type=radio]):not([value=""])')
|| container.querySelector('duet-date-picker[value]:not([value=""])')
|| container.querySelector("select > option:not([value=''])[selected]")
);
}

function toggleHasSelectedItem() {
const dropdown = this.closest('.dropdown');
this.classList.toggle('has-selected-item', dropdown.querySelector('input:checked:not([value=""])'));
this.classList.toggle('has-selected-item', fieldHasValue(dropdown));
this.classList.toggle('font-weight-bold', fieldHasValue(dropdown));
}

function initFilters(sidebar) {
let activeFiltersCount = 0;
Array.from(sidebar.querySelectorAll(".collapsed")).forEach((collapse) => {
const collapseTarget = document.querySelector(collapse.dataset.bsTarget);
if (fieldHasValue(collapseTarget)) {
activeFiltersCount++;
bootstrap.Collapse.getOrCreateInstance(collapseTarget, { delay: 0 }).show();
}
});
if (filtersCount) {
filtersCount.textContent = activeFiltersCount ? ` (${activeFiltersCount})` : "";
}
}

function onLoad(target) {
target.querySelectorAll('.btn-dropdown-filter.dropdown-toggle').forEach((dropdownFilter) => {
dropdownFilter.addEventListener('hide.bs.dropdown', toggleHasSelectedItem);
toggleHasSelectedItem.call(dropdownFilter);
});
if (target.id === filtersContentId) {
initFilters(target);
}
}

if (filtersContent) {
initFilters(filtersContent);
}
target.querySelectorAll('.btn-dropdown-filter.dropdown-toggle').forEach((dropdownFilter) => {
dropdownFilter.addEventListener('hide.bs.dropdown', toggleHasSelectedItem);
toggleHasSelectedItem.call(dropdownFilter);
});
});
htmx.onLoad(onLoad);
})();
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
{% load django_bootstrap5 %}


{% if filters_form.criteria %}
<hr>
<fieldset>
<legend>Critères administratifs déclarés</legend>
{% bootstrap_field filters_form.criteria wrapper_class="" %}
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed" data-bs-toggle="collapse" data-bs-target="#collapseCriteria" type="button" aria-expanded="false" aria-controls="collapseCriteria">
Critères administratifs déclarés
</button>
</legend>
<div class="mt-3 collapse" id="collapseCriteria">{% bootstrap_field filters_form.criteria %}</div>
</fieldset>
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

<hr>
<fieldset>
<legend>Date d'envoi de la candidature</legend>
{% bootstrap_field filters_form.start_date %}
{% bootstrap_field filters_form.end_date %}
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed" data-bs-toggle="collapse" data-bs-target="#collapseDate" type="button" aria-expanded="false" aria-controls="collapseDate">
Date d'envoi de la candidature
</button>
</legend>
<div class="mt-3 collapse" id="collapseDate">
{% bootstrap_field filters_form.start_date %}
{% bootstrap_field filters_form.end_date %}
</div>
</fieldset>
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
{% load django_bootstrap5 %}

{% if filters_form.departments %}
<hr>
<fieldset>
{% bootstrap_field filters_form.departments %}
</fieldset>
{% if filters_form.departments and filters_form.fields.departments.choices %}
{% if btn_dropdown_filter|default:False %}
<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">
{{ filters_form.departments.label | capfirst }}
</button>
<ul class="dropdown-menu">
{% for choice in filters_form.departments %}
<li class="dropdown-item">
<div class="form-check">
<input id="{{ choice.id_for_label }}-top" class="form-check-input" name="{{ choice.data.name }}" type="checkbox" value="{{ choice.data.value }}"{% if choice.data.selected %} checked{% endif %}>
<label for="{{ choice.id_for_label }}-top" class="form-check-label">{{ choice.choice_label }}</label>
</div>
</li>
{% endfor %}
</ul>
</div>
{% else %}
<hr>
<fieldset>
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed"
data-bs-toggle="collapse"
data-bs-target="#collapseDepartments"
type="button"
aria-expanded="false"
aria-controls="collapseDepartments">{{ filters_form.departments.label | capfirst }}</button>
</legend>
<div class="my-3 collapse" id="collapseDepartments">
<ul>
{% for choice in filters_form.departments %}
<li>
<div class="form-check">
<input id="{{ choice.id_for_label }}" class="form-check-input" name="{{ choice.data.name }}" type="checkbox" value="{{ choice.data.value }}"{% if choice.data.selected %} checked{% endif %}>
<label for="{{ choice.id_for_label }}" class="form-check-label">{{ choice.choice_label }}</label>
</div>
</li>
{% endfor %}
</ul>
</div>
</fieldset>
{% endif %}
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
{% if filters_form.eligibility_validated %}
<hr>
<fieldset>
<legend>Éligibilité IAE</legend>
{% bootstrap_field filters_form.eligibility_validated %}
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed"
data-bs-toggle="collapse"
data-bs-target="#collapseEligibilityIAE"
type="button"
aria-expanded="false"
aria-controls="collapseEligibilityIAE">Éligibilité IAE</button>
</legend>
<div class="mt-3 collapse" id="collapseEligibilityIAE">{% bootstrap_field filters_form.eligibility_validated %}</div>
</fieldset>
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
{% if filters_form.job_seekers %}
<hr>
<fieldset>
{% bootstrap_field filters_form.job_seekers %}
<legend>
<button class="btn has-collapse-caret collapsed" data-bs-toggle="collapse" data-bs-target="#collapseJobSeekers" type="button" aria-expanded="false" aria-controls="collapseJobSeekers">
{{ filters_form.job_seekers.label | capfirst }}
</button>
</legend>
<div class="mt-3 collapse" id="collapseJobSeekers">
{% bootstrap_field filters_form.job_seekers show_label=False %}
</div>
</fieldset>
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<form>
{% comment %}
Do not reload the entire offcanvas with HTMX. Otherwise, STR :
1. Select a filter from the top bar (one with btn_dropdown_filter=True)
2. Quickly (before HTMX results are loaded), open the offcanvas by pressing « Tous les filtres »
Results load, offcanvas panel is oob-replaced by the response content, and initially not visible, leaving only
the viewable backdrop and no filter offcanvas.
{% endcomment %}
<div class="c-offcanvas-filters offcanvas offcanvas-end" tabindex="-1" aria-labelledby="offcanvasApplyFiltersLabel" id="offcanvasApplyFilters">
<div class="offcanvas-header">
<h4 class="mb-0 btn-ico" id="offcanvasApplyFiltersLabel">
<i class="ri-sound-module-fill font-weight-medium" aria-hidden="true"></i>
<span>Filtrer</span>
</h4>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
</div>
{% include "apply/includes/job_applications_filters/offcanvas_body.html" %}
{% include "apply/includes/job_applications_filters/offcanvas_footer.html" %}
</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="offcanvas-body" id="offcanvasApplyFiltersContent"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
{% include "apply/includes/job_applications_filters/status.html" %}
{% if job_applications_list_kind is JobApplicationsListKind.SENT or job_applications_list_kind is JobApplicationsListKind.RECEIVED %}
{% include "apply/includes/job_applications_filters/selected_jobs.html" %}
{% include "apply/includes/job_applications_filters/departments.html" %}
{% include "apply/includes/job_applications_filters/sender.html" %}
{% include "apply/includes/job_applications_filters/criteria.html" %}
{% include "apply/includes/job_applications_filters/eligibility_validated.html" %}
{% include "apply/includes/job_applications_filters/pass.html" %}
{% comment %}
Do not render job_seekers:
- The field is meant to quickly find a job seeker and does not make
much sense combined with others.
- It uses a select2 widget. Overriding the id attribute so that the
field present twice on the page (in the top bar and side bar) is
challenging.
{% endcomment %}
{% for job_seeker_id in filters_form.job_seekers.value %}
<input type="hidden" name="{{ filters_form.job_seekers.name }}" value="{{ job_seeker_id }}">
{% endfor %}
{% endif %}
{% include "apply/includes/job_applications_filters/dates.html" %}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="offcanvas-footer gap-3" id="offcanvasApplyFiltersButtons"{% if request.htmx %} hx-swap-oob="true"{% endif %}>
<button class="btn btn-block btn-primary">Voir</button>
{% include "apply/includes/list_reset_filters.html" %}
</div>
14 changes: 11 additions & 3 deletions itou/templates/apply/includes/job_applications_filters/pass.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
{% if filters_form.pass_iae_suspended %}
<hr>
<fieldset>
<legend>Statut du PASS IAE</legend>
{% bootstrap_field filters_form.pass_iae_active wrapper_class="mb-2" %}
{% bootstrap_field filters_form.pass_iae_suspended wrapper_class="" %}
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed" data-bs-toggle="collapse" data-bs-target="#collapsePassIAE" type="button" aria-expanded="false" aria-controls="collapsePassIAE">
Statut du PASS IAE
</button>
</legend>
<div class="my-3 collapse" id="collapsePassIAE">
<ul>
<li>{% bootstrap_field filters_form.pass_iae_active wrapper_class="" %}</li>
<li>{% bootstrap_field filters_form.pass_iae_suspended wrapper_class="" %}</li>
</ul>
</div>
</fieldset>
{% endif %}
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
{% load django_bootstrap5 %}

{% if filters_form.selected_jobs %}
<hr>
<fieldset>
{% bootstrap_field filters_form.selected_jobs %}
</fieldset>
{% if filters_form.selected_jobs and filters_form.selected_jobs.field.choices %}
{% if btn_dropdown_filter|default:False %}
<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">
{{ filters_form.selected_jobs.label | capfirst }}
</button>
<ul class="dropdown-menu">
{% for choice in filters_form.selected_jobs %}
<li class="dropdown-item">
<div class="form-check">
<input id="{{ choice.id_for_label }}-top" class="form-check-input" name="{{ choice.data.name }}" type="checkbox" value="{{ choice.data.value }}"{% if choice.data.selected %} checked{% endif %}>
<label for="{{ choice.id_for_label }}-top" class="form-check-label">{{ choice.choice_label }}</label>
</div>
</li>
{% endfor %}
</ul>
</div>
{% else %}
<hr>
<fieldset>
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed"
data-bs-toggle="collapse"
data-bs-target="#collapseSelectedJob"
type="button"
aria-expanded="false"
aria-controls="collapseSelectedJob">{{ filters_form.selected_jobs.label | capfirst }}</button>
</legend>
<div class="my-3 collapse" id="collapseSelectedJob">
<ul>
{% for choice in filters_form.selected_jobs %}
<li>
<div class="form-check">
<input id="{{ choice.id_for_label }}" class="form-check-input" name="{{ choice.data.name }}" type="checkbox" value="{{ choice.data.value }}"{% if choice.data.selected %} checked{% endif %}>
<label for="{{ choice.id_for_label }}" class="form-check-label">{{ choice.choice_label }}</label>
</div>
</li>
{% endfor %}
</ul>
</div>
</fieldset>
{% endif %}
{% endif %}
27 changes: 16 additions & 11 deletions itou/templates/apply/includes/job_applications_filters/sender.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@
{% if filters_form.senders or filters_form.sender_prescriber_organizations or filters_form.sender_companies %}
<hr>
<fieldset>
<legend>Émetteur</legend>
<legend>
<button class="btn btn-outline-transparent has-collapse-caret collapsed" data-bs-toggle="collapse" data-bs-target="#collapseSenders" type="button" aria-expanded="false" aria-controls="collapseSenders">
Émetteur
</button>
</legend>
<div class="mt-3 collapse" id="collapseSenders">
{% if filters_form.senders %}
{% bootstrap_field filters_form.senders %}
{% endif %}

{% if filters_form.senders %}
{% bootstrap_field filters_form.senders %}
{% endif %}
{% if filters_form.sender_prescriber_organizations %}
{% bootstrap_field filters_form.sender_prescriber_organizations %}
{% endif %}

{% if filters_form.sender_prescriber_organizations %}
{% bootstrap_field filters_form.sender_prescriber_organizations %}
{% endif %}

{% if filters_form.sender_companies %}
{% bootstrap_field filters_form.sender_companies %}
{% endif %}
{% if filters_form.sender_companies %}
{% bootstrap_field filters_form.sender_companies %}
{% endif %}
</div>
</fieldset>
{% endif %}
Loading