From faf1e6a43d75cf826c9b460356a70814eb8427d2 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Oct 2021 15:30:28 -0400 Subject: [PATCH] Add contact/role assignment tables --- netbox/templates/tenancy/contact.html | 13 +++++++++++++ netbox/templates/tenancy/contactrole.html | 6 ++++++ netbox/tenancy/tables.py | 23 ++++++++++++++++++----- netbox/tenancy/views.py | 21 +++++++++++++++++++-- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/netbox/templates/tenancy/contact.html b/netbox/templates/tenancy/contact.html index 2ead52e5a..ca46fdb31 100644 --- a/netbox/templates/tenancy/contact.html +++ b/netbox/templates/tenancy/contact.html @@ -46,6 +46,12 @@ Address {{ object.address|linebreaksbr|placeholder }} + + Assignments + + {{ assignment_count }} + + @@ -60,6 +66,13 @@
+
+
Assignments
+
+ {% include 'inc/table.html' with table=contacts_table %} +
+
+ {% include 'inc/paginator.html' with paginator=contacts_table.paginator page=contacts_table.page %} {% plugin_full_width_page object %}
diff --git a/netbox/templates/tenancy/contactrole.html b/netbox/templates/tenancy/contactrole.html index 688c58177..f081afc34 100644 --- a/netbox/templates/tenancy/contactrole.html +++ b/netbox/templates/tenancy/contactrole.html @@ -21,6 +21,12 @@ Description {{ object.description|placeholder }} + + Assignments + + {{ assignment_count }} + + diff --git a/netbox/tenancy/tables.py b/netbox/tenancy/tables.py index 3401c8fe4..5b254842b 100644 --- a/netbox/tenancy/tables.py +++ b/netbox/tenancy/tables.py @@ -1,7 +1,7 @@ import django_tables2 as tables from utilities.tables import ( - BaseTable, ButtonsColumn, LinkedCountColumn, MarkdownColumn, MPTTColumn, TagColumn, ToggleColumn, + BaseTable, ButtonsColumn, ContentTypeColumn, LinkedCountColumn, MarkdownColumn, MPTTColumn, TagColumn, ToggleColumn, ) from .models import * @@ -126,23 +126,36 @@ class ContactTable(BaseTable): linkify=True ) comments = MarkdownColumn() + assignment_count = tables.Column( + verbose_name='Assignments' + ) tags = TagColumn( url_name='tenancy:tenant_list' ) class Meta(BaseTable.Meta): model = Contact - fields = ('pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'comments', 'tags') - default_columns = ('pk', 'name', 'group', 'title', 'phone', 'email') + fields = ('pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'comments', 'assignment_count', 'tags') + default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email') class ContactAssignmentTable(BaseTable): pk = ToggleColumn() + content_type = ContentTypeColumn( + verbose_name='Object Type' + ) + object = tables.Column( + linkify=True, + orderable=False + ) contact = tables.Column( linkify=True ) + role = tables.Column( + linkify=True + ) class Meta(BaseTable.Meta): model = ContactAssignment - fields = ('pk', 'contact', 'role', 'priority') - default_columns = ('pk', 'contact', 'role', 'priority') + fields = ('pk', 'content_type', 'object', 'contact', 'role', 'priority') + default_columns = ('pk', 'object', 'contact', 'role', 'priority') diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py index e7034ed5f..cdbaebdb1 100644 --- a/netbox/tenancy/views.py +++ b/netbox/tenancy/views.py @@ -7,6 +7,7 @@ from dcim.models import Site, Rack, Device, RackReservation from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF from netbox.views import generic from utilities.tables import paginate_table +from utilities.utils import count_related from virtualization.models import VirtualMachine, Cluster from . import filtersets, forms, tables from .models import * @@ -236,11 +237,12 @@ class ContactRoleView(generic.ObjectView): role=instance ) contacts_table = tables.ContactAssignmentTable(contact_assignments) + contacts_table.columns.hide('role') paginate_table(contacts_table, request) return { 'contacts_table': contacts_table, - 'contact_count': ContactAssignment.objects.filter(role=instance).count(), + 'assignment_count': ContactAssignment.objects.filter(role=instance).count(), } @@ -276,7 +278,9 @@ class ContactRoleBulkDeleteView(generic.BulkDeleteView): # class ContactListView(generic.ObjectListView): - queryset = Contact.objects.all() + queryset = Contact.objects.annotate( + assignment_count=count_related(ContactAssignment, 'contact') + ) filterset = filtersets.ContactFilterSet filterset_form = forms.ContactFilterForm table = tables.ContactTable @@ -285,6 +289,19 @@ class ContactListView(generic.ObjectListView): class ContactView(generic.ObjectView): queryset = Contact.objects.all() + def get_extra_context(self, request, instance): + contact_assignments = ContactAssignment.objects.restrict(request.user, 'view').filter( + contact=instance + ) + contacts_table = tables.ContactAssignmentTable(contact_assignments) + contacts_table.columns.hide('contact') + paginate_table(contacts_table, request) + + return { + 'contacts_table': contacts_table, + 'assignment_count': ContactAssignment.objects.filter(contact=instance).count(), + } + class ContactEditView(generic.ObjectEditView): queryset = Contact.objects.all()