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 %} -
+