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

Replace custom form templates with TabbedFieldGroups

Jeremy Stretch 1 год назад
Родитель
Сommit
2aaa552067

+ 16 - 0
netbox/circuits/forms/model_forms.py

@@ -7,6 +7,7 @@ from ipam.models import ASN
 from netbox.forms import NetBoxModelForm
 from tenancy.forms import TenancyForm
 from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField
+from utilities.forms.rendering import TabbedFieldGroups
 from utilities.forms.widgets import DatePicker, NumberWithOptions
 
 __all__ = (
@@ -146,6 +147,21 @@ class CircuitTerminationForm(NetBoxModelForm):
         selector=True
     )
 
+    fieldsets = (
+        (_('Circuit Termination'), (
+            'circuit',
+            'term_side',
+            'description',
+            'tags',
+            TabbedFieldGroups(
+                (_('Site'), 'site'),
+                (_('Provider Network'), 'provider_network'),
+            ),
+            'mark_connected',
+        )),
+        (_('Termination Details'), ('port_speed', 'upstream_speed', 'xconnect_id', 'pp_info')),
+    )
+
     class Meta:
         model = CircuitTermination
         fields = [

+ 0 - 1
netbox/circuits/views.py

@@ -412,7 +412,6 @@ class CircuitContactsView(ObjectContactsView):
 class CircuitTerminationEditView(generic.ObjectEditView):
     queryset = CircuitTermination.objects.all()
     form = forms.CircuitTerminationForm
-    template_name = 'circuits/circuittermination_edit.html'
 
 
 @register_model_view(CircuitTermination, 'delete')

+ 45 - 1
netbox/ipam/forms/model_forms.py

@@ -16,7 +16,7 @@ from utilities.forms.fields import (
     CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, NumericArrayField,
     SlugField,
 )
-from utilities.forms.rendering import ObjectAttribute
+from utilities.forms.rendering import InlineFields, ObjectAttribute, TabbedFieldGroups
 from utilities.forms.widgets import DatePicker
 from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
 
@@ -308,6 +308,20 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
     )
     comments = CommentField()
 
+    fieldsets = (
+        (_('IP Address'), ('address', 'status', 'role', 'vrf', 'dns_name', 'description', 'tags')),
+        (_('Tenancy'), ('tenant_group', 'tenant')),
+        (_('Assignment'), (
+            TabbedFieldGroups(
+                (_('Device'), 'interface'),
+                (_('Virtual Machine'), 'vminterface'),
+                (_('FHRP Group'), 'fhrpgroup'),
+            ),
+            'primary_for_parent',
+        )),
+        (_('NAT IP (Inside)'), ('nat_inside',)),
+    )
+
     class Meta:
         model = IPAddress
         fields = [
@@ -709,6 +723,20 @@ class ServiceForm(NetBoxModelForm):
     )
     comments = CommentField()
 
+    fieldsets = (
+        (_('Service'), (
+            TabbedFieldGroups(
+                (_('Device'), 'device'),
+                (_('Virtual Machine'), 'virtual_machine'),
+            ),
+            'name',
+            InlineFields(_('Port(s)'), 'protocol', 'ports'),
+            'ipaddresses',
+            'description',
+            'tags',
+        )),
+    )
+
     class Meta:
         model = Service
         fields = [
@@ -723,6 +751,22 @@ class ServiceCreateForm(ServiceForm):
         required=False
     )
 
