diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py
index 34dbcbf30..624eb579b 100644
--- a/netbox/dcim/tables/devices.py
+++ b/netbox/dcim/tables/devices.py
@@ -64,9 +64,19 @@ def get_interface_state_attribute(record):
Get interface enabled state as string to attach to
DOM element.
"""
if record.enabled:
- return "enabled"
+ return 'enabled'
else:
- return "disabled"
+ return 'disabled'
+
+
+def get_interface_connected_attribute(record):
+ """
+ Get interface disconnected state as string to attach to
DOM element.
+ """
+ if record.mark_connected or record.cable:
+ return 'connected'
+ else:
+ return 'disconnected'
#
@@ -674,6 +684,7 @@ class DeviceInterfaceTable(InterfaceTable):
'data-name': lambda record: record.name,
'data-enabled': get_interface_state_attribute,
'data-type': lambda record: record.type,
+ 'data-connected': get_interface_connected_attribute
}
diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js
index 84bfecae3..ac5a68002 100644
Binary files a/netbox/project-static/dist/netbox.js and b/netbox/project-static/dist/netbox.js differ
diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map
index 7f2400ed2..7dbfeca7a 100644
Binary files a/netbox/project-static/dist/netbox.js.map and b/netbox/project-static/dist/netbox.js.map differ
diff --git a/netbox/project-static/src/tables/interfaceTable.ts b/netbox/project-static/src/tables/interfaceTable.ts
index 56a0ae754..70243cf41 100644
--- a/netbox/project-static/src/tables/interfaceTable.ts
+++ b/netbox/project-static/src/tables/interfaceTable.ts
@@ -141,9 +141,10 @@ class TableState {
private virtualButton: ButtonState;
/**
- * Underlying DOM Table Caption Element.
+ * Instance of ButtonState for the 'show/hide virtual rows' button.
*/
- private caption: Nullable = null;
+ // @ts-expect-error null handling is performed in the constructor
+ private disconnectedButton: ButtonState;
/**
* All table rows in table
@@ -166,9 +167,10 @@ class TableState {
this.table,
'button.toggle-virtual',
);
-
- const caption = this.table.querySelector('caption');
- this.caption = caption;
+ const toggleDisconnectedButton = findFirstAdjacent(
+ this.table,
+ 'button.toggle-disconnected',
+ );
if (toggleEnabledButton === null) {
throw new TableStateError("Table is missing a 'toggle-enabled' button.", table);
@@ -182,10 +184,15 @@ class TableState {
throw new TableStateError("Table is missing a 'toggle-virtual' button.", table);
}
+ if (toggleDisconnectedButton === null) {
+ throw new TableStateError("Table is missing a 'toggle-disconnected' button.", table);
+ }
+
// Attach event listeners to the buttons elements.
toggleEnabledButton.addEventListener('click', event => this.handleClick(event, this));
toggleDisabledButton.addEventListener('click', event => this.handleClick(event, this));
toggleVirtualButton.addEventListener('click', event => this.handleClick(event, this));
+ toggleDisconnectedButton.addEventListener('click', event => this.handleClick(event, this));
// Instantiate ButtonState for each button for state management.
this.enabledButton = new ButtonState(
@@ -200,6 +207,10 @@ class TableState {
toggleVirtualButton,
table.querySelectorAll('tr[data-type="virtual"]'),
);
+ this.disconnectedButton = new ButtonState(
+ toggleDisconnectedButton,
+ table.querySelectorAll('tr[data-connected="disconnected"]'),
+ );
} catch (err) {
if (err instanceof TableStateError) {
// This class is useless for tables that don't have toggle buttons.
@@ -211,52 +222,6 @@ class TableState {
}
}
- /**
- * Get the table caption's text.
- */
- private get captionText(): string {
- if (this.caption !== null) {
- return this.caption.innerText;
- }
- return '';
- }
-
- /**
- * Set the table caption's text.
- */
- private set captionText(value: string) {
- if (this.caption !== null) {
- this.caption.innerText = value;
- }
- }
-
- /**
- * Update the table caption's text based on the state of each toggle button.
- */
- private toggleCaption(): void {
- const showEnabled = this.enabledButton.buttonState === 'show';
- const showDisabled = this.disabledButton.buttonState === 'show';
- const showVirtual = this.virtualButton.buttonState === 'show';
-
- if (showEnabled && !showDisabled && !showVirtual) {
- this.captionText = 'Showing Enabled Interfaces';
- } else if (showEnabled && showDisabled && !showVirtual) {
- this.captionText = 'Showing Enabled & Disabled Interfaces';
- } else if (!showEnabled && showDisabled && !showVirtual) {
- this.captionText = 'Showing Disabled Interfaces';
- } else if (!showEnabled && !showDisabled && !showVirtual) {
- this.captionText = 'Hiding Enabled, Disabled & Virtual Interfaces';
- } else if (!showEnabled && !showDisabled && showVirtual) {
- this.captionText = 'Showing Virtual Interfaces';
- } else if (showEnabled && !showDisabled && showVirtual) {
- this.captionText = 'Showing Enabled & Virtual Interfaces';
- } else if (showEnabled && showDisabled && showVirtual) {
- this.captionText = 'Showing Enabled, Disabled & Virtual Interfaces';
- } else {
- this.captionText = '';
- }
- }
-
/**
* When toggle buttons are clicked, reapply visability all rows and
* pass the event to all button handlers
@@ -272,7 +237,7 @@ class TableState {
instance.enabledButton.handleClick(event);
instance.disabledButton.handleClick(event);
instance.virtualButton.handleClick(event);
- instance.toggleCaption();
+ instance.disconnectedButton.handleClick(event);
}
}
diff --git a/netbox/templates/dcim/device/inc/interface_table_controls.html b/netbox/templates/dcim/device/inc/interface_table_controls.html
index 36605cd25..7868d99db 100644
--- a/netbox/templates/dcim/device/inc/interface_table_controls.html
+++ b/netbox/templates/dcim/device/inc/interface_table_controls.html
@@ -9,5 +9,6 @@
+
{% endblock extra_table_controls %}