Files
netwatch/app/modules/devices/list.php

243 lines
6.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* modules/devices/list.php
* Vollständige Geräteübersicht
*/
// =========================
// Filter / Suche einlesen
// =========================
$search = trim($_GET['search'] ?? '');
$typeId = (int)($_GET['type_id'] ?? 0);
$locationId = (int)($_GET['location_id'] ?? 0);
$floorId = (int)($_GET['floor_id'] ?? 0);
$rackId = (int)($_GET['rack_id'] ?? 0);
// =========================
// WHERE-Clause dynamisch bauen
// =========================
$where = [];
$types = '';
$params = [];
if ($search !== '') {
$where[] = "(d.name LIKE ? OR d.serial_number LIKE ? OR dt.name LIKE ?)";
$types .= "sss";
$params[] = "%$search%";
$params[] = "%$search%";
$params[] = "%$search%";
}
if ($typeId > 0) {
$where[] = "dt.id = ?";
$types .= "i";
$params[] = $typeId;
}
if ($locationId > 0) {
$where[] = "l.id = ?";
$types .= "i";
$params[] = $locationId;
}
if ($floorId > 0) {
$where[] = "f.id = ?";
$types .= "i";
$params[] = $floorId;
}
if ($rackId > 0) {
$where[] = "r.id = ?";
$types .= "i";
$params[] = $rackId;
}
$whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
// =========================
// Geräte laden (inkl. Status-Aggregate)
// =========================
$devices = $sql->get(
"
SELECT
d.id,
d.name,
d.serial_number,
d.rack_position_he,
d.rack_height_he,
dt.name AS device_type,
dt.image_path,
dt.image_type,
l.name AS location_name,
f.name AS floor_name,
r.name AS rack_name,
COUNT(dp.id) AS total_ports,
SUM(dp.status = 'active') AS active_ports,
SUM(c.id IS NOT NULL) AS connected_ports
FROM devices d
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
LEFT JOIN buildings b ON b.id = f.building_id
LEFT JOIN locations l ON l.id = b.location_id
LEFT JOIN device_ports dp ON dp.device_id = d.id
LEFT JOIN connections c
ON (c.port_a_type = 'device' AND c.port_a_id = dp.id)
OR (c.port_b_type = 'device' AND c.port_b_id = dp.id)
$whereSql
GROUP BY d.id
ORDER BY l.name, f.level, r.name, d.rack_position_he, d.name
",
$types,
$params
);
// =========================
// Filter-Daten laden
// =========================
$deviceTypes = $sql->get("SELECT id, name FROM device_types ORDER BY name", "", []);
$locations = $sql->get("SELECT id, name FROM locations ORDER BY name", "", []);
$floors = $sql->get("SELECT id, name FROM floors ORDER BY level", "", []);
$racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
?>
<h2>Geräte</h2>
<form method="get" class="toolbar">
<input type="hidden" name="module" value="devices">
<input type="hidden" name="action" value="list">
<input type="text" name="search" placeholder="Suche…" value="<?= htmlspecialchars($search) ?>">
<select name="type_id">
<option value="">Gerätetyp</option>
<?php foreach ($deviceTypes as $t): ?>
<option value="<?= $t['id'] ?>" <?= $t['id'] === $typeId ? 'selected' : '' ?>>
<?= htmlspecialchars($t['name']) ?>
</option>
<?php endforeach; ?>
</select>
<select name="location_id">
<option value="">Standort</option>
<?php foreach ($locations as $l): ?>
<option value="<?= $l['id'] ?>" <?= $l['id'] === $locationId ? 'selected' : '' ?>>
<?= htmlspecialchars($l['name']) ?>
</option>
<?php endforeach; ?>
</select>
<select name="floor_id">
<option value="">Floor</option>
<?php foreach ($floors as $f): ?>
<option value="<?= $f['id'] ?>" <?= $f['id'] === $floorId ? 'selected' : '' ?>>
<?= htmlspecialchars($f['name']) ?>
</option>
<?php endforeach; ?>
</select>
<select name="rack_id">
<option value="">Rack</option>
<?php foreach ($racks as $r): ?>
<option value="<?= $r['id'] ?>" <?= $r['id'] === $rackId ? 'selected' : '' ?>>
<?= htmlspecialchars($r['name']) ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit">Filtern</button>
<a href="/devices/edit" class="button">
+ Neues Gerät
</a>
</form>
<?php if ($devices): ?>
<table class="device-list">
<thead>
<tr>
<th>Vorschau</th>
<th>Name</th>
<th>Typ</th>
<th>Standort</th>
<th>Rack</th>
<th>HE</th>
<th>Ports</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
<?php foreach ($devices as $d):
$freePorts = max(0, $d['total_ports'] - $d['connected_ports']);
?>
<tr>
<td>
<?php if ($d['image_path']): ?>
<img src="<?= htmlspecialchars($d['image_path']) ?>" class="thumb">
<?php else: ?>
<?php endif; ?>
</td>
<td>
<strong><?= htmlspecialchars($d['name']) ?></strong><br>
<small><?= htmlspecialchars($d['serial_number'] ?? '') ?></small>
</td>
<td><?= htmlspecialchars($d['device_type']) ?></td>
<td>
<?= htmlspecialchars($d['location_name'] ?? '—') ?><br>
<small><?= htmlspecialchars($d['floor_name'] ?? '') ?></small>
</td>
<td><?= htmlspecialchars($d['rack_name'] ?? '—') ?></td>
<td>
<?= htmlspecialchars($d['rack_position_he'] ?? '—') ?>
<?php if ($d['rack_height_he']): ?>
<?= $d['rack_position_he'] + $d['rack_height_he'] - 1 ?>
<?php endif; ?>
</td>
<td>
<?= (int)$d['connected_ports'] ?>/<?= (int)$d['total_ports'] ?>
<br>
<small><?= $freePorts ?> frei</small>
</td>
<td class="actions">
<a href="/devices/ports?id=<?= $d['id'] ?>">Ports</a>
<a href="/devices/edit?id=<?= $d['id'] ?>">Bearbeiten</a>
<a href="/devices/delete?id=<?= $d['id'] ?>"
onclick="return confirm('Gerät wirklich löschen?')">
Löschen
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<div class="empty-state">
<p>Keine Geräte gefunden.</p>
</div>
<?php endif; ?>