+    fieldsets = (
+        (_('Service'), (
+            TabbedFieldGroups(
+                (_('Device'), 'device'),
+                (_('Virtual Machine'), 'virtual_machine'),
+            ),
+            TabbedFieldGroups(
+                (_('From Template'), 'service_template'),
+                (_('Custom'), 'name', 'protocol', 'ports'),
+            ),
+            'ipaddresses',
+            'description',
+            'tags',
+        )),
+    )
+
     class Meta(ServiceForm.Meta):
         fields = [
             'device', 'virtual_machine', 'service_template', 'name', 'protocol', 'ports', 'ipaddresses', 'description',

+ 0 - 3
netbox/ipam/views.py

@@ -781,7 +781,6 @@ class IPAddressView(generic.ObjectView):
 class IPAddressEditView(generic.ObjectEditView):
     queryset = IPAddress.objects.all()
     form = forms.IPAddressForm
-    template_name = 'ipam/ipaddress_edit.html'
 
     def alter_object(self, obj, request, url_args, url_kwargs):
 
@@ -1235,14 +1234,12 @@ class ServiceView(generic.ObjectView):
 class ServiceCreateView(generic.ObjectEditView):
     queryset = Service.objects.all()
     form = forms.ServiceCreateForm
-    template_name = 'ipam/service_create.html'
 
 
 @register_model_view(Service, 'edit')
 class ServiceEditView(generic.ObjectEditView):
     queryset = Service.objects.all()
     form = forms.ServiceForm
-    template_name = 'ipam/service_edit.html'
 
 
 @register_model_view(Service, 'delete')

+ 0 - 58
netbox/templates/circuits/circuittermination_edit.html

@@ -1,58 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load static %}
-{% load form_helpers %}
-{% load i18n %}
-
-{% block form %}
-  <div class="field-group my-5">
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Circuit Termination" %}</h5>
-    </div>
-    {% render_field form.circuit %}
-    {% render_field form.term_side %}
-    {% render_field form.tags %}
-    {% render_field form.mark_connected %}
-    {% with providernetwork_tab_active=form.initial.provider_network %}
-      <div class="row">
-        <div class="col-9 offset-3">
-          <ul class="nav nav-pills mb-1" role="tablist">
-            <li class="nav-item" role="presentation">
-              <button class="nav-link{% if not providernetwork_tab_active %} active{% endif %}" role="tab" type="button" data-bs-target="#site" data-bs-toggle="tab">{% trans "Site" %}</button>
-            </li>
-            <li class="nav-item" role="presentation">
-              <button class="nav-link{% if providernetwork_tab_active %} active{% endif %}" role="tab" type="button" data-bs-toggle="tab" data-bs-target="#providernetwork">{% trans "Provider Network" %}</button>
-            </li>
-          </ul>
-        </div>
-      </div>
-      <div class="tab-content p-0 border-0">
-        <div class="tab-pane{% if not providernetwork_tab_active %} active{% endif %}" id="site">
-          {% render_field form.site %}
-        </div>
-        <div class="tab-pane{% if providernetwork_tab_active %} active{% endif %}" id="providernetwork">
-          {% render_field form.provider_network %}
-        </div>
-      </div>
-    {% endwith %}
-  </div>
-
-  <div class="field-group my-5">
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Termination Details" %}</h5>
-    </div>
-    {% render_field form.port_speed %}
-    {% render_field form.upstream_speed %}
-    {% render_field form.xconnect_id %}
-    {% render_field form.pp_info %}
-    {% render_field form.description %}
-  </div>
-
-  {% if form.custom_fields %}
-    <div class="field-group mb-5">
-      <div class="row">
-        <h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
-      </div>
-      {% render_custom_fields form %}
-    </div>
-  {% endif %}
-{% endblock %}

+ 0 - 93
netbox/templates/ipam/ipaddress_edit.html

