Additional table conversions (WIP)

This commit is contained in:
jeremystretch 2023-01-13 21:38:24 -05:00
parent c2b43e2772
commit 30578bfc97
19 changed files with 93 additions and 219 deletions

View File

@ -223,15 +223,8 @@ class RegionView(generic.ObjectView):
child_regions_table = tables.RegionTable(child_regions)
child_regions_table.columns.hide('actions')
sites = Site.objects.restrict(request.user, 'view').filter(
region=instance
)
sites_table = tables.SiteTable(sites, user=request.user, exclude=('region',))
sites_table.configure(request)
return {
'child_regions_table': child_regions_table,
'sites_table': sites_table,
}
@ -311,15 +304,8 @@ class SiteGroupView(generic.ObjectView):
child_groups_table = tables.SiteGroupTable(child_groups)
child_groups_table.columns.hide('actions')
sites = Site.objects.restrict(request.user, 'view').filter(
group=instance
)
sites_table = tables.SiteTable(sites, user=request.user, exclude=('group',))
sites_table.configure(request)
return {
'child_groups_table': child_groups_table,
'sites_table': sites_table,
}
@ -2456,12 +2442,6 @@ class InterfaceView(generic.ObjectView):
orderable=False
)
# Get assigned IP addresses
ipaddress_table = AssignedIPAddressesTable(
data=instance.ip_addresses.restrict(request.user, 'view').prefetch_related('vrf', 'tenant'),
orderable=False
)
# Get bridge interfaces
bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance)
bridge_interfaces_tables = tables.InterfaceTable(
@ -2494,7 +2474,6 @@ class InterfaceView(generic.ObjectView):
return {
'vdc_table': vdc_table,
'ipaddress_table': ipaddress_table,
'bridge_interfaces_table': bridge_interfaces_tables,
'child_interfaces_table': child_interfaces_tables,
'vlan_table': vlan_table,

View File

@ -5,11 +5,9 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import gettext as _
from circuits.models import Provider, Circuit
from circuits.tables import ProviderTable
from circuits.models import Provider
from dcim.filtersets import InterfaceFilterSet
from dcim.models import Interface, Site, Device
from dcim.tables import SiteTable
from netbox.views import generic
from utilities.utils import count_related
from utilities.views import ViewTab, register_model_view
@ -167,17 +165,6 @@ class RIRListView(generic.ObjectListView):
class RIRView(generic.ObjectView):
queryset = RIR.objects.all()
def get_extra_context(self, request, instance):
aggregates = Aggregate.objects.restrict(request.user, 'view').filter(rir=instance).annotate(
child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ())
)
aggregates_table = tables.AggregateTable(aggregates, user=request.user, exclude=('rir', 'utilization'))
aggregates_table.configure(request)
return {
'aggregates_table': aggregates_table,
}
@register_model_view(RIR, 'edit')
class RIREditView(generic.ObjectEditView):
@ -232,22 +219,11 @@ class ASNView(generic.ObjectView):
queryset = ASN.objects.all()
def get_extra_context(self, request, instance):
# Gather assigned Sites
sites = instance.sites.restrict(request.user, 'view')
sites_table = SiteTable(sites, user=request.user)
sites_table.configure(request)
# Gather assigned Providers
providers = instance.providers.restrict(request.user, 'view').annotate(
count_circuits=count_related(Circuit, 'provider')
)
providers_table = ProviderTable(providers, user=request.user)
providers_table.configure(request)
providers = instance.providers.restrict(request.user, 'view')
return {
'sites_table': sites_table,
'sites_count': sites.count(),
'providers_table': providers_table,
'providers_count': providers.count(),
}
@ -392,18 +368,6 @@ class RoleListView(generic.ObjectListView):
class RoleView(generic.ObjectView):
queryset = Role.objects.all()
def get_extra_context(self, request, instance):
prefixes = Prefix.objects.restrict(request.user, 'view').filter(
role=instance
)
prefixes_table = tables.PrefixTable(prefixes, user=request.user, exclude=('role', 'utilization'))
prefixes_table.configure(request)
return {
'prefixes_table': prefixes_table,
}
@register_model_view(Role, 'edit')
class RoleEditView(generic.ObjectEditView):
@ -888,17 +852,9 @@ class VLANGroupView(generic.ObjectView):
vlans_table.columns.show('pk')
vlans_table.configure(request)
# Compile permissions list for rendering the object table
permissions = {
'add': request.user.has_perm('ipam.add_vlan'),
'change': request.user.has_perm('ipam.change_vlan'),
'delete': request.user.has_perm('ipam.delete_vlan'),
}
return {
'vlans_count': vlans_count,
'vlans_table': vlans_table,
'permissions': permissions,
}
@ -954,11 +910,6 @@ class FHRPGroupView(generic.ObjectView):
queryset = FHRPGroup.objects.all()
def get_extra_context(self, request, instance):
# Get assigned IP addresses
ipaddress_table = tables.AssignedIPAddressesTable(
data=instance.ip_addresses.restrict(request.user, 'view'),
orderable=False
)
# Get assigned interfaces
members_table = tables.FHRPGroupAssignmentTable(
@ -968,7 +919,6 @@ class FHRPGroupView(generic.ObjectView):
members_table.columns.hide('group')
return {
'ipaddress_table': ipaddress_table,
'members_table': members_table,
'member_count': FHRPGroupAssignment.objects.filter(group=instance).count(),
}

View File

@ -344,13 +344,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">IP Addresses</h5>
<div class="card-body table-responsive">
{% if ipaddress_table.rows %}
{% render_table ipaddress_table 'inc/table.html' %}
{% else %}
<div class="text-muted">None</div>
{% endif %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'ipam:ipaddress_list' %}?interface_id={{ object.pk }}"
hx-trigger="load"
></div>
{% if perms.ipam.add_ipaddress %}
<div class="card-footer text-end noprint">
<a href="{% url 'ipam:ipaddress_add' %}?device={{ object.device.pk }}&interface={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">

View File

@ -42,7 +42,7 @@
<tr>
<th scope="row">Sites</th>
<td>
<a href="{% url 'dcim:site_list' %}?region_id={{ object.pk }}">{{ sites_table.rows|length }}</a>
<a href="{% url 'dcim:site_list' %}?region_id={{ object.pk }}">{{ object.sites.count }}</a>
</td>
</tr>
</table>
@ -76,10 +76,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Sites</h5>
<div class="card-body table-responsive">
{% render_table sites_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=sites_table.paginator page=sites_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'dcim:site_list' %}?region_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -42,7 +42,7 @@
<tr>
<th scope="row">Sites</th>
<td>
<a href="{% url 'dcim:site_list' %}?group_id={{ object.pk }}">{{ sites_table.rows|length }}</a>
<a href="{% url 'dcim:site_list' %}?group_id={{ object.pk }}">{{ object.groups.count }}</a>
</td>
</tr>
</table>
@ -76,10 +76,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Sites</h5>
<div class="card-body table-responsive">
{% render_table sites_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=sites_table.paginator page=sites_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'dcim:site_list' %}?group_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -70,9 +70,10 @@
<i class="mdi mdi-clipboard-clock"></i>
<span class="ms-1">Change Log</span>
</h6>
<div class="card-body table-responsive">
{% render_table changelog_table 'inc/table.html' %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'extras:objectchange_list' %}?sort=-time"
hx-trigger="load"
></div>
</div>
</div>
</div>

View File

@ -4,10 +4,10 @@
{% with preferences|get_key:"pagination.placement" as paginator_placement %}
{% if paginator_placement == 'top' or paginator_placement == 'both' %}
{% include 'inc/paginator_htmx.html' with paginator=table.paginator page=table.page %}
{% include 'inc/paginator_htmx.html' with table=table paginator=table.paginator page=table.page %}
{% endif %}
{% render_table table 'inc/table_htmx.html' %}
{% if paginator_placement != 'top' %}
{% include 'inc/paginator_htmx.html' with paginator=table.paginator page=table.page %}
{% include 'inc/paginator_htmx.html' with table=table paginator=table.paginator page=table.page %}
{% endif %}
{% endwith %}

View File

@ -7,9 +7,9 @@
<div class="btn-group btn-group-sm" role="group" aria-label="Pages">
{% if page.has_previous %}
<a href="#"
hx-get="{% querystring request page=page.previous_page_number %}"
hx-get="{{ table.htmx_url }}{% querystring request page=page.previous_page_number %}"
hx-target="closest .htmx-container"
hx-push-url="true"
{% if not table.embedded %}hx-push-url="true"{% endif %}
class="btn btn-outline-secondary"
>
<i class="mdi mdi-chevron-double-left"></i>
@ -18,9 +18,9 @@
{% for p in page.smart_pages %}
{% if p %}
<a href="#"
hx-get="{% querystring request page=p %}"
hx-get="{{ table.htmx_url }}{% querystring request page=p %}"
hx-target="closest .htmx-container"
hx-push-url="true"
{% if not table.embedded %}hx-push-url="true"{% endif %}
class="btn btn-outline-secondary{% if page.number == p %} active{% endif %}"
>
{{ p }}
@ -33,9 +33,9 @@
{% endfor %}
{% if page.has_next %}
<a href="#"
hx-get="{% querystring request page=page.next_page_number %}"
hx-get="{{ table.htmx_url }}{% querystring request page=page.next_page_number %}"
hx-target="closest .htmx-container"
hx-push-url="true"
{% if not table.embedded %}hx-push-url="true"{% endif %}
class="btn btn-outline-secondary"
>
<i class="mdi mdi-chevron-double-right"></i>
@ -55,9 +55,9 @@
{% for n in page.paginator.get_page_lengths %}
<li>
<a href="#"
hx-get="{% querystring request per_page=n %}"
hx-get="{{ table.htmx_url }}{% querystring request per_page=n %}"
hx-target="closest .htmx-container"
hx-push-url="true"
{% if not table.embedded %}hx-push-url="true"{% endif %}
class="dropdown-item"
>{{ n }}</a>
</li>

View File

@ -75,17 +75,17 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Sites</h5>
<div class="card-body table-responsive">
{% render_table sites_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=sites_table.paginator page=sites_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'dcim:site_list' %}?asn_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
<div class="card">
<h5 class="card-header">Providers</h5>
<div class="card-body table-responsive">
{% render_table providers_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=providers_table.paginator page=providers_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'circuits:provider_list' %}?asn_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -69,13 +69,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Virtual IP Addresses</h5>
<div class="card-body table-responsive">
{% if ipaddress_table.rows %}
{% render_table ipaddress_table 'inc/table.html' %}
{% else %}
<div class="text-muted">None</div>
{% endif %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'ipam:ipaddress_list' %}?fhrpgroup_id={{ object.pk }}"
hx-trigger="load"
></div>
{% if perms.ipam.add_ipaddress %}
<div class="card-footer text-end">
<a href="{% url 'ipam:ipaddress_add' %}?fhrpgroup={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">

View File

@ -35,16 +35,16 @@
<tr>
<th scope="row">Aggregates</th>
<td>
<a href="{% url 'ipam:aggregate_list' %}?rir_id={{ object.pk }}">{{ aggregates_table.rows|length }}</a>
<a href="{% url 'ipam:aggregate_list' %}?rir_id={{ object.pk }}">{{ object.aggregates.count }}</a>
</td>
</tr>
</table>
</div>
</div>
{% include 'inc/panels/tags.html' %}
{% plugin_left_page object %}
</div>
<div class="col col-md-6">
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
{% plugin_right_page object %}
</div>
@ -53,10 +53,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Aggregates</h5>
<div class="card-body table-responsive">
{% render_table aggregates_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=aggregates_table.paginator page=aggregates_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'ipam:aggregate_list' %}?rir_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -35,40 +35,28 @@
<tr>
<th scope="row">Prefixes</th>
<td>
<a href="{% url 'ipam:prefix_list' %}?role_id={{ object.pk }}">{{ prefixes_table.rows|length }}</a>
<a href="{% url 'ipam:prefix_list' %}?role_id={{ object.pk }}">{{ object.prefixes.count }}</a>
</td>
</tr>
<tr>
<th scope="row">IP Ranges</th>
<td>
{% with ipranges_count=object.ip_ranges.count %}
{% if ipranges_count %}
<a href="{% url 'ipam:iprange_list' %}?role_id={{ object.pk }}">{{ ipranges_count }}</a>
{% else %}
{{ ''|placeholder }}
{% endif %}
{% endwith %}
<a href="{% url 'ipam:iprange_list' %}?role_id={{ object.pk }}">{{ object.ip_ranges.count }}</a>
</td>
</tr>
<tr>
<th scope="row">VLANs</th>
<td>
{% with vlans_count=object.vlans.count %}
{% if vlans_count %}
<a href="{% url 'ipam:vlan_list' %}?role_id={{ object.pk }}">{{ vlans_count }}</a>
{% else %}
{{ ''|placeholder }}
{% endif %}
{% endwith %}
<a href="{% url 'ipam:vlan_list' %}?role_id={{ object.pk }}">{{ object.vlans.count }}</a>
</td>
</tr>
</table>
</div>
</div>
{% include 'inc/panels/tags.html' %}
{% plugin_left_page object %}
</div>
<div class="col col-md-6">
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
{% plugin_right_page object %}
</div>
@ -77,10 +65,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Prefixes</h5>
<div class="card-body table-responsive">
{% render_table prefixes_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=prefixes_table.paginator page=prefixes_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'ipam:prefix_list' %}?role_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -83,17 +83,15 @@
<div class="row">
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">
Prefixes
</h5>
<div class="card-body table-responsive">
{% render_table prefix_table 'inc/table.html' %}
</div>
<h5 class="card-header">Prefixes</h5>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'ipam:prefix_list' %}?vlan_id={{ object.pk }}"
hx-trigger="load"
></div>
{% if perms.ipam.add_prefix %}
<div class="card-footer text-end noprint">
<a href="{% url 'ipam:prefix_add' %}?{% if object.tenant %}tenant={{ object.tenant.pk }}&{% endif %}site={{ object.site.pk }}&vlan={{ object.pk }}" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i>
Add a Prefix
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add a Prefix
</a>
</div>
{% endif %}

View File

@ -31,7 +31,7 @@
<tr>
<th scope="row">Clusters</th>
<td>
<a href="{% url 'virtualization:cluster_list' %}?group_id={{ object.pk }}">{{ clusters_table.rows|length }}</a>
<a href="{% url 'virtualization:cluster_list' %}?group_id={{ object.pk }}">{{ object.clusters.count }}</a>
</td>
</tr>
</table>
@ -50,10 +50,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Clusters</h5>
<div class="card-body table-responsive">
{% render_table clusters_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=clusters_table.paginator page=clusters_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'virtualization:cluster_list' %}?group_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -31,7 +31,7 @@
<tr>
<th scope="row">Clusters</th>
<td>
<a href="{% url 'virtualization:cluster_list' %}?type_id={{ object.pk }}">{{ clusters_table.rows|length }}</a>
<a href="{% url 'virtualization:cluster_list' %}?type_id={{ object.pk }}">{{ object.clusters.count }}</a>
</td>
</tr>
</table>
@ -49,10 +49,10 @@
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">Clusters</h5>
<div class="card-body table-responsive">
{% render_table clusters_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=clusters_table.paginator page=clusters_table.page %}
</div>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'virtualization:cluster_list' %}?type_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -80,16 +80,11 @@
<div class="row mb-3">
<div class="col col-md-12">
<div class="card">
<h5 class="card-header">
IP Addresses
</h5>
<div class="card-body table-responsive">
{% if ipaddress_table.rows %}
{% render_table ipaddress_table 'inc/table.html' %}
{% else %}
<div class="text-muted">None</div>
{% endif %}
</div>
<h5 class="card-header">IP Addresses</h5>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'ipam:ipaddress_list' %}?vminterface_id={{ object.pk }}"
hx-trigger="load"
></div>
{% if perms.ipam.add_ipaddress %}
<div class="card-footer text-end noprint">
<a href="{% url 'ipam:ipaddress_add' %}?virtual_machine={{ object.virtual_machine.pk }}&vminterface={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">

