Compare commits

...

11 Commits

Author SHA1 Message Date
Per von Zweigbergk 8a0a9dcd83
Merge 8fadd6b744 into 4adb44f60d 2024-03-20 10:13:11 +01:00
Per von Zweigbergk 8fadd6b744 Merge branch 'develop' into choices-css-rewrite 2024-01-23 21:50:06 +01:00
Per von Zweigbergk c93413dc9c Move interface colour logic into SCSS where it belongs 2024-01-23 21:33:09 +01:00
Per von Zweigbergk bf362f4679 Hardcode cable status colours 2024-01-23 20:58:10 +01:00
Per von Zweigbergk da7f67c359 Refactor noisy getter methods into neat lambdas 2024-01-23 20:49:10 +01:00
Per von Zweigbergk c728d3c2e8 Fix formatting 2023-09-24 00:08:39 +02:00
Per von Zweigbergk 83e2c45e74 Simplify mark connected/installed implementation
Fixes: #13712 and #13806.
2023-09-23 23:45:08 +02:00
Per von Zweigbergk 27864ec865 Move DeviceInterfaceTable coloring logic into CSS
Preparatory work for simplifying toggle button code for cable status.
2023-09-23 23:07:16 +02:00
Per von Zweigbergk d44f67aea5 Add 15% alpha variants of --nbx-color
Preparatory work for factoring row styling out of Python
2023-09-23 23:01:08 +02:00
Per von Zweigbergk 41e1f24cf7 Add --nbx-color-* variables for theme colors
Preparatory work for moving row styling to CSS
2023-09-23 21:43:32 +02:00
Per von Zweigbergk d76ede17d3 Add data properties for device interface table
Preparatory work for factoring row styling decisions out of Python code.
2023-09-23 21:33:47 +02:00
9 changed files with 72 additions and 81 deletions

View File

