Replace active_tab context for object views

This commit is contained in:
jeremystretch 2022-10-07 12:14:19 -04:00
parent bfe26b46a6
commit 5e1a0733e4
11 changed files with 22 additions and 76 deletions

View File

@ -46,11 +46,6 @@ class DeviceComponentsView(generic.ObjectChildrenView):
def get_children(self, request, parent): def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(device=parent) return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)
def get_extra_context(self, request, instance):
return {
'active_tab': f"{self.child_model._meta.verbose_name_plural.replace(' ', '')}",
}
class DeviceTypeComponentsView(DeviceComponentsView): class DeviceTypeComponentsView(DeviceComponentsView):
queryset = DeviceType.objects.all() queryset = DeviceType.objects.all()
@ -61,9 +56,7 @@ class DeviceTypeComponentsView(DeviceComponentsView):
return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent) return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
model_name = self.child_model._meta.verbose_name_plural
return { return {
'active_tab': f"{model_name.replace(' ', '').replace('template', '')}",
'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}), 'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
} }
@ -77,9 +70,7 @@ class ModuleTypeComponentsView(DeviceComponentsView):
return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent) return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent)
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
model_name = self.child_model._meta.verbose_name_plural
return { return {
'active_tab': f"{model_name.replace(' ', '').replace('template', '')}",
'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}), 'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
} }

View File

@ -352,7 +352,6 @@ class ObjectConfigContextView(generic.ObjectView):
'source_contexts': source_contexts, 'source_contexts': source_contexts,
'format': format, 'format': format,
'base_template': self.base_template, 'base_template': self.base_template,
'active_tab': 'configcontext',
} }

View File

