fix: preserve native reorder rack devices
This commit is contained in:
@@ -117,6 +117,10 @@ Reorder ersetzt seine nativen Gerätekacheln erst, nachdem ein vollständiger
|
||||
und zur JavaScript-Version passender Datensatz geprüft wurde. Bei einer
|
||||
gemischten Installation aus altem Python-Code und neuen statischen Dateien
|
||||
bleibt deshalb die native Ansicht erhalten, statt ein leeres Rack zu zeigen.
|
||||
Ab Version `0.9.4` werden vorhandene Reorder-Kacheln außerdem direkt auf das
|
||||
12-Spalten-Raster erweitert und nicht mehr vorsorglich neu erzeugt. Nur ein
|
||||
zweites, von NetBox' Ein-Gerät-pro-HE-Darstellung unterschlagenes Gerät wird
|
||||
aus den Plugin-Daten ergänzt. Das verhindert browserabhängige leere Racks.
|
||||
Bereits vorhandene Geräte, die dieselbe HE und Rackseite belegen, aber noch
|
||||
keine Plugin-Platzierungszeile besitzen, werden in Rack-SVG, Reorder und der
|
||||
Topology-Rack-Ansicht ohne Datenbankänderung gleichmäßig nebeneinander
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from netbox.plugins import PluginConfig, get_plugin_config
|
||||
|
||||
__version__ = "0.9.3"
|
||||
__version__ = "0.9.4"
|
||||
|
||||
|
||||
class NetBoxUtilitiesConfig(PluginConfig):
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
console.warn('NetBox Utilities received no replacement devices and kept the populated native layout.');
|
||||
return;
|
||||
}
|
||||
const devicesById = new Map(data.devices.map(device => [String(device.id), device]));
|
||||
const nativeItemsByFace = {};
|
||||
|
||||
const setAttribute = (element, name, value) => element.setAttribute(name, String(value));
|
||||
const originalFetch = window.fetch.bind(window);
|
||||
@@ -73,12 +75,26 @@
|
||||
|
||||
Object.entries(gridElements).forEach(([face, grid]) => {
|
||||
setAttribute(grid, 'gs-column', columns);
|
||||
const nativeItemsById = new Map(
|
||||
Array.from(grid.querySelectorAll('.grid-stack-item')).map(item => [item.getAttribute('gs-id'), item]),
|
||||
);
|
||||
grid.querySelectorAll('.grid-stack-item').forEach(item => {
|
||||
// The native Reorder view is based on Rack.get_rack_units(), which can
|
||||
// expose only one device per rack unit. Rebuild the mounted grids from
|
||||
// the complete server payload; keep native non-racked devices intact.
|
||||
// Keep every native widget whenever possible. Rack.get_rack_units() can
|
||||
// expose only one device per unit, so missing shared widgets are added
|
||||
// from the complete payload below.
|
||||
if (face !== 'other') {
|
||||
item.remove();
|
||||
const device = devicesById.get(item.getAttribute('gs-id'));
|
||||
const belongsOnFace = device && (device.face === face || device.full_depth);
|
||||
if (!belongsOnFace) {
|
||||
item.remove();
|
||||
return;
|
||||
}
|
||||
setAttribute(item, 'gs-w', device.grid_width);
|
||||
setAttribute(item, 'gs-h', device.grid_height);
|
||||
setAttribute(item, 'gs-x', device.grid_x);
|
||||
setAttribute(item, 'gs-y', device.grid_y);
|
||||
item.dataset.rackWidth = String(device.width);
|
||||
item.dataset.horizontalPosition = String(device.horizontal_position);
|
||||
return;
|
||||
}
|
||||
setAttribute(item, 'gs-w', columns);
|
||||
@@ -86,6 +102,7 @@
|
||||
item.dataset.rackWidth = '1';
|
||||
item.dataset.horizontalPosition = '1';
|
||||
});
|
||||
nativeItemsByFace[face] = nativeItemsById;
|
||||
});
|
||||
|
||||
const addWidget = (device, gridFace, itemFace, rearSide = false) => {
|
||||
@@ -125,9 +142,14 @@
|
||||
|
||||
data.devices.forEach(device => {
|
||||
const face = device.face === 'rear' ? 'rear' : 'front';
|
||||
addWidget(device, face, face);
|
||||
if (!nativeItemsByFace[face].has(String(device.id))) {
|
||||
addWidget(device, face, face);
|
||||
}
|
||||
if (device.full_depth) {
|
||||
addWidget(device, face === 'front' ? 'rear' : 'front', 'back', true);
|
||||
const oppositeFace = face === 'front' ? 'rear' : 'front';
|
||||
if (!nativeItemsByFace[oppositeFace].has(String(device.id))) {
|
||||
addWidget(device, oppositeFace, 'back', true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -291,6 +291,9 @@ class ReorderRackFrontendTest(SimpleTestCase):
|
||||
self.assertIn("data.schema_version !== 3", script)
|
||||
self.assertIn("data.complete !== true", script)
|
||||
self.assertIn("nativeMountedItems.length", script)
|
||||
self.assertIn("const nativeItemsByFace = {}", script)
|
||||
self.assertIn("const device = devicesById.get", script)
|
||||
self.assertIn("if (!nativeItemsByFace[face].has", script)
|
||||
self.assertNotIn("partialDeviceIds", script)
|
||||
self.assertNotIn("JSON.stringify", script)
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "netbox-utilities"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
description = "Navigation, tenant utilities, partial-width rack devices, bulk uploads, and rack reordering for NetBox 4.6"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
Reference in New Issue
Block a user