ソースを参照

Replace CSS-based cable trace diagrams with SVG images

jeremystretch 4 年 前
コミット
9f615cde79

+ 1 - 4
netbox/dcim/api/views.py

@@ -2,18 +2,15 @@ import socket
 from collections import OrderedDict
 
 from django.conf import settings
-from django.contrib.contenttypes.models import ContentType
-from django.db.models import F
 from django.http import HttpResponseForbidden, HttpResponse
 from django.shortcuts import get_object_or_404
 from drf_yasg import openapi
 from drf_yasg.openapi import Parameter
 from drf_yasg.utils import swagger_auto_schema
 from rest_framework.decorators import action
-from rest_framework.mixins import ListModelMixin
 from rest_framework.response import Response
 from rest_framework.routers import APIRootView
-from rest_framework.viewsets import GenericViewSet, ViewSet
+from rest_framework.viewsets import ViewSet
 
 from circuits.models import Circuit
 from dcim import filtersets

+ 8 - 4
netbox/dcim/views.py

@@ -1,15 +1,14 @@
 import logging
-from copy import deepcopy
 from collections import OrderedDict
 
 from django.contrib import messages
 from django.contrib.contenttypes.models import ContentType
-from django.core.exceptions import ObjectDoesNotExist
 from django.core.paginator import EmptyPage, PageNotAnInteger
 from django.db import transaction
 from django.db.models import F, Prefetch
 from django.forms import ModelMultipleChoiceField, MultipleHiddenInput, modelformset_factory
 from django.shortcuts import get_object_or_404, redirect, render
+from django.urls import reverse
 from django.utils.html import escape
 from django.utils.safestring import mark_safe
 from django.views.generic import View
@@ -23,7 +22,7 @@ from utilities.forms import ConfirmationForm
 from utilities.paginator import EnhancedPaginator, get_paginate_count
 from utilities.permissions import get_permission_for_model
 from utilities.tables import paginate_table
-from utilities.utils import csv_format, count_related
+from utilities.utils import count_related
 from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
 from virtualization.models import VirtualMachine
 from . import filtersets, forms, tables
@@ -2423,11 +2422,16 @@ class PathTraceView(generic.ObjectView):
         # Get the total length of the cable and whether the length is definitive (fully defined)
         total_length, is_definitive = path.get_total_length() if path else (None, False)
 
+        # Determine the path to the SVG trace image
+        api_viewname = f"{path.origin._meta.app_label}-api:{path.origin._meta.model_name}-trace"
+        svg_url = f"{reverse(api_viewname, kwargs={'pk': path.origin.pk})}?render=svg"
+
         return {
             'path': path,
             'related_paths': related_paths,
             'total_length': total_length,
-            'is_definitive': is_definitive
+            'is_definitive': is_definitive,
+            'svg_url': svg_url,
         }
 
 

+ 0 - 41
netbox/project-static/netbox.scss

@@ -720,47 +720,6 @@ table tbody {
   }
 }
 
