From 14f6b93bfb37b625584f8167767c780cb0f1832c Mon Sep 17 00:00:00 2001 From: bluikko <14869000+bluikko@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:59:58 +0700 Subject: [PATCH 1/3] Closes #19926: Remove RHEL firewalld note Closes: #19926 --- docs/installation/3-netbox.md | 7 ------- 1 file changed, 7 deletions(-) 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.** From c579894d78ff23aa6b197af46f594ad986a1f5e8 Mon Sep 17 00:00:00 2001 From: Marco Spizzuoco <49124921+MarcoSpiz@users.noreply.github.com> Date: Tue, 22 Jul 2025 18:44:14 +0200 Subject: [PATCH 2/3] Closes #19902: add clip path to avoid overflow of device name, truncate text to improve centering (#19913) --- netbox/dcim/svg/racks.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) 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: From 0141fc3f0651d581304057c0f405edde7de11336 Mon Sep 17 00:00:00 2001 From: Jason Novinger Date: Wed, 23 Jul 2025 05:35:48 -0500 Subject: [PATCH 3/3] Fixes #19916: restore Rack device representation behavior The select list of 'Images and Label', 'Images Only', and 'Label Only' was broken during recent work while implementing #19823. This fixes the issue by placing the `rack_elevation` class attribute on the
element that contains the SVG after being loaded by HTMX. In addition, we needed to slightly modify the selectors in the frontend code that looked for the elements within the SVG to hide and/or show. Previously, it was looking inside of a contentDocument embedded in an element. The simplified version just looks inside of the SVG containing div. --- netbox/project-static/dist/netbox.js | Bin 382259 -> 382185 bytes netbox/project-static/dist/netbox.js.map | Bin 1733549 -> 1733459 bytes netbox/project-static/src/racks.ts | 4 ++-- netbox/templates/dcim/inc/rack_elevation.html | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index c4dd844613e531feb5575b7d7d79f81a7733cd17..9e2d6b383c2f22e003900f3bd894ce5d117a9676 100644 GIT binary patch delta 118 zcmdnIO8n(Y@rD-07N!>F7M3lnRVTQub5ctbN^CVUZBwTojA0R(zV8GphiIl%bgXq+ fevt-9wn!mAO`$}yX!`9FtVX10*q(Qi^(Z$0F7M3lnRVO5LimY=|OB70MHHvICGHp}!lJoOQQu9hC9|#a< z%$$BOhDAhHQ_(iBG$+Tt$SOM4IxW9Q1EeEgAwNx_L^FT-wiB#IlpC{MF7M2#)7Pc1l7LFFq7OocV7M>Q~7QPn#7J(MQEkZs)(_@2# zzJiFj=?)9HSlW*U3jwh(5Q_k@C=iPQu{aP*Y(E+-d5_1X(AibT)6vn_S;yVcG2BJR z)zQ(>3q*$MWI8!IW;(g+I6FE9g4Ev#iYok6nY&LCkB)7j8vTB4*mqt|qcL`ek~ zZR(gOH~n&=WT0&j$i~D_kd4|-PzQnREOCtjxi=Cl6C4C`OE8dd%>g;f*Iy?X$PeG1 jm?Wvl$Q}e%ncUu)EV;ciSt^Tr`h80&@$CZnQgc}V2t;ZB delta 409 zcmccoEOYJi%!U@m7N!>F7M2#)7Pc1l7LFFq7OocV7M>Q~7QPn#7J(MQEkZs))Bm#a z$W8YP77Cnxe;pUc^i4rR{a~?npcoJf1F;AYivqD25Q_t`#CE@6Nn_qvM@MHJSI0tU zR~=7BM_*?hcSpx?7ZB;_0u*<2^a7EgI@wN+j$t~HKmkvXfRU3BoFQg98@omsZ%LIpjoEZ!xTyva(q_4kDFpwX)oi|BRk&!(FtTMITG+A=HX|hxnH&cAl K_Stz-J6Hgepmt#Z 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 %} -
+