diff --git a/netbox/dcim/ui/panels.py b/netbox/dcim/ui/panels.py index fa7ad848a..f75e3d478 100644 --- a/netbox/dcim/ui/panels.py +++ b/netbox/dcim/ui/panels.py @@ -1,6 +1,8 @@ +from django.contrib.contenttypes.models import ContentType +from django.template.loader import render_to_string from django.utils.translation import gettext_lazy as _ -from netbox.ui import attrs, panels +from netbox.ui import actions, attrs, panels class SitePanel(panels.ObjectAttributesPanel): @@ -189,16 +191,251 @@ 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 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.RelatedObjectAttr('assigned_object', linkify=True, grouped_by='parent_object') + 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') + actions = [ + actions.AddObject( + 'dcim.inventoryitem', + url_params={ + 'component_type': lambda ctx: ContentType.objects.get_for_model(ctx['object']).pk, + 'component_id': lambda ctx: ctx['object'].pk, + }, + ), + ] + + def render(self, context): + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + class VirtualChassisMembersPanel(panels.ObjectPanel): """ A panel which lists all members of a virtual chassis. """ template_name = 'dcim/panels/virtual_chassis_members.html' title = _('Virtual Chassis Members') + actions = [ + actions.AddObject( + 'dcim.device', + url_params={ + 'site': lambda ctx: ctx['object'].master.site_id if ctx['object'].master else '', + 'rack': lambda ctx: ctx['object'].master.rack_id if ctx['object'].master else '', + }, + ), + ] def get_context(self, context): return { **super().get_context(context), + 'virtual_chassis': context.get('virtual_chassis'), 'vc_members': context.get('vc_members'), } @@ -226,3 +463,106 @@ class PowerUtilizationPanel(panels.ObjectPanel): if not obj.powerports.exists() or not obj.poweroutlets.exists(): return '' return super().render(context) + + +class InterfacePanel(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.TemplatedAttr('speed', template_name='dcim/interface/attrs/speed.html', label=_('Speed')) + duplex = attrs.ChoiceAttr('duplex') + mtu = attrs.TextAttr('mtu', label=_('MTU')) + enabled = attrs.BooleanAttr('enabled') + mgmt_only = attrs.BooleanAttr('mgmt_only', label=_('Management only')) + description = attrs.TextAttr('description') + poe_mode = attrs.ChoiceAttr('poe_mode', label=_('PoE mode')) + poe_type = attrs.ChoiceAttr('poe_type', label=_('PoE type')) + mode = attrs.ChoiceAttr('mode', label=_('802.1Q mode')) + qinq_svlan = attrs.RelatedObjectAttr('qinq_svlan', linkify=True, label=_('Q-in-Q SVLAN')) + untagged_vlan = attrs.RelatedObjectAttr('untagged_vlan', linkify=True, label=_('Untagged VLAN')) + tx_power = attrs.TextAttr('tx_power', label=_('Transmit power (dBm)')) + tunnel = attrs.RelatedObjectAttr('tunnel_termination.tunnel', linkify=True, label=_('Tunnel')) + l2vpn = attrs.RelatedObjectAttr('l2vpn_termination.l2vpn', linkify=True, label=_('L2VPN')) + + +class RelatedInterfacesPanel(panels.ObjectAttributesPanel): + title = _('Related Interfaces') + + parent = attrs.RelatedObjectAttr('parent', linkify=True) + bridge = attrs.RelatedObjectAttr('bridge', linkify=True) + lag = attrs.RelatedObjectAttr('lag', linkify=True, label=_('LAG')) + + +class InterfaceAddressingPanel(panels.ObjectAttributesPanel): + title = _('Addressing') + + mac_address = attrs.TemplatedAttr( + 'primary_mac_address', + template_name='dcim/interface/attrs/mac_address.html', + label=_('MAC address'), + ) + wwn = attrs.TextAttr('wwn', style='font-monospace', label=_('WWN')) + vrf = attrs.RelatedObjectAttr('vrf', linkify=True, label=_('VRF')) + vlan_translation = attrs.RelatedObjectAttr('vlan_translation_policy', linkify=True, label=_('VLAN translation')) + + +class InterfaceConnectionPanel(panels.ObjectPanel): + """ + A connection panel for interfaces, which handles cable, wireless link, and virtual circuit cases. + """ + template_name = 'dcim/panels/interface_connection.html' + title = _('Connection') + + def render(self, context): + obj = context.get('object') + if obj and obj.is_virtual: + return '' + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + +class VirtualCircuitPanel(panels.ObjectPanel): + """ + A panel which displays virtual circuit information for a virtual interface. + """ + template_name = 'dcim/panels/interface_virtual_circuit.html' + title = _('Virtual Circuit') + + def render(self, context): + obj = context.get('object') + if not obj or not obj.is_virtual or not obj.virtual_circuit_termination: + return '' + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + +class InterfaceWirelessPanel(panels.ObjectPanel): + """ + A panel which displays wireless RF attributes for an interface, comparing local and peer values. + """ + template_name = 'dcim/panels/interface_wireless.html' + title = _('Wireless') + + def render(self, context): + obj = context.get('object') + if not obj or not obj.is_wireless: + return '' + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) + + +class WirelessLANsPanel(panels.ObjectPanel): + """ + A panel which lists the wireless LANs associated with an interface. + """ + template_name = 'dcim/panels/interface_wireless_lans.html' + title = _('Wireless LANs') + + def render(self, context): + obj = context.get('object') + if not obj or not obj.is_wireless: + return '' + ctx = self.get_context(context) + return render_to_string(self.template_name, ctx, request=ctx.get('request')) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c90f63753..dd3531b84 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -17,10 +17,12 @@ from extras.ui.panels import CustomFieldsPanel, ImageAttachmentsPanel, TagsPanel from extras.views import ObjectConfigContextView, ObjectRenderConfigView from ipam.models import ASN, VLAN, IPAddress, Prefix, VLANGroup from ipam.tables import VLANTranslationRuleTable +from ipam.ui.panels import FHRPGroupAssignmentsPanel from netbox.object_actions import * from netbox.ui import actions, layout from netbox.ui.panels import ( CommentsPanel, + ContextTablePanel, JSONPanel, NestedGroupObjectPanel, ObjectsTablePanel, @@ -1577,7 +1579,7 @@ class ModuleTypeProfileListView(generic.ObjectListView): @register_model_view(ModuleTypeProfile) -class ModuleTypeProfileView(GetRelatedModelsMixin, generic.ObjectView): +class ModuleTypeProfileView(generic.ObjectView): template_name = 'generic/object.html' queryset = ModuleTypeProfile.objects.all() layout = layout.SimpleLayout( @@ -2555,6 +2557,7 @@ class DeviceView(generic.ObjectView): vc_members = [] return { + 'virtual_chassis': instance.virtual_chassis, 'vc_members': vc_members, 'svg_extra': f'highlight=id:{instance.pk}', } @@ -2907,6 +2910,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 +3003,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 +3092,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 +3180,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) @@ -3191,6 +3267,45 @@ class InterfaceListView(generic.ObjectListView): @register_model_view(Interface) class InterfaceView(generic.ObjectView): queryset = Interface.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.InterfacePanel(), + panels.RelatedInterfacesPanel(), + CustomFieldsPanel(), + TagsPanel(), + ], + right_panels=[ + ContextTablePanel('vdc_table', title=_('Virtual Device Contexts')), + panels.InterfaceAddressingPanel(), + panels.VirtualCircuitPanel(), + panels.InterfaceConnectionPanel(), + panels.InterfaceWirelessPanel(), + panels.WirelessLANsPanel(), + FHRPGroupAssignmentsPanel(), + panels.InventoryItemsPanel(), + ], + bottom_panels=[ + ObjectsTablePanel( + model='ipam.IPAddress', + filters={'interface_id': lambda ctx: ctx['object'].pk}, + title=_('IP Addresses'), + ), + ObjectsTablePanel( + model='dcim.MACAddress', + filters={'interface_id': lambda ctx: ctx['object'].pk}, + title=_('MAC Addresses'), + ), + ObjectsTablePanel( + model='ipam.VLAN', + filters={'interface_id': lambda ctx: ctx['object'].pk}, + title=_('VLANs'), + ), + ContextTablePanel('lag_interfaces_table', title=_('LAG Members')), + ContextTablePanel('vlan_translation_table', title=_('VLAN Translation')), + ContextTablePanel('bridge_interfaces_table', title=_('Bridged Interfaces')), + ContextTablePanel('child_interfaces_table', title=_('Child Interfaces')), + ], + ) def get_extra_context(self, request, instance): # Get assigned VDCs @@ -3205,30 +3320,29 @@ class InterfaceView(generic.ObjectView): vdc_table.configure(request) # Get bridge interfaces - bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance) bridge_interfaces_table = tables.InterfaceTable( - bridge_interfaces, + Interface.objects.restrict(request.user, 'view').filter(bridge=instance), exclude=('device', 'parent'), orderable=False ) bridge_interfaces_table.configure(request) # Get child interfaces - child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance) child_interfaces_table = tables.InterfaceTable( - child_interfaces, + Interface.objects.restrict(request.user, 'view').filter(parent=instance), exclude=('device', 'parent'), orderable=False ) child_interfaces_table.configure(request) - # Get LAG interfaces - lag_interfaces = Interface.objects.restrict(request.user, 'view').filter(lag=instance) - lag_interfaces_table = tables.InterfaceLAGMemberTable( - lag_interfaces, - orderable=False - ) - lag_interfaces_table.configure(request) + # Get LAG members (only for LAG interfaces) + lag_interfaces_table = None + if instance.is_lag: + lag_interfaces_table = tables.InterfaceLAGMemberTable( + Interface.objects.restrict(request.user, 'view').filter(lag=instance), + orderable=False + ) + lag_interfaces_table.configure(request) # Get VLAN translation rules vlan_translation_table = None @@ -3241,7 +3355,6 @@ class InterfaceView(generic.ObjectView): return { 'vdc_table': vdc_table, - 'bridge_interfaces': bridge_interfaces, 'bridge_interfaces_table': bridge_interfaces_table, 'child_interfaces_table': child_interfaces_table, 'lag_interfaces_table': lag_interfaces_table, @@ -3329,6 +3442,33 @@ 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'), + }, + ], + ), + TemplatePanel('dcim/panels/front_port_mappings.html'), + ], + ) def get_extra_context(self, request, instance): return { @@ -3405,6 +3545,31 @@ 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'), + }, + ], + ), + TemplatePanel('dcim/panels/rear_port_mappings.html'), + ], + ) def get_extra_context(self, request, instance): return { @@ -3481,6 +3646,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 +3721,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 +3877,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,12 +3965,23 @@ class InventoryItemRoleListView(generic.ObjectListView): @register_model_view(InventoryItemRole) -class InventoryItemRoleView(generic.ObjectView): +class InventoryItemRoleView(GetRelatedModelsMixin, generic.ObjectView): queryset = InventoryItemRole.objects.all() + layout = layout.SimpleLayout( + left_panels=[ + panels.InventoryItemRolePanel(), + TagsPanel(), + ], + right_panels=[ + RelatedObjectsPanel(), + CustomFieldsPanel(), + CommentsPanel(), + ], + ) def get_extra_context(self, request, instance): return { - 'inventoryitem_count': InventoryItem.objects.filter(role=instance).count(), + 'related_models': self.get_related_models(request, instance), } @@ -3940,6 +4149,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,12 +4299,23 @@ 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.VirtualChassisMembersPanel(), + CommentsPanel(), + ], + ) def get_extra_context(self, request, instance): - members = Device.objects.restrict(request.user).filter(virtual_chassis=instance) - + vc_members = Device.objects.restrict(request.user).filter(virtual_chassis=instance).order_by('vc_position') return { - 'members': members, + 'virtual_chassis': instance, + 'vc_members': vc_members, } @@ -4317,6 +4555,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 +4639,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 +4724,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 +4809,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/interface.html b/netbox/templates/dcim/interface.html index 34e941ec9..b8214337f 100644 --- a/netbox/templates/dcim/interface.html +++ b/netbox/templates/dcim/interface.html @@ -1,7 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load render_table from django_tables2 %} {% load i18n %} {% block breadcrumbs %} @@ -19,436 +16,3 @@ {% endif %} {{ block.super }} {% endblock %} - -{% block content %} -
-
-
-

{% trans "Interface" %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {% if object.mode == 'q-in-q' %} - - - - - {% elif object.mode %} - - - - - {% endif %} - - - - - - - - - - - - -
{% 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/Duplex" %} - {{ object.speed|humanize_speed|placeholder }} / - {{ object.get_duplex_display|placeholder }} -
{% trans "MTU" %}{{ object.mtu|placeholder }}
{% trans "Enabled" %}{% checkmark object.enabled %}
{% trans "Management Only" %}{% checkmark object.mgmt_only %}
{% trans "Description" %}{{ object.description|placeholder }}
{% trans "PoE Mode" %}{{ object.get_poe_mode_display|placeholder }}
{% trans "PoE Type" %}{{ object.get_poe_type_display|placeholder }}
{% trans "802.1Q Mode" %}{{ object.get_mode_display|placeholder }}
{% trans "Q-in-Q SVLAN" %}{{ object.qinq_svlan|linkify|placeholder }}
{% trans "Untagged VLAN" %}{{ object.untagged_vlan|linkify|placeholder }}
{% trans "Transmit power (dBm)" %}{{ object.tx_power|placeholder }}
{% trans "Tunnel" %}{{ object.tunnel_termination.tunnel|linkify|placeholder }}
{% trans "L2VPN" %}{{ object.l2vpn_termination.l2vpn|linkify|placeholder }}
-
-
-

{% trans "Related Interfaces" %}

- - - - - - - - - - - - - - - - - -
{% trans "Parent" %}{{ object.parent|linkify|placeholder }}
{% trans "Bridge" %}{{ object.bridge|linkify|placeholder }}
{% trans "Bridged Interfaces" %} - {% if bridge_interfaces %} - {% for interface in bridge_interfaces %} - {{ interface|linkify }} - {% if not forloop.last %}
{% endif %} - {% endfor %} - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "LAG" %}{{ object.lag|linkify|placeholder }}
-
- {% include 'inc/panels/custom_fields.html' %} - {% include 'inc/panels/tags.html' %} - {% plugin_left_page object %} -
-
- {% include 'inc/panel_table.html' with table=vdc_table heading="Virtual Device Contexts" %} -
-

{% trans "Addressing" %}

- - - - - - - - - - - - - - - - - -
{% trans "MAC Address" %} - {% if object.primary_mac_address %} - {{ object.primary_mac_address|linkify }} - {% trans "Primary" %} - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "WWN" %} - {% if object.wwn %} - {{ object.wwn }} - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "VRF" %}{{ object.vrf|linkify|placeholder }}
{% trans "VLAN Translation" %}{{ object.vlan_translation_policy|linkify|placeholder }}
-
- {% if object.is_virtual and object.virtual_circuit_termination %} -
-