@@ -1,93 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load static %}
-{% load form_helpers %}
-{% load helpers %}
-{% load i18n %}
-
-{% block tabs %}
-  {% include 'ipam/inc/ipaddress_edit_header.html' with active_tab='add' %}
-{% endblock tabs %}
-
-{% block form %}
-    <div class="field-group my-5">
-      <div class="row">
-        <h5 class="col-9 offset-3">{% trans "IP Address" %}</h5>
-      </div>
-      {% render_field form.address %}
-      {% render_field form.status %}
-      {% render_field form.role %}
-      {% render_field form.vrf %}
-      {% render_field form.dns_name %}
-      {% render_field form.description %}
-      {% render_field form.tags %}
-    </div>
-
-    <div class="field-group my-5">
-      <div class="row">
-        <h5 class="col-9 offset-3">{% trans "Tenancy" %}</h5>
-      </div>
-      {% render_field form.tenant_group %}
-      {% render_field form.tenant %}
-    </div>
-
-    <div class="field-group my-5">
-      <div class="row">
-        <h5 class="col-9 offset-3">{% trans "Interface Assignment" %}</h5>
-      </div>
-      <div class="row">
-        <div class="col-9 offset-3">
-          <ul class="nav nav-pills mb-1" role="tablist">
-            <li role="presentation" class="nav-item">
-              <button role="tab" type="button" id="device_tab" data-bs-toggle="tab" aria-controls="device" data-bs-target="#device" class="nav-link {% if not form.initial.vminterface and not form.initial.fhrpgroup %}active{% endif %}">
-                {% trans "Device" %}
-              </button>
-            </li>
-            <li role="presentation" class="nav-item">
-              <button role="tab" type="button" id="vm_tab" data-bs-toggle="tab" aria-controls="vm" data-bs-target="#vm" class="nav-link {% if form.initial.vminterface %}active{% endif %}">
-                {% trans "Virtual Machine" %}
-              </button>
-            </li>
-            <li role="presentation" class="nav-item">
-              <button role="tab" type="button" id="fhrpgroup_tab" data-bs-toggle="tab" aria-controls="fhrpgroup" data-bs-target="#fhrpgroup" class="nav-link {% if form.initial.fhrpgroup %}active{% endif %}">
-                {% trans "FHRP Group" %}
-              </button>
-            </li>
-          </ul>
-        </div>
-      </div>
-      <div class="tab-content p-0 border-0">
-        <div class="tab-pane {% if not form.initial.vminterface and not form.initial.fhrpgroup %}active{% endif %}" id="device" role="tabpanel" aria-labeled-by="device_tab">
-          {% render_field form.interface %}
-        </div>
-        <div class="tab-pane {% if form.initial.vminterface %}active{% endif %}" id="vm" role="tabpanel" aria-labeled-by="vm_tab">
-          {% render_field form.vminterface %}
-        </div>
-        <div class="tab-pane {% if form.initial.fhrpgroup %}active{% endif %}" id="fhrpgroup" role="tabpanel" aria-labeled-by="fhrpgroup_tab">
-          {% render_field form.fhrpgroup %}
-        </div>
-        {% render_field form.primary_for_parent %}
-      </div>
-    </div>
-
-    <div class="field-group my-5">
-      <div class="row">
-        <h5 class="col-9 offset-3">{% trans "NAT IP (Inside" %})</h5>
-      </div>
-      <div class="row">
-          {% render_field form.nat_inside %}
-      </div>
-    </div>
-
-    <div class="field-group my-5">
-      {% render_field form.comments %}
-    </div>
-
-    {% if form.custom_fields %}
-      <div class="field-group my-5">
-        <div class="row">
-          <h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
-        </div>
-        {% render_custom_fields form %}
-      </div>
-    {% endif %}
-{% endblock %}

+ 0 - 79
netbox/templates/ipam/service_create.html

