feat: complete package 2 delete flows and package 3 port management
This commit is contained in:
@@ -3,12 +3,20 @@
|
||||
* app/modules/devices/delete.php
|
||||
*
|
||||
* Loescht ein Geraet. Bei Abhaengigkeiten ist force=1 erforderlich.
|
||||
* Unterstuetzt GET-Redirects und AJAX-POST.
|
||||
*/
|
||||
|
||||
$deviceId = (int)($_GET['id'] ?? 0);
|
||||
$forceDelete = (int)($_GET['force'] ?? 0) === 1;
|
||||
$isPost = ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST';
|
||||
$deviceId = (int)($_POST['id'] ?? $_GET['id'] ?? 0);
|
||||
$forceDelete = (int)($_POST['force'] ?? $_GET['force'] ?? 0) === 1;
|
||||
|
||||
if ($deviceId <= 0) {
|
||||
if ($isPost) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Ungueltige Geraete-ID']);
|
||||
exit;
|
||||
}
|
||||
$_SESSION['error'] = "Ungueltige Geraete-ID";
|
||||
header('Location: ?module=devices&action=list');
|
||||
exit;
|
||||
@@ -21,6 +29,12 @@ $device = $sql->single(
|
||||
);
|
||||
|
||||
if (!$device) {
|
||||
if ($isPost) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code(404);
|
||||
echo json_encode(['success' => false, 'message' => 'Geraet nicht gefunden']);
|
||||
exit;
|
||||
}
|
||||
$_SESSION['error'] = "Geraet nicht gefunden";
|
||||
header('Location: ?module=devices&action=list');
|
||||
exit;
|
||||
@@ -70,7 +84,23 @@ if ($hasDependencies && !$forceDelete) {
|
||||
$parts[] = $moduleCount . ' Port-Module';
|
||||
}
|
||||
|
||||
$_SESSION['error'] = "Geraet hat abhaengige Daten (" . implode(', ', $parts) . "). Loeschen bitte bestaetigen.";
|
||||
$dependencyMessage = "Geraet hat abhaengige Daten (" . implode(', ', $parts) . "). Loeschen bitte bestaetigen.";
|
||||
if ($isPost) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code(409);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'requires_force' => true,
|
||||
'message' => $dependencyMessage,
|
||||
'dependencies' => [
|
||||
'connections' => $connectionCount,
|
||||
'ports' => $portCount,
|
||||
'modules' => $moduleCount
|
||||
]
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
$_SESSION['error'] = $dependencyMessage;
|
||||
header('Location: ?module=devices&action=edit&id=' . urlencode((string)$deviceId));
|
||||
exit;
|
||||
}
|
||||
@@ -91,8 +121,19 @@ $deleted = $sql->set(
|
||||
);
|
||||
|
||||
if ($deleted > 0) {
|
||||
if ($isPost) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode(['success' => true, 'message' => "Geraet geloescht: " . $device['name']]);
|
||||
exit;
|
||||
}
|
||||
$_SESSION['success'] = "Geraet geloescht: " . $device['name'];
|
||||
} else {
|
||||
if ($isPost) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Geraet konnte nicht geloescht werden']);
|
||||
exit;
|
||||
}
|
||||
$_SESSION['error'] = "Geraet konnte nicht geloescht werden";
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,19 @@ if ($isEdit) {
|
||||
// =========================
|
||||
$deviceTypes = $sql->get("SELECT id, name, category FROM device_types ORDER BY name", "", []);
|
||||
$racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
$devicePorts = [];
|
||||
|
||||
if ($isEdit) {
|
||||
$devicePorts = $sql->get(
|
||||
"SELECT dp.id, dp.name, dp.status, dp.mode, dp.vlan_config, pt.name AS port_type_name
|
||||
FROM device_ports dp
|
||||
LEFT JOIN port_types pt ON pt.id = dp.port_type_id
|
||||
WHERE dp.device_id = ?
|
||||
ORDER BY dp.id",
|
||||
"i",
|
||||
[$deviceId]
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -160,6 +173,67 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Ports</legend>
|
||||
<?php if ($isEdit): ?>
|
||||
<?php if (!empty($devicePorts)): ?>
|
||||
<p><small>Portstatus und VLAN-Zuordnung koennen hier direkt gepflegt werden (VLANs kommagetrennt, z. B. 10,20,30).</small></p>
|
||||
<table class="device-port-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Port-Typ</th>
|
||||
<th>Status</th>
|
||||
<th>Modus</th>
|
||||
<th>VLANs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($devicePorts as $port): ?>
|
||||
<?php
|
||||
$vlanValue = '';
|
||||
if (!empty($port['vlan_config'])) {
|
||||
$decodedVlans = json_decode((string)$port['vlan_config'], true);
|
||||
if (is_array($decodedVlans)) {
|
||||
$vlanValue = implode(', ', array_map('strval', $decodedVlans));
|
||||
} else {
|
||||
$vlanValue = (string)$port['vlan_config'];
|
||||
}
|
||||
}
|
||||
$statusValue = (string)($port['status'] ?? 'active');
|
||||
if (!in_array($statusValue, ['active', 'disabled'], true)) {
|
||||
$statusValue = 'active';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" name="device_ports[<?php echo (int)$port['id']; ?>][name]" value="<?php echo htmlspecialchars((string)$port['name']); ?>">
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars((string)($port['port_type_name'] ?? '-')); ?></td>
|
||||
<td>
|
||||
<select name="device_ports[<?php echo (int)$port['id']; ?>][status]">
|
||||
<option value="active" <?php echo $statusValue === 'active' ? 'selected' : ''; ?>>aktiv</option>
|
||||
<option value="disabled" <?php echo $statusValue === 'disabled' ? 'selected' : ''; ?>>inaktiv</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="device_ports[<?php echo (int)$port['id']; ?>][mode]" value="<?php echo htmlspecialchars((string)($port['mode'] ?? '')); ?>" placeholder="z. B. access/trunk">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="device_ports[<?php echo (int)$port['id']; ?>][vlan_config]" value="<?php echo htmlspecialchars($vlanValue); ?>" placeholder="10,20,30">
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<p><small>Zu diesem Geraet sind aktuell keine Ports vorhanden.</small></p>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<p><small>Ports werden nach dem ersten Speichern automatisch aus dem Geraetetyp erzeugt und koennen dann hier gepflegt werden.</small></p>
|
||||
<?php endif; ?>
|
||||
</fieldset>
|
||||
|
||||
<!-- =========================
|
||||
Aktionen
|
||||
========================= -->
|
||||
@@ -264,34 +338,64 @@ $racks = $sql->get("SELECT id, name FROM racks ORDER BY name", "", []);
|
||||
.button:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.device-port-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.device-port-table th,
|
||||
.device-port-table td {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.device-port-table input,
|
||||
.device-port-table select {
|
||||
width: 100%;
|
||||
min-width: 120px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<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.href = '?module=devices&action=list';
|
||||
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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ $rackHeightHe = (int)($_POST['rack_height_he'] ?? 1);
|
||||
$serialNumber = trim($_POST['serial_number'] ?? '');
|
||||
$comment = trim($_POST['comment'] ?? '');
|
||||
$webConfigUrl = trim($_POST['web_config_url'] ?? '');
|
||||
$devicePortRows = is_array($_POST['device_ports'] ?? null) ? $_POST['device_ports'] : [];
|
||||
if ($webConfigUrl === '') {
|
||||
$webConfigUrl = null;
|
||||
}
|
||||
@@ -88,6 +89,9 @@ if ($isNewDevice) {
|
||||
if ($isNewDevice && $deviceId > 0) {
|
||||
copyDevicePortsFromType($sql, $deviceId, $deviceTypeId);
|
||||
}
|
||||
if ($deviceId > 0 && !$isNewDevice && !empty($devicePortRows)) {
|
||||
syncDevicePorts($sql, $deviceId, $devicePortRows);
|
||||
}
|
||||
|
||||
$_SESSION['success'] = "Gerät gespeichert";
|
||||
|
||||
@@ -139,3 +143,105 @@ function copyDevicePortsFromType($sql, $deviceId, $deviceTypeId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function syncDevicePorts($sql, $deviceId, array $rows)
|
||||
{
|
||||
$ports = $sql->get(
|
||||
"SELECT id, name FROM device_ports WHERE device_id = ?",
|
||||
"i",
|
||||
[$deviceId]
|
||||
);
|
||||
if (empty($ports)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$allowedIds = [];
|
||||
$currentNames = [];
|
||||
foreach ($ports as $port) {
|
||||
$portId = (int)($port['id'] ?? 0);
|
||||
if ($portId <= 0) {
|
||||
continue;
|
||||
}
|
||||
$allowedIds[$portId] = true;
|
||||
$currentNames[$portId] = (string)($port['name'] ?? '');
|
||||
}
|
||||
|
||||
foreach ($rows as $portIdRaw => $row) {
|
||||
$portId = (int)$portIdRaw;
|
||||
if ($portId <= 0 || !isset($allowedIds[$portId]) || !is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = trim((string)($row['name'] ?? ''));
|
||||
if ($name === '') {
|
||||
$name = $currentNames[$portId] ?? ('Port ' . $portId);
|
||||
}
|
||||
|
||||
$status = trim((string)($row['status'] ?? 'active'));
|
||||
if (!in_array($status, ['active', 'disabled'], true)) {
|
||||
$status = 'active';
|
||||
}
|
||||
|
||||
$mode = trim((string)($row['mode'] ?? ''));
|
||||
$mode = $mode !== '' ? $mode : null;
|
||||
$vlanJson = normalizeVlanConfig($row['vlan_config'] ?? '');
|
||||
|
||||
if ($mode !== null && $vlanJson !== null) {
|
||||
$sql->set(
|
||||
"UPDATE device_ports
|
||||
SET name = ?, status = ?, mode = ?, vlan_config = ?
|
||||
WHERE id = ? AND device_id = ?",
|
||||
"ssssii",
|
||||
[$name, $status, $mode, $vlanJson, $portId, $deviceId]
|
||||
);
|
||||
} elseif ($mode !== null) {
|
||||
$sql->set(
|
||||
"UPDATE device_ports
|
||||
SET name = ?, status = ?, mode = ?, vlan_config = NULL
|
||||
WHERE id = ? AND device_id = ?",
|
||||
"sssii",
|
||||
[$name, $status, $mode, $portId, $deviceId]
|
||||
);
|
||||
} elseif ($vlanJson !== null) {
|
||||
$sql->set(
|
||||
"UPDATE device_ports
|
||||
SET name = ?, status = ?, mode = NULL, vlan_config = ?
|
||||
WHERE id = ? AND device_id = ?",
|
||||
"sssii",
|
||||
[$name, $status, $vlanJson, $portId, $deviceId]
|
||||
);
|
||||
} else {
|
||||
$sql->set(
|
||||
"UPDATE device_ports
|
||||
SET name = ?, status = ?, mode = NULL, vlan_config = NULL
|
||||
WHERE id = ? AND device_id = ?",
|
||||
"ssii",
|
||||
[$name, $status, $portId, $deviceId]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeVlanConfig($raw)
|
||||
{
|
||||
$value = trim((string)$raw);
|
||||
if ($value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = preg_split('/[\s,;]+/', $value);
|
||||
$normalized = [];
|
||||
foreach ((array)$parts as $part) {
|
||||
$entry = trim((string)$part);
|
||||
if ($entry === '') {
|
||||
continue;
|
||||
}
|
||||
$normalized[$entry] = true;
|
||||
}
|
||||
|
||||
if (empty($normalized)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return json_encode(array_keys($normalized), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user