From 58f7eb319faad9f135afbd86e060eb2e2ebf574e Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 6 Jan 2022 16:53:24 -0500 Subject: [PATCH] Initial work on #7679 --- netbox/circuits/tables.py | 4 +-- netbox/dcim/tables/devices.py | 8 +++--- netbox/dcim/tables/devicetypes.py | 5 ++-- netbox/dcim/tables/racks.py | 6 ++-- netbox/dcim/tables/sites.py | 7 +++-- netbox/extras/tables.py | 8 ++---- netbox/ipam/tables/fhrp.py | 7 ++--- netbox/ipam/tables/ip.py | 14 ++++----- netbox/ipam/tables/vlans.py | 12 +++++--- netbox/tenancy/tables.py | 13 ++++----- netbox/utilities/tables.py | 48 +++++++++++++++++++++++++++++++ netbox/virtualization/tables.py | 8 +++--- netbox/wireless/tables.py | 4 +-- 13 files changed, 96 insertions(+), 48 deletions(-) diff --git a/netbox/circuits/tables.py b/netbox/circuits/tables.py index 32c40f269..59ef073d3 100644 --- a/netbox/circuits/tables.py +++ b/netbox/circuits/tables.py @@ -2,7 +2,7 @@ import django_tables2 as tables from django_tables2.utils import Accessor from tenancy.tables import TenantColumn -from utilities.tables import BaseTable, ButtonsColumn, ChoiceFieldColumn, MarkdownColumn, TagColumn, ToggleColumn +from utilities.tables import ActionsColumn, BaseTable, ChoiceFieldColumn, MarkdownColumn, TagColumn, ToggleColumn from .models import * @@ -88,7 +88,7 @@ class CircuitTypeTable(BaseTable): circuit_count = tables.Column( verbose_name='Circuits' ) - actions = ButtonsColumn(CircuitType) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = CircuitType diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index 0c3a5f6a1..21da569a7 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -7,7 +7,7 @@ from dcim.models import ( ) from tenancy.tables import TenantColumn from utilities.tables import ( - BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, + ActionsColumn, BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, MarkdownColumn, TagColumn, TemplateColumn, ToggleColumn, ) from .template_code import * @@ -94,7 +94,7 @@ class DeviceRoleTable(BaseTable): tags = TagColumn( url_name='dcim:devicerole_list' ) - actions = ButtonsColumn(DeviceRole) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = DeviceRole @@ -127,7 +127,7 @@ class PlatformTable(BaseTable): tags = TagColumn( url_name='dcim:platform_list' ) - actions = ButtonsColumn(Platform) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = Platform @@ -839,7 +839,7 @@ class InventoryItemRoleTable(BaseTable): tags = TagColumn( url_name='dcim:inventoryitemrole_list' ) - actions = ButtonsColumn(InventoryItemRole) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = InventoryItemRole diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py index 525c69030..df27a366f 100644 --- a/netbox/dcim/tables/devicetypes.py +++ b/netbox/dcim/tables/devicetypes.py @@ -6,7 +6,8 @@ from dcim.models import ( InventoryItemTemplate, Manufacturer, ModuleBayTemplate, PowerOutletTemplate, PowerPortTemplate, RearPortTemplate, ) from utilities.tables import ( - BaseTable, BooleanColumn, ButtonsColumn, ColorColumn, LinkedCountColumn, MarkdownColumn, TagColumn, ToggleColumn, + ActionsColumn, BaseTable, BooleanColumn, ButtonsColumn, ColorColumn, LinkedCountColumn, MarkdownColumn, TagColumn, + ToggleColumn, ) from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS @@ -48,7 +49,7 @@ class ManufacturerTable(BaseTable): tags = TagColumn( url_name='dcim:manufacturer_list' ) - actions = ButtonsColumn(Manufacturer) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = Manufacturer diff --git a/netbox/dcim/tables/racks.py b/netbox/dcim/tables/racks.py index 14bbe3589..27ddb6f31 100644 --- a/netbox/dcim/tables/racks.py +++ b/netbox/dcim/tables/racks.py @@ -4,7 +4,7 @@ from django_tables2.utils import Accessor from dcim.models import Rack, RackReservation, RackRole from tenancy.tables import TenantColumn from utilities.tables import ( - BaseTable, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, MarkdownColumn, + ActionsColumn, BaseTable, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, MarkdownColumn, TagColumn, ToggleColumn, UtilizationColumn, ) @@ -27,7 +27,7 @@ class RackRoleTable(BaseTable): tags = TagColumn( url_name='dcim:rackrole_list' ) - actions = ButtonsColumn(RackRole) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = RackRole @@ -121,7 +121,7 @@ class RackReservationTable(BaseTable): tags = TagColumn( url_name='dcim:rackreservation_list' ) - actions = ButtonsColumn(RackReservation) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = RackReservation diff --git a/netbox/dcim/tables/sites.py b/netbox/dcim/tables/sites.py index ceca41c86..5b39e31eb 100644 --- a/netbox/dcim/tables/sites.py +++ b/netbox/dcim/tables/sites.py @@ -3,7 +3,8 @@ import django_tables2 as tables from dcim.models import Location, Region, Site, SiteGroup from tenancy.tables import TenantColumn from utilities.tables import ( - BaseTable, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, MarkdownColumn, MPTTColumn, TagColumn, ToggleColumn, + ActionsColumn, BaseTable, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, MarkdownColumn, MPTTColumn, + TagColumn, ToggleColumn, ) from .template_code import LOCATION_ELEVATIONS @@ -32,7 +33,7 @@ class RegionTable(BaseTable): tags = TagColumn( url_name='dcim:region_list' ) - actions = ButtonsColumn(Region) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = Region @@ -57,7 +58,7 @@ class SiteGroupTable(BaseTable): tags = TagColumn( url_name='dcim:sitegroup_list' ) - actions = ButtonsColumn(SiteGroup) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = SiteGroup diff --git a/netbox/extras/tables.py b/netbox/extras/tables.py index 62317e636..defef465f 100644 --- a/netbox/extras/tables.py +++ b/netbox/extras/tables.py @@ -2,7 +2,7 @@ import django_tables2 as tables from django.conf import settings from utilities.tables import ( - BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ContentTypeColumn, ContentTypesColumn, + ActionsColumn, BaseTable, BooleanColumn, ChoiceFieldColumn, ColorColumn, ContentTypeColumn, ContentTypesColumn, MarkdownColumn, ToggleColumn, ) from .models import * @@ -152,7 +152,7 @@ class TagTable(BaseTable): linkify=True ) color = ColorColumn() - actions = ButtonsColumn(Tag) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = Tag @@ -233,9 +233,7 @@ class ObjectJournalTable(BaseTable): comments = tables.TemplateColumn( template_code='{% load helpers %}{{ value|render_markdown|truncatewords_html:50 }}' ) - actions = ButtonsColumn( - model=JournalEntry - ) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = JournalEntry diff --git a/netbox/ipam/tables/fhrp.py b/netbox/ipam/tables/fhrp.py index 94bc50b93..ce472cb1a 100644 --- a/netbox/ipam/tables/fhrp.py +++ b/netbox/ipam/tables/fhrp.py @@ -1,6 +1,6 @@ import django_tables2 as tables -from utilities.tables import BaseTable, ButtonsColumn, MarkdownColumn, TagColumn, ToggleColumn +from utilities.tables import ActionsColumn, BaseTable, MarkdownColumn, TagColumn, ToggleColumn from ipam.models import * __all__ = ( @@ -58,9 +58,8 @@ class FHRPGroupAssignmentTable(BaseTable): group = tables.Column( linkify=True ) - actions = ButtonsColumn( - model=FHRPGroupAssignment, - buttons=('edit', 'delete', 'foo') + actions = ActionsColumn( + actions=('edit', 'delete') ) class Meta(BaseTable.Meta): diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py index 3fddbf48e..cf81fe722 100644 --- a/netbox/ipam/tables/ip.py +++ b/netbox/ipam/tables/ip.py @@ -4,8 +4,8 @@ from django_tables2.utils import Accessor from tenancy.tables import TenantColumn from utilities.tables import ( - BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, TagColumn, - ToggleColumn, UtilizationColumn, + ActionsColumn, BaseTable, BooleanColumn, ChoiceFieldColumn, LinkedCountColumn, TagColumn, ToggleColumn, + UtilizationColumn, ) from ipam.models import * @@ -89,7 +89,7 @@ class RIRTable(BaseTable): tags = TagColumn( url_name='ipam:rir_list' ) - actions = ButtonsColumn(RIR) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = RIR @@ -111,7 +111,7 @@ class ASNTable(BaseTable): url_params={'asn_id': 'pk'}, verbose_name='Sites' ) - actions = ButtonsColumn(ASN) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = ASN @@ -173,7 +173,7 @@ class RoleTable(BaseTable): tags = TagColumn( url_name='ipam:role_list' ) - actions = ButtonsColumn(Role) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = Role @@ -405,9 +405,7 @@ class AssignedIPAddressesTable(BaseTable): ) status = ChoiceFieldColumn() tenant = TenantColumn() - actions = ButtonsColumn( - model=IPAddress - ) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = IPAddress diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index ca8d22552..f1a67c698 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -5,8 +5,8 @@ from django_tables2.utils import Accessor from dcim.models import Interface from tenancy.tables import TenantColumn from utilities.tables import ( - BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ContentTypeColumn, LinkedCountColumn, TagColumn, - TemplateColumn, ToggleColumn, + ActionsColumn, BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ContentTypeColumn, LinkedCountColumn, + TagColumn, TemplateColumn, ToggleColumn, ) from virtualization.models import VMInterface from ipam.models import * @@ -153,7 +153,9 @@ class VLANDevicesTable(VLANMembersTable): device = tables.Column( linkify=True ) - actions = ButtonsColumn(Interface, buttons=['edit']) + actions = ActionsColumn( + actions=('edit',) + ) class Meta(BaseTable.Meta): model = Interface @@ -165,7 +167,9 @@ class VLANVirtualMachinesTable(VLANMembersTable): virtual_machine = tables.Column( linkify=True ) - actions = ButtonsColumn(VMInterface, buttons=['edit']) + actions = ActionsColumn( + actions=('edit',) + ) class Meta(BaseTable.Meta): model = VMInterface diff --git a/netbox/tenancy/tables.py b/netbox/tenancy/tables.py index 0ae1139bf..b74b52528 100644 --- a/netbox/tenancy/tables.py +++ b/netbox/tenancy/tables.py @@ -1,7 +1,7 @@ import django_tables2 as tables from utilities.tables import ( - BaseTable, ButtonsColumn, ContentTypeColumn, LinkedCountColumn, linkify_phone, MarkdownColumn, MPTTColumn, + ActionsColumn, BaseTable, ContentTypeColumn, LinkedCountColumn, linkify_phone, MarkdownColumn, MPTTColumn, TagColumn, ToggleColumn, ) from .models import * @@ -59,7 +59,7 @@ class TenantGroupTable(BaseTable): tags = TagColumn( url_name='tenancy:tenantgroup_list' ) - actions = ButtonsColumn(TenantGroup) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = TenantGroup @@ -103,7 +103,7 @@ class ContactGroupTable(BaseTable): tags = TagColumn( url_name='tenancy:contactgroup_list' ) - actions = ButtonsColumn(ContactGroup) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = ContactGroup @@ -116,7 +116,7 @@ class ContactRoleTable(BaseTable): name = tables.Column( linkify=True ) - actions = ButtonsColumn(ContactRole) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = ContactRole @@ -164,9 +164,8 @@ class ContactAssignmentTable(BaseTable): role = tables.Column( linkify=True ) - actions = ButtonsColumn( - model=ContactAssignment, - buttons=('edit', 'delete') + actions = ActionsColumn( + actions=('edit', 'delete') ) class Meta(BaseTable.Meta): diff --git a/netbox/utilities/tables.py b/netbox/utilities/tables.py index 9000af110..15cbb77c8 100644 --- a/netbox/utilities/tables.py +++ b/netbox/utilities/tables.py @@ -1,3 +1,5 @@ +from collections import namedtuple + import django_tables2 as tables from django.conf import settings from django.contrib.auth.models import AnonymousUser @@ -205,6 +207,52 @@ class TemplateColumn(tables.TemplateColumn): return ret +ActionsMenuItem = namedtuple('ActionsMenuItem', ['title', 'icon']) + + +class ActionsColumn(tables.Column): + attrs = {'td': {'class': 'text-end noprint'}} + empty_values = () + _actions = { + 'edit': ActionsMenuItem('Edit', 'pencil'), + 'delete': ActionsMenuItem('Delete', 'trash-can-outline'), + 'changelog': ActionsMenuItem('Changelog', 'history'), + } + + def __init__(self, *args, actions=('edit', 'delete', 'changelog'), **kwargs): + super().__init__(*args, **kwargs) + + # Determine which actions to enable + self.actions = { + name: self._actions[name] for name in actions + } + + def header(self): + return '' + + def render(self, record, table, **kwargs): + if not self.actions: + return '' + + model = table.Meta.model + viewname_base = f'{model._meta.app_label}:{model._meta.model_name}' + request = getattr(table, 'context', {}).get('request') + url_appendix = f'?return_url={request.path}' if request else '' + + menu = '' + + return mark_safe(menu) + + class ButtonsColumn(tables.TemplateColumn): """ Render edit, delete, and changelog buttons for an object. diff --git a/netbox/virtualization/tables.py b/netbox/virtualization/tables.py index 818b09d33..f04d2825e 100644 --- a/netbox/virtualization/tables.py +++ b/netbox/virtualization/tables.py @@ -2,8 +2,8 @@ import django_tables2 as tables from dcim.tables.devices import BaseInterfaceTable from tenancy.tables import TenantColumn from utilities.tables import ( - BaseTable, ButtonsColumn, ChoiceFieldColumn, ColoredLabelColumn, LinkedCountColumn, MarkdownColumn, TagColumn, - ToggleColumn, + ActionsColumn, BaseTable, ButtonsColumn, ChoiceFieldColumn, ColoredLabelColumn, LinkedCountColumn, MarkdownColumn, + TagColumn, ToggleColumn, ) from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface @@ -40,7 +40,7 @@ class ClusterTypeTable(BaseTable): tags = TagColumn( url_name='virtualization:clustertype_list' ) - actions = ButtonsColumn(ClusterType) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = ClusterType @@ -63,7 +63,7 @@ class ClusterGroupTable(BaseTable): tags = TagColumn( url_name='virtualization:clustergroup_list' ) - actions = ButtonsColumn(ClusterGroup) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = ClusterGroup diff --git a/netbox/wireless/tables.py b/netbox/wireless/tables.py index 4f47ee7f9..b16b31db8 100644 --- a/netbox/wireless/tables.py +++ b/netbox/wireless/tables.py @@ -2,7 +2,7 @@ import django_tables2 as tables from dcim.models import Interface from utilities.tables import ( - BaseTable, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, MPTTColumn, TagColumn, ToggleColumn, + ActionsColumn, BaseTable, ChoiceFieldColumn, LinkedCountColumn, MPTTColumn, TagColumn, ToggleColumn, ) from .models import * @@ -26,7 +26,7 @@ class WirelessLANGroupTable(BaseTable): tags = TagColumn( url_name='wireless:wirelesslangroup_list' ) - actions = ButtonsColumn(WirelessLANGroup) + actions = ActionsColumn() class Meta(BaseTable.Meta): model = WirelessLANGroup