ports beim erstellen des types erstellen

This commit is contained in:
2026-02-11 15:25:52 +01:00
parent 0d3c6e1ae7
commit a6b56ffd75
7 changed files with 199 additions and 33 deletions

View File

@@ -44,10 +44,11 @@ if (!in_array($action, $validActions)) {
}
/* =========================
* Template-Header laden
* Template-Header laden (nur für non-save Aktionen)
* ========================= */
require_once __DIR__ . '/templates/header.php';
// TODO: ggf. Navigation einbinden
if ($action !== 'save') {
require_once __DIR__ . '/templates/header.php';
}
/* =========================
* Modul laden
@@ -58,10 +59,14 @@ if (file_exists($modulePath)) {
require_once $modulePath;
} else {
// TODO: Fehlerseite oder 404
echo "<p>Die Seite existiert noch nicht.</p>".$modulePath;
if ($action !== 'save') {
echo "<p>Die Seite existiert noch nicht.</p>".$modulePath;
}
}
/* =========================
* Template-Footer laden
* Template-Footer laden (nur für non-save Aktionen)
* ========================= */
require_once __DIR__ . '/templates/footer.php';
if ($action !== 'save') {
require_once __DIR__ . '/templates/footer.php';
}

View File

@@ -74,6 +74,13 @@ $pageTitle = $isEdit ? "Gerätetyp bearbeiten: " . htmlspecialchars($deviceType[
<textarea id="comment" name="comment" rows="3"
placeholder="z.B. Rack-Mount, 48 RJ45 + 4 SFP"><?php echo htmlspecialchars($deviceType['comment'] ?? ''); ?></textarea>
</div>
<div class="form-group">
<label for="seed_ports">Ports automatisch anlegen</label>
<input type="number" id="seed_ports" name="seed_ports" min="0" step="1"
value="<?php echo htmlspecialchars((int)($_POST['seed_ports'] ?? 0)); ?>"
placeholder="z.B. 48">
<small>Beim Speichern werden bis zu dieser Zahl Platzhalter-Ports erstellt, bestehende Einträge bleiben erhalten.</small>
</div>
</fieldset>
<!-- =========================

View File

@@ -60,6 +60,31 @@
<!-- TODO: Import / Export -->
</div>
<form id="port-form" class="port-form" aria-hidden="true">
<div>
<label for="port-name">Portname</label>
<input id="port-name" name="name" required placeholder="z.B. Gi1/0/1">
</div>
<div>
<label for="port-type">Port-Typ</label>
<input id="port-type" name="type" required placeholder="RJ45, SFP …">
</div>
<div>
<label for="port-medium">Medium</label>
<input id="port-medium" name="medium" placeholder="Kupfer, LWL …">
</div>
<div>
<label for="port-mode">Modus</label>
<input id="port-mode" name="mode" placeholder="Access, Trunk …">
</div>
<div>
<label for="port-vlan">VLAN</label>
<input id="port-vlan" name="vlan" placeholder="10, 20-30 …">
</div>
<button type="submit" class="button button-primary">Port hinzufügen</button>
<button type="button" class="button" id="cancel-port">Abbrechen</button>
</form>
<!-- =========================
Port-Liste
========================= -->
@@ -76,7 +101,7 @@
<th>Aktionen</th>
</tr>
</thead>
<tbody>
<tbody id="port-list-body">
<?php /* foreach ($ports as $port): */ ?>
<tr>
@@ -142,14 +167,99 @@
JS-Konfiguration
========================= -->
<style>
.port-form {
display: none;
margin: 20px 0;
gap: 10px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 6px;
background: #f9f9f9;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
grid-auto-rows: minmax(50px, auto);
align-items: flex-start;
}
.port-form.visible {
display: grid;
}
.port-form div {
display: flex;
flex-direction: column;
}
.port-form label {
font-size: 0.85rem;
margin-bottom: 4px;
font-weight: bold;
}
.port-form input {
padding: 6px 8px;
border-radius: 4px;
border: 1px solid #bbb;
font-family: inherit;
}
.port-form button {
margin-top: 8px;
}
.port-form .button-primary {
justify-self: flex-start;
}
</style>
<script>
const addPortButton = document.getElementById('add-port');
const portForm = document.getElementById('port-form');
const portListBody = document.getElementById('port-list-body');
const cancelPortButton = document.getElementById('cancel-port');
let portCounter = portListBody.querySelectorAll('tr').length + 1;
function showPortForm(show = true) {
portForm.classList.toggle('visible', show);
portForm.setAttribute('aria-hidden', show ? 'false' : 'true');
if (show) {
portForm.querySelector('input').focus();
}
}
addPortButton.addEventListener('click', (event) => {
event.preventDefault();
showPortForm(portForm.getAttribute('aria-hidden') === 'true');
});
cancelPortButton.addEventListener('click', () => {
showPortForm(false);
portForm.reset();
});
portForm.addEventListener('submit', (event) => {
event.preventDefault();
const data = new FormData(portForm);
const row = document.createElement('tr');
row.innerHTML = `
<td>${portCounter++}</td>
<td>${data.get('name') || '-'}</td>
<td>${data.get('type') || '-'}</td>
<td>${data.get('medium') || '-'}</td>
<td>${data.get('mode') || '-'}</td>
<td>${data.get('vlan') || '-'}</td>
<td>
<button type="button">Bearbeiten</button>
<button type="button">Löschen</button>
</td>
`;
portListBody.appendChild(row);
showPortForm(false);
portForm.reset();
});
/**
* Konfiguration für svg-editor.js
* TODO: Replace this mock logic with real AJAX once ports are
* persisted on the backend.
*/
// TODO: Gerätetyp-ID setzen
// window.DEVICE_TYPE_ID = <?= (int)$deviceTypeId ?>;
// TODO: Ports an JS übergeben
// window.DEVICE_TYPE_PORTS = <?= json_encode($ports) ?>;
</script>

View File

@@ -21,6 +21,7 @@ $deviceTypeId = (int)($_POST['id'] ?? 0);
$name = trim($_POST['name'] ?? '');
$category = $_POST['category'] ?? 'other';
$comment = trim($_POST['comment'] ?? '');
$seedPortCount = max(0, (int)($_POST['seed_ports'] ?? 0));
// =========================
// Validierung
@@ -46,6 +47,7 @@ if (!empty($errors)) {
// Bild-Upload verarbeiten
// =========================
$imagePath = null;
$imageType = null;
if (!empty($_FILES['image']['name'])) {
$file = $_FILES['image'];
$tmpName = $file['tmp_name'];
@@ -71,6 +73,7 @@ if (!empty($_FILES['image']['name'])) {
if (move_uploaded_file($tmpName, $destPath)) {
$imagePath = 'uploads/device_types/' . $newFileName;
$imageType = $fileExt === 'svg' ? 'svg' : 'bitmap';
} else {
$_SESSION['error'] = "Datei-Upload fehlgeschlagen";
header('Location: ?module=device_types&action=edit' . ($deviceTypeId ? "&id=$deviceTypeId" : ""));
@@ -83,22 +86,40 @@ if (!empty($_FILES['image']['name'])) {
// =========================
if ($deviceTypeId > 0) {
// UPDATE
$sql->set(
"UPDATE device_types SET name = ?, category = ?, comment = ?" . ($imagePath ? ", image_path = ?, image_type = ?" : "") . " WHERE id = ?",
$imagePath ? "sssss" : "sssi",
$imagePath ? [$name, $category, $comment, $imagePath, $fileExt, $deviceTypeId] : [$name, $category, $comment, $deviceTypeId]
);
if ($imagePath) {
$sql->set(
"UPDATE device_types SET name = ?, category = ?, comment = ?, image_path = ?, image_type = ? WHERE id = ?",
"sssisi",
[$name, $category, $comment, $imagePath, $imageType, $deviceTypeId]
);
} else {
$sql->set(
"UPDATE device_types SET name = ?, category = ?, comment = ? WHERE id = ?",
"sssi",
[$name, $category, $comment, $deviceTypeId]
);
}
} else {
// INSERT
$imageType = $imagePath ? $fileExt : null;
$sql->set(
"INSERT INTO device_types (name, category, comment, image_path, image_type) VALUES (?, ?, ?, ?, ?)",
"sssss",
[$name, $category, $comment, $imagePath, $imageType]
);
$deviceTypeId = $sql->h->insert_id;
if ($imagePath) {
$deviceTypeId = $sql->set(
"INSERT INTO device_types (name, category, comment, image_path, image_type) VALUES (?, ?, ?, ?, ?)",
"sssss",
[$name, $category, $comment, $imagePath, $imageType],
true
);
} else {
$deviceTypeId = $sql->set(
"INSERT INTO device_types (name, category, comment, image_path, image_type) VALUES (?, ?, ?, NULL, ?)",
"ssss",
[$name, $category, $comment, 'bitmap'],
true
);
}
}
seedDeviceTypePorts($sql, $deviceTypeId, $seedPortCount);
$_SESSION['success'] = $deviceTypeId ? "Gerätetyp gespeichert" : "Fehler beim Speichern";
// =========================
@@ -107,3 +128,28 @@ $_SESSION['success'] = $deviceTypeId ? "Gerätetyp gespeichert" : "Fehler beim S
header('Location: ?module=device_types&action=list');
exit;
function seedDeviceTypePorts($sql, $deviceTypeId, $targetCount)
{
if ($deviceTypeId <= 0 || $targetCount <= 0) {
return;
}
$result = $sql->single(
"SELECT COUNT(*) AS count FROM device_type_ports WHERE device_type_id = ?",
"i",
[$deviceTypeId]
);
$existing = (int)($result['count'] ?? 0);
$toCreate = max(0, $targetCount - $existing);
for ($i = 1; $i <= $toCreate; $i++) {
$index = $existing + $i;
$sql->set(
"INSERT INTO device_type_ports (device_type_id, name, port_type_id, x, y) VALUES (?, ?, NULL, 0, 0)",
"is",
[$deviceTypeId, "Port $index"]
);
}
}

View File

@@ -59,7 +59,7 @@ if ($rackId > 0) {
// INSERT
$sql->set(
"INSERT INTO racks (name, floor_id, height_he, comment) VALUES (?, ?, ?, ?)",
"sii s",
"siis",
[$name, $floorId, $heightHe, $comment]
);
}

View File

@@ -43,12 +43,12 @@
<nav class="main-nav">
<ul>
<?php foreach ($navItems as $module => $label): ?>
<?php foreach ($navItems as $navModule => $label): ?>
<?php
$active = ($currentModule === $module) ? 'active' : '';
$active = ($currentModule === $navModule) ? 'active' : '';
?>
<li class="<?= $active ?>">
<a href="?module=<?= $module ?>&action=list">
<a href="?module=<?= $navModule ?>&action=list">
<?= $label ?>
</a>
</li>