feat: complete package 2 delete flows and package 3 port management
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* modules/devices/list.php
|
||||
* Vollständige Geräteübersicht mit Filter
|
||||
* Vollstaendige Geraeteuebersicht mit Filter
|
||||
*/
|
||||
|
||||
// =========================
|
||||
@@ -22,69 +22,88 @@ $params = [];
|
||||
|
||||
if ($search !== '') {
|
||||
$where[] = "(d.name LIKE ? OR d.serial_number LIKE ? OR dt.name LIKE ?)";
|
||||
$types .= "sss";
|
||||
$types .= 'sss';
|
||||
$params[] = "%$search%";
|
||||
$params[] = "%$search%";
|
||||
$params[] = "%$search%";
|
||||
}
|
||||
|
||||
if ($typeId > 0) {
|
||||
$where[] = "d.device_type_id = ?";
|
||||
$types .= "i";
|
||||
$where[] = 'd.device_type_id = ?';
|
||||
$types .= 'i';
|
||||
$params[] = $typeId;
|
||||
}
|
||||
|
||||
if ($floorId > 0) {
|
||||
$where[] = "f.id = ?";
|
||||
$types .= "i";
|
||||
$where[] = 'f.id = ?';
|
||||
$types .= 'i';
|
||||
$params[] = $floorId;
|
||||
}
|
||||
|
||||
if ($rackId > 0) {
|
||||
$where[] = "d.rack_id = ?";
|
||||
$types .= "i";
|
||||
$where[] = 'd.rack_id = ?';
|
||||
$types .= 'i';
|
||||
$params[] = $rackId;
|
||||
}
|
||||
|
||||
$whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
|
||||
|
||||
// =========================
|
||||
// Geräte laden
|
||||
// Geraete laden
|
||||
// =========================
|
||||
$devices = $sql->get(
|
||||
"
|
||||
SELECT
|
||||
d.id,
|
||||
d.name,
|
||||
d.serial_number,
|
||||
d.rack_position_he,
|
||||
d.rack_height_he,
|
||||
d.web_config_url,
|
||||
dt.name AS device_type,
|
||||
dt.image_path,
|
||||
f.name AS floor_name,
|
||||
r.name AS rack_name,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_ports dp
|
||||
WHERE dp.device_id = d.id
|
||||
) AS port_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_port_modules dpm
|
||||
JOIN device_ports dp2 ON dp2.id = dpm.device_port_id
|
||||
WHERE dp2.device_id = d.id
|
||||
) AS module_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM connections c
|
||||
WHERE (c.port_a_type = 'device' AND c.port_a_id IN (
|
||||
SELECT dp3.id FROM device_ports dp3 WHERE dp3.device_id = d.id
|
||||
))
|
||||
OR (c.port_b_type = 'device' AND c.port_b_id IN (
|
||||
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = d.id
|
||||
))
|
||||
) AS connection_count
|
||||
$devices = $sql->get(
|
||||
"
|
||||
SELECT
|
||||
d.id,
|
||||
d.name,
|
||||
d.serial_number,
|
||||
d.rack_position_he,
|
||||
d.rack_height_he,
|
||||
d.web_config_url,
|
||||
dt.name AS device_type,
|
||||
dt.image_path,
|
||||
f.name AS floor_name,
|
||||
r.name AS rack_name,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_ports dp
|
||||
WHERE dp.device_id = d.id
|
||||
) AS port_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_ports dp
|
||||
WHERE dp.device_id = d.id
|
||||
AND dp.status = 'active'
|
||||
) AS active_port_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_ports dp
|
||||
WHERE dp.device_id = d.id
|
||||
AND dp.status = 'disabled'
|
||||
) AS disabled_port_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_ports dp
|
||||
WHERE dp.device_id = d.id
|
||||
AND dp.vlan_config IS NOT NULL
|
||||
AND dp.vlan_config <> '[]'
|
||||
) AS vlan_port_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM device_port_modules dpm
|
||||
JOIN device_ports dp2 ON dp2.id = dpm.device_port_id
|
||||
WHERE dp2.device_id = d.id
|
||||
) AS module_count,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM connections c
|
||||
WHERE (c.port_a_type = 'device' AND c.port_a_id IN (
|
||||
SELECT dp3.id FROM device_ports dp3 WHERE dp3.device_id = d.id
|
||||
))
|
||||
OR (c.port_b_type = 'device' AND c.port_b_id IN (
|
||||
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = d.id
|
||||
))
|
||||
) AS connection_count
|
||||
FROM devices d
|
||||
JOIN device_types dt ON dt.id = d.device_type_id
|
||||
LEFT JOIN racks r ON r.id = d.rack_id
|
||||
@@ -99,22 +118,19 @@ $whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
|
||||
// =========================
|
||||
// Filter-Daten laden
|
||||
// =========================
|
||||
$deviceTypes = $sql->get("SELECT id, name FROM device_types ORDER BY name", "", []);
|
||||
$floors = $sql->get("SELECT id, name FROM floors ORDER BY name", "", []);
|
||||
$racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
$deviceTypes = $sql->get('SELECT id, name FROM device_types ORDER BY name', '', []);
|
||||
$floors = $sql->get('SELECT id, name FROM floors ORDER BY name', '', []);
|
||||
$racks = $sql->get('SELECT id, name FROM racks ORDER BY name', '', []);
|
||||
?>
|
||||
|
||||
<div class="devices-container">
|
||||
<h1>Geräte</h1>
|
||||
<h1>Geraete</h1>
|
||||
|
||||
<!-- =========================
|
||||
Filter-Toolbar
|
||||
========================= -->
|
||||
<form method="get" class="filter-form">
|
||||
<input type="hidden" name="module" value="devices">
|
||||
<input type="hidden" name="action" value="list">
|
||||
|
||||
<input type="text" name="search" placeholder="Suche nach Name oder Seriennummer…"
|
||||
<input type="text" name="search" placeholder="Suche nach Name oder Seriennummer..."
|
||||
value="<?php echo htmlspecialchars($search); ?>" class="search-input">
|
||||
|
||||
<select name="type_id">
|
||||
@@ -149,16 +165,13 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
<a href="?module=devices&action=list" class="button">Reset</a>
|
||||
|
||||
<a href="?module=devices&action=edit" class="button button-primary" style="margin-left: auto;">
|
||||
+ Neues Gerät
|
||||
+ Neues Geraet
|
||||
</a>
|
||||
</form>
|
||||
|
||||
<!-- =========================
|
||||
Geräte-Liste
|
||||
========================= -->
|
||||
<?php if (!empty($devices)): ?>
|
||||
<div class="device-stats">
|
||||
<p>Gefundene Geräte: <strong><?php echo count($devices); ?></strong></p>
|
||||
<p>Gefundene Geraete: <strong><?php echo count($devices); ?></strong></p>
|
||||
</div>
|
||||
|
||||
<table class="device-list">
|
||||
@@ -169,6 +182,7 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
<th>Stockwerk</th>
|
||||
<th>Rack</th>
|
||||
<th>Position (HE)</th>
|
||||
<th>Ports</th>
|
||||
<th>Seriennummer</th>
|
||||
<th>Webconfig</th>
|
||||
<th>Aktionen</th>
|
||||
@@ -186,28 +200,37 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<?php echo htmlspecialchars($d['floor_name'] ?? '—'); ?>
|
||||
<?php echo htmlspecialchars($d['floor_name'] ?? '-'); ?>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<?php echo htmlspecialchars($d['rack_name'] ?? '—'); ?>
|
||||
<?php echo htmlspecialchars($d['rack_name'] ?? '-'); ?>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<?php
|
||||
if ($d['rack_position_he']) {
|
||||
echo $d['rack_position_he'];
|
||||
echo (int)$d['rack_position_he'];
|
||||
if ($d['rack_height_he']) {
|
||||
echo "–" . ($d['rack_position_he'] + $d['rack_height_he'] - 1);
|
||||
echo '-' . ((int)$d['rack_position_he'] + (int)$d['rack_height_he'] - 1);
|
||||
}
|
||||
} else {
|
||||
echo "—";
|
||||
echo '-';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<small><?php echo htmlspecialchars($d['serial_number'] ?? '—'); ?></small>
|
||||
<small>
|
||||
<?php echo (int)$d['port_count']; ?> gesamt<br>
|
||||
<?php echo (int)$d['active_port_count']; ?> aktiv /
|
||||
<?php echo (int)$d['disabled_port_count']; ?> inaktiv<br>
|
||||
VLAN gesetzt: <?php echo (int)$d['vlan_port_count']; ?>
|
||||
</small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<small><?php echo htmlspecialchars($d['serial_number'] ?? '-'); ?></small>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@@ -216,13 +239,13 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
Webconfig
|
||||
</a>
|
||||
<?php else: ?>
|
||||
—
|
||||
-
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
|
||||
<td class="actions">
|
||||
<a href="?module=devices&action=edit&id=<?php echo $d['id']; ?>" class="button button-small">Bearbeiten</a>
|
||||
<a href="?module=devices&action=delete&id=<?php echo (int)$d['id']; ?>" class="button button-small button-danger" onclick="return confirmDelete(this, <?php echo (int)$d['id']; ?>, <?php echo (int)$d['connection_count']; ?>, <?php echo (int)$d['port_count']; ?>, <?php echo (int)$d['module_count']; ?>)">Löschen</a>
|
||||
<a href="?module=devices&action=delete&id=<?php echo (int)$d['id']; ?>" class="button button-small button-danger" onclick="return confirmDelete(this, <?php echo (int)$d['id']; ?>, <?php echo (int)$d['connection_count']; ?>, <?php echo (int)$d['port_count']; ?>, <?php echo (int)$d['module_count']; ?>)">Loeschen</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@@ -231,10 +254,10 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<p>Keine Geräte gefunden.</p>
|
||||
<p>Keine Geraete gefunden.</p>
|
||||
<p>
|
||||
<a href="?module=devices&action=edit" class="button button-primary">
|
||||
Erstes Gerät anlegen
|
||||
Erstes Geraet anlegen
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
@@ -351,33 +374,41 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
|
||||
<script>
|
||||
function confirmDelete(link, id, connectionCount, portCount, moduleCount) {
|
||||
if (confirm('Dieses Gerät wirklich löschen?')) {
|
||||
const hasDependencies = (connectionCount > 0) || (portCount > 0) || (moduleCount > 0);
|
||||
if (hasDependencies) {
|
||||
const details = [];
|
||||
if (connectionCount > 0) {
|
||||
details.push(connectionCount + ' Verbindungen');
|
||||
}
|
||||
if (portCount > 0) {
|
||||
details.push(portCount + ' Ports');
|
||||
}
|
||||
if (moduleCount > 0) {
|
||||
details.push(moduleCount + ' Port-Module');
|
||||
}
|
||||
const dependencyMessage = 'Es gibt abhängige Daten (' + details.join(', ') + '). Diese auch löschen?';
|
||||
if (!confirm(dependencyMessage)) {
|
||||
return false;
|
||||
}
|
||||
window.location.href = (link && link.href ? link.href : ('?module=devices&action=delete&id=' + encodeURIComponent(id))) + '&force=1';
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!confirm('Dieses Geraet wirklich loeschen?')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const requestDelete = (forceDelete) => {
|
||||
const body = ['id=' + encodeURIComponent(id)];
|
||||
if (forceDelete) {
|
||||
body.push('force=1');
|
||||
}
|
||||
|
||||
fetch('?module=devices&action=delete', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
||||
body: body.join('&')
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data && data.success) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data && data.requires_force) {
|
||||
if (confirm(data.message || 'Es gibt abhaengige Daten. Trotzdem loeschen?')) {
|
||||
requestDelete(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
alert((data && data.message) ? data.message : 'Loeschen fehlgeschlagen');
|
||||
})
|
||||
.catch(() => alert('Loeschen fehlgeschlagen'));
|
||||
};
|
||||
|
||||
requestDelete(false);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user