@ -51,34 +51,6 @@ def get_cabletermination_row_class(record):
return ''
def get_interface_row_class(record):
if not record.enabled:
return 'danger'
elif record.is_virtual:
return 'primary'
return get_cabletermination_row_class(record)
def get_interface_state_attribute(record):
"""
Get interface enabled state as string to attach to <tr/> DOM element.
"""
if record.enabled:
return 'enabled'
else:
return 'disabled'
def get_interface_connected_attribute(record):
"""
Get interface disconnected state as string to attach to <tr/> DOM element.
"""
if record.mark_connected or record.cable:
return 'connected'
else:
return 'disconnected'
#
# Device roles
#
@ -706,11 +678,12 @@ class DeviceInterfaceTable(InterfaceTable):
'cable', 'connection',
)
row_attrs = {
'class': get_interface_row_class,
'data-name': lambda record: record.name,
'data-enabled': get_interface_state_attribute,
'data-type': lambda record: record.type,
'data-connected': get_interface_connected_attribute
'data-enabled': lambda record: "enabled" if record.enabled else "disabled",
'data-virtual': lambda record: "true" if record.is_virtual else "false",
'data-mark-connected': lambda record: "true" if record.mark_connected else "false",
'data-cable-status': lambda record: record.cable.status if record.cable else "",
'data-type': lambda record: record.type
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -7,10 +7,10 @@ import { isTruthy, apiPatch, hasError, getElements } from '../util';
*
* @param element Connection Toggle Button Element
*/
function toggleConnection(element: HTMLButtonElement): void {
function setConnectionStatus(element: HTMLButtonElement, status: string): void {
// Get the button's row to change its data-cable-status attribute
const row = element.parentElement?.parentElement as HTMLTableRowElement;
const url = element.getAttribute('data-url');
const connected = element.classList.contains('connected');
const status = connected ? 'planned' : 'connected';
if (isTruthy(url)) {
apiPatch(url, { status }).then(res => {
@ -19,34 +19,18 @@ function toggleConnection(element: HTMLButtonElement): void {
createToast('danger', 'Error', res.error).show();
return;
} else {
// Get the button's row to change its styles.
const row = element.parentElement?.parentElement as HTMLTableRowElement;
// Get the button's icon to change its CSS class.
const icon = element.querySelector('i.mdi, span.mdi') as HTMLSpanElement;
if (connected) {
row.classList.remove('success');
row.classList.add('info');
element.classList.remove('connected', 'btn-warning');
element.classList.add('btn-info');
element.title = 'Mark Installed';
icon.classList.remove('mdi-lan-disconnect');
icon.classList.add('mdi-lan-connect');
} else {
row.classList.remove('info');
row.classList.add('success');
element.classList.remove('btn-success');
element.classList.add('connected', 'btn-warning');
element.title = 'Mark Installed';
icon.classList.remove('mdi-lan-connect');
icon.classList.add('mdi-lan-disconnect');
}
// Update cable status in DOM
row.setAttribute('data-cable-status', status);
}
});
}
}
export function initConnectionToggle(): void {
for (const element of getElements<HTMLButtonElement>('button.cable-toggle')) {
element.addEventListener('click', () => toggleConnection(element));
for (const element of getElements<HTMLButtonElement>('button.mark-planned')) {
element.addEventListener('click', () => setConnectionStatus(element, 'planned'));
}
for (const element of getElements<HTMLButtonElement>('button.mark-installed')) {
element.addEventListener('click', () => setConnectionStatus(element, 'connected'));
}
}

View File

@ -1075,4 +1075,41 @@ html {
display: none;
}
}
}
// Apply row colours to interface lists
&[data-netbox-url-name='device_interfaces'] {
tr[data-cable-status=connected] {
background-color: rgba(map.get($theme-colors, "green"), 0.15);
}
tr[data-cable-status=planned] {
background-color: rgba(map.get($theme-colors, "blue"), 0.15);
}
tr[data-cable-status=decommissioning] {
background-color: rgba(map.get($theme-colors, "yellow"), 0.15);
}
tr[data-mark-connected=true] {
background-color: rgba(map.get($theme-colors, "success"), 0.15);
}
tr[data-virtual=true] {
background-color: rgba(map.get($theme-colors, "primary"), 0.15);
}
tr[data-enabled=disabled] {
background-color: rgba(map.get($theme-colors, "danger"), 0.15);
}
// Only show the correct button depending on the cable status
tr[data-cable-status=connected] button.mark-installed {
display: none;
}
tr:not([data-cable-status=connected]) button.mark-planned {
display: none;
}
}
}

View File

@ -1,12 +1,9 @@
{% load i18n %}
{% if perms.dcim.change_cable %}
{% if cable.status == 'connected' %}
<button type="button" class="btn btn-warning btn-sm cable-toggle connected" title="{% trans "Mark Planned" %}" data-url="{% url 'dcim-api:cable-detail' pk=cable.pk %}">
<i class="mdi mdi-lan-disconnect" aria-hidden="true"></i>
</button>
{% else %}
<button type="button" class="btn btn-info btn-sm cable-toggle" title="{% trans "Mark Installed" %}" data-url="{% url 'dcim-api:cable-detail' pk=cable.pk %}">
<i class="mdi mdi-lan-connect" aria-hidden="true"></i>
</button>
{% endif %}
<button type="button" class="btn btn-warning btn-sm mark-planned" title="{% trans "Mark Planned" %}" data-url="{% url 'dcim-api:cable-detail' pk=cable.pk %}">
<i class="mdi mdi-lan-disconnect" aria-hidden="true"></i>
</button>
<button type="button" class="btn btn-info btn-sm mark-installed" title="{% trans "Mark Installed" %}" data-url="{% url 'dcim-api:cable-detail' pk=cable.pk %}">
<i class="mdi mdi-lan-connect" aria-hidden="true"></i>
</button>
{% endif %}