From 7163840279c3f2970e70ac66084371a6b31674fa Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 18 Mar 2026 12:31:54 -0400 Subject: [PATCH] #20923: Migrate remaining DCIM views to new UI layouts --- netbox/dcim/ui/panels.py | 267 +++++++++++++++++ netbox/dcim/views.py | 282 +++++++++++++++++- netbox/templates/dcim/cable.html | 86 ------ netbox/templates/dcim/consoleport.html | 87 ------ netbox/templates/dcim/consoleserverport.html | 87 ------ netbox/templates/dcim/devicebay.html | 62 ---- netbox/templates/dcim/frontport.html | 148 --------- netbox/templates/dcim/inventoryitem.html | 73 ----- netbox/templates/dcim/inventoryitemrole.html | 52 ---- netbox/templates/dcim/macaddress.html | 54 ---- .../dcim/macaddress/attrs/assignment.html | 7 + netbox/templates/dcim/modulebay.html | 82 ----- .../dcim/panels/cable_termination_a.html | 6 + .../dcim/panels/cable_termination_b.html | 6 + .../panels/component_inventory_items.html | 40 +++ netbox/templates/dcim/panels/connection.html | 96 ++++++ .../dcim/panels/installed_device.html | 21 ++ .../dcim/panels/installed_module.html | 33 ++ .../templates/dcim/panels/port_mappings.html | 31 ++ .../virtual_chassis_detail_members.html | 36 +++ netbox/templates/dcim/powerfeed.html | 129 +------- .../powerfeed/attrs/connected_device.html | 6 + .../dcim/powerfeed/attrs/utilization.html | 15 + netbox/templates/dcim/poweroutlet.html | 92 ------ netbox/templates/dcim/powerpanel.html | 74 +---- netbox/templates/dcim/powerport.html | 88 ------ netbox/templates/dcim/rearport.html | 142 --------- netbox/templates/dcim/virtualchassis.html | 89 ------ .../templates/dcim/virtualdevicecontext.html | 86 ------ 29 files changed, 842 insertions(+), 1435 deletions(-) create mode 100644 netbox/templates/dcim/macaddress/attrs/assignment.html create mode 100644 netbox/templates/dcim/panels/cable_termination_a.html create mode 100644 netbox/templates/dcim/panels/cable_termination_b.html create mode 100644 netbox/templates/dcim/panels/component_inventory_items.html create mode 100644 netbox/templates/dcim/panels/connection.html create mode 100644 netbox/templates/dcim/panels/installed_device.html create mode 100644 netbox/templates/dcim/panels/installed_module.html create mode 100644 netbox/templates/dcim/panels/port_mappings.html create mode 100644 netbox/templates/dcim/panels/virtual_chassis_detail_members.html create mode 100644 netbox/templates/dcim/powerfeed/attrs/connected_device.html create mode 100644 netbox/templates/dcim/powerfeed/attrs/utilization.html diff --git a/netbox/dcim/ui/panels.py b/netbox/dcim/ui/panels.py index fa7ad848a..981644825 100644 --- a/netbox/dcim/ui/panels.py +++ b/netbox/dcim/ui/panels.py @@ -1,3 +1,4 @@ +from django.template.loader import render_to_string from django.utils.translation import gettext_lazy as _ from netbox.ui import attrs, panels @@ -189,6 +190,272 @@ class PlatformPanel(panels.NestedGroupObjectPanel): config_template = attrs.RelatedObjectAttr('config_template', linkify=True) +class ConsolePortPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + type = attrs.ChoiceAttr('type') + speed = attrs.ChoiceAttr('speed') + description = attrs.TextAttr('description') + + +class ConsoleServerPortPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + type = attrs.ChoiceAttr('type') + speed = attrs.ChoiceAttr('speed') + description = attrs.TextAttr('description') + + +class PowerPortPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + type = attrs.ChoiceAttr('type') + description = attrs.TextAttr('description') + maximum_draw = attrs.TextAttr('maximum_draw') + allocated_draw = attrs.TextAttr('allocated_draw') + + +class PowerOutletPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + type = attrs.ChoiceAttr('type') + status = attrs.ChoiceAttr('status') + description = attrs.TextAttr('description') + color = attrs.ColorAttr('color') + power_port = attrs.RelatedObjectAttr('power_port', linkify=True) + feed_leg = attrs.ChoiceAttr('feed_leg') + + +class FrontPortPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + type = attrs.ChoiceAttr('type') + color = attrs.ColorAttr('color') + positions = attrs.TextAttr('positions') + description = attrs.TextAttr('description') + + +class RearPortPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + type = attrs.ChoiceAttr('type') + color = attrs.ColorAttr('color') + positions = attrs.TextAttr('positions') + description = attrs.TextAttr('description') + + +class ModuleBayPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + module = attrs.RelatedObjectAttr('module', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + position = attrs.TextAttr('position') + description = attrs.TextAttr('description') + + +class DeviceBayPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + description = attrs.TextAttr('description') + + +class InventoryItemPanel(panels.ObjectAttributesPanel): + device = attrs.RelatedObjectAttr('device', linkify=True) + parent = attrs.RelatedObjectAttr('parent', linkify=True, label=_('Parent item')) + name = attrs.TextAttr('name') + label = attrs.TextAttr('label') + status = attrs.ChoiceAttr('status') + role = attrs.RelatedObjectAttr('role', linkify=True) + component = attrs.GenericForeignKeyAttr('component', linkify=True) + manufacturer = attrs.RelatedObjectAttr('manufacturer', linkify=True) + part_id = attrs.TextAttr('part_id', label=_('Part ID')) + serial = attrs.TextAttr('serial') + asset_tag = attrs.TextAttr('asset_tag') + description = attrs.TextAttr('description') + + +class InventoryItemRolePanel(panels.OrganizationalObjectPanel): + color = attrs.ColorAttr('color') + + +class CablePanel(panels.ObjectAttributesPanel): + type = attrs.ChoiceAttr('type') + status = attrs.ChoiceAttr('status') + profile = attrs.ChoiceAttr('profile') + tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group') + label = attrs.TextAttr('label') + description = attrs.TextAttr('description') + color = attrs.ColorAttr('color') + length = attrs.NumericAttr('length', unit_accessor='get_length_unit_display') + + +class VirtualChassisPanel(panels.ObjectAttributesPanel): + domain = attrs.TextAttr('domain') + master = attrs.RelatedObjectAttr('master', linkify=True) + description = attrs.TextAttr('description') + + +class VirtualChassisDetailMembersPanel(panels.ObjectPanel): + """ + A panel which lists all members of a virtual chassis on the VirtualChassis detail view. + """ + template_name = 'dcim/panels/virtual_chassis_detail_members.html' + title = _('Members') + + def get_context(self, context): + return { + **super().get_context(context), + 'members': context.get('members'), + } + + def render(self, context): + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + +class PowerPanelPanel(panels.ObjectAttributesPanel): + site = attrs.RelatedObjectAttr('site', linkify=True) + location = attrs.NestedObjectAttr('location', linkify=True) + description = attrs.TextAttr('description') + + +class PowerFeedPanel(panels.ObjectAttributesPanel): + power_panel = attrs.RelatedObjectAttr('power_panel', linkify=True) + rack = attrs.RelatedObjectAttr('rack', linkify=True) + type = attrs.ChoiceAttr('type') + status = attrs.ChoiceAttr('status') + description = attrs.TextAttr('description') + tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group') + connected_device = attrs.TemplatedAttr( + 'connected_endpoints', + label=_('Connected device'), + template_name='dcim/powerfeed/attrs/connected_device.html', + ) + utilization = attrs.TemplatedAttr( + 'connected_endpoints', + label=_('Utilization (allocated)'), + template_name='dcim/powerfeed/attrs/utilization.html', + ) + + +class PowerFeedElectricalPanel(panels.ObjectAttributesPanel): + title = _('Electrical Characteristics') + + supply = attrs.ChoiceAttr('supply') + voltage = attrs.TextAttr('voltage', format_string=_('{}V')) + amperage = attrs.TextAttr('amperage', format_string=_('{}A')) + phase = attrs.ChoiceAttr('phase') + max_utilization = attrs.TextAttr('max_utilization', format_string='{}%') + + +class VirtualDeviceContextPanel(panels.ObjectAttributesPanel): + name = attrs.TextAttr('name') + device = attrs.RelatedObjectAttr('device', linkify=True) + identifier = attrs.TextAttr('identifier') + status = attrs.ChoiceAttr('status') + primary_ip4 = attrs.TemplatedAttr( + 'primary_ip4', + label=_('Primary IPv4'), + template_name='dcim/device/attrs/ipaddress.html', + ) + primary_ip6 = attrs.TemplatedAttr( + 'primary_ip6', + label=_('Primary IPv6'), + template_name='dcim/device/attrs/ipaddress.html', + ) + tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group') + + +class MACAddressPanel(panels.ObjectAttributesPanel): + mac_address = attrs.TextAttr('mac_address', label=_('MAC address'), style='font-monospace', copy_button=True) + description = attrs.TextAttr('description') + assignment = attrs.TemplatedAttr( + 'assigned_object', + template_name='dcim/macaddress/attrs/assignment.html', + ) + is_primary = attrs.BooleanAttr('is_primary', label=_('Primary for interface')) + + +class ConnectionPanel(panels.ObjectPanel): + """ + A panel which displays connection information for a cabled object. + """ + template_name = 'dcim/panels/connection.html' + title = _('Connection') + + def __init__(self, trace_url_name, connect_options=None, show_endpoints=True, **kwargs): + super().__init__(**kwargs) + self.trace_url_name = trace_url_name + self.connect_options = connect_options or [] + self.show_endpoints = show_endpoints + + def get_context(self, context): + return { + **super().get_context(context), + 'trace_url_name': self.trace_url_name, + 'connect_options': self.connect_options, + 'show_endpoints': self.show_endpoints, + } + + def render(self, context): + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + +class InventoryItemsPanel(panels.ObjectPanel): + """ + A panel which displays inventory items associated with a component. + """ + template_name = 'dcim/panels/component_inventory_items.html' + title = _('Inventory Items') + + def render(self, context): + obj = context['object'] + if not obj.inventory_items.exists(): + return '' + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + +class PortMappingsPanel(panels.ObjectPanel): + """ + A panel which displays port position mappings for front/rear ports. + """ + template_name = 'dcim/panels/port_mappings.html' + title = _('Port Mappings') + + def __init__(self, context_key, label_column, position_field, port_field, port_position_field, **kwargs): + super().__init__(**kwargs) + self.context_key = context_key + self.label_column = label_column + self.position_field = position_field + self.port_field = port_field + self.port_position_field = port_position_field + + def get_context(self, context): + return { + **super().get_context(context), + 'mappings': context.get(self.context_key, []), + 'label_column': self.label_column, + 'position_field': self.position_field, + 'port_field': self.port_field, + 'port_position_field': self.port_position_field, + } + + class VirtualChassisMembersPanel(panels.ObjectPanel): """ A panel which lists all members of a virtual chassis. diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c90f63753..5fc25ebff 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -2907,6 +2907,28 @@ class ConsolePortListView(generic.ObjectListView): @register_model_view(ConsolePort) class ConsolePortView(generic.ObjectView): queryset = ConsolePort.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.ConsolePortPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:consoleport_trace', + connect_options=[ + { + 'a_type': 'dcim.consoleport', + 'b_type': 'dcim.consoleserverport', + 'label': _('Console Server Port'), + }, + {'a_type': 'dcim.consoleport', 'b_type': 'dcim.frontport', 'label': _('Front Port')}, + {'a_type': 'dcim.consoleport', 'b_type': 'dcim.rearport', 'label': _('Rear Port')}, + ], + ), + panels.InventoryItemsPanel(), + ], + ) @register_model_view(ConsolePort, 'add', detail=False) @@ -2978,6 +3000,24 @@ class ConsoleServerPortListView(generic.ObjectListView): @register_model_view(ConsoleServerPort) class ConsoleServerPortView(generic.ObjectView): queryset = ConsoleServerPort.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.ConsoleServerPortPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:consoleserverport_trace', + connect_options=[ + {'a_type': 'dcim.consoleserverport', 'b_type': 'dcim.consoleport', 'label': _('Console Port')}, + {'a_type': 'dcim.consoleserverport', 'b_type': 'dcim.frontport', 'label': _('Front Port')}, + {'a_type': 'dcim.consoleserverport', 'b_type': 'dcim.rearport', 'label': _('Rear Port')}, + ], + ), + panels.InventoryItemsPanel(), + ], + ) @register_model_view(ConsoleServerPort, 'add', detail=False) @@ -3049,6 +3089,23 @@ class PowerPortListView(generic.ObjectListView): @register_model_view(PowerPort) class PowerPortView(generic.ObjectView): queryset = PowerPort.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.PowerPortPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:powerport_trace', + connect_options=[ + {'a_type': 'dcim.powerport', 'b_type': 'dcim.poweroutlet', 'label': _('Power Outlet')}, + {'a_type': 'dcim.powerport', 'b_type': 'dcim.powerfeed', 'label': _('Power Feed')}, + ], + ), + panels.InventoryItemsPanel(), + ], + ) @register_model_view(PowerPort, 'add', detail=False) @@ -3120,6 +3177,22 @@ class PowerOutletListView(generic.ObjectListView): @register_model_view(PowerOutlet) class PowerOutletView(generic.ObjectView): queryset = PowerOutlet.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.PowerOutletPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:poweroutlet_trace', + connect_options=[ + {'a_type': 'dcim.poweroutlet', 'b_type': 'dcim.powerport', 'label': _('Power Port')}, + ], + ), + panels.InventoryItemsPanel(), + ], + ) @register_model_view(PowerOutlet, 'add', detail=False) @@ -3329,6 +3402,39 @@ class FrontPortListView(generic.ObjectListView): @register_model_view(FrontPort) class FrontPortView(generic.ObjectView): queryset = FrontPort.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.FrontPortPanel(), + CustomFieldsPanel(), + TagsPanel(), + panels.InventoryItemsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:frontport_trace', + show_endpoints=False, + connect_options=[ + {'a_type': 'dcim.frontport', 'b_type': 'dcim.interface', 'label': _('Interface')}, + {'a_type': 'dcim.frontport', 'b_type': 'dcim.consoleserverport', 'label': _('Console Server Port')}, + {'a_type': 'dcim.frontport', 'b_type': 'dcim.consoleport', 'label': _('Console Port')}, + {'a_type': 'dcim.frontport', 'b_type': 'dcim.frontport', 'label': _('Front Port')}, + {'a_type': 'dcim.frontport', 'b_type': 'dcim.rearport', 'label': _('Rear Port')}, + { + 'a_type': 'dcim.frontport', + 'b_type': 'circuits.circuittermination', + 'label': _('Circuit Termination'), + }, + ], + ), + panels.PortMappingsPanel( + context_key='rear_port_mappings', + label_column=_('Rear Port'), + position_field='front_port_position', + port_field='rear_port', + port_position_field='rear_port_position', + ), + ], + ) def get_extra_context(self, request, instance): return { @@ -3405,6 +3511,37 @@ class RearPortListView(generic.ObjectListView): @register_model_view(RearPort) class RearPortView(generic.ObjectView): queryset = RearPort.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.RearPortPanel(), + CustomFieldsPanel(), + TagsPanel(), + panels.InventoryItemsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:rearport_trace', + show_endpoints=False, + connect_options=[ + {'a_type': 'dcim.rearport', 'b_type': 'dcim.interface', 'label': _('Interface')}, + {'a_type': 'dcim.rearport', 'b_type': 'dcim.frontport', 'label': _('Front Port')}, + {'a_type': 'dcim.rearport', 'b_type': 'dcim.rearport', 'label': _('Rear Port')}, + { + 'a_type': 'dcim.rearport', + 'b_type': 'circuits.circuittermination', + 'label': _('Circuit Termination'), + }, + ], + ), + panels.PortMappingsPanel( + context_key='front_port_mappings', + label_column=_('Front Port'), + position_field='rear_port_position', + port_field='front_port', + port_position_field='front_port_position', + ), + ], + ) def get_extra_context(self, request, instance): return { @@ -3481,6 +3618,19 @@ class ModuleBayListView(generic.ObjectListView): @register_model_view(ModuleBay) class ModuleBayView(generic.ObjectView): queryset = ModuleBay.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.ModuleBayPanel(), + TagsPanel(), + ], + right_panels=[ + CustomFieldsPanel(), + Panel( + title=_('Installed Module'), + template_name='dcim/panels/installed_module.html', + ), + ], + ) @register_model_view(ModuleBay, 'add', detail=False) @@ -3543,6 +3693,19 @@ class DeviceBayListView(generic.ObjectListView): @register_model_view(DeviceBay) class DeviceBayView(generic.ObjectView): queryset = DeviceBay.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.DeviceBayPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + Panel( + title=_('Installed Device'), + template_name='dcim/panels/installed_device.html', + ), + ], + ) @register_model_view(DeviceBay, 'add', detail=False) @@ -3686,6 +3849,13 @@ class InventoryItemListView(generic.ObjectListView): @register_model_view(InventoryItem) class InventoryItemView(generic.ObjectView): queryset = InventoryItem.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.InventoryItemPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + ) @register_model_view(InventoryItem, 'edit') @@ -3767,13 +3937,19 @@ class InventoryItemRoleListView(generic.ObjectListView): @register_model_view(InventoryItemRole) -class InventoryItemRoleView(generic.ObjectView): +class InventoryItemRoleView(GetRelatedModelsMixin, generic.ObjectView): queryset = InventoryItemRole.objects.all() - - def get_extra_context(self, request, instance): - return { - 'inventoryitem_count': InventoryItem.objects.filter(role=instance).count(), - } + layout = layout.SimpleLayout( + left_panels=[ + panels.InventoryItemRolePanel(), + TagsPanel(), + ], + right_panels=[ + RelatedObjectsPanel(), + CommentsPanel(), + CustomFieldsPanel(), + ], + ) @register_model_view(InventoryItemRole, 'add', detail=False) @@ -3940,6 +4116,24 @@ class CableListView(generic.ObjectListView): @register_model_view(Cable) class CableView(generic.ObjectView): queryset = Cable.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.CablePanel(), + CustomFieldsPanel(), + TagsPanel(), + CommentsPanel(), + ], + right_panels=[ + Panel( + title=_('Termination A'), + template_name='dcim/panels/cable_termination_a.html', + ), + Panel( + title=_('Termination B'), + template_name='dcim/panels/cable_termination_b.html', + ), + ], + ) @register_model_view(Cable, 'add', detail=False) @@ -4072,6 +4266,17 @@ class VirtualChassisListView(generic.ObjectListView): @register_model_view(VirtualChassis) class VirtualChassisView(generic.ObjectView): queryset = VirtualChassis.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.VirtualChassisPanel(), + TagsPanel(), + CustomFieldsPanel(), + ], + right_panels=[ + panels.VirtualChassisDetailMembersPanel(), + CommentsPanel(), + ], + ) def get_extra_context(self, request, instance): members = Device.objects.restrict(request.user).filter(virtual_chassis=instance) @@ -4317,6 +4522,27 @@ class PowerPanelListView(generic.ObjectListView): @register_model_view(PowerPanel) class PowerPanelView(GetRelatedModelsMixin, generic.ObjectView): queryset = PowerPanel.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.PowerPanelPanel(), + TagsPanel(), + CommentsPanel(), + ], + right_panels=[ + RelatedObjectsPanel(), + CustomFieldsPanel(), + ImageAttachmentsPanel(), + ], + bottom_panels=[ + ObjectsTablePanel( + model='dcim.PowerFeed', + filters={'power_panel_id': lambda ctx: ctx['object'].pk}, + actions=[ + actions.AddObject('dcim.PowerFeed', url_params={'power_panel': lambda ctx: ctx['object'].pk}), + ], + ), + ], + ) def get_extra_context(self, request, instance): return { @@ -4380,6 +4606,23 @@ class PowerFeedListView(generic.ObjectListView): @register_model_view(PowerFeed) class PowerFeedView(generic.ObjectView): queryset = PowerFeed.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.PowerFeedPanel(), + panels.PowerFeedElectricalPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + panels.ConnectionPanel( + trace_url_name='dcim:powerfeed_trace', + connect_options=[ + {'a_type': 'dcim.powerfeed', 'b_type': 'dcim.powerport', 'label': _('Power Port')}, + ], + ), + CommentsPanel(), + ], + ) @register_model_view(PowerFeed, 'add', detail=False) @@ -4448,6 +4691,23 @@ class VirtualDeviceContextListView(generic.ObjectListView): @register_model_view(VirtualDeviceContext) class VirtualDeviceContextView(GetRelatedModelsMixin, generic.ObjectView): queryset = VirtualDeviceContext.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.VirtualDeviceContextPanel(), + TagsPanel(), + ], + right_panels=[ + RelatedObjectsPanel(), + CommentsPanel(), + CustomFieldsPanel(), + ], + bottom_panels=[ + ObjectsTablePanel( + model='dcim.Interface', + filters={'vdc_id': lambda ctx: ctx['object'].pk}, + ), + ], + ) def get_extra_context(self, request, instance): return { @@ -4516,6 +4776,16 @@ class MACAddressListView(generic.ObjectListView): @register_model_view(MACAddress) class MACAddressView(generic.ObjectView): queryset = MACAddress.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.MACAddressPanel(), + TagsPanel(), + CustomFieldsPanel(), + ], + right_panels=[ + CommentsPanel(), + ], + ) @register_model_view(MACAddress, 'add', detail=False) diff --git a/netbox/templates/dcim/cable.html b/netbox/templates/dcim/cable.html index 8e685c514..f15e1d050 100644 --- a/netbox/templates/dcim/cable.html +++ b/netbox/templates/dcim/cable.html @@ -1,87 +1 @@ {% extends 'generic/object.html' %} -{% load buttons %} -{% load helpers %} -{% load perms %} -{% load plugins %} -{% load i18n %} - -{% block content %} -
-
-
-