{% trans "Virtual Circuit" %}

- - - - - - - - - - - - - - - - - - - - - -
{% trans "Provider" %}{{ object.virtual_circuit_termination.virtual_circuit.provider|linkify }}
{% trans "Provider Network" %}{{ object.virtual_circuit_termination.virtual_circuit.provider_network|linkify }}
{% trans "Circuit ID" %}{{ object.virtual_circuit_termination.virtual_circuit|linkify }}
{% trans "Role" %}{{ object.virtual_circuit_termination.get_role_display }}
{% trans "Connections" %} - {% for termination in object.virtual_circuit_termination.peer_terminations %} - {{ termination.interface.parent_object }} - - {{ termination.interface }} - ({{ termination.get_role_display }}) - {% if not forloop.last %}
{% endif %} - {% endfor %} -
-
- {% elif not object.is_virtual %} -
-

{% trans "Connection" %}

- {% if object.mark_connected %} -
- - {% trans "Marked as Connected" %} -
- {% elif object.cable %} - {% include 'dcim/inc/connection_endpoints.html' with trace_url='dcim:interface_trace' %} - {% elif object.wireless_link %} - - - - - - {% with peer_interface=object.link_peers.0 %} - - - - - - - - - - - - - {% endwith %} -
{% trans "Wireless Link" %} - {{ object.wireless_link|linkify }} - - - -
{% trans "Device" %}{{ peer_interface.device|linkify }}
{% trans "Name" %}{{ peer_interface|linkify }}
{% trans "Type" %}{{ peer_interface.get_type_display }}
- {% else %} -
- {% trans "Not Connected" %} - {% if object.is_wired and perms.dcim.add_cable %} - - {% elif object.is_wireless and perms.wireless.add_wirelesslink %} - - {% endif %} -
- {% endif %} -
- {% endif %} - {% if object.is_wireless %} -
-