@ -141,8 +141,6 @@ urlpatterns = [
path('vlans/edit/', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'), path('vlans/edit/', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
path('vlans/delete/', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'), path('vlans/delete/', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),
path('vlans/<int:pk>/', views.VLANView.as_view(), name='vlan'), path('vlans/<int:pk>/', views.VLANView.as_view(), name='vlan'),
path('vlans/<int:pk>/interfaces/', views.VLANInterfacesView.as_view(), name='vlan_interfaces'),
path('vlans/<int:pk>/vm-interfaces/', views.VLANVMInterfacesView.as_view(), name='vlan_vminterfaces'),
path('vlans/<int:pk>/edit/', views.VLANEditView.as_view(), name='vlan_edit'), path('vlans/<int:pk>/edit/', views.VLANEditView.as_view(), name='vlan_edit'),
path('vlans/<int:pk>/delete/', views.VLANDeleteView.as_view(), name='vlan_delete'), path('vlans/<int:pk>/delete/', views.VLANDeleteView.as_view(), name='vlan_delete'),
path('vlans/<int:pk>/', include(get_model_urls('ipam', 'vlan'))), path('vlans/<int:pk>/', include(get_model_urls('ipam', 'vlan'))),

View File

@ -319,7 +319,6 @@ class AggregatePrefixesView(generic.ObjectChildrenView):
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
return { return {
'bulk_querystring': f'within={instance.prefix}', 'bulk_querystring': f'within={instance.prefix}',
'active_tab': 'prefixes',
'first_available_prefix': instance.get_first_available_prefix(), 'first_available_prefix': instance.get_first_available_prefix(),
'show_available': bool(request.GET.get('show_available', 'true') == 'true'), 'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'), 'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
@ -502,7 +501,6 @@ class PrefixPrefixesView(generic.ObjectChildrenView):
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
return { return {
'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&within={instance.prefix}", 'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&within={instance.prefix}",
'active_tab': 'prefixes',
'first_available_prefix': instance.get_first_available_prefix(), 'first_available_prefix': instance.get_first_available_prefix(),
'show_available': bool(request.GET.get('show_available', 'true') == 'true'), 'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'), 'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
@ -530,7 +528,6 @@ class PrefixIPRangesView(generic.ObjectChildrenView):
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
return { return {
'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}", 'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
'active_tab': 'ipranges',
'first_available_ip': instance.get_first_available_ip(), 'first_available_ip': instance.get_first_available_ip(),
} }
@ -559,7 +556,6 @@ class PrefixIPAddressesView(generic.ObjectChildrenView):
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
return { return {
'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}", 'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
'active_tab': 'ipaddresses',
'first_available_ip': instance.get_first_available_ip(), 'first_available_ip': instance.get_first_available_ip(),
} }
@ -623,11 +619,6 @@ class IPRangeIPAddressesView(generic.ObjectChildrenView):
def get_children(self, request, parent): def get_children(self, request, parent):
return parent.get_child_ips().restrict(request.user, 'view') return parent.get_child_ips().restrict(request.user, 'view')
def get_extra_context(self, request, instance):
return {
'active_tab': 'ipaddresses',
}
class IPRangeEditView(generic.ObjectEditView): class IPRangeEditView(generic.ObjectEditView):
queryset = IPRange.objects.all() queryset = IPRange.objects.all()
@ -1032,37 +1023,39 @@ class VLANView(generic.ObjectView):
} }
@register_model_view(VLAN, 'interfaces')
class VLANInterfacesView(generic.ObjectChildrenView): class VLANInterfacesView(generic.ObjectChildrenView):
queryset = VLAN.objects.all() queryset = VLAN.objects.all()
child_model = Interface child_model = Interface
table = tables.VLANDevicesTable table = tables.VLANDevicesTable
filterset = InterfaceFilterSet filterset = InterfaceFilterSet
template_name = 'ipam/vlan/interfaces.html' template_name = 'ipam/vlan/interfaces.html'
tab = ViewTab(
label=_('Device Interfaces'),
badge=lambda x: x.get_interfaces().count(),
permission='dcim.view_interface'
)
def get_children(self, request, parent): def get_children(self, request, parent):
return parent.get_interfaces().restrict(request.user, 'view') return parent.get_interfaces().restrict(request.user, 'view')
def get_extra_context(self, request, instance):
return {
'active_tab': 'interfaces',
}
@register_model_view(VLAN, 'vminterfaces', path='vm-interfaces')
class VLANVMInterfacesView(generic.ObjectChildrenView): class VLANVMInterfacesView(generic.ObjectChildrenView):
queryset = VLAN.objects.all() queryset = VLAN.objects.all()
child_model = VMInterface child_model = VMInterface
table = tables.VLANVirtualMachinesTable table = tables.VLANVirtualMachinesTable
filterset = VMInterfaceFilterSet filterset = VMInterfaceFilterSet
template_name = 'ipam/vlan/vminterfaces.html' template_name = 'ipam/vlan/vminterfaces.html'
tab = ViewTab(
label=_('VM Interfaces'),
badge=lambda x: x.get_vminterfaces().count(),
permission='virtualization.view_vminterface'
)
def get_children(self, request, parent): def get_children(self, request, parent):
return parent.get_vminterfaces().restrict(request.user, 'view') return parent.get_vminterfaces().restrict(request.user, 'view')
def get_extra_context(self, request, instance):
return {
'active_tab': 'vminterfaces',
}
class VLANEditView(generic.ObjectEditView): class VLANEditView(generic.ObjectEditView):
queryset = VLAN.objects.all() queryset = VLAN.objects.all()

View File

@ -14,6 +14,7 @@ class BaseObjectView(ObjectPermissionRequiredMixin, View):
""" """
queryset = None queryset = None
template_name = None template_name = None
tab = None
def get_object(self, **kwargs): def get_object(self, **kwargs):
""" """

View File

@ -62,7 +62,7 @@ class ObjectChangeLogView(View):
'object': obj, 'object': obj,
'table': objectchanges_table, 'table': objectchanges_table,
'base_template': self.base_template, 'base_template': self.base_template,
'active_tab': 'changelog', 'tab': self.tab,
}) })
@ -122,5 +122,5 @@ class ObjectJournalView(View):
'form': form, 'form': form,
'table': journalentry_table, 'table': journalentry_table,
'base_template': self.base_template, 'base_template': self.base_template,
'active_tab': 'journal', 'tab': self.tab,
}) })

View File

@ -5,7 +5,6 @@ from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction from django.db import transaction
from django.db.models import ProtectedError from django.db.models import ProtectedError
from django.forms.widgets import HiddenInput
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.urls import reverse from django.urls import reverse
from django.utils.html import escape from django.utils.html import escape
@ -67,6 +66,7 @@ class ObjectView(BaseObjectView):
return render(request, self.get_template_name(), { return render(request, self.get_template_name(), {
'object': instance, 'object': instance,
'tab': self.tab,
**self.get_extra_context(request, instance), **self.get_extra_context(request, instance),
}) })
@ -141,6 +141,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
'child_model': self.child_model, 'child_model': self.child_model,
'table': table, 'table': table,
'actions': actions, 'actions': actions,
'tab': self.tab,
**self.get_extra_context(request, instance), **self.get_extra_context(request, instance),
}) })

View File

