Closes #16933: Enable toggling true/false marks on BooleanColumn

This commit is contained in:
Jeremy Stretch 2024-07-18 12:10:55 -04:00
parent 3028f262cc
commit 424dda5be6
8 changed files with 53 additions and 19 deletions

View File

@ -19,6 +19,7 @@ REVISION_BUTTONS = """
class ConfigRevisionTable(NetBoxTable): class ConfigRevisionTable(NetBoxTable):
is_active = columns.BooleanColumn( is_active = columns.BooleanColumn(
verbose_name=_('Is Active'), verbose_name=_('Is Active'),
false_mark=None
) )
actions = columns.ActionsColumn( actions = columns.ActionsColumn(
actions=('delete',), actions=('delete',),

View File

@ -63,7 +63,10 @@ class DeviceRoleTable(NetBoxTable):
verbose_name=_('VMs') verbose_name=_('VMs')
) )
color = columns.ColorColumn() color = columns.ColorColumn()
vm_role = columns.BooleanColumn() vm_role = columns.BooleanColumn(
verbose_name=_('VM role'),
false_mark=None
)
config_template = tables.Column( config_template = tables.Column(
linkify=True linkify=True
) )
@ -329,6 +332,7 @@ class CableTerminationTable(NetBoxTable):
) )
mark_connected = columns.BooleanColumn( mark_connected = columns.BooleanColumn(
verbose_name=_('Mark Connected'), verbose_name=_('Mark Connected'),
false_mark=None
) )
class Meta: class Meta:
@ -586,7 +590,8 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
} }
) )
mgmt_only = columns.BooleanColumn( mgmt_only = columns.BooleanColumn(
verbose_name=_('Management Only') verbose_name=_('Management Only'),
false_mark=None
) )
speed_formatted = columns.TemplateColumn( speed_formatted = columns.TemplateColumn(
template_code='{% load helpers %}{{ value|humanize_speed }}', template_code='{% load helpers %}{{ value|humanize_speed }}',
@ -913,6 +918,7 @@ class InventoryItemTable(DeviceComponentTable):
) )
discovered = columns.BooleanColumn( discovered = columns.BooleanColumn(
verbose_name=_('Discovered'), verbose_name=_('Discovered'),
false_mark=None
) )
parent = tables.Column( parent = tables.Column(
linkify=True, linkify=True,

View File

@ -86,7 +86,8 @@ class DeviceTypeTable(NetBoxTable):
linkify=True linkify=True
) )
is_full_depth = columns.BooleanColumn( is_full_depth = columns.BooleanColumn(
verbose_name=_('Full Depth') verbose_name=_('Full Depth'),
false_mark=None
) )
comments = columns.MarkdownColumn( comments = columns.MarkdownColumn(
verbose_name=_('Comments'), verbose_name=_('Comments'),
@ -98,7 +99,10 @@ class DeviceTypeTable(NetBoxTable):
verbose_name=_('U Height'), verbose_name=_('U Height'),
template_code='{{ value|floatformat }}' template_code='{{ value|floatformat }}'
) )
exclude_from_utilization = columns.BooleanColumn() exclude_from_utilization = columns.BooleanColumn(
verbose_name=_('Exclude from utilization'),
false_mark=None
)
weight = columns.TemplateColumn( weight = columns.TemplateColumn(
verbose_name=_('Weight'), verbose_name=_('Weight'),
template_code=WEIGHT, template_code=WEIGHT,
@ -221,7 +225,8 @@ class InterfaceTemplateTable(ComponentTemplateTable):
verbose_name=_('Enabled'), verbose_name=_('Enabled'),
) )
mgmt_only = columns.BooleanColumn( mgmt_only = columns.BooleanColumn(
verbose_name=_('Management Only') verbose_name=_('Management Only'),
false_mark=None
) )
actions = columns.ActionsColumn( actions = columns.ActionsColumn(
actions=('edit', 'delete'), actions=('edit', 'delete'),

View File

@ -47,7 +47,8 @@ class CustomFieldTable(NetBoxTable):
verbose_name=_('Object Types') verbose_name=_('Object Types')
) )
required = columns.BooleanColumn( required = columns.BooleanColumn(
verbose_name=_('Required') verbose_name=_('Required'),
false_mark=None
) )
ui_visible = columns.ChoiceFieldColumn( ui_visible = columns.ChoiceFieldColumn(
verbose_name=_('Visible') verbose_name=_('Visible')
@ -72,6 +73,7 @@ class CustomFieldTable(NetBoxTable):
) )
is_cloneable = columns.BooleanColumn( is_cloneable = columns.BooleanColumn(
verbose_name=_('Is Cloneable'), verbose_name=_('Is Cloneable'),
false_mark=None
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
@ -105,6 +107,7 @@ class CustomFieldChoiceSetTable(NetBoxTable):
) )
order_alphabetically = columns.BooleanColumn( order_alphabetically = columns.BooleanColumn(
verbose_name=_('Order Alphabetically'), verbose_name=_('Order Alphabetically'),
false_mark=None
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
@ -129,6 +132,7 @@ class CustomLinkTable(NetBoxTable):
) )
new_window = columns.BooleanColumn( new_window = columns.BooleanColumn(
verbose_name=_('New Window'), verbose_name=_('New Window'),
false_mark=None
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
@ -150,6 +154,7 @@ class ExportTemplateTable(NetBoxTable):
) )
as_attachment = columns.BooleanColumn( as_attachment = columns.BooleanColumn(
verbose_name=_('As Attachment'), verbose_name=_('As Attachment'),
false_mark=None
) )
data_source = tables.Column( data_source = tables.Column(
verbose_name=_('Data Source'), verbose_name=_('Data Source'),
@ -218,6 +223,7 @@ class SavedFilterTable(NetBoxTable):
) )
shared = columns.BooleanColumn( shared = columns.BooleanColumn(
verbose_name=_('Shared'), verbose_name=_('Shared'),
false_mark=None
) )
def value_parameters(self, value): def value_parameters(self, value):

View File

@ -86,7 +86,8 @@ class RIRTable(NetBoxTable):
linkify=True linkify=True
) )
is_private = columns.BooleanColumn( is_private = columns.BooleanColumn(
verbose_name=_('Private') verbose_name=_('Private'),
false_mark=None
) )
aggregate_count = columns.LinkedCountColumn( aggregate_count = columns.LinkedCountColumn(
viewname='ipam:aggregate_list', viewname='ipam:aggregate_list',
@ -258,10 +259,12 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
linkify=True linkify=True
) )
is_pool = columns.BooleanColumn( is_pool = columns.BooleanColumn(
verbose_name=_('Pool') verbose_name=_('Pool'),
false_mark=None
) )
mark_utilized = columns.BooleanColumn( mark_utilized = columns.BooleanColumn(
verbose_name=_('Marked Utilized') verbose_name=_('Marked Utilized'),
false_mark=None
) )
utilization = PrefixUtilizationColumn( utilization = PrefixUtilizationColumn(
verbose_name=_('Utilization'), verbose_name=_('Utilization'),
@ -314,7 +317,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
linkify=True linkify=True
) )
mark_utilized = columns.BooleanColumn( mark_utilized = columns.BooleanColumn(
verbose_name=_('Marked Utilized') verbose_name=_('Marked Utilized'),
false_mark=None
) )
utilization = columns.UtilizationColumn( utilization = columns.UtilizationColumn(
verbose_name=_('Utilization'), verbose_name=_('Utilization'),
@ -386,7 +390,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
assigned = columns.BooleanColumn( assigned = columns.BooleanColumn(
accessor='assigned_object_id', accessor='assigned_object_id',
linkify=lambda record: record.assigned_object.get_absolute_url(), linkify=lambda record: record.assigned_object.get_absolute_url(),
verbose_name=_('Assigned') verbose_name=_('Assigned'),
false_mark=None
) )
comments = columns.MarkdownColumn( comments = columns.MarkdownColumn(
verbose_name=_('Comments'), verbose_name=_('Comments'),

View File

@ -211,6 +211,7 @@ class InterfaceVLANTable(NetBoxTable):
) )
tagged = columns.BooleanColumn( tagged = columns.BooleanColumn(
verbose_name=_('Tagged'), verbose_name=_('Tagged'),
false_mark=None
) )
site = tables.Column( site = tables.Column(
verbose_name=_('Site'), verbose_name=_('Site'),

View File

@ -30,7 +30,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
verbose_name=_('RD') verbose_name=_('RD')
) )
enforce_unique = columns.BooleanColumn( enforce_unique = columns.BooleanColumn(
verbose_name=_('Unique') verbose_name=_('Unique'),
false_mark=None
) )
import_targets = columns.TemplateColumn( import_targets = columns.TemplateColumn(
verbose_name=_('Import Targets'), verbose_name=_('Import Targets'),

View File

@ -194,14 +194,23 @@ class BooleanColumn(tables.Column):
Custom implementation of BooleanColumn to render a nicely-formatted checkmark or X icon instead of a Unicode Custom implementation of BooleanColumn to render a nicely-formatted checkmark or X icon instead of a Unicode
character. character.
""" """
TRUE_MARK = mark_safe('<span class="text-success"><i class="mdi mdi-check-bold"></i></span>')
FALSE_MARK = mark_safe('<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>')
EMPTY_MARK = mark_safe('<span class="text-muted">&mdash;</span>') # Placeholder
def __init__(self, *args, true_mark=TRUE_MARK, false_mark=FALSE_MARK, **kwargs):
self.true_mark = true_mark
self.false_mark = false_mark
super().__init__(*args, **kwargs)
def render(self, value): def render(self, value):
if value: if value is None:
rendered = '<span class="text-success"><i class="mdi mdi-check-bold"></i></span>' return self.EMPTY_MARK
elif value is None: if value and self.true_mark:
rendered = '<span class="text-muted">&mdash;</span>' return self.true_mark
else: if not value and self.false_mark:
rendered = '<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>' return self.false_mark
return mark_safe(rendered) return self.EMPTY_MARK
def value(self, value): def value(self, value):
return str(value) return str(value)