Przeglądaj źródła

Fixes #5243: Redirect user to appropriate tab after modifying device components

Jeremy Stretch 5 lat temu
rodzic
commit
dde52309d2

+ 3 - 0
docs/release-notes/version-2.9.md

@@ -5,6 +5,9 @@
 ### Bug Fixes
 
 * [#5113](https://github.com/netbox-community/netbox/issues/5113) - Fix incorrect caching of permission object assignments to user groups in the admin panel
+* [#5243](https://github.com/netbox-community/netbox/issues/5243) - Redirect user to appropriate tab after modifying device components
+
+---
 
 ## v2.9.7 (2020-10-12)
 

+ 16 - 8
netbox/dcim/tables.py

@@ -432,7 +432,8 @@ class ComponentTemplateTable(BaseTable):
 class ConsolePortTemplateTable(ComponentTemplateTable):
     actions = ButtonsColumn(
         model=ConsolePortTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_consoleports'
     )
 
     class Meta(BaseTable.Meta):
@@ -444,7 +445,8 @@ class ConsolePortTemplateTable(ComponentTemplateTable):
 class ConsoleServerPortTemplateTable(ComponentTemplateTable):
     actions = ButtonsColumn(
         model=ConsoleServerPortTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_consoleserverports'
     )
 
     class Meta(BaseTable.Meta):
@@ -456,7 +458,8 @@ class ConsoleServerPortTemplateTable(ComponentTemplateTable):
 class PowerPortTemplateTable(ComponentTemplateTable):
     actions = ButtonsColumn(
         model=PowerPortTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_powerports'
     )
 
     class Meta(BaseTable.Meta):
@@ -468,7 +471,8 @@ class PowerPortTemplateTable(ComponentTemplateTable):
 class PowerOutletTemplateTable(ComponentTemplateTable):
     actions = ButtonsColumn(
         model=PowerOutletTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_poweroutlets'
     )
 
     class Meta(BaseTable.Meta):
@@ -483,7 +487,8 @@ class InterfaceTemplateTable(ComponentTemplateTable):
     )
     actions = ButtonsColumn(
         model=InterfaceTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_interfaces'
     )
 
     class Meta(BaseTable.Meta):
@@ -498,7 +503,8 @@ class FrontPortTemplateTable(ComponentTemplateTable):
     )
     actions = ButtonsColumn(
         model=FrontPortTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_frontports'
     )
 
     class Meta(BaseTable.Meta):
@@ -510,7 +516,8 @@ class FrontPortTemplateTable(ComponentTemplateTable):
 class RearPortTemplateTable(ComponentTemplateTable):
     actions = ButtonsColumn(
         model=RearPortTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_rearports'
     )
 
     class Meta(BaseTable.Meta):
@@ -522,7 +529,8 @@ class RearPortTemplateTable(ComponentTemplateTable):
 class DeviceBayTemplateTable(ComponentTemplateTable):
     actions = ButtonsColumn(
         model=DeviceBayTemplate,
-        buttons=('edit', 'delete')
+        buttons=('edit', 'delete'),
+        return_url_extra='%23tab_devicebays'
     )
 
     class Meta(BaseTable.Meta):

+ 56 - 46
netbox/templates/dcim/device.html

@@ -48,28 +48,28 @@
                 </button>
                 <ul class="dropdown-menu">
                     {% if perms.dcim.add_consoleport %}
-                        <li><a href="{% url 'dcim:consoleport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Console Ports</a></li>
+                        <li><a href="{% url 'dcim:consoleport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_consoleports">Console Ports</a></li>
                     {% endif %}
                     {% if perms.dcim.add_consoleserverport %}
-                        <li><a href="{% url 'dcim:consoleserverport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Console Server Ports</a></li>
+                        <li><a href="{% url 'dcim:consoleserverport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_consoleserverports">Console Server Ports</a></li>
                     {% endif %}
                     {% if perms.dcim.add_powerport %}
-                        <li><a href="{% url 'dcim:powerport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Power Ports</a></li>
+                        <li><a href="{% url 'dcim:powerport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_powerports">Power Ports</a></li>
                     {% endif %}
                     {% if perms.dcim.add_poweroutlet %}
-                        <li><a href="{% url 'dcim:poweroutlet_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Power Outlets</a></li>
+                        <li><a href="{% url 'dcim:poweroutlet_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_poweroutlets">Power Outlets</a></li>
                     {% endif %}
                     {% if perms.dcim.add_interface %}
