Merge branch 'develop' into feature
This commit is contained in:
commit
51bd98bdfc
|
@ -26,7 +26,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: NetBox Version
|
label: NetBox Version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v3.7.7
|
placeholder: v3.7.8
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
|
|
@ -14,7 +14,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v3.7.7
|
placeholder: v3.7.8
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
|
|
@ -1,5 +1,22 @@
|
||||||
# NetBox v3.7
|
# NetBox v3.7
|
||||||
|
|
||||||
|
## v3.7.8 (2024-05-06)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* [#12127](https://github.com/netbox-community/netbox/issues/12127) - Enable adding new cables directly from navigation menu
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* [#15877](https://github.com/netbox-community/netbox/issues/15877) - Account for virtual chassis membership when assigning related interfaces via bulk edit
|
||||||
|
* [#15917](https://github.com/netbox-community/netbox/issues/15917) - Fix pagination through search results within dropdown fields
|
||||||
|
* [#15925](https://github.com/netbox-community/netbox/issues/15925) - Fix SVG rendering of cable traces to circuit terminations
|
||||||
|
* [#15948](https://github.com/netbox-community/netbox/issues/15948) - Fix cable trace SVG generation for cables with multiple terminations at both ends
|
||||||
|
* [#15960](https://github.com/netbox-community/netbox/issues/15960) - Replace CSV export formatting for several many-to-many fields
|
||||||
|
* [#15961](https://github.com/netbox-community/netbox/issues/15961) - Fix secret toggle button for IKE policies
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v3.7.7 (2024-05-01)
|
## v3.7.7 (2024-05-01)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
|
@ -1420,9 +1420,9 @@ class InterfaceBulkEditForm(
|
||||||
device = Device.objects.filter(pk=self.initial['device']).first()
|
device = Device.objects.filter(pk=self.initial['device']).first()
|
||||||
|
|
||||||
# Restrict parent/bridge/LAG interface assignment by device
|
# Restrict parent/bridge/LAG interface assignment by device
|
||||||
self.fields['parent'].widget.add_query_param('device_id', device.pk)
|
self.fields['parent'].widget.add_query_param('virtual_chassis_member_id', device.pk)
|
||||||
self.fields['bridge'].widget.add_query_param('device_id', device.pk)
|
self.fields['bridge'].widget.add_query_param('virtual_chassis_member_id', device.pk)
|
||||||
self.fields['lag'].widget.add_query_param('device_id', device.pk)
|
self.fields['lag'].widget.add_query_param('virtual_chassis_member_id', device.pk)
|
||||||
|
|
||||||
# Limit VLAN choices by device
|
# Limit VLAN choices by device
|
||||||
self.fields['untagged_vlan'].widget.add_query_param('available_on_device', device.pk)
|
self.fields['untagged_vlan'].widget.add_query_param('available_on_device', device.pk)
|
||||||
|
|
|
@ -17,7 +17,7 @@ PADDING = 10
|
||||||
LINE_HEIGHT = 20
|
LINE_HEIGHT = 20
|
||||||
FANOUT_HEIGHT = 35
|
FANOUT_HEIGHT = 35
|
||||||
FANOUT_LEG_HEIGHT = 15
|
FANOUT_LEG_HEIGHT = 15
|
||||||
CABLE_HEIGHT = 4 * LINE_HEIGHT + FANOUT_HEIGHT + FANOUT_LEG_HEIGHT
|
CABLE_HEIGHT = 5 * LINE_HEIGHT + FANOUT_HEIGHT + FANOUT_LEG_HEIGHT
|
||||||
|
|
||||||
|
|
||||||
class Node(Hyperlink):
|
class Node(Hyperlink):
|
||||||
|
@ -223,7 +223,7 @@ class CableTraceSVG:
|
||||||
nodes_height = 0
|
nodes_height = 0
|
||||||
nodes = []
|
nodes = []
|
||||||
# Sort them by name to make renders more readable
|
# Sort them by name to make renders more readable
|
||||||
for i, term in enumerate(sorted(terminations, key=lambda x: x.name)):
|
for i, term in enumerate(sorted(terminations, key=lambda x: str(x))):
|
||||||
node = Node(
|
node = Node(
|
||||||
position=(offset_x + i * width, self.cursor),
|
position=(offset_x + i * width, self.cursor),
|
||||||
width=width,
|
width=width,
|
||||||
|
@ -266,7 +266,7 @@ class CableTraceSVG:
|
||||||
Draw the far-end objects and its terminations and return all created nodes
|
Draw the far-end objects and its terminations and return all created nodes
|
||||||
"""
|
"""
|
||||||
# Make sure elements are sorted by name for readability
|
# Make sure elements are sorted by name for readability
|
||||||
objects = sorted(obj_list, key=lambda x: x.name)
|
objects = sorted(obj_list, key=lambda x: str(x))
|
||||||
width = self.width / len(objects)
|
width = self.width / len(objects)
|
||||||
|
|
||||||
# Max-height of created terminations
|
# Max-height of created terminations
|
||||||
|
@ -361,7 +361,8 @@ class CableTraceSVG:
|
||||||
# Connector (a Cable or WirelessLink)
|
# Connector (a Cable or WirelessLink)
|
||||||
if links:
|
if links:
|
||||||
|
|
||||||
parent_object_nodes, far_terminations = self.draw_far_objects(set(end.parent_object for end in far_ends), far_ends)
|
obj_list = {end.parent_object for end in far_ends}
|
||||||
|
parent_object_nodes, far_terminations = self.draw_far_objects(obj_list, far_ends)
|
||||||
for cable in links:
|
for cable in links:
|
||||||
# Fill in labels and description with all available data
|
# Fill in labels and description with all available data
|
||||||
description = [
|
description = [
|
||||||
|
@ -404,7 +405,17 @@ class CableTraceSVG:
|
||||||
end = far[0].top_center
|
end = far[0].top_center
|
||||||
text_offset = 0
|
text_offset = 0
|
||||||
|
|
||||||
if len(near) > 1:
|
if len(near) > 1 and len(far) > 1:
|
||||||
|
start_center = sum([pos.bottom_center[0] for pos in near]) / len(near)
|
||||||
|
end_center = sum([pos.bottom_center[0] for pos in far]) / len(far)
|
||||||
|
center_x = (start_center + end_center) / 2
|
||||||
|
|
||||||
|
start = (center_x, start[1] + FANOUT_HEIGHT + FANOUT_LEG_HEIGHT)
|
||||||
|
end = (center_x, end[1] - FANOUT_HEIGHT - FANOUT_LEG_HEIGHT)
|
||||||
|
text_offset -= (FANOUT_HEIGHT + FANOUT_LEG_HEIGHT)
|
||||||
|
self.draw_fanin(start, near, color)
|
||||||
|
self.draw_fanout(end, far, color)
|
||||||
|
elif len(near) > 1:
|
||||||
# Handle Fan-In - change start position to be directly below start
|
# Handle Fan-In - change start position to be directly below start
|
||||||
start = (end[0], start[1] + FANOUT_HEIGHT + FANOUT_LEG_HEIGHT)
|
start = (end[0], start[1] + FANOUT_HEIGHT + FANOUT_LEG_HEIGHT)
|
||||||
self.draw_fanin(start, near, color)
|
self.draw_fanin(start, near, color)
|
||||||
|
|
|
@ -618,7 +618,7 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
|
||||||
verbose_name=_('VRF'),
|
verbose_name=_('VRF'),
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
inventory_items = tables.ManyToManyColumn(
|
inventory_items = columns.ManyToManyColumn(
|
||||||
linkify_item=True,
|
linkify_item=True,
|
||||||
verbose_name=_('Inventory Items'),
|
verbose_name=_('Inventory Items'),
|
||||||
)
|
)
|
||||||
|
|
|
@ -394,6 +394,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 2
|
# Delete cable 2
|
||||||
cable2.delete()
|
cable2.delete()
|
||||||
path1 = self.assertPathExists(
|
path1 = self.assertPathExists(
|
||||||
|
@ -450,6 +453,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 2
|
# Delete cable 2
|
||||||
cable2.delete()
|
cable2.delete()
|
||||||
path1 = self.assertPathExists(
|
path1 = self.assertPathExists(
|
||||||
|
@ -558,6 +564,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 3
|
# Delete cable 3
|
||||||
cable3.delete()
|
cable3.delete()
|
||||||
|
|
||||||
|
@ -673,6 +682,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 3
|
# Delete cable 3
|
||||||
cable3.delete()
|
cable3.delete()
|
||||||
|
|
||||||
|
@ -804,6 +816,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 3
|
# Delete cable 3
|
||||||
cable3.delete()
|
cable3.delete()
|
||||||
|
|
||||||
|
@ -931,6 +946,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 5
|
# Delete cable 5
|
||||||
cable5.delete()
|
cable5.delete()
|
||||||
|
|
||||||
|
@ -1034,6 +1052,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 3
|
# Delete cable 3
|
||||||
cable3.delete()
|
cable3.delete()
|
||||||
|
|
||||||
|
@ -1093,6 +1114,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 3)
|
self.assertEqual(CablePath.objects.count(), 3)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 1
|
# Delete cable 1
|
||||||
cable1.delete()
|
cable1.delete()
|
||||||
|
|
||||||
|
@ -1135,6 +1159,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 1)
|
self.assertEqual(CablePath.objects.count(), 1)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
def test_210_interface_to_circuittermination(self):
|
def test_210_interface_to_circuittermination(self):
|
||||||
"""
|
"""
|
||||||
[IF1] --C1-- [CT1]
|
[IF1] --C1-- [CT1]
|
||||||
|
@ -1156,6 +1183,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 1)
|
self.assertEqual(CablePath.objects.count(), 1)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 1
|
# Delete cable 1
|
||||||
cable1.delete()
|
cable1.delete()
|
||||||
self.assertEqual(CablePath.objects.count(), 0)
|
self.assertEqual(CablePath.objects.count(), 0)
|
||||||
|
@ -1212,6 +1242,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 2
|
# Delete cable 2
|
||||||
cable2.delete()
|
cable2.delete()
|
||||||
path1 = self.assertPathExists(
|
path1 = self.assertPathExists(
|
||||||
|
@ -1277,6 +1310,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 2
|
# Delete cable 2
|
||||||
cable2.delete()
|
cable2.delete()
|
||||||
path1 = self.assertPathExists(
|
path1 = self.assertPathExists(
|
||||||
|
@ -1314,6 +1350,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 1)
|
self.assertEqual(CablePath.objects.count(), 1)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 1
|
# Delete cable 1
|
||||||
cable1.delete()
|
cable1.delete()
|
||||||
self.assertEqual(CablePath.objects.count(), 0)
|
self.assertEqual(CablePath.objects.count(), 0)
|
||||||
|
@ -1342,6 +1381,9 @@ class CablePathTestCase(TestCase):
|
||||||
self.assertEqual(CablePath.objects.count(), 1)
|
self.assertEqual(CablePath.objects.count(), 1)
|
||||||
self.assertTrue(CablePath.objects.first().is_complete)
|
self.assertTrue(CablePath.objects.first().is_complete)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 1
|
# Delete cable 1
|
||||||
cable1.delete()
|
cable1.delete()
|
||||||
self.assertEqual(CablePath.objects.count(), 0)
|
self.assertEqual(CablePath.objects.count(), 0)
|
||||||
|
@ -1439,6 +1481,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cables 3-4
|
# Delete cables 3-4
|
||||||
cable3.delete()
|
cable3.delete()
|
||||||
cable4.delete()
|
cable4.delete()
|
||||||
|
@ -1495,6 +1540,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 2
|
# Delete cable 2
|
||||||
cable2.delete()
|
cable2.delete()
|
||||||
path1 = self.assertPathExists(
|
path1 = self.assertPathExists(
|
||||||
|
@ -1578,6 +1626,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 2
|
# Delete cable 2
|
||||||
cable2.delete()
|
cable2.delete()
|
||||||
|
|
||||||
|
@ -1697,6 +1748,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 4)
|
self.assertEqual(CablePath.objects.count(), 4)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
# Delete cable 3
|
# Delete cable 3
|
||||||
cable3.delete()
|
cable3.delete()
|
||||||
|
|
||||||
|
@ -1784,6 +1838,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 2)
|
self.assertEqual(CablePath.objects.count(), 2)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
def test_220_interface_to_interface_duplex_via_multiple_front_and_rear_ports(self):
|
def test_220_interface_to_interface_duplex_via_multiple_front_and_rear_ports(self):
|
||||||
"""
|
"""
|
||||||
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
|
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
|
||||||
|
@ -1877,6 +1934,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 3)
|
self.assertEqual(CablePath.objects.count(), 3)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
def test_221_non_symmetric_paths(self):
|
def test_221_non_symmetric_paths(self):
|
||||||
"""
|
"""
|
||||||
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- -------------------------------------- [IF2]
|
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- -------------------------------------- [IF2]
|
||||||
|
@ -1997,6 +2057,9 @@ class CablePathTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(CablePath.objects.count(), 3)
|
self.assertEqual(CablePath.objects.count(), 3)
|
||||||
|
|
||||||
|
# Test SVG generation
|
||||||
|
CableTraceSVG(interface1).render()
|
||||||
|
|
||||||
def test_301_create_path_via_existing_cable(self):
|
def test_301_create_path_via_existing_cable(self):
|
||||||
"""
|
"""
|
||||||
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
|
[IF1] --C1-- [FP1] [RP1] --C2-- [RP2] [FP2] --C3-- [IF2]
|
||||||
|
|
|
@ -3160,12 +3160,6 @@ class CableListView(generic.ObjectListView):
|
||||||
filterset = filtersets.CableFilterSet
|
filterset = filtersets.CableFilterSet
|
||||||
filterset_form = forms.CableFilterForm
|
filterset_form = forms.CableFilterForm
|
||||||
table = tables.CableTable
|
table = tables.CableTable
|
||||||
actions = {
|
|
||||||
'import': {'add'},
|
|
||||||
'export': {'view'},
|
|
||||||
'bulk_edit': {'change'},
|
|
||||||
'bulk_delete': {'delete'},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@register_model_view(Cable)
|
@register_model_view(Cable)
|
||||||
|
|
|
@ -378,7 +378,7 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
|
||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name=_('NAT (Inside)')
|
verbose_name=_('NAT (Inside)')
|
||||||
)
|
)
|
||||||
nat_outside = tables.ManyToManyColumn(
|
nat_outside = columns.ManyToManyColumn(
|
||||||
linkify_item=True,
|
linkify_item=True,
|
||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name=_('NAT (Outside)')
|
verbose_name=_('NAT (Outside)')
|
||||||
|
|
|
@ -101,7 +101,7 @@ CONNECTIONS_MENU = Menu(
|
||||||
MenuGroup(
|
MenuGroup(
|
||||||
label=_('Connections'),
|
label=_('Connections'),
|
||||||
items=(
|
items=(
|
||||||
get_model_item('dcim', 'cable', _('Cables'), actions=['import']),
|
get_model_item('dcim', 'cable', _('Cables')),
|
||||||
get_model_item('wireless', 'wirelesslink', _('Wireless Links')),
|
get_model_item('wireless', 'wirelesslink', _('Wireless Links')),
|
||||||
MenuItem(
|
MenuItem(
|
||||||
link='dcim:interface_connections_list',
|
link='dcim:interface_connections_list',
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -60,18 +60,17 @@ function handleSecretToggle(state: StateManager<SecretState>, button: HTMLButton
|
||||||
toggleSecretButton(hidden, button);
|
toggleSecretButton(hidden, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleCallback(event: MouseEvent) {
|
||||||
|
handleSecretToggle(secretState, event.currentTarget as HTMLButtonElement);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize secret toggle button.
|
* Initialize secret toggle button.
|
||||||
*/
|
*/
|
||||||
export function initSecretToggle(): void {
|
export function initSecretToggle(): void {
|
||||||
hideSecret();
|
hideSecret();
|
||||||
for (const button of getElements<HTMLButtonElement>('button.toggle-secret')) {
|
for (const button of getElements<HTMLButtonElement>('button.toggle-secret')) {
|
||||||
button.addEventListener(
|
button.removeEventListener('click', toggleCallback);
|
||||||
'click',
|
button.addEventListener('click', toggleCallback);
|
||||||
event => {
|
|
||||||
handleSecretToggle(secretState, event.currentTarget as HTMLButtonElement);
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -63,7 +63,7 @@ class IKEPolicyTable(NetBoxTable):
|
||||||
mode = tables.Column(
|
mode = tables.Column(
|
||||||
verbose_name=_('Mode')
|
verbose_name=_('Mode')
|
||||||
)
|
)
|
||||||
proposals = tables.ManyToManyColumn(
|
proposals = columns.ManyToManyColumn(
|
||||||
linkify_item=True,
|
linkify_item=True,
|
||||||
verbose_name=_('Proposals')
|
verbose_name=_('Proposals')
|
||||||
)
|
)
|
||||||
|
@ -129,7 +129,7 @@ class IPSecPolicyTable(NetBoxTable):
|
||||||
verbose_name=_('Name'),
|
verbose_name=_('Name'),
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
proposals = tables.ManyToManyColumn(
|
proposals = columns.ManyToManyColumn(
|
||||||
linkify_item=True,
|
linkify_item=True,
|
||||||
verbose_name=_('Proposals')
|
verbose_name=_('Proposals')
|
||||||
)
|
)
|
||||||
|
|
|
@ -91,7 +91,7 @@ class TunnelTerminationTable(TenancyColumnsMixin, NetBoxTable):
|
||||||
verbose_name=_('Tunnel interface'),
|
verbose_name=_('Tunnel interface'),
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
ip_addresses = tables.ManyToManyColumn(
|
ip_addresses = columns.ManyToManyColumn(
|
||||||
accessor=tables.A('termination__ip_addresses'),
|
accessor=tables.A('termination__ip_addresses'),
|
||||||
orderable=False,
|
orderable=False,
|
||||||
linkify_item=True,
|
linkify_item=True,
|
||||||
|
|
|
@ -18,10 +18,10 @@ drf-spectacular==0.27.2
|
||||||
drf-spectacular-sidecar==2024.5.1
|
drf-spectacular-sidecar==2024.5.1
|
||||||
feedparser==6.0.11
|
feedparser==6.0.11
|
||||||
gunicorn==22.0.0
|
gunicorn==22.0.0
|
||||||
Jinja2==3.1.3
|
Jinja2==3.1.4
|
||||||
Markdown==3.6
|
Markdown==3.6
|
||||||
mkdocs-material==9.5.20
|
mkdocs-material==9.5.21
|
||||||
mkdocstrings[python-legacy]==0.25.0
|
mkdocstrings[python-legacy]==0.25.1
|
||||||
netaddr==1.2.1
|
netaddr==1.2.1
|
||||||
nh3==0.2.17
|
nh3==0.2.17
|
||||||
Pillow==10.3.0
|
Pillow==10.3.0
|
||||||
|
|
Loading…
Reference in New Issue