ui: place offline SVG button directly beside "SVG herunterladen"
NetBox renders the native download link inside each per-face elevation card, not through a plugin buttons() extension point, so there's no server-side hook to inject a matching link next to it. The right_page() extension now emits only a script (no separate sidebar panel) that finds every a[href*="render=svg"] link, reads its face= param, and inserts a matching "SVG offline" button right after it. The button's href stays in sync with the rack-view select the same way the previous panel's links did. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from netbox.plugins import PluginConfig, get_plugin_config
|
||||
|
||||
__version__ = "0.12.1"
|
||||
__version__ = "0.12.2"
|
||||
|
||||
|
||||
class NetBoxUtilitiesConfig(PluginConfig):
|
||||
|
||||
@@ -156,6 +156,10 @@ class RackUtilitiesContent(PluginTemplateExtension):
|
||||
models = ["dcim.rack"]
|
||||
|
||||
def right_page(self):
|
||||
# Injects a script (no visible panel here) which places an "SVG
|
||||
# offline" button right next to each native "SVG herunterladen"
|
||||
# link, since NetBox renders those inside the per-face elevation
|
||||
# cards rather than through a plugin buttons() extension point.
|
||||
if not offline_svg_export_enabled():
|
||||
return ""
|
||||
rack = self.context["object"]
|
||||
|
||||
@@ -1,37 +1,49 @@
|
||||
<div class="card">
|
||||
<h2 class="card-header">SVG offline exportieren</h2>
|
||||
<div class="card-body d-flex flex-column gap-2">
|
||||
<a href="{% url 'plugins:netbox_utilities:rack_elevation_offline_svg' pk=rack.pk %}?face=front"
|
||||
class="btn btn-outline-secondary netbox-utilities-offline-svg-link" data-face="front"
|
||||
title="Vorderseite als linkfreie SVG-Datei herunterladen">
|
||||
<i class="mdi mdi-download" aria-hidden="true"></i>
|
||||
Vorderseite
|
||||
</a>
|
||||
<a href="{% url 'plugins:netbox_utilities:rack_elevation_offline_svg' pk=rack.pk %}?face=rear"
|
||||
class="btn btn-outline-secondary netbox-utilities-offline-svg-link" data-face="rear"
|
||||
title="Rückseite als linkfreie SVG-Datei herunterladen">
|
||||
<i class="mdi mdi-download" aria-hidden="true"></i>
|
||||
Rückseite
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function () {
|
||||
var links = document.querySelectorAll(".netbox-utilities-offline-svg-link");
|
||||
var offlineBaseUrl = "{% url 'plugins:netbox_utilities:rack_elevation_offline_svg' pk=rack.pk %}";
|
||||
var viewSelect = document.querySelector("select.rack-view");
|
||||
if (!links.length || !viewSelect) {
|
||||
return;
|
||||
|
||||
function currentView() {
|
||||
return viewSelect ? viewSelect.value : "images-and-labels";
|
||||
}
|
||||
|
||||
function syncLinks() {
|
||||
links.forEach(function (link) {
|
||||
var url = new URL(link.href, window.location.origin);
|
||||
url.searchParams.set("view", viewSelect.value);
|
||||
link.href = url.toString();
|
||||
function buildHref(face) {
|
||||
var url = new URL(offlineBaseUrl, window.location.origin);
|
||||
url.searchParams.set("face", face);
|
||||
url.searchParams.set("view", currentView());
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function insertOfflineButtons() {
|
||||
document.querySelectorAll('a[href*="render=svg"]').forEach(function (nativeLink) {
|
||||
if (nativeLink.dataset.netboxUtilitiesOfflineInserted) {
|
||||
return;
|
||||
}
|
||||
nativeLink.dataset.netboxUtilitiesOfflineInserted = "true";
|
||||
|
||||
var nativeUrl = new URL(nativeLink.href, window.location.origin);
|
||||
var face = nativeUrl.searchParams.get("face") || "front";
|
||||
|
||||
var offlineLink = document.createElement("a");
|
||||
offlineLink.className = nativeLink.className + " netbox-utilities-offline-svg-link";
|
||||
offlineLink.title = "Wie \"SVG herunterladen\", aber ohne interne Links – funktioniert offline";
|
||||
offlineLink.href = buildHref(face);
|
||||
offlineLink.innerHTML = '<i class="mdi mdi-download" aria-hidden="true"></i> SVG offline';
|
||||
|
||||
nativeLink.insertAdjacentElement("afterend", offlineLink);
|
||||
});
|
||||
}
|
||||
|
||||
viewSelect.addEventListener("change", syncLinks);
|
||||
syncLinks();
|
||||
insertOfflineButtons();
|
||||
|
||||
if (viewSelect) {
|
||||
viewSelect.addEventListener("change", function () {
|
||||
document.querySelectorAll(".netbox-utilities-offline-svg-link").forEach(function (link) {
|
||||
var url = new URL(link.href, window.location.origin);
|
||||
url.searchParams.set("view", currentView());
|
||||
link.href = url.toString();
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user