-                        <li><a href="{% url 'dcim:interface_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Interfaces</a></li>
+                        <li><a href="{% url 'dcim:interface_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_interfaces">Interfaces</a></li>
                     {% endif %}
                     {% if perms.dcim.add_frontport %}
-                        <li><a href="{% url 'dcim:frontport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Front Ports</a></li>
+                        <li><a href="{% url 'dcim:frontport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_frontports">Front Ports</a></li>
                     {% endif %}
                     {% if perms.dcim.add_rearport %}
-                        <li><a href="{% url 'dcim:rearport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Rear Ports</a></li>
+                        <li><a href="{% url 'dcim:rearport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_rearports">Rear Ports</a></li>
                     {% endif %}
                     {% if perms.dcim.add_devicebay %}
-                        <li><a href="{% url 'dcim:devicebay_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Device Bays</a></li>
+                        <li><a href="{% url 'dcim:devicebay_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_devicebays">Device Bays</a></li>
                     {% endif %}
                     {% if perms.dcim.add_inventoryitem %}
                         <li><a href="{% url 'dcim:inventoryitem_add' %}?device={{ device.pk }}&return_url={% url 'dcim:device_inventory' pk=device.pk %}">Inventory Items</a></li>
@@ -537,26 +537,26 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if interfaces and perms.dcim.change_interface %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:interface_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:interface_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_interfaces" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:interface_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:interface_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_interfaces" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
                                 {% endif %}
                                 {% if interfaces and perms.dcim.change_interface %}
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:interface_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:interface_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_interfaces" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if interfaces and perms.dcim.delete_interface %}
-                                    <button type="submit" name="_delete" formaction="{% url 'dcim:interface_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_delete" formaction="{% url 'dcim:interface_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_interfaces" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_interface %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:interface_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
+                                        <a href="{% url 'dcim:interface_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_interfaces" class="btn btn-primary btn-xs">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add interfaces
                                         </a>
                                     </div>
@@ -597,24 +597,24 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if frontports and perms.dcim.change_frontport %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:frontport_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:frontport_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_frontports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:frontport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:frontport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_frontports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:frontport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:frontport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_frontports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if frontports and perms.dcim.delete_frontport %}
-                                    <button type="submit" formaction="{% url 'dcim:frontport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" formaction="{% url 'dcim:frontport_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_frontports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_frontport %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:frontport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
+                                        <a href="{% url 'dcim:frontport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_frontports" class="btn btn-primary btn-xs">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add front ports
                                         </a>
                                     </div>
@@ -654,24 +654,24 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if rearports and perms.dcim.change_rearport %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:rearport_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:rearport_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_rearports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:rearport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:rearport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_rearports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:rearport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:rearport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_rearports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if rearports and perms.dcim.delete_rearport %}
-                                    <button type="submit" formaction="{% url 'dcim:rearport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" formaction="{% url 'dcim:rearport_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_rearports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_rearport %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:rearport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
+                                        <a href="{% url 'dcim:rearport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_rearports" class="btn btn-primary btn-xs">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add rear ports
                                         </a>
                                     </div>
@@ -708,24 +708,24 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if consoleports and perms.dcim.change_consoleport %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:consoleport_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:consoleport_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_consoleports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:consoleport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:consoleport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_consoleports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_consoleports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if consoleports and perms.dcim.delete_consoleport %}
-                                    <button type="submit" name="_delete" formaction="{% url 'dcim:consoleport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_delete" formaction="{% url 'dcim:consoleport_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_consoleports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_consoleport %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:consoleport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-xs btn-primary">
+                                        <a href="{% url 'dcim:consoleport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_consoleports" class="btn btn-xs btn-primary">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add console port
                                         </a>
                                     </div>
@@ -763,24 +763,24 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if consoleserverports and perms.dcim.change_consoleport %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:consoleserverport_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:consoleserverport_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_consoleserverports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:consoleserverport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:consoleserverport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_consoleserverports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleserverport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:consoleserverport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_consoleserverports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if consoleserverports and perms.dcim.delete_consoleserverport %}
-                                    <button type="submit" formaction="{% url 'dcim:consoleserverport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" formaction="{% url 'dcim:consoleserverport_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_consoleserverports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_consoleserverport %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:consoleserverport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
+                                        <a href="{% url 'dcim:consoleserverport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_consoleserverports" class="btn btn-primary btn-xs">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add console server ports
                                         </a>
                                     </div>