-// Cable Tracing
-.cable-trace {
-  max-width: 38rem;
-  margin: 1rem auto;
-  text-align: center;
-}
-.cable-trace .node {
-  background-color: var(--nbx-cable-node-bg);
-  border: $border-width solid var(--nbx-cable-node-border-color);
-  border-radius: $border-radius;
-  padding: 1.5rem 1rem;
-  position: relative;
-  z-index: 1;
-}
-.cable-trace .termination {
-  background-color: var(--nbx-cable-termination-bg);
-  border: $border-width solid var(--nbx-cable-termination-border-color);
-  box-shadow: $box-shadow;
-  border-radius: $border-radius;
-  margin: -1rem auto;
-  padding: 0.5rem;
-  position: relative;
-  width: 60%;
-  z-index: 2;
-}
-.cable-trace .active {
-  border: 0.25rem solid $success;
-}
-.cable-trace .cable {
-  border-left-style: solid;
-  border-left-width: 0.25rem;
-  margin: 1rem 0 1rem 50%;
-  padding: 1.5rem;
-  text-align: left;
-  width: 50%;
-}
-.cable-trace .trace-end {
-  margin-top: 2rem;
-  text-align: center;
-}
-
 pre.change-data {
   padding-left: 0;
   padding-right: 0;

+ 38 - 77
netbox/templates/dcim/cable_trace.html

@@ -1,89 +1,50 @@
 {% extends 'base/layout.html' %}
 {% load helpers %}
 
-{% block header %}
-    <h1>{% block title %}Cable Trace for {{ object|meta:"verbose_name"|bettertitle }} {{ object }}{% endblock %}</h1>
-{% endblock %}
+{% block title %}Cable Trace for {{ object|meta:"verbose_name"|bettertitle }} {{ object }}{% endblock %}
 
 {% block content %}
     <div class="row">
         <div class="col col-md-5">
+            <object data="{{ svg_url }}" class="rack_elevation"></object>
+            <div class="text-center mt-3">
+                <a class="btn btn-outline-primary btn-sm" href="{{ svg_url }}">
+                    <i class="mdi mdi-file-download"></i> Download SVG
+                </a>
+            </div>
             <div class="cable-trace">
                 {% with traced_path=path.origin.trace %}
-                    {% for near_end, cable, far_end in traced_path %}
-
-                        {# Near end #}
-                        {% if near_end.device %}
-                            {% include 'dcim/trace/device.html' with device=near_end.device %}
-                            {% include 'dcim/trace/termination.html' with termination=near_end %}
-                        {% elif near_end.power_panel %}
-                            {% include 'dcim/trace/powerpanel.html' with powerpanel=near_end.power_panel %}
-                            {% include 'dcim/trace/termination.html' with termination=far_end%}
-                        {% elif near_end.circuit %}
-                            {% include 'dcim/trace/circuit.html' with circuit=near_end.circuit %}
-                            {% include 'dcim/trace/termination.html' with termination=near_end %}
-                        {% endif %}
-
-                        {# Cable #}
-                        {% if cable %}
-                            {% include 'dcim/trace/cable.html' %}
-                        {% elif far_end %}
-                            {% include 'dcim/trace/attachment.html' %}
-                        {% endif %}
-
-                        {# Far end #}
-                        {% if far_end.device %}
-                            {% include 'dcim/trace/termination.html' with termination=far_end %}
-                            {% if forloop.last %}
-                                {% include 'dcim/trace/device.html' with device=far_end.device %}
-                            {% endif %}
-                        {% elif far_end.power_panel %}
-                            {% include 'dcim/trace/termination.html' with termination=far_end %}
-                            {% include 'dcim/trace/powerpanel.html' with powerpanel=far_end.power_panel %}
-                        {% elif far_end.circuit %}
-                            {% include 'dcim/trace/termination.html' with termination=far_end %}
-                            {% if forloop.last %}
-                                {% include 'dcim/trace/circuit.html' with circuit=far_end.circuit %}
-                            {% endif %}
-                        {% elif far_end %}
-                            {% include 'dcim/trace/object.html' with object=far_end %}
-                        {% endif %}
-
-                        {% if forloop.last %}
-                            {% if path.is_split %}
-                                <div class="trace-end">
-                                    <h3 class="text-danger">Path split!</h3>
-                                    <p>Select a node below to continue:</p>
-                                    <ul class="text-start">
-                                        {% for next_node in path.get_split_nodes %}
-                                            {% if next_node.cable %}
-                                                <li>
-                                                    <a href="{% url 'dcim:frontport_trace' pk=next_node.pk %}">{{ next_node }}</a>
-                                                    (Cable <a href="{{ next_node.cable.get_absolute_url }}">{{ next_node.cable }}</a>)
-                                                </li>
-                                            {% else %}
-                                                <li class="text-muted">{{ next_node }}</li>
-                                            {% endif %}
-                                        {% endfor %}
-                                    </ul>
-                                </div>
-                            {% else %}
-                                <div class="trace-end">
-                                    <h3{% if far_end %} class="text-success"{% endif %}>Trace Completed</h3>
-                                    <h5>Total Segments: {{ traced_path|length }}</h5>
-                                    <h5>Total Length:
-                                        {% if total_length %}
-                                            {{ total_length|floatformat:"-2" }}{% if not is_definitive %}+{% endif %} Meters /
-                                            {{ total_length|meters_to_feet|floatformat:"-2" }} Feet
-                                        {% else %}
-                                            <span class="text-muted">N/A</span>
-                                        {% endif %}
-                                    </h5>
-                                </div>
-                            {% endif %}
-                        {% endif %}
-
-                    {% endfor %}
+                    {% if path.is_split %}
+                        <div class="trace-end">
+                            <h3 class="text-danger">Path split!</h3>
+                            <p>Select a node below to continue:</p>
+                            <ul class="text-start">
+                                {% for next_node in path.get_split_nodes %}
+                                    {% if next_node.cable %}
+                                        <li>
+                                            <a href="{% url 'dcim:frontport_trace' pk=next_node.pk %}">{{ next_node }}</a>
+                                            (Cable <a href="{{ next_node.cable.get_absolute_url }}">{{ next_node.cable }}</a>)
+                                        </li>
+                                    {% else %}
+                                        <li class="text-muted">{{ next_node }}</li>
+                                    {% endif %}
+                                {% endfor %}
+                            </ul>
+                        </div>
+                    {% else %}
+                        <div class="trace-end">
+                            <h3 class="text-success">Trace Completed</h3>
+                            <h5>Total Segments: {{ traced_path|length }}</h5>
+                            <h5>Total Length:
+                                {% if total_length %}
+                                    {{ total_length|floatformat:"-2" }}{% if not is_definitive %}+{% endif %} Meters /
+                                    {{ total_length|meters_to_feet|floatformat:"-2" }} Feet
+                                {% else %}
+                                    <span class="text-muted">N/A</span>
+                                {% endif %}
+                            </h5>
+                        </div>
+                    {% endif %}
                 {% endwith %}
             </div>
         </div>