Compare commits

..

2 Commits

Author SHA1 Message Date
2c90ff8ddf WIP: #8 2026-02-13 12:06:46 +01:00
39f7f9b733 WIP: device löschen 2026-02-13 11:55:18 +01:00
6 changed files with 174 additions and 17 deletions

View File

@@ -234,3 +234,4 @@ Hinweis: Die Eintraege sind direkt aus den Quelldateien aggregiert.
- [ ] L241: ### TODO: Patchpanel-Infrastruktur - [ ] L241: ### TODO: Patchpanel-Infrastruktur
- [ ] L253: - TODO: SVG-Editor um Drag & Drop für diese Objekte erweitern und Klicks direkt mit dem Modul verbinden. - [ ] L253: - TODO: SVG-Editor um Drag & Drop für diese Objekte erweitern und Klicks direkt mit dem Modul verbinden.
- [ ] //TODO infrastruktur patchfelder löschen soll implementiert werden.

View File

@@ -8,6 +8,8 @@
// Statistiken aus DB laden // Statistiken aus DB laden
// ========================= // =========================
//TODO eine große zoombare verschiebbare svg wand machen, mit allen punkten drauf. anklicken der punkte erzeugt ein overlay, mit der reingezoomten ansicht zb einem rack
$stats = [ $stats = [
'devices' => $sql->single("SELECT COUNT(*) as cnt FROM devices", "", [])['cnt'] ?? 0, 'devices' => $sql->single("SELECT COUNT(*) as cnt FROM devices", "", [])['cnt'] ?? 0,
'device_types' => $sql->single("SELECT COUNT(*) as cnt FROM device_types", "", [])['cnt'] ?? 0, 'device_types' => $sql->single("SELECT COUNT(*) as cnt FROM device_types", "", [])['cnt'] ?? 0,

View File

@@ -2,13 +2,14 @@
/** /**
* app/modules/devices/delete.php * app/modules/devices/delete.php
* *
* Löscht ein Gerät inkl. abhängiger Verbindungen. * Loescht ein Geraet. Bei Abhaengigkeiten ist force=1 erforderlich.
*/ */
$deviceId = (int)($_GET['id'] ?? 0); $deviceId = (int)($_GET['id'] ?? 0);
$forceDelete = (int)($_GET['force'] ?? 0) === 1;
if ($deviceId <= 0) { if ($deviceId <= 0) {
$_SESSION['error'] = "Ungültige Geräte-ID"; $_SESSION['error'] = "Ungueltige Geraete-ID";
header('Location: ?module=devices&action=list'); header('Location: ?module=devices&action=list');
exit; exit;
} }
@@ -20,12 +21,61 @@ $device = $sql->single(
); );
if (!$device) { if (!$device) {
$_SESSION['error'] = "Gerät nicht gefunden"; $_SESSION['error'] = "Geraet nicht gefunden";
header('Location: ?module=devices&action=list'); header('Location: ?module=devices&action=list');
exit; exit;
} }
// Verbindungen auf Ports dieses Geräts entfernen (keine FK auf device_ports in connections). $dependencies = $sql->single(
"SELECT
(
SELECT COUNT(*)
FROM device_ports dp
WHERE dp.device_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 = ?
) 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 = ?
))
OR (c.port_b_type = 'device' AND c.port_b_id IN (
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = ?
))
) AS connection_count",
"iiii",
[$deviceId, $deviceId, $deviceId, $deviceId]
);
$portCount = (int)($dependencies['port_count'] ?? 0);
$moduleCount = (int)($dependencies['module_count'] ?? 0);
$connectionCount = (int)($dependencies['connection_count'] ?? 0);
$hasDependencies = $portCount > 0 || $moduleCount > 0 || $connectionCount > 0;
if ($hasDependencies && !$forceDelete) {
$parts = [];
if ($connectionCount > 0) {
$parts[] = $connectionCount . ' Verbindungen';
}
if ($portCount > 0) {
$parts[] = $portCount . ' Ports';
}
if ($moduleCount > 0) {
$parts[] = $moduleCount . ' Port-Module';
}
$_SESSION['error'] = "Geraet hat abhaengige Daten (" . implode(', ', $parts) . "). Loeschen bitte bestaetigen.";
header('Location: ?module=devices&action=edit&id=' . urlencode((string)$deviceId));
exit;
}
// Connections referenzieren device_ports nur logisch, daher manuell entfernen.
$sql->set( $sql->set(
"DELETE FROM connections "DELETE FROM connections
WHERE (port_a_type = 'device' AND port_a_id IN (SELECT id FROM device_ports WHERE device_id = ?)) WHERE (port_a_type = 'device' AND port_a_id IN (SELECT id FROM device_ports WHERE device_id = ?))
@@ -41,9 +91,9 @@ $deleted = $sql->set(
); );
if ($deleted > 0) { if ($deleted > 0) {
$_SESSION['success'] = "Gerät gelöscht: " . $device['name']; $_SESSION['success'] = "Geraet geloescht: " . $device['name'];
} else { } else {
$_SESSION['error'] = "Gerät konnte nicht gelöscht werden"; $_SESSION['error'] = "Geraet konnte nicht geloescht werden";
} }
header('Location: ?module=devices&action=list'); header('Location: ?module=devices&action=list');

View File

@@ -24,6 +24,40 @@ if ($deviceId > 0) {
$isEdit = !empty($device); $isEdit = !empty($device);
$pageTitle = $isEdit ? "Gerät bearbeiten: " . htmlspecialchars($device['name']) : "Neues Gerät"; $pageTitle = $isEdit ? "Gerät bearbeiten: " . htmlspecialchars($device['name']) : "Neues Gerät";
$dependencyCounts = [
'port_count' => 0,
'module_count' => 0,
'connection_count' => 0
];
if ($isEdit) {
$dependencyCounts = $sql->single(
"SELECT
(
SELECT COUNT(*)
FROM device_ports dp
WHERE dp.device_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 = ?
) 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 = ?
))
OR (c.port_b_type = 'device' AND c.port_b_id IN (
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = ?
))
) AS connection_count",
"iiii",
[$deviceId, $deviceId, $deviceId, $deviceId]
) ?: $dependencyCounts;
}
// ========================= // =========================
// Optionen laden // Optionen laden
@@ -133,7 +167,7 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
<button type="submit" class="button button-primary">Speichern</button> <button type="submit" class="button button-primary">Speichern</button>
<a href="?module=devices&action=list" class="button">Abbrechen</a> <a href="?module=devices&action=list" class="button">Abbrechen</a>
<?php if ($isEdit): ?> <?php if ($isEdit): ?>
<a href="#" class="button button-danger" onclick="confirmDelete(<?php echo $deviceId; ?>)">Löschen</a> <a href="?module=devices&action=delete&id=<?php echo (int)$deviceId; ?>" class="button button-danger" onclick="return confirmDelete(this, <?php echo (int)$deviceId; ?>, <?php echo (int)$dependencyCounts['connection_count']; ?>, <?php echo (int)$dependencyCounts['port_count']; ?>, <?php echo (int)$dependencyCounts['module_count']; ?>)">Löschen</a>
<?php endif; ?> <?php endif; ?>
</fieldset> </fieldset>
@@ -233,9 +267,34 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
</style> </style>
<script> <script>
function confirmDelete(id) { function confirmDelete(link, id, connectionCount, portCount, moduleCount) {
if (confirm('Dieses Gerät wirklich löschen?')) { if (confirm('Dieses Gerät wirklich löschen?')) {
window.location.href = '?module=devices&action=delete&id=' + encodeURIComponent(id); 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;
}
return false;
} }
</script> </script>

View File

@@ -63,7 +63,28 @@ $whereSql = $where ? 'WHERE ' . implode(' AND ', $where) : '';
dt.name AS device_type, dt.name AS device_type,
dt.image_path, dt.image_path,
f.name AS floor_name, f.name AS floor_name,
r.name AS rack_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
FROM devices d FROM devices d
JOIN device_types dt ON dt.id = d.device_type_id JOIN device_types dt ON dt.id = d.device_type_id
LEFT JOIN racks r ON r.id = d.rack_id LEFT JOIN racks r ON r.id = d.rack_id
@@ -201,10 +222,7 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
<td class="actions"> <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=edit&id=<?php echo $d['id']; ?>" class="button button-small">Bearbeiten</a>
<a href="#" class="button button-small button-danger" onclick="confirmDelete(<?php echo $d['id']; ?>)">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']; ?>)">Löschen</a>
<?php
//TODO löschen geht nicht
?>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
@@ -332,9 +350,34 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
</style> </style>
<script> <script>
function confirmDelete(id) { function confirmDelete(link, id, connectionCount, portCount, moduleCount) {
if (confirm('Dieses Gerät wirklich löschen?')) { if (confirm('Dieses Gerät wirklich löschen?')) {
window.location.href = '?module=devices&action=delete&id=' + encodeURIComponent(id); 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;
}
return false;
} }
</script> </script>

View File

@@ -14,6 +14,8 @@
$search = trim($_GET['search'] ?? ''); $search = trim($_GET['search'] ?? '');
$floorId = (int)($_GET['floor_id'] ?? 0); $floorId = (int)($_GET['floor_id'] ?? 0);
//TODO racks beim editieren auf der stockwerkkarte platzieren und verschieben können
// ========================= // =========================
// WHERE-Clause bauen // WHERE-Clause bauen
// ========================= // =========================