View File

@ -40,16 +40,16 @@
<tr>
<th scope="row">Wireless LANs</th>
<td>
<a href="{% url 'wireless:wirelesslan_list' %}?group_id={{ object.pk }}">{{ wirelesslans_table.rows|length }}</a>
<a href="{% url 'wireless:wirelesslan_list' %}?group_id={{ object.pk }}">{{ object.wirelesslans.count }}</a>
</td>
</tr>
</table>
</div>
</div>
{% include 'inc/panels/tags.html' %}
{% plugin_left_page object %}
</div>
<div class="col col-md-6">
{% include 'inc/panels/tags.html' %}
{% include 'inc/panels/custom_fields.html' %}
{% plugin_right_page object %}
</div>
@ -57,11 +57,11 @@
<div class="row mb-3">
<div class="col col-md-12">
<div class="card">
<div class="card-header">Wireless LANs</div>
<div class="card-body table-responsive">
{% render_table wirelesslans_table 'inc/table.html' %}
{% include 'inc/paginator.html' with paginator=wirelesslans_table.paginator page=wirelesslans_table.page %}
</div>
<h5 class="card-header">Wireless LANs</h5>
<div class="card-body htmx-container table-responsive"
hx-get="{% url 'wireless:wirelesslan_list' %}?group_id={{ object.pk }}"
hx-trigger="load"
></div>
</div>
{% plugin_full_width_page object %}
</div>

