From 4efd54613a0f0595ed28ebecca20782fe181dd26 Mon Sep 17 00:00:00 2001 From: fixclean Date: Mon, 16 Feb 2026 09:53:35 +0100 Subject: [PATCH] connection edit bugfix --- app/assets/js/connections-edit-form.js | 58 +++++++ app/modules/connections/edit.php | 211 +++++++++++++++++++++++++ app/modules/connections/list.php | 4 +- app/modules/connections/save.php | 2 +- 4 files changed, 272 insertions(+), 3 deletions(-) create mode 100644 app/assets/js/connections-edit-form.js create mode 100644 app/modules/connections/edit.php diff --git a/app/assets/js/connections-edit-form.js b/app/assets/js/connections-edit-form.js new file mode 100644 index 0000000..49ab786 --- /dev/null +++ b/app/assets/js/connections-edit-form.js @@ -0,0 +1,58 @@ +(() => { + function applyTypeFilter(typeSelect, portSelect, selectedId) { + const endpointType = typeSelect.value; + let visibleCount = 0; + let matchedSelected = false; + const currentValue = selectedId || portSelect.value || ''; + + for (const option of portSelect.options) { + const optionType = option.dataset.endpointType || ''; + if (!optionType) { + option.hidden = false; + option.disabled = false; + continue; + } + + const visible = optionType === endpointType; + option.hidden = !visible; + option.disabled = !visible; + + if (visible) { + visibleCount += 1; + if (option.value === currentValue) { + option.selected = true; + matchedSelected = true; + } + } else if (option.selected) { + option.selected = false; + } + } + + const placeholder = portSelect.options[0]; + if (placeholder) { + placeholder.textContent = visibleCount > 0 ? '- Port waehlen -' : '- Keine Ports verfuegbar -'; + } + + if (!matchedSelected) { + portSelect.value = ''; + } + } + + function bindPair(typeSelectId, portSelectId) { + const typeSelect = document.getElementById(typeSelectId); + const portSelect = document.getElementById(portSelectId); + if (!typeSelect || !portSelect) { + return; + } + + applyTypeFilter(typeSelect, portSelect, portSelect.dataset.selectedId || ''); + typeSelect.addEventListener('change', () => { + applyTypeFilter(typeSelect, portSelect, ''); + }); + } + + document.addEventListener('DOMContentLoaded', () => { + bindPair('port_a_type', 'port_a_id'); + bindPair('port_b_type', 'port_b_id'); + }); +})(); diff --git a/app/modules/connections/edit.php b/app/modules/connections/edit.php new file mode 100644 index 0000000..0a0d75a --- /dev/null +++ b/app/modules/connections/edit.php @@ -0,0 +1,211 @@ + 0) { + $connection = $sql->single( + "SELECT id, port_a_type, port_a_id, port_b_type, port_b_id, vlan_config, comment + FROM connections + WHERE id = ?", + "i", + [$connectionId] + ); +} + +$normalizePortType = static function (string $value): string { + $map = [ + 'device' => 'device', + 'device_ports' => 'device', + 'module' => 'module', + 'module_ports' => 'module', + 'outlet' => 'outlet', + 'network_outlet_ports' => 'outlet', + 'patchpanel' => 'patchpanel', + 'floor_patchpanel' => 'patchpanel', + 'floor_patchpanel_ports' => 'patchpanel', + ]; + $key = strtolower(trim($value)); + return $map[$key] ?? 'device'; +}; + +$portAType = $normalizePortType((string)($connection['port_a_type'] ?? 'device')); +$portBType = $normalizePortType((string)($connection['port_b_type'] ?? 'device')); +$portAId = (int)($connection['port_a_id'] ?? 0); +$portBId = (int)($connection['port_b_id'] ?? 0); + +$endpointOptions = [ + 'device' => [], + 'module' => [], + 'outlet' => [], + 'patchpanel' => [], +]; + +$devicePorts = $sql->get( + "SELECT dp.id, dp.name, d.name AS owner_name + FROM device_ports dp + JOIN devices d ON d.id = dp.device_id + ORDER BY d.name, dp.name", + "", + [] +); +foreach ($devicePorts as $row) { + $endpointOptions['device'][] = [ + 'id' => (int)$row['id'], + 'label' => $row['owner_name'] . ' / ' . $row['name'], + ]; +} + +$modulePorts = $sql->get( + "SELECT + mp.id, + mp.name, + m.name AS module_name, + MIN(d.name) AS device_name + FROM module_ports mp + JOIN modules m ON m.id = mp.module_id + LEFT JOIN device_port_modules dpm ON dpm.module_id = m.id + LEFT JOIN device_ports dp ON dp.id = dpm.device_port_id + LEFT JOIN devices d ON d.id = dp.device_id + GROUP BY mp.id, mp.name, m.name + ORDER BY device_name, module_name, mp.name", + "", + [] +); +foreach ($modulePorts as $row) { + $deviceName = trim((string)($row['device_name'] ?? '')) ?: 'Unzugeordnet'; + $endpointOptions['module'][] = [ + 'id' => (int)$row['id'], + 'label' => $deviceName . ' / ' . $row['module_name'] . ' / ' . $row['name'], + ]; +} + +$outletPorts = $sql->get( + "SELECT nop.id, nop.name, no.name AS outlet_name, r.name AS room_name, f.name AS floor_name + FROM network_outlet_ports nop + JOIN network_outlets no ON no.id = nop.outlet_id + LEFT JOIN rooms r ON r.id = no.room_id + LEFT JOIN floors f ON f.id = r.floor_id + ORDER BY floor_name, room_name, outlet_name, nop.name", + "", + [] +); +foreach ($outletPorts as $row) { + $parts = array_filter([(string)($row['floor_name'] ?? ''), (string)($row['room_name'] ?? ''), (string)$row['outlet_name'], (string)$row['name']]); + $endpointOptions['outlet'][] = [ + 'id' => (int)$row['id'], + 'label' => implode(' / ', $parts), + ]; +} + +$patchpanelPorts = $sql->get( + "SELECT fpp.id, fpp.name, fp.name AS patchpanel_name, f.name AS floor_name + FROM floor_patchpanel_ports fpp + JOIN floor_patchpanels fp ON fp.id = fpp.patchpanel_id + LEFT JOIN floors f ON f.id = fp.floor_id + ORDER BY floor_name, patchpanel_name, fpp.name", + "", + [] +); +foreach ($patchpanelPorts as $row) { + $parts = array_filter([(string)($row['floor_name'] ?? ''), (string)$row['patchpanel_name'], (string)$row['name']]); + $endpointOptions['patchpanel'][] = [ + 'id' => (int)$row['id'], + 'label' => implode(' / ', $parts), + ]; +} + +$vlanValue = ''; +if (!empty($connection['vlan_config'])) { + $decoded = json_decode((string)$connection['vlan_config'], true); + if (is_array($decoded)) { + $vlanValue = implode(',', array_map('trim', $decoded)); + } else { + $vlanValue = (string)$connection['vlan_config']; + } +} + +$renderEndpointOptions = static function (array $optionsByType, int $selectedId): void { + foreach ($optionsByType as $type => $options) { + foreach ($options as $entry) { + $isSelected = ((int)$entry['id'] === $selectedId) ? ' selected' : ''; + echo ''; + } + } +}; +?> + +
+

