Repository: netbox-community/netbox

Issue:
Add buttons to edit cables
### NetBox version

v3.3.4

### Feature type

Change to existing functionality

### Proposed functionality

The device view provides tabs for interfaces, power ports etc. On every line we have a button to connect a cable or, if a cable is connected already, a button to disconnect the cable.

I've got a PR ready that adds a button to all kinds of connection overviews (console ports, power ports, front ports, interfaces etc.). It looks like this:

![grafik](https://user-images.githubusercontent.com/20901110/192557227-fac9f468-5338-4ef4-8da3-f180e5e3932d.png)


### Use case

What I miss here is a button to go directly to the edit page of the cable including a redirect to the page we came from. Best thing you can do at the moment is to click the link in the "Cable" column (if not hidden), edit the cable and go back to the connections overview manually. This approach is kinda cumbersome.



### Database changes

None

### External dependencies

None


Discussion:

Resolving patch:
diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py
--- a/netbox/dcim/tables/template_code.py
+++ b/netbox/dcim/tables/template_code.py
@@ -115,10 +115,28 @@
 {% if record.cable %}
     <a href="{% url 'dcim:consoleport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif perms.dcim.add_cable %}
     <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
@@ -147,10 +165,28 @@
 {% if record.cable %}
     <a href="{% url 'dcim:consoleserverport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif perms.dcim.add_cable %}
     <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
@@ -179,10 +215,28 @@
 {% if record.cable %}
     <a href="{% url 'dcim:powerport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif perms.dcim.add_cable %}
     <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
@@ -210,10 +264,28 @@
 {% if record.cable %}
     <a href="{% url 'dcim:poweroutlet_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif perms.dcim.add_cable %}
     <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
@@ -258,10 +330,28 @@
 {% endif %}
 {% if record.cable %}
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif record.wireless_link %}
     {% if perms.wireless.delete_wirelesslink %}
@@ -303,10 +393,28 @@
 {% if record.cable %}
     <a href="{% url 'dcim:frontport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif perms.dcim.add_cable %}
     <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
@@ -340,10 +448,28 @@
 {% if record.cable %}
     <a href="{% url 'dcim:rearport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
     {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
-    {% if perms.dcim.delete_cable %}
-        <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
-            <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
-        </a>
+    {% if perms.dcim.change_cable or perms.dcim.delete_cable %}
+        <span class="dropdown">
+            <button type="button" class="btn btn-warning btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
+            </button>
+            <ul class="dropdown-menu dropdown-menu-end">
+            {% if perms.dcim.change_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_edit' pk=record.cable.pk %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}">
+                    <i class="mdi mdi-pencil-outline"></i>
+                    Edit cable
+                    </a>
+                </li>
+            {% endif %}
+            {% if perms.dcim.delete_cable %}
+                <li><a class="dropdown-item" href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}">
+                    <i class="mdi mdi-trash-can-outline"></i>
+                    Delete cable
+                    </a>
+                </li>
+            {% endif %}
+            </ul>
+        </span>
     {% endif %}
 {% elif perms.dcim.add_cable %}
     <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>


Test patch: