diff --git a/app/modules/dashboard/list.php b/app/modules/dashboard/list.php index 1cdeb5e..6642d0d 100644 --- a/app/modules/dashboard/list.php +++ b/app/modules/dashboard/list.php @@ -31,12 +31,18 @@ $topologyDevices = $sql->get( r.id AS rack_id, r.name AS rack_name, f.id AS floor_id, - f.name AS floor_name + f.name AS floor_name, + b.id AS building_id, + b.name AS building_name, + l.id AS location_id, + l.name AS location_name FROM devices d LEFT JOIN device_types dt ON dt.id = d.device_type_id LEFT JOIN racks r ON r.id = d.rack_id LEFT JOIN floors f ON f.id = r.floor_id - ORDER BY floor_name, rack_name, device_name", + LEFT JOIN buildings b ON b.id = f.building_id + LEFT JOIN locations l ON l.id = b.location_id + ORDER BY location_name, building_name, floor_name, rack_name, device_name", "", [] ); @@ -50,8 +56,127 @@ $topologyPayload = array_map(static function (array $row): array { 'rack_name' => (string)($row['rack_name'] ?? ''), 'floor_id' => (int)($row['floor_id'] ?? 0), 'floor_name' => (string)($row['floor_name'] ?? ''), + 'building_id' => (int)($row['building_id'] ?? 0), + 'building_name' => (string)($row['building_name'] ?? ''), + 'location_id' => (int)($row['location_id'] ?? 0), + 'location_name' => (string)($row['location_name'] ?? ''), ]; }, $topologyDevices); + +$rackInfoRows = $sql->get( + "SELECT + r.id AS rack_id, + r.name AS rack_name, + f.id AS floor_id, + f.name AS floor_name, + b.id AS building_id, + b.name AS building_name, + l.id AS location_id, + l.name AS location_name + FROM racks r + LEFT JOIN floors f ON f.id = r.floor_id + LEFT JOIN buildings b ON b.id = f.building_id + LEFT JOIN locations l ON l.id = b.location_id", + "", + [] +); + +$rackInfoById = []; +foreach ($rackInfoRows as $row) { + $rackId = (int)($row['rack_id'] ?? 0); + if ($rackId <= 0) { + continue; + } + $rackInfoById[$rackId] = [ + 'rack_id' => $rackId, + 'rack_name' => (string)($row['rack_name'] ?? ''), + 'floor_id' => (int)($row['floor_id'] ?? 0), + 'floor_name' => (string)($row['floor_name'] ?? ''), + 'building_id' => (int)($row['building_id'] ?? 0), + 'building_name' => (string)($row['building_name'] ?? ''), + 'location_id' => (int)($row['location_id'] ?? 0), + 'location_name' => (string)($row['location_name'] ?? ''), + ]; +} + +$devicePortRacks = []; +foreach ($sql->get( + "SELECT dp.id AS port_id, d.rack_id + FROM device_ports dp + JOIN devices d ON d.id = dp.device_id + WHERE d.rack_id IS NOT NULL", + "", + [] +) as $row) { + $devicePortRacks[(int)$row['port_id']] = (int)$row['rack_id']; +} + +$modulePortRacks = []; +foreach ($sql->get( + "SELECT mp.id AS port_id, d.rack_id + FROM module_ports mp + JOIN modules m ON m.id = mp.module_id + JOIN device_port_modules dpm ON dpm.module_id = m.id + JOIN device_ports dp ON dp.id = dpm.device_port_id + JOIN devices d ON d.id = dp.device_id + WHERE d.rack_id IS NOT NULL", + "", + [] +) as $row) { + $modulePortRacks[(int)$row['port_id']] = (int)$row['rack_id']; +} + +$resolveRackId = static function (string $endpointType, int $endpointId) use ($devicePortRacks, $modulePortRacks): int { + if ($endpointType === 'device') { + return (int)($devicePortRacks[$endpointId] ?? 0); + } + if ($endpointType === 'module') { + return (int)($modulePortRacks[$endpointId] ?? 0); + } + return 0; +}; + +$rackLinksByKey = []; +foreach ($sql->get( + "SELECT id, port_a_type, port_a_id, port_b_type, port_b_id + FROM connections", + "", + [] +) as $row) { + $rackA = $resolveRackId((string)($row['port_a_type'] ?? ''), (int)($row['port_a_id'] ?? 0)); + $rackB = $resolveRackId((string)($row['port_b_type'] ?? ''), (int)($row['port_b_id'] ?? 0)); + if ($rackA <= 0 || $rackB <= 0 || $rackA === $rackB) { + continue; + } + + $from = min($rackA, $rackB); + $to = max($rackA, $rackB); + $key = $from . ':' . $to; + if (!isset($rackLinksByKey[$key])) { + $rackLinksByKey[$key] = [ + 'from_rack_id' => $from, + 'to_rack_id' => $to, + 'count' => 0 + ]; + } + $rackLinksByKey[$key]['count']++; +} + +$rackLinkPayload = []; +foreach ($rackLinksByKey as $entry) { + $fromId = (int)$entry['from_rack_id']; + $toId = (int)$entry['to_rack_id']; + $fromMeta = $rackInfoById[$fromId] ?? ['rack_name' => 'Rack #' . $fromId]; + $toMeta = $rackInfoById[$toId] ?? ['rack_name' => 'Rack #' . $toId]; + + $rackLinkPayload[] = [ + 'from_rack_id' => $fromId, + 'to_rack_id' => $toId, + 'count' => (int)$entry['count'], + 'from_rack_name' => (string)($fromMeta['rack_name'] ?? ('Rack #' . $fromId)), + 'to_rack_name' => (string)($toMeta['rack_name'] ?? ('Rack #' . $toId)), + ]; +} ?>
@@ -70,11 +195,12 @@ $topologyPayload = array_map(static function (array $row): array {
-

Mausrad zoomt, Ziehen verschiebt. Klick auf einen Punkt zoomt auf den Rack-Kontext und oeffnet die Detailkarte.

+

Hierarchie: Standort → Gebaeude → Stockwerk → Rack → Geraet. Linien zeigen Rack-Verbindungen (dicker = mehr Links).

- + + @@ -147,6 +273,7 @@ $topologyPayload = array_map(static function (array $row): array { +