Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions netbox/templates/extras/dashboard/widget.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% load dashboard %}
{% load helpers %}

<div
class="grid-stack-item"
Expand All @@ -16,18 +17,18 @@
hx-target="#htmx-modal-content"
data-bs-toggle="modal"
data-bs-target="#htmx-modal"
><i class="mdi mdi-cog text-gray"></i></a>
><i class="mdi mdi-cog {% if not widget.color %}text-gray{% endif %}" {% if widget.color %}style="color: {{ widget.color|fgcolor|lighten }};"{% endif %}></i></a>
</div>
<div class="float-end pe-1">
<a href="#"
hx-get="{% url 'extras:dashboardwidget_delete' id=widget.id %}"
hx-target="#htmx-modal-content"
data-bs-toggle="modal"
data-bs-target="#htmx-modal"
><i class="mdi mdi-close text-gray"></i></a>
><i class="mdi mdi-close {% if not widget.color %}text-gray{% endif %}" {% if widget.color %}style="color: {{ widget.color|fgcolor|lighten }};"{% endif %}></i></a>
</div>
{% if widget.title %}
<strong>{{ widget.title }}</strong>
<strong {% if widget.color %}style="color: {{ widget.color|fgcolor }};"{% endif %}>{{ widget.title }}</strong>
{% endif %}
</div>
<div class="card-body p-2 overflow-auto">
Expand Down
34 changes: 34 additions & 0 deletions netbox/utilities/colors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import colorsys


def hex_to_rgb(hex_str):
"""Returns a tuple representing the given hex string as RGB.
"""
if hex_str.startswith('#'):
hex_str = hex_str[1:]
return tuple([int(hex_str[i:i + 2], 16) for i in range(0, len(hex_str), 2)])


def rgb_to_hex(rgb):
"""Converts an rgb tuple to hex string for web.
"""
return ''.join(["%0.2X" % int(c) for c in rgb])


def adjust_color_lightness(r, g, b, factor):
hue, luminous, saturation = colorsys.rgb_to_hls(r / 255.0, g / 255.0, b / 255.0)
luminous = max(min(luminous * factor, 0.9), 0.1)
r, g, b = colorsys.hls_to_rgb(hue, luminous, saturation)
return int(r * 255), int(g * 255), int(b * 255)


def lighten_color(color, factor=0.1):
color = color.strip('#')
r, g, b = hex_to_rgb(color)
return rgb_to_hex(adjust_color_lightness(r, g, b, 1 + factor))


def darken_color(color, factor=0.1):
color = color.strip('#')
r, g, b = hex_to_rgb(color)
return rgb_to_hex(adjust_color_lightness(r, g, b, 1 - factor))
39 changes: 38 additions & 1 deletion netbox/utilities/templatetags/builtins/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

from netbox.config import get_config
from utilities.markdown import StrikethroughExtension
from utilities.choices import ButtonColorChoices
from utilities.colors import lighten_color
from utilities.utils import clean_html, foreground_color, title

__all__ = (
Expand All @@ -30,11 +32,36 @@

register = template.Library()

BOOTSTRAP_BUTTON_COLOR_MAP = {
"outline-dark": "ffffff",
"primary": "337ab7",
"secondary": "6c757d",
"success": "198754",
"info": "54d6f0",
"warning": "ffc107",
"danger": "dc3545",
"light": "e9ecef",
"dark": "343a40",
"blue": "0d6efd",
"indigo": "6610f2",
"purple": "6f42c1",
"pink": "d63384",
"red": "dc3545",
"orange": "fd7e14",
"yellow": "ffc107",
"green": "198754",
"teal": "20c997",
"cyan": "0dcaf0",
"gray": "adb5bd",
"black": "000000",
"white": "ffffff",
}

#
# General
#


@register.filter()
def linkify(instance, attr=None):
"""
Expand Down Expand Up @@ -77,10 +104,20 @@ def fgcolor(value, dark='000000', light='ffffff'):
"""
value = value.lower().strip('#')
if not re.match('^[0-9a-f]{6}$', value):
return ''
colors = [color[0] for color in ButtonColorChoices.CHOICES]
if value in colors:
value = BOOTSTRAP_BUTTON_COLOR_MAP[value]
else:
return ''
return f'#{foreground_color(value, dark, light)}'


@register.filter()
def lighten(color, amount=0.5):
c = lighten_color(color, factor=0.5)
return f'#{c}'


@register.filter()
def meta(model, attr):
"""
Expand Down