Просмотр исходного кода

Move rack reservations panel to separate tab

jeremystretch 3 лет назад
Родитель
Сommit
2525eefefd

+ 19 - 3
netbox/dcim/views.py

@@ -677,8 +677,6 @@ class RackView(generic.ObjectView):
         next_rack = peer_racks.filter(_name__gt=instance._name).first()
         next_rack = peer_racks.filter(_name__gt=instance._name).first()
         prev_rack = peer_racks.filter(_name__lt=instance._name).reverse().first()
         prev_rack = peer_racks.filter(_name__lt=instance._name).reverse().first()
 
 
-        reservations = RackReservation.objects.restrict(request.user, 'view').filter(rack=instance)
-
         # Determine any additional parameters to pass when embedding the rack elevations
         # Determine any additional parameters to pass when embedding the rack elevations
         svg_extra = '&'.join([
         svg_extra = '&'.join([
             f'highlight=id:{pk}' for pk in request.GET.getlist('device')
             f'highlight=id:{pk}' for pk in request.GET.getlist('device')
@@ -686,7 +684,6 @@ class RackView(generic.ObjectView):
 
 
         return {
         return {
             'related_models': related_models,
             'related_models': related_models,
-            'reservations': reservations,
             'nonracked_devices': nonracked_devices,
             'nonracked_devices': nonracked_devices,
             'next_rack': next_rack,
             'next_rack': next_rack,
             'prev_rack': prev_rack,
             'prev_rack': prev_rack,
@@ -694,6 +691,25 @@ class RackView(generic.ObjectView):
         }
         }
 
 
 
 
+@register_model_view(Rack, 'reservations')
+class RackRackReservationsView(generic.ObjectChildrenView):
+    queryset = Rack.objects.all()
+    child_model = RackReservation
+    table = tables.RackReservationTable
+    filterset = filtersets.RackReservationFilterSet
+    template_name = 'dcim/rack/reservations.html'
+    tab = ViewTab(
+        label=_('Reservations'),
+        badge=lambda obj: obj.reservations.count(),
+        permission='dcim.view_rackreservation',
+        weight=510,
+        hide_if_empty=True
+    )
+
+    def get_children(self, request, parent):
+        return parent.reservations.restrict(request.user, 'view')
+
+
 @register_model_view(Rack, 'edit')
 @register_model_view(Rack, 'edit')
 class RackEditView(generic.ObjectEditView):
 class RackEditView(generic.ObjectEditView):
     queryset = Rack.objects.all()
     queryset = Rack.objects.all()

+ 1 - 72
netbox/templates/dcim/rack.html

@@ -1,31 +1,9 @@
-{% extends 'generic/object.html' %}
+{% extends 'dcim/rack/base.html' %}
 {% load buttons %}
 {% load buttons %}
 {% load helpers %}
 {% load helpers %}
 {% load static %}
 {% load static %}
 {% load plugins %}
 {% load plugins %}
 
 
-{% block title %}Rack {{ object }}{% endblock %}
-
-{% block breadcrumbs %}
-  {{ block.super }}
-  <li class="breadcrumb-item"><a href="{% url 'dcim:rack_list' %}?site_id={{ object.site.pk }}">{{ object.site }}</a></li>
-  {% if object.location %}
-    {% for location in object.location.get_ancestors %}
-      <li class="breadcrumb-item"><a href="{% url 'dcim:rack_list' %}?location_id={{ location.pk }}">{{ location }}</a></li>
-    {% endfor %}
-    <li class="breadcrumb-item"><a href="{% url 'dcim:rack_list' %}?location_id={{ object.location.pk }}">{{ object.location }}</a></li>
-  {% endif %}
-{% endblock %}
-
-{% block extra_controls %}
-  <a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}{% endif %}" class="btn btn-sm btn-primary{% if not prev_rack %} disabled{% endif %}">
-    <i class="mdi mdi-chevron-left" aria-hidden="true"></i> Previous
-  </a>
-  <a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}{% endif %}" class="btn btn-sm btn-primary{% if not next_rack %} disabled{% endif %}">
-    <i class="mdi mdi-chevron-right" aria-hidden="true"></i> Next
-  </a>
-{% endblock %}
-
 {% block content %}
 {% block content %}
   <div class="row">
   <div class="row">
 	  <div class="col col-12 col-xl-5">
 	  <div class="col col-12 col-xl-5">
@@ -187,55 +165,6 @@
         {% include 'inc/panels/tags.html' %}
         {% include 'inc/panels/tags.html' %}
         {% include 'inc/panels/comments.html' %}
         {% include 'inc/panels/comments.html' %}
         {% include 'inc/panels/image_attachments.html' %}
         {% include 'inc/panels/image_attachments.html' %}
-        <div class="card">
-            <h5 class="card-header">
-                Reservations
-            </h5>
-            <div class="card-body">
-            {% if reservations %}
-                <table class="table table-hover">
-                    <tr>
-                        <th>Units</th>
-                        <th>Tenant</th>
-                        <th>Description</th>
-                        <th></th>
-                    </tr>
-                    {% for resv in reservations %}
-                        <tr>
-                            <td>{{ resv|linkify:"unit_list" }}</td>
-                            <td>{{ resv.tenant|linkify|placeholder }}</td>
-                            <td>
-                                {{ resv.description }}<br />
-                                <small>{{ resv.user }} &middot; {{ resv.created|annotated_date }}</small>
-                            </td>
-                            <td class="text-end noprint">
-                                {% if perms.dcim.change_rackreservation %}
-                                    <a href="{% url 'dcim:rackreservation_edit' pk=resv.pk %}?return_url={{ object.get_absolute_url }}" class="btn btn-warning btn-sm" title="Edit Reservation">
-                                        <i class="mdi mdi-pencil" aria-hidden="true"></i>
-                                    </a>
-                                {% endif %}
-                                {% if perms.dcim.delete_rackreservation %}
-                                    <a href="{% url 'dcim:rackreservation_delete' pk=resv.pk %}?return_url={{ object.get_absolute_url }}" class="btn btn-danger btn-sm" title="Delete Reservation">
-                                        <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i>
-                                    </a>
-                                {% endif %}
-                            </td>
-                        </tr>
-                    {% endfor %}
-                </table>
-            {% else %}
-                <div class="text-muted">None</div>
-            {% endif %}
-            </div>
-            {% if perms.dcim.add_rackreservation %}
-                <div class="card-footer text-end noprint">
-                    <a href="{% url 'dcim:rackreservation_add' %}?rack={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-primary btn-sm">
-                        <i class="mdi mdi-plus-thick" aria-hidden="true"></i>
-                        Add a Reservation
-                    </a>
-                </div>
-            {% endif %}
-        </div>
         {% plugin_left_page object %}
         {% plugin_left_page object %}
 	  </div>
 	  </div>
     <div class="col col-12 col-xl-7">
     <div class="col col-12 col-xl-7">

+ 23 - 0
netbox/templates/dcim/rack/base.html

@@ -0,0 +1,23 @@
+{% extends 'generic/object.html' %}
+
+{% block title %}Rack {{ object }}{% endblock %}
+
+{% block breadcrumbs %}
+  {{ block.super }}
+  <li class="breadcrumb-item"><a href="{% url 'dcim:rack_list' %}?site_id={{ object.site.pk }}">{{ object.site }}</a></li>
+  {% if object.location %}
+    {% for location in object.location.get_ancestors %}
+      <li class="breadcrumb-item"><a href="{% url 'dcim:rack_list' %}?location_id={{ location.pk }}">{{ location }}</a></li>
+    {% endfor %}
+    <li class="breadcrumb-item"><a href="{% url 'dcim:rack_list' %}?location_id={{ object.location.pk }}">{{ object.location }}</a></li>
+  {% endif %}
+{% endblock %}
+
+{% block extra_controls %}
+  <a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}{% endif %}" class="btn btn-sm btn-primary{% if not prev_rack %} disabled{% endif %}">
+    <i class="mdi mdi-chevron-left" aria-hidden="true"></i> Previous
+  </a>
+  <a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}{% endif %}" class="btn btn-sm btn-primary{% if not next_rack %} disabled{% endif %}">
+    <i class="mdi mdi-chevron-right" aria-hidden="true"></i> Next
+  </a>
+{% endblock %}