+ +
+ + + + +
+ Endpunkt A +
+ + +
+
+ + +
+
+ +
+ Endpunkt B +
+ + +
+
+ + +
+
+ +
+ Details +
+ + +
+
+ + +
+
+ +
+ + Abbrechen +
+
+
+ diff --git a/app/modules/connections/list.php b/app/modules/connections/list.php index 2fd8f35..58b0d0e 100644 --- a/app/modules/connections/list.php +++ b/app/modules/connections/list.php @@ -258,7 +258,7 @@ if ($deviceId > 0) { Reset - + Neue Verbindung + + Neue Verbindung @@ -344,7 +344,7 @@ if ($deviceId > 0) {

Keine Verbindungen gefunden.

- + Erste Verbindung anlegen

diff --git a/app/modules/connections/save.php b/app/modules/connections/save.php index 96068d7..86b7e6a 100644 --- a/app/modules/connections/save.php +++ b/app/modules/connections/save.php @@ -53,7 +53,7 @@ if ($portAId <= 0 || $portBId <= 0) { if (!empty($errors)) { $_SESSION['error'] = implode(', ', $errors); - $redirectUrl = $connId ? "?module=connections&action=edit&id=$connId" : "?module=connections&action=list"; + $redirectUrl = $connId ? "?module=connections&action=edit&id=$connId" : "?module=connections&action=edit"; header("Location: $redirectUrl"); exit; }