@@ -818,24 +818,24 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if powerports and perms.dcim.change_powerport %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:powerport_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:powerport_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_powerports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:powerport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:powerport_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_powerports" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:powerport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:powerport_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_powerports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if powerports and perms.dcim.delete_powerport %}
-                                    <button type="submit" name="_delete" formaction="{% url 'dcim:powerport_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_delete" formaction="{% url 'dcim:powerport_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_powerports" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_powerport %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:powerport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-xs btn-primary">
+                                        <a href="{% url 'dcim:powerport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_powerports" class="btn btn-xs btn-primary">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add power port
                                         </a>
                                     </div>
@@ -874,24 +874,24 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if poweroutlets and perms.dcim.change_powerport %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:poweroutlet_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:poweroutlet_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_poweroutlets" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
-                                    <button type="submit" name="_edit" formaction="{% url 'dcim:poweroutlet_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_edit" formaction="{% url 'dcim:poweroutlet_bulk_edit' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_poweroutlets" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit
                                     </button>
-                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:poweroutlet_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" name="_disconnect" formaction="{% url 'dcim:poweroutlet_bulk_disconnect' %}?return_url={{ device.get_absolute_url }}%23tab_poweroutlets" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-resize-full" aria-hidden="true"></span> Disconnect
                                     </button>
                                 {% endif %}
                                 {% if poweroutlets and perms.dcim.delete_poweroutlet %}
-                                    <button type="submit" formaction="{% url 'dcim:poweroutlet_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" formaction="{% url 'dcim:poweroutlet_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_poweroutlets" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_poweroutlet %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:poweroutlet_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
+                                        <a href="{% url 'dcim:poweroutlet_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_poweroutlets" class="btn btn-primary btn-xs">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add power outlets
                                         </a>
                                     </div>
@@ -933,18 +933,18 @@
                             </table>
                             <div class="panel-footer noprint">
                                 {% if devicebays and perms.dcim.change_devicebay %}
-                                    <button type="submit" name="_rename" formaction="{% url 'dcim:devicebay_bulk_rename' %}?return_url={{ device.get_absolute_url }}" class="btn btn-warning btn-xs">
+                                    <button type="submit" name="_rename" formaction="{% url 'dcim:devicebay_bulk_rename' %}?return_url={{ device.get_absolute_url }}%23tab_devicebays" class="btn btn-warning btn-xs">
                                         <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Rename
                                     </button>
                                 {% endif %}
                                 {% if devicebays and perms.dcim.delete_devicebay %}
-                                    <button type="submit" formaction="{% url 'dcim:devicebay_bulk_delete' %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
+                                    <button type="submit" formaction="{% url 'dcim:devicebay_bulk_delete' %}?return_url={{ device.get_absolute_url }}%23tab_devicebays" class="btn btn-danger btn-xs">
                                         <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete selected
                                     </button>
                                 {% endif %}
                                 {% if perms.dcim.add_devicebay %}
                                     <div class="pull-right">
-                                        <a href="{% url 'dcim:devicebay_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
+                                        <a href="{% url 'dcim:devicebay_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}%23tab_devicebays" class="btn btn-primary btn-xs">
                                             <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add device bays
                                         </a>
                                     </div>
@@ -963,6 +963,16 @@
 
 {% block javascript %}
 <script type="text/javascript">