+ 43 - 0
netbox/templates/dcim/rack/reservations.html

@@ -0,0 +1,43 @@
+{% extends 'dcim/rack/base.html' %}
+{% load helpers %}
+
+{% block content %}
+  {% include 'inc/table_controls_htmx.html' with table_modal="RackReservationTable_config" %}
+
+  <form method="post">
+    {% csrf_token %}
+
+    <div class="card">
+      <div class="card-body htmx-container table-responsive" id="object_list">
+        {% include 'htmx/table.html' %}
+      </div>
+    </div>
+
+    <div class="noprint bulk-buttons">
+      <div class="bulk-button-group">
+        {% if 'bulk_edit' in actions %}
+          <button type="submit" name="_edit" formaction="{% url 'dcim:rackreservation_bulk_edit' %}?return_url={% url 'dcim:rack_reservations' pk=object.pk %}" class="btn btn-warning btn-sm">
+            <i class="mdi mdi-pencil" aria-hidden="true"></i> Edit
+          </button>
+        {% endif %}
+        {% if 'bulk_delete' in actions %}
+          <button type="submit" formaction="{% url 'dcim:rackreservation_bulk_delete' %}?return_url={% url 'dcim:rack_reservations' pk=object.pk %}" class="btn btn-danger btn-sm">
+            <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
+          </button>
+        {% endif %}
+      </div>
+      {% if perms.dcim.add_rackreservation %}
+        <div class="bulk-button-group">
+          <a href="{% url 'dcim:rackreservation_add' %}?rack={{ object.pk }}&return_url={% url 'dcim:rack_reservations' pk=object.pk %}" class="btn btn-primary btn-sm">
+            <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add reservation
+          </a>
+        </div>
+      {% endif %}
+    </div>
+  </form>
+{% endblock %}
+
+{% block modals %}
+  {{ block.super }}
+  {% table_config_form table %}
+{% endblock modals %}