{% trans "Cable" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Type" %}{{ object.get_type_display|placeholder }}
{% trans "Status" %}{% badge object.get_status_display bg_color=object.get_status_color %}
{% trans "Profile" %}{% badge object.get_profile_display %}
{% trans "Tenant" %} - {% if object.tenant.group %} - {{ object.tenant.group|linkify }} / - {% endif %} - {{ object.tenant|linkify|placeholder }} -
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "Color" %} - {% if object.color %} -   - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Length" %} - {% if object.length is not None %} - {{ object.length|floatformat }} {{ object.get_length_unit_display }} - {% else %} - {{ ''|placeholder }} - {% endif %} -
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% include 'inc/panels/comments.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Termination" %} A

- {% include 'dcim/inc/cable_termination.html' with terminations=object.a_terminations %} -
-
-

{% trans "Termination" %} B

- {% include 'dcim/inc/cable_termination.html' with terminations=object.b_terminations %} -
- {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/consoleport.html b/netbox/templates/dcim/consoleport.html index 986b38dc8..313d6aec6 100644 --- a/netbox/templates/dcim/consoleport.html +++ b/netbox/templates/dcim/consoleport.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,88 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Console Port" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Type" %}{{ object.get_type_display }}
{% trans "Speed" %}{{ object.get_speed_display }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- - {% trans "Marked as connected" %} -
- {% elif object.cable %} - {% include 'dcim/inc/connection_endpoints.html' with trace_url='dcim:consoleport_trace' %} - {% else %} -
- {% trans "Not Connected" %} - {% if perms.dcim.add_cable %} - - {% endif %} -
- {% endif %} -
- {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/consoleserverport.html b/netbox/templates/dcim/consoleserverport.html index 0ec0ac6fb..80f0e54a2 100644 --- a/netbox/templates/dcim/consoleserverport.html +++ b/netbox/templates/dcim/consoleserverport.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,88 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Console Server Port" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Type" %}{{ object.get_type_display|placeholder }}
{% trans "Speed" %}{{ object.get_speed_display|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- - {% trans "Marked as connected" %} -
- {% elif object.cable %} - {% include 'dcim/inc/connection_endpoints.html' with trace_url='dcim:consoleserverport_trace' %} - {% else %} -
- {% trans "Not Connected" %} - {% if perms.dcim.add_cable %} - - {% endif %} -
- {% endif %} -
- {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/devicebay.html b/netbox/templates/dcim/devicebay.html index 1148a30e3..afc3ad506 100644 --- a/netbox/templates/dcim/devicebay.html +++ b/netbox/templates/dcim/devicebay.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,63 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Device Bay" %}

- - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Installed Device" %}

- {% if object.installed_device %} - {% with device=object.installed_device %} - - - - - - - - - -
{% trans "Device" %}{{ device|linkify }}
{% trans "Device Type" %}{{ device.device_type }}
- {% endwith %} - {% else %} -
- {% trans "None" %} -
- {% endif %} -
- {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/frontport.html b/netbox/templates/dcim/frontport.html index f93e8282f..74d42616c 100644 --- a/netbox/templates/dcim/frontport.html +++ b/netbox/templates/dcim/frontport.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,149 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Front Port" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Type" %}{{ object.get_type_display }}
{% trans "Color" %} - {% if object.color %} -   - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Positions" %}{{ object.positions }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- {% trans "Marked as Connected" %} -
- {% elif object.cable %} - - - - - - - - - -
{% trans "Cable" %} - {{ object.cable|linkify }} - - - -
{% trans "Connection Status" %} - {% if object.cable.status %} - {{ object.cable.get_status_display }} - {% else %} - {{ object.cable.get_status_display }} - {% endif %} -
- {% else %} -
- {% trans "Not Connected" %} - {% if perms.dcim.add_cable %} - - {% endif %} -
- {% endif %} -
-
-

{% trans "Port Mappings" %}

- - {% if rear_port_mappings %} - - - - - - - {% endif %} - {% for mapping in rear_port_mappings %} - - - - - {% empty %} - {% trans "No mappings defined" %} - {% endfor %} -
{% trans "Position" %}{% trans "Rear Port" %}
{{ mapping.front_port_position }} - {{ mapping.rear_port }}:{{ mapping.rear_port_position }} -
-
- {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/inventoryitem.html b/netbox/templates/dcim/inventoryitem.html index d389abe8e..3d5a2cf27 100644 --- a/netbox/templates/dcim/inventoryitem.html +++ b/netbox/templates/dcim/inventoryitem.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,74 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Inventory Item" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Parent Item" %}{{ object.parent|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Status" %}{% badge object.get_status_display bg_color=object.get_status_color %}
{% trans "Role" %}{{ object.role|linkify|placeholder }}
{% trans "Component" %}{{ object.component|linkify|placeholder }}
{% trans "Manufacturer" %}{{ object.manufacturer|linkify|placeholder }}
{% trans "Part ID" %}{{ object.part_id|placeholder }}
{% trans "Serial" %}{{ object.serial|placeholder }}
{% trans "Asset Tag" %}{{ object.asset_tag|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
- {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/inventoryitemrole.html b/netbox/templates/dcim/inventoryitemrole.html index 4791e1ab3..f15e1d050 100644 --- a/netbox/templates/dcim/inventoryitemrole.html +++ b/netbox/templates/dcim/inventoryitemrole.html @@ -1,53 +1 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load render_table from django_tables2 %} -{% load i18n %} - -{% block breadcrumbs %} - -{% endblock %} - -{% block content %} -
-
-
-

{% trans "Inventory Item Role" %}

- - - - - - - - - - - - - - - - - -
{% trans "Name" %}{{ object.name }}
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "Color" %} -   -
{% trans "Inventory Items" %} - {{ inventoryitem_count }} -
-
- {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
- {% include 'inc/panels/comments.html' %} - {% include 'inc/panels/custom_fields.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/macaddress.html b/netbox/templates/dcim/macaddress.html index 489d55c08..f15e1d050 100644 --- a/netbox/templates/dcim/macaddress.html +++ b/netbox/templates/dcim/macaddress.html @@ -1,55 +1 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load render_table from django_tables2 %} -{% load i18n %} - -{% block content %} -
-
-
-

{% trans "MAC Address" %}

- - - - - - - - - - - - - - - - - -
{% trans "MAC Address" %} - {{ object.mac_address|placeholder }} - {% copy_content object.pk prefix="macaddress_" %} -
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "Assignment" %} - {% if object.assigned_object %} - {{ object.assigned_object.parent_object|linkify }} / - {{ object.assigned_object|linkify }} - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Primary for interface" %}{% checkmark object.is_primary %}
-
- {% include 'inc/panels/tags.html' %} - {% include 'inc/panels/custom_fields.html' %} - {% plugin_left_page object %} -
-
- {% include 'inc/panels/comments.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/macaddress/attrs/assignment.html b/netbox/templates/dcim/macaddress/attrs/assignment.html new file mode 100644 index 000000000..872788bd2 --- /dev/null +++ b/netbox/templates/dcim/macaddress/attrs/assignment.html @@ -0,0 +1,7 @@ +{% load helpers %} +{% if value %} + {{ value.parent_object|linkify }} / + {{ value|linkify }} +{% else %} + {{ ''|placeholder }} +{% endif %} diff --git a/netbox/templates/dcim/modulebay.html b/netbox/templates/dcim/modulebay.html index 054a13b1c..ca711665b 100644 --- a/netbox/templates/dcim/modulebay.html +++ b/netbox/templates/dcim/modulebay.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,83 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Module Bay" %}

- - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %} - {{ object.device }} -
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Position" %}{{ object.position|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
- {% include 'inc/panels/custom_fields.html' %} -
-

{% trans "Installed Module" %}

- {% if object.installed_module %} - {% with module=object.installed_module %} - - - - - - - - - - - - - - - - - - - - - -
{% trans "Module" %}{{ module|linkify }}
{% trans "Manufacturer" %}{{ module.module_type.manufacturer|linkify }}
{% trans "Module Type" %}{{ module.module_type|linkify }}
{% trans "Serial Number" %}{{ module.serial|placeholder }}
{% trans "Asset Tag" %}{{ module.asset_tag|placeholder }}
- {% endwith %} - {% else %} -
{% trans "None" %}
- {% endif %} -
- {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/panels/cable_termination_a.html b/netbox/templates/dcim/panels/cable_termination_a.html new file mode 100644 index 000000000..50f7b028d --- /dev/null +++ b/netbox/templates/dcim/panels/cable_termination_a.html @@ -0,0 +1,6 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% include 'dcim/inc/cable_termination.html' with terminations=object.a_terminations %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/cable_termination_b.html b/netbox/templates/dcim/panels/cable_termination_b.html new file mode 100644 index 000000000..bfd56f621 --- /dev/null +++ b/netbox/templates/dcim/panels/cable_termination_b.html @@ -0,0 +1,6 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% include 'dcim/inc/cable_termination.html' with terminations=object.b_terminations %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/component_inventory_items.html b/netbox/templates/dcim/panels/component_inventory_items.html new file mode 100644 index 000000000..02b3e1d6a --- /dev/null +++ b/netbox/templates/dcim/panels/component_inventory_items.html @@ -0,0 +1,40 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + + + + + + + + + + + {% for item in object.inventory_items.all %} + + + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Name" %}{% trans "Label" %}{% trans "Role" %}
{{ item|linkify:"name" }}{{ item.label|placeholder }}{{ item.role|linkify|placeholder }} + {% if perms.dcim.change_inventoryitem %} + + + + {% endif %} + {% if perms.dcim.delete_inventoryitem %} + + + + {% endif %} +
{% trans "None" %}
+{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/connection.html b/netbox/templates/dcim/panels/connection.html new file mode 100644 index 000000000..454418227 --- /dev/null +++ b/netbox/templates/dcim/panels/connection.html @@ -0,0 +1,96 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% if object.mark_connected %} +
+ + {% trans "Marked as connected" %} +
+ {% elif object.cable %} + {% if show_endpoints %} + + + + + + + + + + + + + +
{% trans "Cable" %} + {{ object.cable|linkify }} + + + +
{% trans "Path Status" %} + {% if object.path.is_complete and object.path.is_active %} + {% trans "Reachable" %} + {% else %} + {% trans "Not Reachable" %} + {% endif %} +
{% trans "Path Endpoints" %} + {% for endpoint in object.connected_endpoints %} + {% if endpoint.parent_object %} + {{ endpoint.parent_object|linkify }} + + {% endif %} + {{ endpoint|linkify }} + {% if not forloop.last %}
{% endif %} + {% empty %} + {{ ''|placeholder }} + {% endfor %} +
+ {% else %} + + + + + + + + + +
{% trans "Cable" %} + {{ object.cable|linkify }} + + + +
{% trans "Connection Status" %} + {% if object.cable.status %} + {{ object.cable.get_status_display }} + {% else %} + {{ object.cable.get_status_display }} + {% endif %} +
+ {% endif %} + {% else %} +
+ {% trans "Not Connected" %} + {% if perms.dcim.add_cable %} + {% if connect_options|length > 1 %} + + {% elif connect_options|length == 1 %} + + {% trans "Connect" %} + + {% endif %} + {% endif %} +
+ {% endif %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/installed_device.html b/netbox/templates/dcim/panels/installed_device.html new file mode 100644 index 000000000..118ba5137 --- /dev/null +++ b/netbox/templates/dcim/panels/installed_device.html @@ -0,0 +1,21 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% if object.installed_device %} + {% with device=object.installed_device %} + + + + + + + + + +
{% trans "Device" %}{{ device|linkify }}
{% trans "Device Type" %}{{ device.device_type }}
+ {% endwith %} + {% else %} +
{% trans "None" %}
+ {% endif %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/installed_module.html b/netbox/templates/dcim/panels/installed_module.html new file mode 100644 index 000000000..38ee3ecc9 --- /dev/null +++ b/netbox/templates/dcim/panels/installed_module.html @@ -0,0 +1,33 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% if object.installed_module %} + {% with module=object.installed_module %} + + + + + + + + + + + + + + + + + + + + + +
{% trans "Module" %}{{ module|linkify }}
{% trans "Manufacturer" %}{{ module.module_type.manufacturer|linkify }}
{% trans "Module Type" %}{{ module.module_type|linkify }}
{% trans "Serial Number" %}{{ module.serial|placeholder }}
{% trans "Asset Tag" %}{{ module.asset_tag|placeholder }}
+ {% endwith %} + {% else %} +
{% trans "None" %}
+ {% endif %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/port_mappings.html b/netbox/templates/dcim/panels/port_mappings.html new file mode 100644 index 000000000..3e702c1cc --- /dev/null +++ b/netbox/templates/dcim/panels/port_mappings.html @@ -0,0 +1,31 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + + {% if mappings %} + + + + + + + {% endif %} + + {% for mapping in mappings %} + + {% with position=mapping|getattr:position_field port=mapping|getattr:port_field port_position=mapping|getattr:port_position_field %} + + + {% endwith %} + + {% empty %} + + + + {% endfor %} + +
{% trans "Position" %}{{ label_column }}
{{ position }} + {{ port }}:{{ port_position }} +
{% trans "No mappings defined" %}
+{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/virtual_chassis_detail_members.html b/netbox/templates/dcim/panels/virtual_chassis_detail_members.html new file mode 100644 index 000000000..3fe917884 --- /dev/null +++ b/netbox/templates/dcim/panels/virtual_chassis_detail_members.html @@ -0,0 +1,36 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + + + + + + + + + + + {% for vc_member in members %} + + + + + + + {% endfor %} + +
{% trans "Device" %}{% trans "Position" %}{% trans "Master" %}{% trans "Priority" %}
{{ vc_member|linkify }}{% badge vc_member.vc_position show_empty=True %} + {% if object.master == vc_member %} + {% checkmark True %} + {% endif %} + {{ vc_member.vc_priority|placeholder }}
+ {% if perms.dcim.change_virtualchassis and object.master %} + + {% endif %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/powerfeed.html b/netbox/templates/dcim/powerfeed.html index f03ead88b..1304a58db 100644 --- a/netbox/templates/dcim/powerfeed.html +++ b/netbox/templates/dcim/powerfeed.html @@ -1,9 +1,5 @@ {% extends 'generic/object.html' %} -{% load buttons %} -{% load static %} -{% load helpers %} -{% load plugins %} -{% load i18n %} +{% load helpers i18n %} {% block breadcrumbs %} {{ block.super }} @@ -13,126 +9,3 @@ {% endif %} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Power Feed" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {% with utilization=object.connected_endpoints.0.get_power_draw %} - {% if utilization %} - - {% else %} - - {% endif %} - {% endwith %} - -
{% trans "Power Panel" %}{{ object.power_panel|linkify }}
{% trans "Rack" %}{{ object.rack|linkify|placeholder }}
{% trans "Type" %}{% badge object.get_type_display bg_color=object.get_type_color %}
{% trans "Status" %}{% badge object.get_status_display bg_color=object.get_status_color %}
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "Tenant" %} - {% if object.tenant.group %} - {{ object.tenant.group|linkify }} / - {% endif %} - {{ object.tenant|linkify|placeholder }} -
{% trans "Connected Device" %} - {% if object.connected_endpoints %} - {{ object.connected_endpoints.0.device|linkify }} ({{ object.connected_endpoints.0|linkify:"name" }}) - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Utilization (Allocated" %}) - {{ utilization.allocated }}{% trans "VA" %} / {{ object.available_power }}{% trans "VA" %} - {% if object.available_power > 0 %} - {% utilization_graph utilization.allocated|percentage:object.available_power %} - {% endif %} - {{ ''|placeholder }}
-
-
-

{% trans "Electrical Characteristics" %}

- - - - - - - - - - - - - - - - - - - - - -
{% trans "Supply" %}{{ object.get_supply_display }}
{% trans "Voltage" %}{{ object.voltage }}{% trans "V" context "Abbreviation for volts" %}
{% trans "Amperage" %}{{ object.amperage }}{% trans "A" context "Abbreviation for amperes" %}
{% trans "Phase" %}{{ object.get_phase_display }}
{% trans "Max Utilization" %}{{ object.max_utilization }}%
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- - {% trans "Marked as connected" %} -
- {% elif object.cable %} - {% include 'dcim/inc/connection_endpoints.html' with trace_url='dcim:powerfeed_trace' %} - {% else %} -
- {% trans "Not connected" %} - {% if perms.dcim.add_cable %} - - {% trans "Connect" %} - - {% endif %} -
- {% endif %} -
- {% include 'inc/panels/comments.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/powerfeed/attrs/connected_device.html b/netbox/templates/dcim/powerfeed/attrs/connected_device.html new file mode 100644 index 000000000..5a660f5ad --- /dev/null +++ b/netbox/templates/dcim/powerfeed/attrs/connected_device.html @@ -0,0 +1,6 @@ +{% load helpers %} +{% if value %} + {{ value.0.device|linkify }} ({{ value.0|linkify:"name" }}) +{% else %} + {{ ''|placeholder }} +{% endif %} diff --git a/netbox/templates/dcim/powerfeed/attrs/utilization.html b/netbox/templates/dcim/powerfeed/attrs/utilization.html new file mode 100644 index 000000000..a0dbf6801 --- /dev/null +++ b/netbox/templates/dcim/powerfeed/attrs/utilization.html @@ -0,0 +1,15 @@ +{% load helpers i18n %} +{% if value %} + {% with utilization=value.0.get_power_draw %} + {% if utilization %} + {{ utilization.allocated }}{% trans "VA" %} / {{ object.available_power }}{% trans "VA" %} + {% if object.available_power > 0 %} + {% utilization_graph utilization.allocated|percentage:object.available_power %} + {% endif %} + {% else %} + {{ ''|placeholder }} + {% endif %} + {% endwith %} +{% else %} + {{ ''|placeholder }} +{% endif %} diff --git a/netbox/templates/dcim/poweroutlet.html b/netbox/templates/dcim/poweroutlet.html index a3cbb2a8e..bef31cd55 100644 --- a/netbox/templates/dcim/poweroutlet.html +++ b/netbox/templates/dcim/poweroutlet.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,93 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Power Outlet" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Type" %}{{ object.get_type_display }}
{% trans "Status" %}{% badge object.get_status_display bg_color=object.get_status_color %}
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "Color" %} - {% if object.color %} -   - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Power Port" %}{{ object.power_port|linkify|placeholder }}
{% trans "Feed Leg" %}{{ object.get_feed_leg_display|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- - {% trans "Marked as Connected" %} -
- {% elif object.cable %} - {% include 'dcim/inc/connection_endpoints.html' with trace_url='dcim:poweroutlet_trace' %} - {% else %} -
- {% trans "Not Connected" %} - {% if perms.dcim.add_cable %} - - {% trans "Connect" %} - - {% endif %} -
- {% endif %} -
- {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/powerpanel.html b/netbox/templates/dcim/powerpanel.html index a685789f5..55bf70f9c 100644 --- a/netbox/templates/dcim/powerpanel.html +++ b/netbox/templates/dcim/powerpanel.html @@ -1,8 +1,5 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load render_table from django_tables2 %} -{% load i18n %} +{% load helpers i18n %} {% block breadcrumbs %} {{ block.super }} @@ -11,72 +8,3 @@ {% endif %} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Power Panel" %}

- - - - - - - - - - - - - -
{% trans "Site" %}{{ object.site|linkify }}
{% trans "Location" %}{{ object.location|linkify|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/tags.html' %} - {% include 'inc/panels/comments.html' %} - {% plugin_left_page object %} -
-
- {% include 'inc/panels/related_objects.html' %} - {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/image_attachments.html' %} - {% plugin_right_page object %} -
-
-
-
-
- {% csrf_token %} -
-

{% trans "Power Feeds" %}

- {% htmx_table 'dcim:powerfeed_list' power_panel_id=object.pk %} - -
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/powerport.html b/netbox/templates/dcim/powerport.html index be05fdae2..3b8c8a00a 100644 --- a/netbox/templates/dcim/powerport.html +++ b/netbox/templates/dcim/powerport.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,89 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Power Port" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Type" %}{{ object.get_type_display|placeholder }}
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "Maximum Draw" %}{{ object.maximum_draw|placeholder }}
{% trans "Allocated Draw" %}{{ object.allocated_draw|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- - {% trans "Marked as Connected" %} -
- {% elif object.cable %} - {% include 'dcim/inc/connection_endpoints.html' with trace_url='dcim:powerport_trace' %} - {% else %} -
- {% trans "Not Connected" %} - {% if perms.dcim.add_cable %} - - - - - {% endif %} -
- {% endif %} -
- {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/rearport.html b/netbox/templates/dcim/rearport.html index a4c111ecf..50cdf9e4e 100644 --- a/netbox/templates/dcim/rearport.html +++ b/netbox/templates/dcim/rearport.html @@ -1,6 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} {% load i18n %} {% block breadcrumbs %} @@ -9,143 +7,3 @@ {{ object.device }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Rear Port" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Module" %}{{ object.module|linkify|placeholder }}
{% trans "Name" %}{{ object.name }}
{% trans "Label" %}{{ object.label|placeholder }}
{% trans "Type" %}{{ object.get_type_display }}
{% trans "Color" %} - {% if object.color %} -   - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Positions" %}{{ object.positions }}
{% trans "Description" %}{{ object.description|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_left_page object %} -
-
-
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- {% trans "Marked as Connected" %} -
- {% elif object.cable %} - - - - - - - - - -
{% trans "Cable" %} - {{ object.cable|linkify }} - - - -
{% trans "Connection Status" %} - {% if object.cable.status %} - {{ object.cable.get_status_display }} - {% else %} - {{ object.cable.get_status_display }} - {% endif %} -
- {% else %} -
- {% trans "Not connected" %} - {% if perms.dcim.add_cable %} - - - - - {% endif %} -
- {% endif %} -
-
-

{% trans "Port Mappings" %}

- - {% if front_port_mappings %} - - - - - - - {% endif %} - {% for mapping in front_port_mappings %} - - - - - {% empty %} - {% trans "No mappings defined" %} - {% endfor %} -
{% trans "Position" %}{% trans "Front Port" %}
{{ mapping.rear_port_position }} - {{ mapping.front_port }}:{{ mapping.front_port_position }} -
-
- {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/virtualchassis.html b/netbox/templates/dcim/virtualchassis.html index da5a812a2..f15e1d050 100644 --- a/netbox/templates/dcim/virtualchassis.html +++ b/netbox/templates/dcim/virtualchassis.html @@ -1,90 +1 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load i18n %} - -{% block content %} -
-
-
-

{% trans "Virtual Chassis" %}

- - - - - - - - - - - - - - - - - -
{% trans "Domain" %}{{ object.domain|placeholder }}
{% trans "Master" %}{{ object.master|linkify }}
{% trans "Description" %}{{ object.description|placeholder }}
Members - {% if object.member_count %} - {{ object.member_count }} - {% else %} - {{ object.member_count }} - {% endif %} -
-
- {% include 'inc/panels/tags.html' %} - {% include 'inc/panels/custom_fields.html' %} - {% plugin_left_page object %} -
-
-
-

- {% trans "Members" %} - {% if perms.dcim.change_virtualchassis %} - - {% endif %} -

- - - - - - - - - - {% for vc_member in members %} - - - - - - - {% endfor %} -
{% trans "Device" %}{% trans "Position" %}{% trans "Master" %}{% trans "Priority" %}
- {{ vc_member|linkify }} - - {% badge vc_member.vc_position show_empty=True %} - - {% if object.master == vc_member %} - {% checkmark True %} - {% endif %} - - {{ vc_member.vc_priority|placeholder }} -
-
- {% include 'inc/panels/comments.html' %} - {% plugin_right_page object %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/virtualdevicecontext.html b/netbox/templates/dcim/virtualdevicecontext.html index 2aec494b8..f15e1d050 100644 --- a/netbox/templates/dcim/virtualdevicecontext.html +++ b/netbox/templates/dcim/virtualdevicecontext.html @@ -1,87 +1 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load render_table from django_tables2 %} -{% load i18n %} - -{% block breadcrumbs %} - -{% endblock %} - -{% block content %} -
-
-
-

{% trans "Virtual Device Context" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans "Name" %}{{ object.name }}
{% trans "Device" %}{{ object.device|linkify }}
{% trans "Identifier" %}{{ object.identifier|placeholder }}
{% trans "Primary IPv4" %} - {% if object.primary_ip4 %} - {{ object.primary_ip4 }} - {% copy_content "primary_ip4" %} - {% else %} - - {% endif %} -
{% trans "Primary IPv6" %} - {% if object.primary_ip6 %} - {{ object.primary_ip6 }} - {% copy_content "primary_ip6" %} - {% else %} - - {% endif %} -
{% trans "Tenant" %} - {% if object.tenant.group %} - {{ object.tenant.group|linkify }} / - {% endif %} - {{ object.tenant|linkify|placeholder }} -
{% trans "Interfaces" %} - {{ object.interfaces.count }} -
-
- {% plugin_left_page object %} - {% include 'inc/panels/tags.html' %} -
-
- {% include 'inc/panels/related_objects.html' %} - {% include 'inc/panels/comments.html' %} - {% include 'inc/panels/custom_fields.html' %} - {% plugin_right_page object %} -
-
-
-
-
-

{% trans "Interfaces" %}

- {% htmx_table 'dcim:interface_list' vdc_id=object.pk %} -
- {% plugin_full_width_page object %} -
-
-{% endblock %}