View File

@ -100,20 +100,6 @@ class ClusterGroupListView(generic.ObjectListView):
class ClusterGroupView(generic.ObjectView):
queryset = ClusterGroup.objects.all()
def get_extra_context(self, request, instance):
clusters = Cluster.objects.restrict(request.user, 'view').filter(
group=instance
).annotate(
device_count=count_related(Device, 'cluster'),
vm_count=count_related(VirtualMachine, 'cluster')
)
clusters_table = tables.ClusterTable(clusters, user=request.user, exclude=('group',))
clusters_table.configure(request)
return {
'clusters_table': clusters_table,
}
@register_model_view(ClusterGroup, 'edit')
class ClusterGroupEditView(generic.ObjectEditView):
@ -444,11 +430,6 @@ class VMInterfaceView(generic.ObjectView):
queryset = VMInterface.objects.all()
def get_extra_context(self, request, instance):
# Get assigned IP addresses
ipaddress_table = AssignedIPAddressesTable(
data=instance.ip_addresses.restrict(request.user, 'view'),
orderable=False
)
# Get child interfaces
child_interfaces = VMInterface.objects.restrict(request.user, 'view').filter(parent=instance)
@ -473,7 +454,6 @@ class VMInterfaceView(generic.ObjectView):
)
return {
'ipaddress_table': ipaddress_table,
'child_interfaces_table': child_interfaces_tables,
'vlan_table': vlan_table,
}

View File

@ -27,17 +27,6 @@ class WirelessLANGroupListView(generic.ObjectListView):
class WirelessLANGroupView(generic.ObjectView):
queryset = WirelessLANGroup.objects.all()
def get_extra_context(self, request, instance):
wirelesslans = WirelessLAN.objects.restrict(request.user, 'view').filter(
group=instance
)
wirelesslans_table = tables.WirelessLANTable(wirelesslans, user=request.user, exclude=('group',))
wirelesslans_table.configure(request)
return {
'wirelesslans_table': wirelesslans_table,
}
@register_model_view(WirelessLANGroup, 'edit')
class WirelessLANGroupEditView(generic.ObjectEditView):