mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
Closes #4369: Add a dedicated view for rack reservations
This commit is contained in:
parent
459bcd88a9
commit
c5776d9da4
@ -5,6 +5,7 @@
|
|||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
* [#4309](https://github.com/netbox-community/netbox/issues/4309) - Add descriptive tooltip to custom fields on object views
|
* [#4309](https://github.com/netbox-community/netbox/issues/4309) - Add descriptive tooltip to custom fields on object views
|
||||||
|
* [#4369](https://github.com/netbox-community/netbox/issues/4369) - Add a dedicated view for rack reservations
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -769,6 +769,9 @@ class RackReservation(ChangeLoggedModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Reservation for rack {}".format(self.rack)
|
return "Reservation for rack {}".format(self.rack)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('dcim:rackreservation', args=[self.pk])
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
if self.units:
|
if self.units:
|
||||||
|
@ -338,21 +338,38 @@ class RackDetailTable(RackTable):
|
|||||||
|
|
||||||
class RackReservationTable(BaseTable):
|
class RackReservationTable(BaseTable):
|
||||||
pk = ToggleColumn()
|
pk = ToggleColumn()
|
||||||
|
reservation = tables.LinkColumn(
|
||||||
|
viewname='dcim:rackreservation',
|
||||||
|
args=[Accessor('pk')],
|
||||||
|
accessor='pk'
|
||||||
|
)
|
||||||
site = tables.LinkColumn(
|
site = tables.LinkColumn(
|
||||||
viewname='dcim:site',
|
viewname='dcim:site',
|
||||||
accessor=Accessor('rack.site'),
|
accessor=Accessor('rack.site'),
|
||||||
args=[Accessor('rack.site.slug')],
|
args=[Accessor('rack.site.slug')],
|
||||||
)
|
)
|
||||||
tenant = tables.TemplateColumn(template_code=COL_TENANT)
|
tenant = tables.TemplateColumn(
|
||||||
rack = tables.LinkColumn('dcim:rack', args=[Accessor('rack.pk')])
|
template_code=COL_TENANT
|
||||||
unit_list = tables.Column(orderable=False, verbose_name='Units')
|
)
|
||||||
|
rack = tables.LinkColumn(
|
||||||
|
viewname='dcim:rack',
|
||||||
|
args=[Accessor('rack.pk')]
|
||||||
|
)
|
||||||
|
unit_list = tables.Column(
|
||||||
|
orderable=False,
|
||||||
|
verbose_name='Units'
|
||||||
|
)
|
||||||
actions = tables.TemplateColumn(
|
actions = tables.TemplateColumn(
|
||||||
template_code=RACKRESERVATION_ACTIONS, attrs={'td': {'class': 'text-right noprint'}}, verbose_name=''
|
template_code=RACKRESERVATION_ACTIONS,
|
||||||
|
attrs={'td': {'class': 'text-right noprint'}},
|
||||||
|
verbose_name=''
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = RackReservation
|
model = RackReservation
|
||||||
fields = ('pk', 'site', 'rack', 'unit_list', 'user', 'created', 'tenant', 'description', 'actions')
|
fields = (
|
||||||
|
'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'created', 'tenant', 'description', 'actions',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -172,9 +172,6 @@ class RackRoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
|
|||||||
class RackReservationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
class RackReservationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||||
model = RackReservation
|
model = RackReservation
|
||||||
|
|
||||||
# Disable inapplicable tests
|
|
||||||
test_get_object = None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ urlpatterns = [
|
|||||||
path('rack-reservations/import/', views.RackReservationImportView.as_view(), name='rackreservation_import'),
|
path('rack-reservations/import/', views.RackReservationImportView.as_view(), name='rackreservation_import'),
|
||||||
path('rack-reservations/edit/', views.RackReservationBulkEditView.as_view(), name='rackreservation_bulk_edit'),
|
path('rack-reservations/edit/', views.RackReservationBulkEditView.as_view(), name='rackreservation_bulk_edit'),
|
||||||
path('rack-reservations/delete/', views.RackReservationBulkDeleteView.as_view(), name='rackreservation_bulk_delete'),
|
path('rack-reservations/delete/', views.RackReservationBulkDeleteView.as_view(), name='rackreservation_bulk_delete'),
|
||||||
|
path('rack-reservations/<int:pk>/', views.RackReservationView.as_view(), name='rackreservation'),
|
||||||
path('rack-reservations/<int:pk>/edit/', views.RackReservationEditView.as_view(), name='rackreservation_edit'),
|
path('rack-reservations/<int:pk>/edit/', views.RackReservationEditView.as_view(), name='rackreservation_edit'),
|
||||||
path('rack-reservations/<int:pk>/delete/', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'),
|
path('rack-reservations/<int:pk>/delete/', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'),
|
||||||
path('rack-reservations/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rackreservation_changelog', kwargs={'model': RackReservation}),
|
path('rack-reservations/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='rackreservation_changelog', kwargs={'model': RackReservation}),
|
||||||
|
@ -473,6 +473,18 @@ class RackReservationListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
action_buttons = ('export',)
|
action_buttons = ('export',)
|
||||||
|
|
||||||
|
|
||||||
|
class RackReservationView(PermissionRequiredMixin, View):
|
||||||
|
permission_required = 'dcim.view_rackreservation'
|
||||||
|
|
||||||
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
rackreservation = get_object_or_404(RackReservation.objects.prefetch_related('rack'), pk=pk)
|
||||||
|
|
||||||
|
return render(request, 'dcim/rackreservation.html', {
|
||||||
|
'rackreservation': rackreservation,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class RackReservationCreateView(PermissionRequiredMixin, ObjectEditView):
|
class RackReservationCreateView(PermissionRequiredMixin, ObjectEditView):
|
||||||
permission_required = 'dcim.add_rackreservation'
|
permission_required = 'dcim.add_rackreservation'
|
||||||
model = RackReservation
|
model = RackReservation
|
||||||
|
@ -271,7 +271,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% for resv in reservations %}
|
{% for resv in reservations %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ resv.unit_list }}</td>
|
<td>
|
||||||
|
<a href="{{ resv.get_absolute_url }}">{{ resv.unit_list }}</a>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if resv.tenant %}
|
{% if resv.tenant %}
|
||||||
<a href="{{ resv.tenant.get_absolute_url }}">{{ resv.tenant }}</a>
|
<a href="{{ resv.tenant.get_absolute_url }}">{{ resv.tenant }}</a>
|
||||||
|
146
netbox/templates/dcim/rackreservation.html
Normal file
146
netbox/templates/dcim/rackreservation.html
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
{% extends '_base.html' %}
|
||||||
|
{% load buttons %}
|
||||||
|
{% load custom_links %}
|
||||||
|
{% load helpers %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
<div class="row noprint">
|
||||||
|
<div class="col-sm-8 col-md-9">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="{% url 'dcim:rackreservation_list' %}">Rack Reservations</a></li>
|
||||||
|
<li><a href="{{ rackreservation.rack.get_absolute_url }}">{{ rackreservation.rack }}</a></li>
|
||||||
|
<li>Units {{ rackreservation.unit_list }}</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4 col-md-3">
|
||||||
|
<form action="{% url 'dcim:rackreservation_list' %}" method="get">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" name="q" class="form-control" placeholder="Search racks" />
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<span class="fa fa-search" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pull-right noprint">
|
||||||
|
{% if perms.dcim.change_rackreservation %}
|
||||||
|
{% edit_button rackreservation %}
|
||||||
|
{% endif %}
|
||||||
|
{% if perms.dcim.delete_rackreservation %}
|
||||||
|
{% delete_button rackreservation %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<h1>{% block title %}{{ rackreservation }}{% endblock %}</h1>
|
||||||
|
{% include 'inc/created_updated.html' with obj=rackreservation %}
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
|
||||||
|
<a href="{{ rackreservation.get_absolute_url }}">Rack</a>
|
||||||
|
</li>
|
||||||
|
{% if perms.extras.view_objectchange %}
|
||||||
|
<li role="presentation"{% if active_tab == 'changelog' %} class="active"{% endif %}>
|
||||||
|
<a href="{% url 'dcim:rackreservation_changelog' pk=rackreservation.pk %}">Change Log</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<strong>Rack</strong>
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover panel-body attr-table">
|
||||||
|
{% with rack=rackreservation.rack %}
|
||||||
|
<tr>
|
||||||
|
<td>Site</td>
|
||||||
|
<td>
|
||||||
|
{% if rack.site.region %}
|
||||||
|
<a href="{{ rack.site.region.get_absolute_url }}">{{ rack.site.region }}</a>
|
||||||
|
<i class="fa fa-angle-right"></i>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{% url 'dcim:site' slug=rack.site.slug %}">{{ rack.site }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Group</td>
|
||||||
|
<td>
|
||||||
|
{% if rack.group %}
|
||||||
|
<a href="{% url 'dcim:rack_list' %}?site={{ rack.site.slug }}&group={{ rack.group.slug }}">{{ rack.group }}</a>
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">None</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Rack</td>
|
||||||
|
<td>
|
||||||
|
<a href="{{ rack.get_absolute_url }}">{{ rack }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<strong>Reservation Details</strong>
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover panel-body attr-table">
|
||||||
|
<tr>
|
||||||
|
<td>Units</td>
|
||||||
|
<td>{{ rackreservation.unit_list }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Tenant</td>
|
||||||
|
<td>
|
||||||
|
{% if rackreservation.tenant %}
|
||||||
|
{% if rackreservation.tenant.group %}
|
||||||
|
<a href="{{ rackreservation.tenant.group.get_absolute_url }}">{{ rackreservation.tenant.group }}</a>
|
||||||
|
<i class="fa fa-angle-right"></i>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ rackreservation.tenant.get_absolute_url }}">{{ rackreservation.tenant }}</a>
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">None</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>User</td>
|
||||||
|
<td>{{ rackreservation.user }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Description</td>
|
||||||
|
<td>{{ rackreservation.description }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
{% with rack=rackreservation.rack %}
|
||||||
|
<div class="row" style="margin-bottom: 20px">
|
||||||
|
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||||
|
<div class="rack_header">
|
||||||
|
<h4>Front</h4>
|
||||||
|
</div>
|
||||||
|
{% include 'dcim/inc/rack_elevation.html' with face='front' %}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-6 col-xs-12">
|
||||||
|
<div class="rack_header">
|
||||||
|
<h4>Rear</h4>
|
||||||
|
</div>
|
||||||
|
{% include 'dcim/inc/rack_elevation.html' with face='rear' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endwith %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascript %}
|
||||||
|
<script src="{% static 'js/rack_elevations.js' %}?v{{ settings.VERSION }}"></script>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user