@@ -1,79 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load form_helpers %}
-{% load i18n %}
-
-{% block form %}
-  <div class="field-group my-5">
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Service" %}</h5>
-    </div>
-
-    {# Device/VM selection #}
-    <div class="row">
-      <div class="col-9 offset-3">
-        <ul class="nav nav-pills mb-1" role="tablist">
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="device_tab" data-bs-toggle="tab" aria-controls="device" data-bs-target="#device" class="nav-link {% if not form.initial.virtual_machine %}active{% endif %}">
-              {% trans "Device" %}
-            </button>
-          </li>
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="vm_tab" data-bs-toggle="tab" aria-controls="vm" data-bs-target="#vm" class="nav-link {% if form.initial.virtual_machine %}active{% endif %}">
-              {% trans "Virtual Machine" %}
-            </button>
-          </li>
-        </ul>
-      </div>
-    </div>
-    <div class="tab-content p-0 border-0">
-      <div class="tab-pane {% if not form.initial.virtual_machine %}active{% endif %}" id="device" role="tabpanel" aria-labeled-by="device_tab">
-        {% render_field form.device %}
-      </div>
-      <div class="tab-pane {% if form.initial.virtual_machine %}active{% endif %}" id="vm" role="tabpanel" aria-labeled-by="vm_tab">
-        {% render_field form.virtual_machine %}
-      </div>
-    </div>
-
-    {# Template or custom #}
-    <div class="row">
-      <div class="col-9 offset-3">
-        <ul class="nav nav-pills mb-1" role="tablist">
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="template_tab" data-bs-toggle="tab" data-bs-target="#template" class="nav-link active">
-              {% trans "From Template" %}
-            </button>
-          </li>
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="custom_tab" data-bs-toggle="tab" data-bs-target="#custom" class="nav-link">
-              {% trans "Custom" %}
-            </button>
-          </li>
-        </ul>
-      </div>
-    </div>
-    <div class="tab-content p-0 border-0">
-      <div class="tab-pane active" id="template" role="tabpanel" aria-labeled-by="template_tab">
-        {% render_field form.service_template %}
-      </div>
-      <div class="tab-pane" id="custom" role="tabpanel" aria-labeled-by="custom_tab">
-        {% render_field form.name %}
-        {% render_field form.protocol %}
-        {% render_field form.ports %}
-      </div>
-    </div>
-    {% render_field form.ipaddresses %}
-    {% render_field form.description %}
-    {% render_field form.tags %}
-  </div>
-
-  <div class="field-group my-5">
-    {% render_field form.comments %}
-  </div>
-
-  {% if form.custom_fields %}
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
-    </div>
-    {% render_custom_fields form %}
-  {% endif %}
-{% endblock %}

+ 0 - 66
netbox/templates/ipam/service_edit.html

@@ -1,66 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load form_helpers %}
-{% load i18n %}
-
-{% block form %}
-  <div class="field-group my-5">
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Service" %}</h5>
-    </div>
-
-    <div class="row">
-      <div class="col-9 offset-3">
-        <ul class="nav nav-pills mb-1" role="tablist">
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="device_tab" data-bs-toggle="tab" aria-controls="device" data-bs-target="#device" class="nav-link {% if not form.initial.virtual_machine %}active{% endif %}">
-              {% trans "Device" %}
-            </button>
-          </li>
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="vm_tab" data-bs-toggle="tab" aria-controls="vm" data-bs-target="#vm" class="nav-link {% if form.initial.virtual_machine %}active{% endif %}">
-              {% trans "Virtual Machine" %}
-            </button>
-          </li>
-        </ul>
-      </div>
-    </div>
-    <div class="tab-content p-0 border-0">
-      <div class="tab-pane {% if not form.initial.virtual_machine %}active{% endif %}" id="device" role="tabpanel" aria-labeled-by="device_tab">
-        {% render_field form.device %}
-      </div>
-      <div class="tab-pane {% if form.initial.virtual_machine %}active{% endif %}" id="vm" role="tabpanel" aria-labeled-by="vm_tab">
-        {% render_field form.virtual_machine %}
-      </div>
-    </div>
-    {% render_field form.name %}
-    <div class="row">
-        <label class="col-sm-3 col-form-label text-lg-end">{% trans "Port(s)" %}</label>
-        <div class="col-3">
-            {{ form.protocol }}
-        </div>
-        <div class="col-6">
-            {{ form.ports }}
-        </div>
-    </div>
-    <div class="row mb-3">
-        <div class="col-3"></div>
-        <div class="col-9">
-            <span class="form-text">{{ form.ports.help_text }}</span>
-        </div>
-    </div>
-    {% render_field form.ipaddresses %}
-    {% render_field form.description %}
-    {% render_field form.tags %}
-  </div>
-
-  <div class="field-group my-5">
-    {% render_field form.comments %}
-  </div>
-
-  {% if form.custom_fields %}
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
-    </div>
-    {% render_custom_fields form %}
-  {% endif %}
-{% endblock %}

+ 0 - 56
netbox/templates/vpn/l2vpntermination_edit.html

@@ -1,56 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load helpers %}
-{% load form_helpers %}
-{% load i18n %}
-
-{% block form %}
-  <div class="field-group my-5">
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "L2VPN Termination" %}</h5>
-    </div>
-    {% render_field form.l2vpn %}
-    <div class="row">
-      <div class="col-9 offset-3">
-        <ul class="nav nav-pills mb-1" role="tablist">
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="vlan_tab" data-bs-toggle="tab" aria-controls="vlan" data-bs-target="#vlan" class="nav-link {% if not form.initial.interface and not form.initial.vminterface %}active{% endif %}">
-              {% trans "VLAN" %}
-            </button>
-          </li>
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="interface_tab" data-bs-toggle="tab" aria-controls="interface" data-bs-target="#interface" class="nav-link {% if form.initial.interface %}active{% endif %}">
-              {% trans "Device" %}
-            </button>
-          </li>
-          <li role="presentation" class="nav-item">
-            <button role="tab" type="button" id="vminterface_tab" data-bs-toggle="tab" aria-controls="vminterface" data-bs-target="#vminterface" class="nav-link {% if form.initial.vminterface %}active{% endif %}">
-              {% trans "Virtual Machine" %}
-            </button>
-          </li>
-        </ul>
-      </div>
-    </div>
-    <div class="row mb-3">
-      <div class="tab-content p-0 border-0">
-        <div class="tab-pane {% if not form.initial.interface and not form.initial.vminterface %}active{% endif %}" id="vlan" role="tabpanel" aria-labeled-by="vlan_tab">
-          {% render_field form.vlan %}
-        </div>
-        <div class="tab-pane {% if form.initial.interface %}active{% endif %}" id="interface" role="tabpanel" aria-labeled-by="interface_tab">
-          {% render_field form.interface %}
-        </div>
-        <div class="tab-pane {% if form.initial.vminterface %}active{% endif %}" id="vminterface" role="tabpanel" aria-labeled-by="vminterface_tab">
-          {% render_field form.vminterface %}
-        </div>
-        {% render_field form.tags %}
-      </div>
-    </div>
-  </div>
- {% if form.custom_fields %}
-  <div class="field-group my-5">
-    <div class="row">
-      <h5 class="col-9 offset-3">{% trans "Custom Fields" %}</h5>
-    </div>
-    {% render_custom_fields form %}
-  </div>
-{% endif %}
-{% endblock %}

