Просмотр исходного кода

Fixes #2921: Replace tags filter with Select2 widget

Saria Hajjar 6 лет назад
Родитель
Сommit
834fd408bd

+ 1 - 0
docs/release-notes/version-2.6.md

@@ -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

+ 0 - 1
netbox/templates/circuits/circuit_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/circuits/provider_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/dcim/device_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/dcim/devicetype_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/dcim/powerfeed_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/dcim/rack_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/dcim/site_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/dcim/virtualchassis_list.html

@@ -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 %}

+ 0 - 13
netbox/templates/inc/tags_panel.html

@@ -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>

+ 0 - 1
netbox/templates/ipam/aggregate_list.html

@@ -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>

+ 0 - 1
netbox/templates/ipam/ipaddress_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/ipam/prefix_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/ipam/service_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/ipam/vlan_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/ipam/vrf_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/secrets/secret_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/tenancy/tenant_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/virtualization/cluster_list.html

@@ -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 %}

+ 0 - 1
netbox/templates/virtualization/virtualmachine_list.html

@@ -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 %}

+ 14 - 8
netbox/utilities/views.py

@@ -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
-        if hasattr(model, 'tags'):
+        # Add the tags filter field to the from if the model has 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:
-            tags = None
+            choices = [(str(tag.slug), '{} ({})'.format(tag.name, tag.count)) for tag in tags]
+
+            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,
-            'tags': tags,
+            'filter_form': filter_form,
         }
         }
         context.update(self.extra_context())
         context.update(self.extra_context())