fix: render rack integrations server-side

This commit is contained in:
2026-08-13 10:15:13 +02:00
parent 33490d40c4
commit 270d821219
9 changed files with 302 additions and 11 deletions
@@ -9,6 +9,17 @@
<script src="{% static 'netbox_utilities/navigation.js' %}?v={{ asset_version }}" defer></script>
{% endif %}
{% if topology_rack_width_data %}
{% if topology_rack_width_data.complete %}
<style id="netbox-utilities-topology-rack-width-styles">
{% for device in topology_rack_width_data.devices %}
.rack-device[href="{{ device.url|escapejs }}"] {
right: auto !important;
left: calc({{ device.left_percent }}% + 3px) !important;
width: calc({{ device.width_percent }}% - 6px) !important;
}
{% endfor %}
</style>
{% endif %}
{{ topology_rack_width_data|json_script:"netbox-utilities-topology-rack-width-data" }}
<script src="{% static 'netbox_utilities/topology-rack-width.js' %}?v={{ asset_version }}" defer></script>
{% endif %}
@@ -0,0 +1,51 @@
{% extends "netbox_reorder_rack/rack.html" %}
{% load perms %}
{% load rack %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="d-flex justify-content-end btn-list mb-2">
<select class="btn btn-outline-secondary no-ts rack-view" id="view-selector">
<option value="images-and-labels"{% if images and labels %} selected{% endif %}>{% trans "Images and Labels" %}</option>
<option value="images-only"{% if images and not labels %} selected{% endif %}>{% trans "Images only" %}</option>
<option value="labels-only"{% if labels and not images %} selected{% endif %}>{% trans "Labels only" %}</option>
</select>
<button class="btn btn-success" id="saveButton" disabled>Save</button>
</div>
</div>
<div class="container mt-2">
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-12 text-center">
<h4>Front</h4>
{% include "netbox_utilities/reorder_rack_grid.html" with face="front" grid_id=0 %}
</div>
<div class="col-lg-4 col-md-6 col-sm-12 text-center">
<h4>Back</h4>
{% include "netbox_utilities/reorder_rack_grid.html" with face="rear" grid_id=1 %}
</div>
<div class="col-lg-4 col-md-6 col-sm-12 text-center">
<h4>Non-Racked Devices</h4>
<div class="d-flex justify-content-center">
<div class="grid-stack rack" id="grid-other" gs-column="12" gs-max-row="150"
gs-min-row="{{ object.u_height|mul:2 }}" data-grid-id="2">
{% for device in non_racked %}
<div class="grid-stack-item" gs-w="12" gs-h="{{ device.device_type.u_height|mul:2 }}"
gs-x="0" gs-id="{{ device.pk }}" data-item-face="none"
data-item-color="{{ device.role.color|default:'1685fc' }}"
data-item-text-color="{% if device.role.color %}{{ device.role.color|text_color }}{% else %}000000{% endif %}"
data-full-depth="{{ device.device_type.is_full_depth }}"
gs-locked="{% if not request.user|can_change:device %}true{% else %}false{% endif %}"
gs-no-move="{% if not request.user|can_change:device %}true{% else %}false{% endif %}">
<div class="grid-stack-item-content"
style="background-color: #{{ device.role.color|default:'1685fc' }}; color: #{% if device.role.color %}{{ device.role.color|text_color }}{% else %}000000{% endif %}">
{{ device.name|default:device.device_type }}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
@@ -0,0 +1,33 @@
{% load rack %}
<div class="d-flex justify-content-center">
<div class="rack_front d-flex">
<ul class="unit_numbers">
{% for unit in object.units %}
{% if unit|rack_unit %}<li>{{ unit|rack_unit_to_int }}</li>{% else %}<li></li>{% endif %}
{% endfor %}
</ul>
<div class="grid-stack rack" id="grid-{{ face }}" gs-column="12"
gs-max-row="{{ object.u_height|mul:2 }}" gs-min-row="{{ object.u_height|mul:2 }}"
data-grid-id="{{ grid_id }}">
{% for device in reorder_devices %}
{% if device.face == face or device.full_depth %}
<div class="grid-stack-item" gs-w="{{ device.grid_width }}" gs-h="{{ device.grid_height }}"
gs-x="{{ device.grid_x }}" gs-y="{{ device.grid_y }}" gs-id="{{ device.id }}"
gs-locked="{% if device.locked %}true{% else %}false{% endif %}"
gs-no-move="{% if device.locked %}true{% else %}false{% endif %}"
data-item-color="{{ device.color }}" data-item-text-color="{{ device.text_color }}"
data-full-depth="{% if device.full_depth %}True{% else %}False{% endif %}"
data-item-face="{% if device.face == face %}{{ face }}{% else %}back{% endif %}"
data-rack-width="{{ device.width }}"
data-horizontal-position="{{ device.horizontal_position }}">
<div class="grid-stack-item-content{% if device.face != face %} device_rear{% endif %}"
style="{% if device.face == face %}background-color: #{{ device.color }}; color: #{{ device.text_color }}{% else %}color: #000000{% endif %}">
{{ device.label }}
</div>
</div>
{% endif %}
{% endfor %}
</div>
<ul class="indexes"></ul>
</div>
</div>