diff --git a/docs/installation/3-netbox.md b/docs/installation/3-netbox.md
index 60a118977..a91ce5e9c 100644
--- a/docs/installation/3-netbox.md
+++ b/docs/installation/3-netbox.md
@@ -302,13 +302,6 @@ Quit the server with CONTROL-C.
Next, connect to the name or IP of the server (as defined in `ALLOWED_HOSTS`) on port 8000; for example, . You should be greeted with the NetBox home page. Try logging in using the username and password specified when creating a superuser.
-!!! note
- By default RHEL based distros will likely block your testing attempts with firewalld. The development server port can be opened with `firewall-cmd` (add `--permanent` if you want the rule to survive server restarts):
-
- ```no-highlight
- firewall-cmd --zone=public --add-port=8000/tcp
- ```
-
!!! danger "Not for production use"
The development server is for development and testing purposes only. It is neither performant nor secure enough for production use. **Do not use it in production.**
diff --git a/netbox/dcim/svg/racks.py b/netbox/dcim/svg/racks.py
index de695664a..7bea9d91d 100644
--- a/netbox/dcim/svg/racks.py
+++ b/netbox/dcim/svg/racks.py
@@ -3,6 +3,7 @@ import svgwrite
from svgwrite.container import Hyperlink
from svgwrite.image import Image
from svgwrite.gradients import LinearGradient
+from svgwrite.masking import ClipPath
from svgwrite.shapes import Rect
from svgwrite.text import Text
@@ -67,6 +68,20 @@ def get_device_description(device):
return description
+def truncate_text(text, width, font_size=15):
+ """
+ Truncate text to fit within the width of a rectangle.
+
+ :param text: The text to truncate
+ :param width: Width of rectangle
+ :param font_size: Font size (default is 15, ~0.875rem)
+ """
+ char_width = font_size * 0.6 # 0.6 is an approximation of the average character width in pixels
+ max_char = int(width / char_width)
+
+ return text if len(text) <= max_char else text[:max_char] + '...'
+
+
class RackElevationSVG:
"""
Use this class to render a rack elevation as an SVG image.
@@ -177,12 +192,26 @@ class RackElevationSVG:
link = Hyperlink(href=f'{self.base_url}{device.get_absolute_url()}', target="_parent")
link.set_desc(description)
+ # Create clipPath element
+ # This is necessary as fallback because the truncate_text method is an approximation
+ clip_id = f"clip-{device.id}"
+ clip_path = ClipPath(id=clip_id)
+ clip_path.add(Rect(coords, size))
+
+ self.drawing.defs.add(clip_path)
+
+ # Name to display
+ display_name = truncate_text(name, size[0])
+
# Add rect element to hyperlink
if color:
link.add(Rect(coords, size, style=f'fill: #{color}', class_=f'slot{css_extra}'))
else:
link.add(Rect(coords, size, class_=f'slot blocked{css_extra}'))
- link.add(Text(name, insert=text_coords, fill=text_color, class_=f'label{css_extra}'))
+ link.add(
+ Text(display_name, insert=text_coords, fill=text_color, clip_path=f"url(#{clip_id})",
+ class_=f'label{css_extra}')
+ )
# Embed device type image if provided
if self.include_images and image:
diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js
index c4dd84461..9e2d6b383 100644
Binary files a/netbox/project-static/dist/netbox.js and b/netbox/project-static/dist/netbox.js differ
diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map
index d71bcc1ff..0ba7a62d1 100644
Binary files a/netbox/project-static/dist/netbox.js.map and b/netbox/project-static/dist/netbox.js.map differ
diff --git a/netbox/project-static/src/racks.ts b/netbox/project-static/src/racks.ts
index cae9897fc..54b144363 100644
--- a/netbox/project-static/src/racks.ts
+++ b/netbox/project-static/src/racks.ts
@@ -35,7 +35,7 @@ function showRackElements(
selector: string,
elevation: HTMLObjectElement,
): void {
- const elements = elevation.contentDocument?.querySelectorAll(selector) ?? [];
+ const elements = elevation.querySelectorAll(selector) ?? [];
for (const element of elements) {
element.classList.remove('hidden');
}
@@ -45,7 +45,7 @@ function hideRackElements(
selector: string,
elevation: HTMLObjectElement,
): void {
- const elements = elevation.contentDocument?.querySelectorAll(selector) ?? [];
+ const elements = elevation.querySelectorAll(selector) ?? [];
for (const element of elements) {
element.classList.add('hidden');
}
diff --git a/netbox/templates/dcim/inc/rack_elevation.html b/netbox/templates/dcim/inc/rack_elevation.html
index c51bcec24..d2fb62e0d 100644
--- a/netbox/templates/dcim/inc/rack_elevation.html
+++ b/netbox/templates/dcim/inc/rack_elevation.html
@@ -1,5 +1,5 @@
{% load i18n %}
-