@ -81,7 +81,7 @@ Context:
<ul class="nav nav-tabs px-3"> <ul class="nav nav-tabs px-3">
{# Primary tab #} {# Primary tab #}
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<a class="nav-link{% if not active_tab %} active{% endif %}" href="{{ object.get_absolute_url }}">{{ object|meta:"verbose_name"|bettertitle }}</a> <a class="nav-link{% if not tab %} active{% endif %}" href="{{ object.get_absolute_url }}">{{ object|meta:"verbose_name"|bettertitle }}</a>
</li> </li>
{# Include any extra tabs passed by the view #} {# Include any extra tabs passed by the view #}

View File

@ -13,27 +13,3 @@
<li class="breadcrumb-item"><a href="{% url 'ipam:vlan_list' %}?group_id={{ object.group.pk }}">{{ object.group }}</a></li> <li class="breadcrumb-item"><a href="{% url 'ipam:vlan_list' %}?group_id={{ object.group.pk }}">{{ object.group }}</a></li>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block tabs %}
<ul class="nav nav-tabs px-3">
<li class="nav-item" role="presentation">
<a class="nav-link{% if not active_tab %} active{% endif %}" href="{% url 'ipam:vlan' pk=object.pk %}">VLAN</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link{% if active_tab == 'interfaces' %} active{% endif %}" href="{% url 'ipam:vlan_interfaces' pk=object.pk %}">Device Interfaces {% badge object.get_interfaces.count %}</a>
</li>
<li class="nav-item" role="presentation">
<a class="nav-link{% if active_tab == 'vminterfaces' %} active{% endif %}" href="{% url 'ipam:vlan_vminterfaces' pk=object.pk %}">VM Interfaces {% badge object.get_vminterfaces.count %}</a>
</li>
{% if perms.extras.view_journalentry %}
<li class="nav-item" role="presentation">
<a class="nav-link{% if active_tab == 'journal' %} active{% endif %}" href="{% url 'ipam:vlan_journal' pk=object.pk %}">Journal</a>
</li>
{% endif %}
{% if perms.extras.view_objectchange %}
<li class="nav-item" role="presentation">
<a class="nav-link{% if active_tab == 'changelog' %} active{% endif %}" href="{% url 'ipam:vlan_changelog' pk=object.pk %}">Change Log</a>
</li>
{% endif %}
</ul>
{% endblock %}

View File

@ -41,12 +41,14 @@ def model_view_tabs(context, instance):
if not tab.always_display and not badge_value: if not tab.always_display and not badge_value:
continue continue
viewname = f"{app_label}:{model_name}_{config['name']}"
active_tab = context.get('tab')
tabs.append({ tabs.append({
'name': config['name'], 'name': config['name'],
'url': reverse(f"{app_label}:{model_name}_{config['name']}", args=[instance.pk]), 'url': reverse(viewname, args=[instance.pk]),
'label': tab.label, 'label': tab.label,
'badge_value': badge_value, 'badge_value': badge_value,
'is_active': context.get('active_tab') == config['name'], 'is_active': active_tab and active_tab == tab,
}) })
return { return {

View File

@ -179,11 +179,6 @@ class ClusterVirtualMachinesView(generic.ObjectChildrenView):
def get_children(self, request, parent): def get_children(self, request, parent):
return VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=parent) return VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=parent)
def get_extra_context(self, request, instance):
return {
'active_tab': 'virtualmachines',
}
@register_model_view(Cluster, 'devices') @register_model_view(Cluster, 'devices')
class ClusterDevicesView(generic.ObjectChildrenView): class ClusterDevicesView(generic.ObjectChildrenView):
@ -201,11 +196,6 @@ class ClusterDevicesView(generic.ObjectChildrenView):
def get_children(self, request, parent): def get_children(self, request, parent):
return Device.objects.restrict(request.user, 'view').filter(cluster=parent) return Device.objects.restrict(request.user, 'view').filter(cluster=parent)
def get_extra_context(self, request, instance):
return {
'active_tab': 'devices',
}
class ClusterEditView(generic.ObjectEditView): class ClusterEditView(generic.ObjectEditView):
queryset = Cluster.objects.all() queryset = Cluster.objects.all()
@ -377,11 +367,6 @@ class VirtualMachineInterfacesView(generic.ObjectChildrenView):
'tags', 'tags',
) )
def get_extra_context(self, request, instance):
return {
'active_tab': 'interfaces',
}
@register_model_view(VirtualMachine, 'configcontext', path='config-context') @register_model_view(VirtualMachine, 'configcontext', path='config-context')
class VirtualMachineConfigContextView(ObjectConfigContextView): class VirtualMachineConfigContextView(ObjectConfigContextView):