Fixes #2921: Replace tags filter with Select2 widget

This commit is contained in:
Saria Hajjar 2020-01-11 15:18:27 +00:00
parent b7e78028ce
commit 834fd408bd
21 changed files with 15 additions and 39 deletions

View File

@ -6,6 +6,7 @@
* [#2050](https://github.com/netbox-community/netbox/issues/2050) - Preview image attachments when hovering the link * [#2050](https://github.com/netbox-community/netbox/issues/2050) - Preview image attachments when hovering the link
* [#2113](https://github.com/netbox-community/netbox/issues/2113) - Allow NAPALM driver settings to be changed with request headers * [#2113](https://github.com/netbox-community/netbox/issues/2113) - Allow NAPALM driver settings to be changed with request headers
* [#2589](https://github.com/netbox-community/netbox/issues/2589) - Toggle for showing available prefixes/ip addresses * [#2589](https://github.com/netbox-community/netbox/issues/2589) - Toggle for showing available prefixes/ip addresses
* [#2921](https://github.com/netbox-community/netbox/issues/2921) - Replace tags filter with Select2 widget
* [#3009](https://github.com/netbox-community/netbox/issues/3009) - Search by description when assigning IP address * [#3009](https://github.com/netbox-community/netbox/issues/3009) - Search by description when assigning IP address
* [#3090](https://github.com/netbox-community/netbox/issues/3090) - Add filter field for device interfaces * [#3090](https://github.com/netbox-community/netbox/issues/3090) - Add filter field for device interfaces
* [#3187](https://github.com/netbox-community/netbox/issues/3187) - Add rack selection field to rack elevations * [#3187](https://github.com/netbox-community/netbox/issues/3187) - Add rack selection field to rack elevations

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -13,7 +13,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,13 +0,0 @@
{% load helpers %}
<div class="panel panel-default">
<div class="panel-heading">
<span class="fa fa-tags" aria-hidden="true"></span>
<strong>Tags</strong>
</div>
<div class="panel-body text-center">
{% for tag in tags %}
<a href="{% querystring request tag=tag.slug %}" class="btn btn-sm {% if tag.slug in request.GET.tag %}btn-primary{% else %}btn-link{% endif %}">{{ tag }} <span class="badge">{{ tag.count }}</span></a>
{% endfor %}
</div>
</div>

View File

@ -17,7 +17,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<strong><i class="fa fa-bar-chart"></i> Statistics</strong> <strong><i class="fa fa-bar-chart"></i> Statistics</strong>

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -21,7 +21,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -12,7 +12,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -15,7 +15,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -16,7 +16,6 @@
</div> </div>
<div class="col-md-3 noprint"> <div class="col-md-3 noprint">
{% include 'inc/search_panel.html' %} {% include 'inc/search_panel.html' %}
{% include 'inc/tags_panel.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from django.db.models import Count, ProtectedError from django.db.models import Count, ProtectedError
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.forms import CharField, Form, ModelMultipleChoiceField, MultipleHiddenInput, Textarea from django.forms import CharField, Form, ModelMultipleChoiceField, MultipleChoiceField, MultipleHiddenInput, Textarea
from django.http import HttpResponse, HttpResponseServerError from django.http import HttpResponse, HttpResponseServerError
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader from django.template import loader
@ -24,7 +24,7 @@ from django_tables2 import RequestConfig
from extras.models import CustomField, CustomFieldValue, ExportTemplate from extras.models import CustomField, CustomFieldValue, ExportTemplate
from extras.querysets import CustomFieldQueryset from extras.querysets import CustomFieldQueryset
from utilities.forms import BootstrapMixin, CSVDataField from utilities.forms import BootstrapMixin, CSVDataField, StaticSelect2Multiple
from utilities.utils import csv_format from utilities.utils import csv_format
from .error_handlers import handle_protectederror from .error_handlers import handle_protectederror
from .forms import ConfirmationForm from .forms import ConfirmationForm
@ -94,6 +94,7 @@ class ObjectListView(View):
model = self.queryset.model model = self.queryset.model
content_type = ContentType.objects.get_for_model(model) content_type = ContentType.objects.get_for_model(model)
filter_form = self.filter_form(request.GET, label_suffix='') if self.filter_form else None
if self.filter: if self.filter:
self.queryset = self.filter(request.GET, self.queryset).qs self.queryset = self.filter(request.GET, self.queryset).qs
@ -142,11 +143,17 @@ class ObjectListView(View):
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']): if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
table.columns.show('pk') table.columns.show('pk')
# Construct queryset for tags list # Add the tags filter field to the from if the model has tags
if hasattr(model, 'tags'): if hasattr(model, 'tags') and filter_form:
tags = model.tags.annotate(count=Count('extras_taggeditem_items')).order_by('name') tags = model.tags.annotate(count=Count('extras_taggeditem_items')).order_by('name')
else: choices = [(str(tag.slug), '{} ({})'.format(tag.name, tag.count)) for tag in tags]
tags = None
filter_form.fields['tag'] = MultipleChoiceField(
label='Tags',
choices=choices,
required=False,
widget=StaticSelect2Multiple(),
)
# Apply the request context # Apply the request context
paginate = { paginate = {
@ -159,8 +166,7 @@ class ObjectListView(View):
'content_type': content_type, 'content_type': content_type,
'table': table, 'table': table,
'permissions': permissions, 'permissions': permissions,
'filter_form': self.filter_form(request.GET, label_suffix='') if self.filter_form else None, 'filter_form': filter_form,
'tags': tags,
} }
context.update(self.extra_context()) context.update(self.extra_context())