diff --git a/README.md b/README.md
index 554d1a0..fa68de0 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,10 @@ mehrwertige Reverse-Relationen. Das behebt unter NetBox 4.6.8 insbesondere den
Fehler `'RelatedManager' object has no attribute '_meta'` beim Öffnen der
Seite zum Anlegen einer VLAN-Gruppe.
+Ab Version `0.10.2` befindet sich die VLAN-Auswahl beim Anlegen und Bearbeiten
+eines Kabels direkt im Abschnitt **B-Seite**, unterhalb des B-seitigen
+Verbindungsendes.
+
## Kompatibilität
- NetBox `>=4.6.5,<4.7`
diff --git a/netbox_utilities/__init__.py b/netbox_utilities/__init__.py
index 73551f7..305cd9e 100644
--- a/netbox_utilities/__init__.py
+++ b/netbox_utilities/__init__.py
@@ -1,6 +1,6 @@
from netbox.plugins import PluginConfig, get_plugin_config
-__version__ = "0.10.1"
+__version__ = "0.10.2"
class NetBoxUtilitiesConfig(PluginConfig):
diff --git a/netbox_utilities/templates/netbox_utilities/cable_edit_form.html b/netbox_utilities/templates/netbox_utilities/cable_edit_form.html
index ce1af16..e28b983 100644
--- a/netbox_utilities/templates/netbox_utilities/cable_edit_form.html
+++ b/netbox_utilities/templates/netbox_utilities/cable_edit_form.html
@@ -1,12 +1,120 @@
+{% load static %}
+{% load helpers %}
{% load form_helpers %}
+{% load i18n %}
-{% include 'dcim/htmx/cable_edit.html' %}
+{% for field in form.hidden_fields %}
+ {{ field }}
+{% endfor %}
-{% if form.utilities_vlans %}
+{# A side termination #}
+
+
+
{% trans "A Side" %}
+
+ {% render_field form.a_terminations_type %}
+ {% if 'termination_a_device' in form.fields %}
+ {% render_field form.termination_a_device %}
+ {% endif %}
+ {% if 'termination_a_powerpanel' in form.fields %}
+ {% render_field form.termination_a_powerpanel %}
+ {% endif %}
+ {% if 'termination_a_circuit' in form.fields %}
+ {% render_field form.termination_a_circuit %}
+ {% endif %}
+ {% if 'a_terminations' in form.fields %}
+ {% render_field form.a_terminations %}
+ {% endif %}
+
+
+{# B side termination and connection VLANs #}
+
+
+
{% trans "B Side" %}
+
+ {% render_field form.b_terminations_type %}
+ {% if 'termination_b_device' in form.fields %}
+ {% render_field form.termination_b_device %}
+ {% endif %}
+ {% if 'termination_b_powerpanel' in form.fields %}
+ {% render_field form.termination_b_powerpanel %}
+ {% endif %}
+ {% if 'termination_b_circuit' in form.fields %}
+ {% render_field form.termination_b_circuit %}
+ {% endif %}
+ {% if 'b_terminations' in form.fields %}
+ {% render_field form.b_terminations %}
+ {% endif %}
+ {% if form.utilities_vlans %}
+ {% render_field form.utilities_vlans %}
+ {% endif %}
+
+
+{# Cable attributes #}
+
+
+
{% trans "Cable" %}
+
+ {% render_field form.status %}
+ {% render_field form.profile %}
+ {% render_field form.type %}
+ {% render_field form.bundle %}
+ {% render_field form.label %}
+ {% render_field form.description %}
+ {% render_field form.color %}
+
+ {% render_field form.tags %}
+
+
+
+
+
{% trans "Tenancy" %}
+
+ {% render_field form.tenant_group %}
+ {% render_field form.tenant %}
+
+
+
+
+
{% trans "Ownership" %}
+
+ {% render_field form.owner_group %}
+ {% render_field form.owner %}
+
+
+{% if form.custom_fields %}
-
VLANs der Verbindung
+ {% trans "Custom Fields" %}
- {% render_field form.utilities_vlans %}
+ {% render_custom_fields form %}
{% endif %}
+
+
+
{% trans "Comments" %}
+ {% render_field form.comments %}
+
+
+{# Meta fields #}
+
+ {% render_field form.changelog_message %}
+
diff --git a/netbox_utilities/tests/test_connection_vlans.py b/netbox_utilities/tests/test_connection_vlans.py
index e191547..f3cc37c 100644
--- a/netbox_utilities/tests/test_connection_vlans.py
+++ b/netbox_utilities/tests/test_connection_vlans.py
@@ -1,8 +1,10 @@
+from pathlib import Path
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
from django import forms
from django.forms.utils import ErrorDict
+from django.template.loader import get_template
from django.test import SimpleTestCase
from netbox_utilities.connection_vlans import (
@@ -14,6 +16,19 @@ from netbox_utilities.models import CableVLANAssignment, WirelessLinkVLANAssignm
class ConnectionVLANTest(SimpleTestCase):
+ def test_cable_vlan_field_is_rendered_below_b_side(self):
+ self.assertIsNotNone(get_template("netbox_utilities/cable_edit_form.html"))
+ template_path = Path(__file__).parents[1] / "templates" / "netbox_utilities" / "cable_edit_form.html"
+ template = template_path.read_text(encoding="utf-8")
+
+ b_side = template.index('{% trans "B Side" %}')
+ vlan_field = template.index("{% render_field form.utilities_vlans %}")
+ cable_section = template.index('{% trans "Cable" %}')
+
+ self.assertLess(b_side, vlan_field)
+ self.assertLess(vlan_field, cable_section)
+ self.assertEqual(template.count("{% render_field form.utilities_vlans %}"), 1)
+
def test_assignment_models_are_tied_to_their_connection_and_vlans(self):
self.assertEqual(
CableVLANAssignment._meta.get_field("cable").remote_field.model._meta.label_lower, "dcim.cable"
diff --git a/netbox_utilities/tests/test_reorder_rack.py b/netbox_utilities/tests/test_reorder_rack.py
index e0b57c4..cf0d12e 100644
--- a/netbox_utilities/tests/test_reorder_rack.py
+++ b/netbox_utilities/tests/test_reorder_rack.py
@@ -449,7 +449,7 @@ class ReorderRackFrontendTest(SimpleTestCase):
self.assertEqual(template_name, "netbox_utilities/reorder_rack.html")
self.assertEqual(context["reorder_devices"][0]["label"], "LEO-Fritzbox")
self.assertEqual(context["reorder_devices"][0]["grid_width"], 6)
- self.assertEqual(context["asset_version"], "0.10.1")
+ self.assertEqual(context["asset_version"], "0.10.2")
self.assertIs(context["reorder_rack_width_data"], get_width_data.return_value)
get_width_data.assert_called_once()
self.assertIs(get_width_data.call_args.kwargs["rack"], rack)
diff --git a/netbox_utilities/tests/test_topology_views.py b/netbox_utilities/tests/test_topology_views.py
index b0eace9..9614535 100644
--- a/netbox_utilities/tests/test_topology_views.py
+++ b/netbox_utilities/tests/test_topology_views.py
@@ -246,7 +246,7 @@ class TopologyViewsRackWidthTest(SimpleTestCase):
self.assertIn('id="netbox-utilities-topology-rack-width-styles"', html)
self.assertIn('.rack-device[href="/dcim/devices/334/"]', html)
self.assertIn("left: calc(50% + 3px) !important", html)
- self.assertIn("netbox_utilities/topology-rack-width.js?v=0.10.1", html)
+ self.assertIn("netbox_utilities/topology-rack-width.js?v=0.10.2", html)
self.assertIn("left:calc(0% + 3px)!important", html)
self.assertIn("left:calc(50% + 3px)!important", html)
self.assertIn("width:calc(50% - 6px)!important", html)
diff --git a/pyproject.toml b/pyproject.toml
index 6a1c01d..813b957 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "netbox-utilities"
-version = "0.10.1"
+version = "0.10.2"
description = "Navigation, tenant utilities, connection VLANs, partial-width racks, and bulk operations for NetBox 4.6"
readme = "README.md"
requires-python = ">=3.12"