Feature 15348 - Quick Access Saved Filters (#15862)

* Added dropdown for Saved Filters.

* Added dropdown for Saved Filters.

* Added dropdown for Saved Filters.

* Fixed linter issues in savedFiltersSelect.ts

* Fixed linter issues in netbox.ts

* Fixed linter issues in netbox.ts

* Removed the blue tag with the filters when saved filters is selected.

* Adjusts in table_controls_htmx.html to vertical height of the Quick Search match to the dropdown.

* Adjusts in table_controls_htmx.html to vertical height of the Quick Search match to the dropdown.

* Adjusts in table_controls_htmx.html to vertical height of the Quick Search match to the dropdown.

* Minor adjusts in savedFiltersSelect.ts

* Addressed PR comment.

* Addressed PR comment.

* Addressed PR comment.

* Omit saved filters from 'applied filters'; clean up form widget

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Julio Oliveira at Encora 2024-06-18 12:58:54 -03:00 committed by GitHub
parent 207c91ef6b
commit 81292df048
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 63 additions and 6 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,30 @@
import { isTruthy } from '../util';
/**
* Handle saved filter change event.
*
* @param event "change" event for the saved filter select
*/
function handleSavedFilterChange(event: Event): void {
const savedFilter = event.currentTarget as HTMLSelectElement;
let baseUrl = savedFilter.baseURI.split('?')[0];
const preFilter = '?';
const selectedOptions = Array.from(savedFilter.options)
.filter(option => option.selected)
.map(option => `filter_id=${option.value}`)
.join('&');
baseUrl += `${preFilter}${selectedOptions}`;
document.location.href = baseUrl;
}
export function initSavedFilterSelect(): void {
const divResults = document.getElementById('results');
if (isTruthy(divResults)) {
const savedFilterSelect = document.getElementById('id_filter_id');
if (isTruthy(savedFilterSelect)) {
savedFilterSelect.addEventListener('change', handleSavedFilterChange);
}
}
}

View File

@ -13,6 +13,7 @@ import { initSideNav } from './sidenav';
import { initDashboard } from './dashboard';
import { initRackElevation } from './racks';
import { initHtmx } from './htmx';
import { initSavedFilterSelect } from './forms/savedFiltersSelect';
function initDocument(): void {
for (const init of [
@ -31,6 +32,7 @@ function initDocument(): void {
initDashboard,
initRackElevation,
initHtmx,
initSavedFilterSelect,
]) {
init();
}

View File

@ -7,6 +7,7 @@
// Overrides of external libraries
@import 'overrides/bootstrap';
@import 'overrides/tabler';
@import 'overrides/tomselect';
// Transitional styling to ease migration of templates from NetBox v3.x
@import 'transitional/badges';

View File

@ -0,0 +1,8 @@
.ts-wrapper.multi {
.ts-control {
padding: 7px 7px 3px 7px;
div {
margin: 0 4px 4px 0;
}
}
}

View File

@ -1,25 +1,37 @@
{% load helpers %}
{% load i18n %}
<div class="row mb-3">
<div class="row mb-3" id="results">
<div class="col-auto d-print-none">
<div class="input-group input-group-flat me-2 quicksearch" hx-disinherit="hx-select hx-swap">
<input type="search" results="5" name="q" id="quicksearch" class="form-control px-2 py-1" placeholder="Quick search"
hx-get="{{ request.full_path }}" hx-target="#object_list" hx-trigger="keyup changed delay:500ms, search" />
<input type="search" results="5" name="q" id="quicksearch" class="form-control" placeholder="{% trans "Quick search" %}"
hx-get="{{ request.full_path }}" hx-target="#object_list" hx-trigger="keyup changed delay:500ms, search"/>
<span class="input-group-text py-1">
<a href="#" id="quicksearch_clear" class="invisible text-secondary"><i class="mdi mdi-close-circle"></i></a>
</span>
{% block extra_table_controls %}{% endblock %}
{% block extra_table_controls %}{% endblock %}
</div>
</div>
<div class="col-auto d-print-none">
<div class="input-group">
<div class="input-group-text">
<i class="mdi mdi-filter" title="{% trans "Saved filter" %}"></i>
</div>
{{ filter_form.filter_id }}
</div>
</div>
<div class="col-auto ms-auto d-print-none">
{% if request.user.is_authenticated and table_modal %}
<div class="table-configure input-group">
<button type="button" data-bs-toggle="modal" title="{% trans "Configure Table" %}" data-bs-target="#{{ table_modal }}"
class="btn">
<button type="button" data-bs-toggle="modal" title="{% trans "Configure Table" %}"
data-bs-target="#{{ table_modal }}"
class="btn">
<i class="mdi mdi-cog"></i> {% trans "Configure Table" %}
</button>
</div>
{% endif %}
</div>
</div>

View File

@ -281,6 +281,10 @@ def applied_filters(context, model, form, query_params):
if filter_name not in querydict:
continue
# Skip saved filters, as they're displayed alongside the quick search widget
if filter_name == 'filter_id':
continue
bound_field = form.fields[filter_name].get_bound_field(form, filter_name)
querydict.pop(filter_name)
display_value = ', '.join([str(v) for v in get_selected_values(form, filter_name)])