+// Redirect user to appropriate components tab if specified
+var hash = document.location.hash;
+var prefix = "tab_";
+if (hash) {
+    $('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
+}
+$('.nav-tabs a').on('shown.bs.tab', function (e) {
+    window.location.hash = e.target.hash.replace("#", "#" + prefix);
+});
+
 function toggleConnection(elem) {
     var url = netbox_api_path + "dcim/cables/" + elem.attr('data') + "/";
     if (elem.hasClass('connected')) {

+ 38 - 8
netbox/templates/dcim/devicetype.html

@@ -24,14 +24,30 @@
                     <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Components <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu">
-                    {% if perms.dcim.add_consoleporttemplate %}<li><a href="{% url 'dcim:consoleporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Console Ports</a></li>{% endif %}
-                    {% if perms.dcim.add_consoleserverporttemplate %}<li><a href="{% url 'dcim:consoleserverporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Console Server Ports</a></li>{% endif %}
-                    {% if perms.dcim.add_powerporttemplate %}<li><a href="{% url 'dcim:powerporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Power Ports</a></li>{% endif %}
-                    {% if perms.dcim.add_poweroutlettemplate %}<li><a href="{% url 'dcim:poweroutlettemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Power Outlets</a></li>{% endif %}
-                    {% if perms.dcim.add_interfacetemplate %}<li><a href="{% url 'dcim:interfacetemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Interfaces</a></li>{% endif %}
-                    {% if perms.dcim.add_frontporttemplate %}<li><a href="{% url 'dcim:frontporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Front Ports</a></li>{% endif %}
-                    {% if perms.dcim.add_rearporttemplate %}<li><a href="{% url 'dcim:rearporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Rear Ports</a></li>{% endif %}
-                    {% if perms.dcim.add_devicebaytemplate %}<li><a href="{% url 'dcim:devicebaytemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}">Device Bays</a></li>{% endif %}
+                    {% if perms.dcim.add_consoleporttemplate %}
+                        <li><a href="{% url 'dcim:consoleporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_consoleports">Console Ports</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_consoleserverporttemplate %}
+                        <li><a href="{% url 'dcim:consoleserverporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_consoleserverports">Console Server Ports</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_powerporttemplate %}
+                        <li><a href="{% url 'dcim:powerporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_powerports">Power Ports</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_poweroutlettemplate %}
+                        <li><a href="{% url 'dcim:poweroutlettemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_poweroutlets">Power Outlets</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_interfacetemplate %}
+                        <li><a href="{% url 'dcim:interfacetemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_interfaces">Interfaces</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_frontporttemplate %}
+                        <li><a href="{% url 'dcim:frontporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_frontports">Front Ports</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_rearporttemplate %}
+                        <li><a href="{% url 'dcim:rearporttemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_rearports">Rear Ports</a></li>
+                    {% endif %}
+                    {% if perms.dcim.add_devicebaytemplate %}
+                        <li><a href="{% url 'dcim:devicebaytemplate_add' %}?device_type={{ devicetype.pk }}&return_url={{ devicetype.get_absolute_url }}%23tab_devicebays">Device Bays</a></li>
+                    {% endif %}
                 </ul>
             </div>
         {% endif %}
@@ -217,3 +233,17 @@
         </div>
     </div>
 {% endblock %}
+
+{% block javascript %}
+<script type="text/javascript">
+// Redirect user to appropriate components tab if specified
+var hash = document.location.hash;
+var prefix = "tab_";
+if (hash) {
+    $('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
+}
+$('.nav-tabs a').on('shown.bs.tab', function (e) {
+    window.location.hash = e.target.hash.replace("#", "#" + prefix);
+});
+</script>
+{% endblock %}

+ 6 - 3
netbox/utilities/tables.py

@@ -130,6 +130,7 @@ class ButtonsColumn(tables.TemplateColumn):
 
     :param model: Model class to use for calculating URL view names
     :param prepend_content: Additional template content to render in the column (optional)
+    :param return_url_extra: String to append to the return URL (e.g. for specifying a tab) (optional)
     """
     buttons = ('changelog', 'edit', 'delete')
     attrs = {'td': {'class': 'text-right text-nowrap noprint'}}
@@ -141,18 +142,19 @@ class ButtonsColumn(tables.TemplateColumn):
         </a>
     {{% endif %}}
     {{% if "edit" in buttons and perms.{app_label}.change_{model_name} %}}
-        <a href="{{% url '{app_label}:{model_name}_edit' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}" class="btn btn-xs btn-warning" title="Edit">
+        <a href="{{% url '{app_label}:{model_name}_edit' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="btn btn-xs btn-warning" title="Edit">
             <i class="fa fa-pencil"></i>
         </a>
     {{% endif %}}
     {{% if "delete" in buttons and perms.{app_label}.delete_{model_name} %}}
-        <a href="{{% url '{app_label}:{model_name}_delete' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}" class="btn btn-xs btn-danger" title="Delete">
+        <a href="{{% url '{app_label}:{model_name}_delete' {pk_field}=record.{pk_field} %}}?return_url={{{{ request.path }}}}{{{{ return_url_extra }}}}" class="btn btn-xs btn-danger" title="Delete">
             <i class="fa fa-trash"></i>
         </a>
     {{% endif %}}
     """
 
-    def __init__(self, model, *args, pk_field='pk', buttons=None, prepend_template=None, **kwargs):
+    def __init__(self, model, *args, pk_field='pk', buttons=None, prepend_template=None, return_url_extra='',
+                 **kwargs):
         if prepend_template:
             prepend_template = prepend_template.replace('{', '{{')
             prepend_template = prepend_template.replace('}', '}}')
@@ -169,6 +171,7 @@ class ButtonsColumn(tables.TemplateColumn):
 
         self.extra_context.update({
             'buttons': buttons or self.buttons,
+            'return_url_extra': return_url_extra,
         })
 
     def header(self):