This commit is contained in:
Daniel Sheppard 2024-04-23 16:46:51 +02:00 committed by GitHub
commit 2ed75042e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 99 additions and 7 deletions

View File

@ -21,12 +21,15 @@ from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup
from ipam.tables import InterfaceVLANTable
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
from netbox.views import generic
from netbox.views.generic.utils import get_prerequisite_model
from tenancy.views import ObjectContactsView
from utilities.forms import ConfirmationForm
from utilities.forms import ConfirmationForm, restrict_form_fields
from utilities.htmx import htmx_partial
from utilities.paginator import EnhancedPaginator, get_paginate_count
from utilities.permissions import get_permission_for_model
from utilities.query import count_related
from utilities.query_functions import CollateAsChar
from utilities.querydict import normalize_querydict
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin, ViewTab, register_model_view
from virtualization.models import VirtualMachine
from . import filtersets, forms, tables
@ -3191,7 +3194,7 @@ class CableEditView(generic.ObjectEditView):
return super().dispatch(request, *args, **kwargs)
def get_object(self, **kwargs):
def get_object(self, a_terminations_type=None, b_terminations_type=None, **kwargs):
"""
Hack into get_object() to set the form class when editing an existing Cable, since ObjectEditView
doesn't currently provide a hook for dynamic class resolution.
@ -3204,6 +3207,13 @@ class CableEditView(generic.ObjectEditView):
a_type = termination_a.termination._meta.model if termination_a else None
termination_b = obj.terminations.filter(cable_end='B').first()
b_type = termination_b.termination._meta.model if termination_b else None
# Set type if available
if not a_type and a_terminations_type:
a_type = CABLE_TERMINATION_TYPES.get(a_terminations_type)
if not b_type and b_terminations_type:
b_type = CABLE_TERMINATION_TYPES.get(b_terminations_type)
self.form = forms.get_cable_form(a_type, b_type)
return obj
@ -3221,6 +3231,51 @@ class CableEditView(generic.ObjectEditView):
return params
def get(self, request, *args, **kwargs):
"""
GET request handler.
Args:
request: The current request
"""
# Set termination types if available
if request.GET.get('a_terminations_type'):
kwargs.update({'a_terminations_type': request.GET.get('a_terminations_type')})
if request.GET.get('b_terminations_type'):
kwargs.update({'b_terminations_type': request.GET.get('b_terminations_type')})
obj = self.get_object(**kwargs)
obj = self.alter_object(obj, request, args, kwargs)
model = self.queryset.model
initial_data = normalize_querydict(request.GET)
form = self.form(instance=obj, initial=initial_data)
restrict_form_fields(form, request.user)
return render(request, self.template_name, {
'model': model,
'object': obj,
'form': form,
'return_url': self.get_return_url(request, obj),
'prerequisite_model': get_prerequisite_model(self.queryset),
**self.get_extra_context(request, obj),
})
def post(self, request, *args, **kwargs):
"""
POST request handler.
Args:
request: The current request
"""
# Set termination types if available
if request.GET.get('a_terminations_type'):
kwargs.update({'a_terminations_type': request.GET.get('a_terminations_type')})
if request.GET.get('b_terminations_type'):
kwargs.update({'b_terminations_type': request.GET.get('b_terminations_type')})
return super().post(request, *args, **kwargs)
@register_model_view(Cable, 'delete')
class CableDeleteView(generic.ObjectDeleteView):

View File

@ -5,9 +5,8 @@
{% load i18n %}
{% block form %}
{# A side termination #}
<div class="field-group mb-5">
<div id="a_termination_block" class="field-group mb-5" hx-swap-oob="true">
<div class="row">
<h5 class="col-9 offset-3">{% trans "A Side" %}</h5>
</div>
@ -20,11 +19,30 @@
{% if 'termination_a_circuit' in form.fields %}
{% render_field form.termination_a_circuit %}
{% endif %}
{% render_field form.a_terminations %}
{% if 'a_terminations' in form.fields %}
{% render_field form.a_terminations %}
{% elif 'b_terminations' in form.fields %}
<div class="row mb-3">
<label class="col-sm-3 col-form-label text-lg-end">{% trans "Termination Type" %}</label>
<div class="col" hx-swap="none" hx-push-url="true">
<button class="btn btn-primary" hx-get="?a_terminations_type=dcim.interface">{% trans "Interface" %}</button>
<button class="btn btn-primary" hx-get="?a_terminations_type=dcim.frontport">{% trans "Front Port" %}</button>
<button class="btn btn-primary" hx-get="?a_terminations_type=dcim.rearport">{% trans "Rear Port" %}</button>
<button class="btn btn-primary" hx-get="?a_terminations_type=circuits.circuittermination">{% trans "Circuit Termination" %}</button>
</div>
</div>
{% else %}
<div class="row mb-3">
<label for="a_terminations" class="col-sm-3 col-form-label text-lg-end">{% trans "Termination Type" %}</label>
<div class="col col-form-label">Cannot initialize dynamic cable termination selection form</div>
<select class="ts-hidden-accessible" name="a_terminations" required></select>
<div class="invalid-feedback">This field is required.</div>
</div>
{% endif %}
</div>
{# B side termination #}
<div class="field-group mb-5">
<div id="b_termination_block" class="field-group mb-5" hx-swap-oob="true">
<div class="row">
<h5 class="col-9 offset-3">{% trans "B Side" %}</h5>
</div>
@ -37,7 +55,26 @@
{% if 'termination_b_circuit' in form.fields %}
{% render_field form.termination_b_circuit %}
{% endif %}
{% render_field form.b_terminations %}
{% if 'b_terminations' in form.fields %}
{% render_field form.b_terminations %}
{% elif 'a_terminations' in form.fields %}
<div class="row mb-3">
<label class="col-sm-3 col-form-label text-lg-end">{% trans "Termination Type" %}</label>
<div class="col" hx-swap="none" hx-push-url="true">
<button class="btn btn-primary" hx-get="?b_terminations_type=dcim.interface">{% trans "Interface" %}</button>
<button class="btn btn-primary" hx-get="?b_terminations_type=dcim.frontport">{% trans "Front Port" %}</button>
<button class="btn btn-primary" hx-get="?b_terminations_type=dcim.rearport">{% trans "Rear Port" %}</button>
<button class="btn btn-primary" hx-get="?b_terminations_type=circuits.circuittermination">{% trans "Circuit Termination" %}</button>
</div>
</div>
{% else %}
<div class="row mb-3">
<label for="b_terminantions" class="col-sm-3 col-form-label text-lg-end">{% trans "Termination Type" %}</label>
<div class="col col-form-label">Cannot initialize dynamic cable termination selection form</div>
<select class="ts-hidden-accessible" name="b_terminations" required></select>
<div class="invalid-feedback">This field is required.</div>
</div>
{% endif %}
</div>
{# Cable attributes #}