Consolidate wireless link interface templates into ObjectPanel subclass

Replace duplicate wirelesslink_interface_{a,b}.html templates with a
single shared template and WirelessLinkInterfacePanel(ObjectPanel)
subclass that injects the correct interface via get_context().
This commit is contained in:
Jason Novinger
2026-03-11 14:04:49 -05:00
parent 8663a24214
commit 4e95f0cd39
4 changed files with 30 additions and 63 deletions

View File

@@ -1,34 +1,34 @@
{% extends "ui/panels/_base.html" %}
{% load helpers %} {% load helpers %}
{% load i18n %} {% load i18n %}
<div class="card"> {% block panel_content %}
<h2 class="card-header">{% trans "Interface" %} A</h2>
<table class="table table-hover attr-table"> <table class="table table-hover attr-table">
<tr> <tr>
<th scope="row">{% trans "Device" %}</th> <th scope="row">{% trans "Device" %}</th>
<td>{{ object.interface_a.device|linkify }}</td> <td>{{ interface.device|linkify }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Interface" %}</th> <th scope="row">{% trans "Interface" %}</th>
<td>{{ object.interface_a|linkify }}</td> <td>{{ interface|linkify }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Type" %}</th> <th scope="row">{% trans "Type" %}</th>
<td>{{ object.interface_a.get_type_display }}</td> <td>{{ interface.get_type_display }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Role" %}</th> <th scope="row">{% trans "Role" %}</th>
<td>{{ object.interface_a.get_rf_role_display|placeholder }}</td> <td>{{ interface.get_rf_role_display|placeholder }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Channel" %}</th> <th scope="row">{% trans "Channel" %}</th>
<td>{{ object.interface_a.get_rf_channel_display|placeholder }}</td> <td>{{ interface.get_rf_channel_display|placeholder }}</td>
</tr> </tr>
<tr> <tr>
<th scope="row">{% trans "Channel Frequency" %}</th> <th scope="row">{% trans "Channel Frequency" %}</th>
<td> <td>
{% if object.interface_a.rf_channel_frequency %} {% if interface.rf_channel_frequency %}
{{ object.interface_a.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" context "Abbreviation for megahertz" %} {{ interface.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" context "Abbreviation for megahertz" %}
{% else %} {% else %}
{{ ''|placeholder }} {{ ''|placeholder }}
{% endif %} {% endif %}
@@ -37,12 +37,12 @@
<tr> <tr>
<th scope="row">{% trans "Channel Width" %}</th> <th scope="row">{% trans "Channel Width" %}</th>
<td> <td>
{% if object.interface_a.rf_channel_width %} {% if interface.rf_channel_width %}
{{ object.interface_a.rf_channel_width|floatformat:"-3" }} {% trans "MHz" context "Abbreviation for megahertz" %} {{ interface.rf_channel_width|floatformat:"-3" }} {% trans "MHz" context "Abbreviation for megahertz" %}
{% else %} {% else %}
{{ ''|placeholder }} {{ ''|placeholder }}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
</table> </table>
</div> {% endblock panel_content %}

View File

@@ -1,48 +0,0 @@
{% load helpers %}
{% load i18n %}
<div class="card">
<h2 class="card-header">{% trans "Interface" %} B</h2>
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Device" %}</th>
<td>{{ object.interface_b.device|linkify }}</td>
</tr>
<tr>
<th scope="row">{% trans "Interface" %}</th>
<td>{{ object.interface_b|linkify }}</td>
</tr>
<tr>
<th scope="row">{% trans "Type" %}</th>
<td>{{ object.interface_b.get_type_display }}</td>
</tr>
<tr>
<th scope="row">{% trans "Role" %}</th>
<td>{{ object.interface_b.get_rf_role_display|placeholder }}</td>
</tr>
<tr>
<th scope="row">{% trans "Channel" %}</th>
<td>{{ object.interface_b.get_rf_channel_display|placeholder }}</td>
</tr>
<tr>
<th scope="row">{% trans "Channel Frequency" %}</th>
<td>
{% if object.interface_b.rf_channel_frequency %}
{{ object.interface_b.rf_channel_frequency|floatformat:"-2" }} {% trans "MHz" context "Abbreviation for megahertz" %}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Channel Width" %}</th>
<td>
{% if object.interface_b.rf_channel_width %}
{{ object.interface_b.rf_channel_width|floatformat:"-3" }} {% trans "MHz" context "Abbreviation for megahertz" %}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
</tr>
</table>
</div>

View File

@@ -25,6 +25,22 @@ class WirelessLANAuthenticationPanel(panels.ObjectAttributesPanel):
auth_psk = attrs.TemplatedAttr('auth_psk', label=_('PSK'), template_name='wireless/attrs/auth_psk.html') auth_psk = attrs.TemplatedAttr('auth_psk', label=_('PSK'), template_name='wireless/attrs/auth_psk.html')
class WirelessLinkInterfacePanel(panels.ObjectPanel):
template_name = 'wireless/panels/wirelesslink_interface.html'
def __init__(self, accessor, title, **kwargs):
super().__init__(**kwargs)
self.accessor = accessor
self.title = title
def get_context(self, context):
obj = context['object']
return {
**super().get_context(context),
'interface': getattr(obj, self.accessor),
}
class WirelessLinkPropertiesPanel(panels.ObjectAttributesPanel): class WirelessLinkPropertiesPanel(panels.ObjectAttributesPanel):
title = _('Link Properties') title = _('Link Properties')

View File

@@ -9,7 +9,6 @@ from netbox.ui.panels import (
ObjectsTablePanel, ObjectsTablePanel,
PluginContentPanel, PluginContentPanel,
RelatedObjectsPanel, RelatedObjectsPanel,
TemplatePanel,
) )
from netbox.views import generic from netbox.views import generic
from utilities.query import count_related from utilities.query import count_related
@@ -223,14 +222,14 @@ class WirelessLinkView(generic.ObjectView):
layout = layout.Layout( layout = layout.Layout(
Row( Row(
Column( Column(
TemplatePanel('wireless/panels/wirelesslink_interface_a.html'), panels.WirelessLinkInterfacePanel('interface_a', title=_('Interface A')),
panels.WirelessLinkPropertiesPanel(), panels.WirelessLinkPropertiesPanel(),
TagsPanel(), TagsPanel(),
CommentsPanel(), CommentsPanel(),
PluginContentPanel('left_page'), PluginContentPanel('left_page'),
), ),
Column( Column(
TemplatePanel('wireless/panels/wirelesslink_interface_b.html'), panels.WirelessLinkInterfacePanel('interface_b', title=_('Interface B')),
panels.WirelessLANAuthenticationPanel(), panels.WirelessLANAuthenticationPanel(),
CustomFieldsPanel(), CustomFieldsPanel(),
PluginContentPanel('right_page'), PluginContentPanel('right_page'),