+ 13 - 11
netbox/utilities/templates/form_helpers/render_fieldset.html

@@ -26,7 +26,7 @@
     {% elif layout == 'inline' %}
       {# Multiple form fields on the same line #}
       <div class="row mb-3">
-        <label class="col col-form-label text-lg-end">{{ title|default:'' }}</label>
+        <label class="col col-3 col-form-label text-lg-end">{{ title|default:'' }}</label>
         {% for field in items %}
           <div class="col mb-1">
             {{ field }}
@@ -37,16 +37,18 @@
 
     {% elif layout == 'tabs' %}
       {# Tabbed groups of fields #}
-      <div class="row offset-sm-3">
-        <ul class="nav nav-pills mb-1" role="tablist">
-          {% for tab in items %}
-            <li role="presentation" class="nav-item">
-              <button role="tab" type="button" id="{{ tab.id }}_tab" data-bs-toggle="tab" aria-controls="{{ tab.id }}" data-bs-target="#{{ tab.id }}" class="nav-link {% if tab.active %}active{% endif %}">
-                {% trans tab.title %}
-              </button>
-            </li>
-          {% endfor %}
-        </ul>
+      <div class="row">
+        <div class="col offset-3">
+          <ul class="nav nav-pills mb-1" role="tablist">
+            {% for tab in items %}
+              <li role="presentation" class="nav-item">
+                <button role="tab" type="button" id="{{ tab.id }}_tab" data-bs-toggle="tab" aria-controls="{{ tab.id }}" data-bs-target="#{{ tab.id }}" class="nav-link {% if tab.active %}active{% endif %}">
+                  {% trans tab.title %}
+                </button>
+              </li>
+            {% endfor %}
+          </ul>
+        </div>
       </div>
       <div class="tab-content p-0 border-0">
         {% for tab in items %}

+ 13 - 0
netbox/vpn/forms/model_forms.py

@@ -7,6 +7,7 @@ from ipam.models import IPAddress, RouteTarget, VLAN
 from netbox.forms import NetBoxModelForm
 from tenancy.forms import TenancyForm
 from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField
+from utilities.forms.rendering import TabbedFieldGroups
 from utilities.forms.utils import add_blank_choice, get_field_value
 from utilities.forms.widgets import HTMXSelect
 from virtualization.models import VirtualMachine, VMInterface
@@ -444,6 +445,18 @@ class L2VPNTerminationForm(NetBoxModelForm):
         label=_('Interface')
     )
 
+    fieldsets = (
+        (None, (
+            'l2vpn',
+            TabbedFieldGroups(
+                (_('VLAN'), 'vlan'),
+                (_('Device'), 'interface'),
+                (_('Virtual Machine'), 'vminterface'),
+            ),
+            'tags',
+        )),
+    )
+
     class Meta:
         model = L2VPNTermination
         fields = ('l2vpn', 'tags')

+ 0 - 1
netbox/vpn/views.py

@@ -479,7 +479,6 @@ class L2VPNTerminationView(generic.ObjectView):
 class L2VPNTerminationEditView(generic.ObjectEditView):
     queryset = L2VPNTermination.objects.all()
     form = forms.L2VPNTerminationForm
-    template_name = 'vpn/l2vpntermination_edit.html'
 
 
 @register_model_view(L2VPNTermination, 'delete')