Compare commits

...

2 Commits

Author SHA1 Message Date
Marco Spizzuoco
d571cb4867 Closes #19902: add clip path to avoid overflow of device name, truncate text to improve centering (#19913)
Some checks failed
CI / build (20.x, 3.10) (push) Has been cancelled
CI / build (20.x, 3.11) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled
2025-07-22 09:44:14 -07:00
bluikko
2129355c30 Closes #19926: Remove RHEL firewalld note
Closes: #19926
2025-07-22 08:04:53 -04:00
2 changed files with 30 additions and 8 deletions

View File

@@ -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, <http://127.0.0.1:8000/>. You should be greeted with the NetBox home page. Try logging in using the username and password specified when creating a superuser. Next, connect to the name or IP of the server (as defined in `ALLOWED_HOSTS`) on port 8000; for example, <http://127.0.0.1:8000/>. 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" !!! 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.** 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.**

View File

@@ -3,6 +3,7 @@ import svgwrite
from svgwrite.container import Hyperlink from svgwrite.container import Hyperlink
from svgwrite.image import Image from svgwrite.image import Image
from svgwrite.gradients import LinearGradient from svgwrite.gradients import LinearGradient
from svgwrite.masking import ClipPath
from svgwrite.shapes import Rect from svgwrite.shapes import Rect
from svgwrite.text import Text from svgwrite.text import Text
@@ -67,6 +68,20 @@ def get_device_description(device):
return description 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: class RackElevationSVG:
""" """
Use this class to render a rack elevation as an SVG image. 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 = Hyperlink(href=f'{self.base_url}{device.get_absolute_url()}', target="_parent")
link.set_desc(description) 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 # Add rect element to hyperlink
if color: if color:
link.add(Rect(coords, size, style=f'fill: #{color}', class_=f'slot{css_extra}')) link.add(Rect(coords, size, style=f'fill: #{color}', class_=f'slot{css_extra}'))
else: else:
link.add(Rect(coords, size, class_=f'slot blocked{css_extra}')) 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 # Embed device type image if provided
if self.include_images and image: if self.include_images and image: