import django_tables2 as tables from django.utils.html import escape, format_html from django.utils.safestring import mark_safe from netbox.tables.columns import ToggleColumn from utilities.paginator import EnhancedPaginator from netbox_librenms_plugin.utils import ( get_table_paginate_count, get_virtual_chassis_member, ) class LibreNMSCableTable(tables.Table): """ Table for displaying LibreNMS cable data. """ selection = ToggleColumn( accessor="local_port_id", orderable=False, visible=True, attrs={"td": {"data-col": "selection"}, "input": {"name": "select"}}, ) local_port = tables.Column(verbose_name="Local Port", attrs={"td": {"data-col": "local_port"}}) remote_port = tables.Column( accessor="remote_port_name", verbose_name="Remote Port", attrs={"td": {"data-col": "remote_port"}}, ) remote_device = tables.Column(verbose_name="Remote Device", attrs={"td": {"data-col": "remote_device"}}) cable_status = tables.Column(verbose_name="Cable Status", attrs={"td": {"data-col": "cable_status"}}) actions = tables.TemplateColumn( template_code=""" {% if record.can_create_cable %} {% endif %} """, verbose_name="", orderable=False, attrs={"td": {"data-col": "actions"}}, ) def __init__(self, *args, device=None, **kwargs): """Initialize table with optional device context.""" self.device = device super().__init__(*args, **kwargs) self.tab = "cables" self.htmx_url = None self.prefix = "cables_" def render_remote_device(self, value, record): """Render remote device name as a link if URL is available.""" if url := record.get("remote_device_url"): return format_html('{}', url, value) return value def render_local_port(self, value, record): """Render local port name as a link if URL is available.""" if url := record.get("local_port_url"): return format_html('{}', url, value) return value def render_remote_port(self, value, record): """Render remote port name as a link if URL is available.""" if url := record.get("remote_port_url"): return format_html('{}', url, value) return value def render_cable_status(self, value, record): """Render cable status as a link if cable URL is available.""" if url := record.get("cable_url"): return format_html('{}', url, value) return value def configure(self, request): """Configure pagination for the table using the current request.""" paginate = { "paginator_class": EnhancedPaginator, "per_page": get_table_paginate_count(request, self.prefix), } tables.RequestConfig(request, paginate).configure(self) class Meta: """Define column sequence, row attributes, and table styling.""" sequence = [ "selection", "local_port", "remote_port", "remote_device", "cable_status", "actions", ] row_attrs = { "data-interface": lambda record: record["local_port_id"], "data-device": lambda record: record["device_id"], "data-name": lambda record: record["local_port"], } attrs = {"class": "table table-hover object-list", "id": "librenms-cable-table"} class VCCableTable(LibreNMSCableTable): """ Table for displaying LibreNMS cable data for Virtual Chassis devices. """ device_selection = tables.Column( verbose_name="Virtual Chassis Member", accessor="local_port_id", attrs={"td": {"class": "device-selection-col", "data-col": "device_selection"}}, ) def __init__(self, *args, device=None, **kwargs): """Initialize the VC cable table with device context.""" super().__init__(*args, device=device, **kwargs) def render_device_selection(self, value, record): """Render a dropdown to select the virtual chassis member for a port.""" members = self.device.virtual_chassis.members.all() chassis_member = get_virtual_chassis_member(self.device, record["local_port"]) selected_member_id = chassis_member.id if chassis_member else self.device.id port_id = record["local_port_id"] options = [ f'' for member in members ] return format_html( '', port_id, mark_safe("".join(options)), ) class Meta(LibreNMSCableTable.Meta): """Define column sequence and attributes for the VC cable table.""" sequence = [ "selection", "device_selection", "local_port", "remote_port", "remote_device", "cable_status", "actions", ] row_attrs = { "data-interface": lambda record: record["local_port_id"], "data-device": lambda record: record["device_id"], "data-name": lambda record: record["local_port"], "id": lambda record: record["local_port_id"], } attrs = { "class": "table table-hover object-list", "id": "librenms-cable-table-vc", }