diff --git a/netbox_utilities/__init__.py b/netbox_utilities/__init__.py index 743a75c..b645c51 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.12.0" +__version__ = "0.12.1" class NetBoxUtilitiesConfig(PluginConfig): diff --git a/netbox_utilities/svg_export.py b/netbox_utilities/svg_export.py index 8ebce93..2a0800e 100644 --- a/netbox_utilities/svg_export.py +++ b/netbox_utilities/svg_export.py @@ -11,24 +11,30 @@ _IMAGE_TAGS = (f"{{{SVG_NS}}}image", "image") _HREF_ATTRS = ("href", f"{{{XLINK_NS}}}href") RACK_VIEW_MODES = {"images-and-labels", "images-only", "labels-only"} -_LABEL_CLASSES = {"label"} -_IMAGE_CLASSES = {"device-image", "device-image-label"} +_PLAIN_LABEL_CLASS = "label" +_IMAGE_CLASS = "device-image" +_IMAGE_LABEL_CLASS = "device-image-label" def apply_rack_view_mode(svg_source, mode): - """Mirror the rack elevation page's "Bilder"/"Beschriftungen" toggle server-side. + """Filter the rack elevation SVG down to images-only or labels-only content. - That toggle only hides elements client-side via CSS after the browser - already has the full SVG, so a freshly server-rendered export needs its - own equivalent to honor the mode the user had selected. + NetBox's own "Bilder"/"Beschriftungen" toggle never actually removes the + plain .label text: it just leaves an opaque .device-image sitting on top + of it, so a device without a photo still shows its name in "images-only" + live. A downloaded, static export has no such fallback text to hide + behind an image, so here "images-only" removes every label outright + (.label and .device-image-label) to always produce a pure image view, + and "labels-only" removes the image layer to reproduce the same + box-with-text view NetBox itself already shows for that mode. """ if mode not in RACK_VIEW_MODES or mode == "images-and-labels": return svg_source root = ET.fromstring(svg_source) if mode == "images-only": - _remove_elements_with_class(root, _LABEL_CLASSES) + _remove_elements_with_class(root, {_PLAIN_LABEL_CLASS, _IMAGE_LABEL_CLASS}) elif mode == "labels-only": - _remove_elements_with_class(root, _IMAGE_CLASSES) + _remove_elements_with_class(root, {_IMAGE_CLASS, _IMAGE_LABEL_CLASS}) return ET.tostring(root, encoding="unicode") diff --git a/netbox_utilities/tests/test_svg_export.py b/netbox_utilities/tests/test_svg_export.py index 18665dd..bcbb642 100644 --- a/netbox_utilities/tests/test_svg_export.py +++ b/netbox_utilities/tests/test_svg_export.py @@ -105,14 +105,14 @@ class ApplyRackViewModeTest(SimpleTestCase): def test_images_and_labels_leaves_svg_untouched(self): self.assertEqual(apply_rack_view_mode(self.SVG, "images-and-labels"), self.SVG) - def test_images_only_removes_label_text(self): + def test_images_only_keeps_only_the_image(self): result = apply_rack_view_mode(self.SVG, "images-only") self.assertNotIn('class="label"', result) + self.assertNotIn("device-image-label", result) self.assertIn('class="device-image"', result) - self.assertIn('class="device-image-label"', result) - def test_labels_only_removes_device_images(self): + def test_labels_only_keeps_only_the_plain_label(self): result = apply_rack_view_mode(self.SVG, "labels-only") self.assertIn('class="label"', result) diff --git a/pyproject.toml b/pyproject.toml index 4c1f1f1..47dd135 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "netbox-utilities" -version = "0.12.0" +version = "0.12.1" description = "Navigation, tenant utilities, connection VLANs, partial-width racks, and bulk operations for NetBox 4.6/4.7" readme = "README.md" requires-python = ">=3.12"