{% trans "Wireless" %}

- {% with peer=object.connected_endpoints.0 %} - - - - - - {% if peer %} - - {% endif %} - - - - - - {% if peer %} - - {% endif %} - - - - - {% if peer %} - - {{ peer.get_rf_channel_display|placeholder }} - - {% endif %} - - - - - {% if peer %} - - {% if peer.rf_channel_frequency %} - {{ peer.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" %} - {% else %} - {{ ''|placeholder }} - {% endif %} - - {% endif %} - - - - - {% if peer %} - - {% if peer.rf_channel_width %} - {{ peer.rf_channel_width|floatformat:"-3" }} {% trans "MHz" %} - {% else %} - {{ ''|placeholder }} - {% endif %} - - {% endif %} - -
{% trans "Local" %}{% trans "Peer" %}
{% trans "Role" %}{{ object.get_rf_role_display|placeholder }}{{ peer.get_rf_role_display|placeholder }}
{% trans "Channel" %}{{ object.get_rf_channel_display|placeholder }}
{% trans "Channel Frequency" %} - {% if object.rf_channel_frequency %} - {{ object.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" %} - {% else %} - {{ ''|placeholder }} - {% endif %} -
{% trans "Channel Width" %} - {% if object.rf_channel_width %} - {{ object.rf_channel_width|floatformat:"-3" }} {% trans "MHz" %} - {% else %} - {{ ''|placeholder }} - {% endif %} -
- {% endwith %} -
-
-

{% trans "Wireless LANs" %}

- - - - - - - - - {% for wlan in object.wireless_lans.all %} - - - - - {% empty %} - - - - {% endfor %} - -
{% trans "Group" %}{% trans "SSID" %}
{{ wlan.group|linkify|placeholder }}{{ wlan|linkify:"ssid" }}
{% trans "None" %}
-
- {% endif %} - {% include 'ipam/inc/panels/fhrp_groups.html' %} - {% include 'dcim/inc/panels/inventory_items.html' %} - {% plugin_right_page object %} -
-
-
-
-
-

- {% trans "IP Addresses" %} - {% if perms.ipam.add_ipaddress %} - - {% endif %} -

- {% htmx_table 'ipam:ipaddress_list' interface_id=object.pk %} -
-
-
-
-
-
-

- {% trans "MAC Addresses" %} - {% if perms.dcim.add_macaddress %} - - {% endif %} -

- {% htmx_table 'dcim:macaddress_list' interface_id=object.pk %} -
-
-
-
-
-
-

{% trans "VLANs" %}

- {% htmx_table 'ipam:vlan_list' interface_id=object.pk %} -
-
-
- {% if object.is_lag %} -
-
- {% include 'inc/panel_table.html' with table=lag_interfaces_table heading="LAG Members" %} -
-
- {% endif %} - {% if object.vlan_translation_policy %} -
-
- {% include 'inc/panel_table.html' with table=vlan_translation_table heading="VLAN Translation" %} -
-
- {% endif %} -
-
- {% include 'inc/panel_table.html' with table=bridge_interfaces_table heading="Bridged Interfaces" %} -
-
-
-
- {% include 'inc/panel_table.html' with table=child_interfaces_table heading="Child Interfaces" %} -
-
-
-
- {% plugin_full_width_page object %} -
-
-{% endblock %} diff --git a/netbox/templates/dcim/interface/attrs/mac_address.html b/netbox/templates/dcim/interface/attrs/mac_address.html new file mode 100644 index 000000000..abb3c9cb8 --- /dev/null +++ b/netbox/templates/dcim/interface/attrs/mac_address.html @@ -0,0 +1,3 @@ +{% load helpers i18n %} +{{ value|linkify }} +{% trans "Primary" %} diff --git a/netbox/templates/dcim/interface/attrs/speed.html b/netbox/templates/dcim/interface/attrs/speed.html new file mode 100644 index 000000000..fc4b15d28 --- /dev/null +++ b/netbox/templates/dcim/interface/attrs/speed.html @@ -0,0 +1,2 @@ +{% load helpers %} +{{ value|humanize_speed }} 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/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..59b24520b --- /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/front_port_mappings.html b/netbox/templates/dcim/panels/front_port_mappings.html new file mode 100644 index 000000000..aef48cb2c --- /dev/null +++ b/netbox/templates/dcim/panels/front_port_mappings.html @@ -0,0 +1,29 @@ +{% load i18n %} + +
+

{% trans "Port Mappings" %}

+ + {% if rear_port_mappings %} + + + + + + + {% endif %} + + {% for mapping in rear_port_mappings %} + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Position" %}{% trans "Rear Port" %}
{{ mapping.front_port_position }} + {{ mapping.rear_port }}:{{ mapping.rear_port_position }} +
{% trans "No mappings defined" %}
+
diff --git a/netbox/templates/dcim/panels/installed_device.html b/netbox/templates/dcim/panels/installed_device.html new file mode 100644 index 000000000..c95bf7f5d --- /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..8125d2a63 --- /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/interface_connection.html b/netbox/templates/dcim/panels/interface_connection.html new file mode 100644 index 000000000..781c69d90 --- /dev/null +++ b/netbox/templates/dcim/panels/interface_connection.html @@ -0,0 +1,105 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% if object.mark_connected %} +
+ + {% trans "Marked as connected" %} +
+ {% elif object.cable %} + + + + + + + + + + + + + +
{% 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 %} +
+ {% elif object.wireless_link %} + + + + + + {% with peer_interface=object.link_peers.0 %} + + + + + + + + + + + + + {% endwith %} +
{% trans "Wireless Link" %} + {{ object.wireless_link|linkify }} + + + +
{% trans "Device" %}{{ peer_interface.device|linkify }}
{% trans "Name" %}{{ peer_interface|linkify }}
{% trans "Type" %}{{ peer_interface.get_type_display }}
+ {% else %} +
+ {% trans "Not Connected" %} + {% if object.is_wired and perms.dcim.add_cable %} + + {% elif object.is_wireless and perms.wireless.add_wirelesslink %} + + {% endif %} +
+ {% endif %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/interface_virtual_circuit.html b/netbox/templates/dcim/panels/interface_virtual_circuit.html new file mode 100644 index 000000000..70e0c065c --- /dev/null +++ b/netbox/templates/dcim/panels/interface_virtual_circuit.html @@ -0,0 +1,35 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + + + + + + + + + + + + + + + + + + + + + +
{% trans "Provider" %}{{ object.virtual_circuit_termination.virtual_circuit.provider|linkify }}
{% trans "Provider Network" %}{{ object.virtual_circuit_termination.virtual_circuit.provider_network|linkify }}
{% trans "Circuit ID" %}{{ object.virtual_circuit_termination.virtual_circuit|linkify }}
{% trans "Role" %}{{ object.virtual_circuit_termination.get_role_display }}
{% trans "Connections" %} + {% for termination in object.virtual_circuit_termination.peer_terminations %} + {{ termination.interface.parent_object }} + + {{ termination.interface }} + ({{ termination.get_role_display }}) + {% if not forloop.last %}
{% endif %} + {% endfor %} +
+{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/interface_wireless.html b/netbox/templates/dcim/panels/interface_wireless.html new file mode 100644 index 000000000..dfc7a3452 --- /dev/null +++ b/netbox/templates/dcim/panels/interface_wireless.html @@ -0,0 +1,72 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + {% with peer=object.connected_endpoints.0 %} + + + + + + {% if peer %} + + {% endif %} + + + + + + {% if peer %} + + {% endif %} + + + + + {% if peer %} + + {{ peer.get_rf_channel_display|placeholder }} + + {% endif %} + + + + + {% if peer %} + + {% if peer.rf_channel_frequency %} + {{ peer.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" %} + {% else %} + {{ ''|placeholder }} + {% endif %} + + {% endif %} + + + + + {% if peer %} + + {% if peer.rf_channel_width %} + {{ peer.rf_channel_width|floatformat:"-3" }} {% trans "MHz" %} + {% else %} + {{ ''|placeholder }} + {% endif %} + + {% endif %} + +
{% trans "Local" %}{% trans "Peer" %}
{% trans "Role" %}{{ object.get_rf_role_display|placeholder }}{{ peer.get_rf_role_display|placeholder }}
{% trans "Channel" %}{{ object.get_rf_channel_display|placeholder }}
{% trans "Channel frequency" %} + {% if object.rf_channel_frequency %} + {{ object.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" %} + {% else %} + {{ ''|placeholder }} + {% endif %} +
{% trans "Channel width" %} + {% if object.rf_channel_width %} + {{ object.rf_channel_width|floatformat:"-3" }} {% trans "MHz" %} + {% else %} + {{ ''|placeholder }} + {% endif %} +
+ {% endwith %} +{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/interface_wireless_lans.html b/netbox/templates/dcim/panels/interface_wireless_lans.html new file mode 100644 index 000000000..30c83101d --- /dev/null +++ b/netbox/templates/dcim/panels/interface_wireless_lans.html @@ -0,0 +1,25 @@ +{% extends "ui/panels/_base.html" %} +{% load helpers i18n %} + +{% block panel_content %} + + + + + + + + + {% for wlan in object.wireless_lans.all %} + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Group" %}{% trans "SSID" %}
{{ wlan.group|linkify|placeholder }}{{ wlan|linkify:"ssid" }}
{% trans "None" %}
+{% endblock panel_content %} diff --git a/netbox/templates/dcim/panels/rear_port_mappings.html b/netbox/templates/dcim/panels/rear_port_mappings.html new file mode 100644 index 000000000..557229589 --- /dev/null +++ b/netbox/templates/dcim/panels/rear_port_mappings.html @@ -0,0 +1,29 @@ +{% load i18n %} + +
+

{% trans "Port Mappings" %}

+ + {% if front_port_mappings %} + + + + + + + {% endif %} + + {% for mapping in front_port_mappings %} + + + + + {% empty %} + + + + {% endfor %} + +
{% trans "Position" %}{% trans "Front Port" %}
{{ mapping.rear_port_position }} + {{ mapping.front_port }}:{{ mapping.front_port_position }} +
{% trans "No mappings defined" %}
+
diff --git a/netbox/templates/dcim/panels/virtual_chassis_members.html b/netbox/templates/dcim/panels/virtual_chassis_members.html index 29e422ea6..43e14cc32 100644 --- a/netbox/templates/dcim/panels/virtual_chassis_members.html +++ b/netbox/templates/dcim/panels/virtual_chassis_members.html @@ -17,7 +17,7 @@ {{ vc_member|linkify }} {% badge vc_member.vc_position show_empty=True %} - {% if object.virtual_chassis.master == vc_member %} + {% if virtual_chassis.master == vc_member %} {% checkmark True %} {% else %} {{ ''|placeholder }} diff --git a/netbox/templates/dcim/powerfeed.html b/netbox/templates/dcim/powerfeed.html index f03ead88b..bbb1609b9 100644 --- a/netbox/templates/dcim/powerfeed.html +++ b/netbox/templates/dcim/powerfeed.html @@ -1,9 +1,4 @@ {% extends 'generic/object.html' %} -{% load buttons %} -{% load static %} -{% load helpers %} -{% load plugins %} -{% load i18n %} {% block breadcrumbs %} {{ block.super }} @@ -13,126 +8,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..56f3c5f30 100644 --- a/netbox/templates/dcim/powerpanel.html +++ b/netbox/templates/dcim/powerpanel.html @@ -1,8 +1,4 @@ {% extends 'generic/object.html' %} -{% load helpers %} -{% load plugins %} -{% load render_table from django_tables2 %} -{% load i18n %} {% block breadcrumbs %} {{ block.super }} @@ -11,72 +7,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 %}