feat: Implement floors, locations, and racks management

- Added list, edit, and save functionalities for floors, locations, and racks.
- Enhanced UI with search and filter options for better usability.
- Implemented SVG upload for floor plans in the floors module.
- Added validation for required fields in the save processes.
- Improved navigation in the header to reflect new modules.
- Styled forms and tables for a consistent look and feel across modules.
This commit is contained in:
2026-02-11 14:34:07 +01:00
parent 2f341bff9f
commit 0d3c6e1ae7
26 changed files with 3753 additions and 1045 deletions

View File

@@ -5,216 +5,83 @@
* Speichert / aktualisiert ein Gerät
* - Basisdaten
* - Rack-Zuordnung
* - Ports (automatisch aus Device-Type oder manuell)
*
* Erwartet POST (form-data ODER JSON)
*/
require_once __DIR__ . '/../../bootstrap.php';
// =========================
// Request prüfen
// =========================
// Nur POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Invalid request method']);
header('Location: ?module=devices&action=list');
exit;
}
// =========================
// Daten einlesen (JSON oder POST)
// Daten einlesen
// =========================
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (str_contains($contentType, 'application/json')) {
$data = json_decode(file_get_contents('php://input'), true) ?? [];
} else {
$data = $_POST;
}
// =========================
// Basisfelder
// =========================
$deviceId = isset($data['id']) ? (int)$data['id'] : null;
$name = trim($data['name'] ?? '');
$comment = trim($data['comment'] ?? '');
$deviceTypeId = (int)($data['device_type_id'] ?? 0);
$rackId = isset($data['rack_id']) ? (int)$data['rack_id'] : null;
$rackPositionHe = isset($data['rack_position_he']) ? (int)$data['rack_position_he'] : null;
$rackHeightHe = isset($data['rack_height_he']) ? (int)$data['rack_height_he'] : null;
$serialNumber = trim($data['serial_number'] ?? '');
$portsData = $data['ports'] ?? null;
$deviceId = (int)($_POST['id'] ?? 0);
$name = trim($_POST['name'] ?? '');
$deviceTypeId = (int)($_POST['device_type_id'] ?? 0);
$rackId = (int)($_POST['rack_id'] ?? 0);
$rackPositionHe = (int)($_POST['rack_position_he'] ?? 0);
$rackHeightHe = (int)($_POST['rack_height_he'] ?? 1);
$serialNumber = trim($_POST['serial_number'] ?? '');
$comment = trim($_POST['comment'] ?? '');
// =========================
// Validierung
// =========================
$errors = [];
if ($name === '') {
$errors[] = 'Name darf nicht leer sein';
if (empty($name)) {
$errors[] = "Name ist erforderlich";
}
$deviceType = $sql->single(
"SELECT * FROM device_types WHERE id = ?",
"i",
[$deviceTypeId]
);
if (!$deviceType) {
$errors[] = 'Ungültiger Gerätetyp';
if ($deviceTypeId <= 0) {
$errors[] = "Gerätetyp ist erforderlich";
}
if ($rackId !== null) {
$rack = $sql->single(
"SELECT * FROM racks WHERE id = ?",
"i",
[$rackId]
);
if (!$rack) {
$errors[] = 'Ungültiges Rack';
} elseif ($rackHeightHe !== null && $rackPositionHe !== null) {
if ($rackPositionHe < 1 || ($rackPositionHe + $rackHeightHe - 1) > $rack['height_he']) {
$errors[] = 'Gerät passt nicht ins Rack';
}
}
if ($rackId <= 0) {
$errors[] = "Rack ist erforderlich";
}
if ($errors) {
http_response_code(400);
echo json_encode([
'status' => 'error',
'errors' => $errors
]);
if ($rackPositionHe <= 0) {
$errors[] = "Rack-Position muss >= 1 sein";
}
if ($rackHeightHe < 1) {
$errors[] = "Höhe muss >= 1 sein";
}
// Falls Fehler: zurück zum Edit-Formular
if (!empty($errors)) {
$_SESSION['error'] = implode(', ', $errors);
$redirectUrl = $deviceId ? "?module=devices&action=edit&id=$deviceId" : "?module=devices&action=edit";
header("Location: $redirectUrl");
exit;
}
// =========================
// Device speichern
// In DB speichern
// =========================
if ($deviceId) {
if ($deviceId > 0) {
// UPDATE
$sql->set(
"
UPDATE devices SET
name = ?,
comment = ?,
device_type_id = ?,
rack_id = ?,
rack_position_he = ?,
rack_height_he = ?,
serial_number = ?
WHERE id = ?
",
"ssiiii si",
[
$name,
$comment,
$deviceTypeId,
$rackId,
$rackPositionHe,
$rackHeightHe,
$serialNumber,
$deviceId
]
"UPDATE devices SET name = ?, device_type_id = ?, rack_id = ?, rack_position_he = ?, rack_height_he = ?, serial_number = ?, comment = ? WHERE id = ?",
"siiiissi",
[$name, $deviceTypeId, $rackId, $rackPositionHe, $rackHeightHe, $serialNumber, $comment, $deviceId]
);
} else {
$deviceId = $sql->set(
"
INSERT INTO devices
(name, comment, device_type_id, rack_id, rack_position_he, rack_height_he, serial_number)
VALUES
(?, ?, ?, ?, ?, ?, ?)
",
"ssiiiii",
[
$name,
$comment,
$deviceTypeId,
$rackId,
$rackPositionHe,
$rackHeightHe,
$serialNumber
],
true
// INSERT
$sql->set(
"INSERT INTO devices (name, device_type_id, rack_id, rack_position_he, rack_height_he, serial_number, comment) VALUES (?, ?, ?, ?, ?, ?, ?)",
"siiiiss",
[$name, $deviceTypeId, $rackId, $rackPositionHe, $rackHeightHe, $serialNumber, $comment]
);
// =========================
// Ports vom Device-Type übernehmen (nur bei NEU)
// =========================
$typePorts = $sql->get(
"
SELECT name, port_type_id
FROM device_type_ports
WHERE device_type_id = ?
ORDER BY id
",
"i",
[$deviceTypeId]
);
foreach ($typePorts as $tp) {
$sql->set(
"
INSERT INTO device_ports
(device_id, name, port_type_id)
VALUES
(?, ?, ?)
",
"isi",
[
$deviceId,
$tp['name'],
$tp['port_type_id']
]
);
}
$deviceId = $sql->h->insert_id;
}
// =========================
// Ports aktualisieren (optional, z. B. VLAN / Mode)
// =========================
if (is_array($portsData)) {
foreach ($portsData as $portId => $port) {
$status = $port['status'] ?? 'active';
$mode = $port['mode'] ?? null;
$vlan = isset($port['vlan_config']) ? json_encode($port['vlan_config']) : null;
$sql->set(
"
UPDATE device_ports SET
status = ?,
mode = ?,
vlan_config = ?
WHERE id = ? AND device_id = ?
",
"sssii",
[
$status,
$mode,
$vlan,
(int)$portId,
$deviceId
]
);
}
}
$_SESSION['success'] = "Gerät gespeichert";
// =========================
// Antwort
// Redirect
// =========================
echo json_encode([
'status' => 'ok',
'id' => $deviceId
]);
header('Location: ?module=devices&action=list');
exit;