Files
deskhub/DeskHub-Webseite/staff/custom_lists.php
T
2026-11-05 21:21:48 +00:00

161 lines
8.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/../includes/bootstrap.php';
require_once __DIR__ . '/_ui.php';
$staff = require_admin_or_permission('manage_custom_fields');
$pdo = get_db();
$errors = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'create' || $action === 'update') {
$id = (int) ($_POST['id'] ?? 0);
$name = trim($_POST['name'] ?? '');
$sort = (int) ($_POST['sort_order'] ?? 0);
$notes = trim($_POST['notes'] ?? '');
// Einträge: eine Zeile = ein Wert; Reihenfolge der Zeilen = Sortierung, doppelte Werte entfallen
$values = [];
foreach (preg_split('/\R/', (string) ($_POST['items'] ?? '')) as $line) {
$line = trim($line);
if ($line !== '' && !in_array($line, $values, true)) $values[] = $line;
}
if ($name === '') $errors[] = 'Bitte einen Namen angeben.';
$dup = $pdo->prepare('SELECT COUNT(*) FROM custom_lists WHERE LOWER(name) = LOWER(?) AND id <> ?');
$dup->execute([$name, $id]);
if ($dup->fetchColumn() > 0) $errors[] = 'Eine Liste mit diesem Namen existiert bereits.';
if (!$errors) {
if ($action === 'create') {
$pdo->prepare('INSERT INTO custom_lists (name, sort_order, notes, created_at, updated_at) VALUES (?,?,?,?,?)')->execute([$name, $sort, $notes ?: null, db_now(), db_now()]);
$id = (int) $pdo->lastInsertId();
audit_log($staff['id'], "Liste erstellt: {$name}");
flash('success', 'Liste erstellt.');
} else {
$pdo->prepare('UPDATE custom_lists SET name=?, sort_order=?, notes=?, updated_at=? WHERE id=?')->execute([$name, $sort, $notes ?: null, db_now(), $id]);
audit_log($staff['id'], "Liste aktualisiert: {$name}");
flash('success', 'Änderungen gespeichert.');
}
// Einträge abgleichen: Bestehende behalten (und umsortieren), neue anlegen, entfernte löschen
$existing = $pdo->prepare('SELECT id, value FROM custom_list_items WHERE list_id = ?');
$existing->execute([$id]);
$byValue = array_column($existing->fetchAll(), 'id', 'value');
$upd = $pdo->prepare('UPDATE custom_list_items SET sort_order = ? WHERE id = ?');
$ins = $pdo->prepare('INSERT INTO custom_list_items (list_id, value, sort_order) VALUES (?,?,?)');
foreach ($values as $i => $val) {
if (isset($byValue[$val])) { $upd->execute([($i + 1) * 10, $byValue[$val]]); unset($byValue[$val]); }
else $ins->execute([$id, $val, ($i + 1) * 10]);
}
$del = $pdo->prepare('DELETE FROM custom_list_items WHERE id = ?');
foreach ($byValue as $itemId) $del->execute([$itemId]);
redirect('/staff/custom_lists.php');
}
}
if ($action === 'delete') {
$id = (int) $_POST['id'];
$pdo->prepare('DELETE FROM custom_list_items WHERE list_id = ?')->execute([$id]);
$pdo->prepare('DELETE FROM custom_lists WHERE id = ?')->execute([$id]);
audit_log($staff['id'], "Liste gelöscht: #{$id}");
flash('success', 'Liste gelöscht.');
redirect('/staff/custom_lists.php');
}
}
$isNew = isset($_GET['new']);
$editId = (int) ($_GET['edit'] ?? 0);
$showForm = $isNew || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true));
$lists = $pdo->query('SELECT l.*, (SELECT COUNT(*) FROM custom_list_items i WHERE i.list_id = l.id) AS item_count FROM custom_lists l ORDER BY l.sort_order, l.name')->fetchAll();
$editList = null; $editItems = [];
if ($editId) {
$es = $pdo->prepare('SELECT * FROM custom_lists WHERE id = ?'); $es->execute([$editId]);
$editList = $es->fetch() ?: null;
$ei = $pdo->prepare('SELECT value FROM custom_list_items WHERE list_id = ? ORDER BY sort_order, value'); $ei->execute([$editId]);
$editItems = $ei->fetchAll(PDO::FETCH_COLUMN);
}
$pageTitle = 'Benutzerdefinierte Listen'; $activePage = 'custom_lists';
require __DIR__ . '/_header.php';
?>
<?php foreach ($errors as $err): ?><div class="flash error"><?= e($err) ?></div><?php endforeach; ?>
<?php if ($showForm): ?>
<?php
$f = fn(string $k, $default = '') => $_POST[$k] ?? $default;
$v = fn(string $k, string $col, $default = '') => $f($k, $editList[$col] ?? $default);
?>
<h1>
<?= $editList ? 'Liste aktualisieren' : 'Neue Liste' ?>
<?php if ($editList): ?><span class="muted" style="font-size:1rem;font-weight:400">— <?= e($editList['name']) ?></span><?php endif; ?>
</h1>
<form method="post" class="card" style="padding:0">
<?= csrf_field() ?>
<input type="hidden" name="action" value="<?= $editList ? 'update' : 'create' ?>">
<?php if ($editList): ?><input type="hidden" name="id" value="<?= (int) $editList['id'] ?>"><?php endif; ?>
<?php ui_tab_bar(['list' => 'Liste', 'items' => 'Einträge']); ?>
<div class="tab-pane" data-pane="list" style="padding:16px 20px">
<h3 style="margin-top:0">Listeninformationen</h3>
<label for="name">Name *</label>
<input type="text" id="name" name="name" value="<?= e($v('name', 'name')) ?>" placeholder="z. B. Betriebssysteme" required>
<label for="sort_order">Sortierung</label>
<input type="number" id="sort_order" name="sort_order" value="<?= e((string) $v('sort_order', 'sort_order', '0')) ?>" style="max-width:140px">
<h3>Administratornotizen <span class="muted" style="font-weight:400;font-size:.85rem">– Interne Notizen, sichtbar für alle Administratoren</span></h3>
<textarea name="notes" rows="5"><?= e($v('notes', 'notes')) ?></textarea>
<p class="muted" style="font-size:.82rem">Wiederverwendbare Auswahllisten für Ticket-Felder: Wähle in einem <a href="/staff/custom_fields.php">Ticket-Feld</a> den Typ „Liste“ und verknüpfe diese Liste.</p>
</div>
<div class="tab-pane" data-pane="items" style="padding:16px 20px;display:none">
<label for="items" style="margin-top:0">Einträge – ein Wert pro Zeile, die Reihenfolge entspricht der Anzeige</label>
<textarea id="items" name="items" rows="14" style="font-family:monospace"><?= e($_POST ? (string) ($_POST['items'] ?? '') : implode("\n", $editItems)) ?></textarea>
<p class="muted" style="font-size:.78rem">Entfernte Zeilen werden gelöscht, bereits in Tickets gespeicherte Werte bleiben dort unverändert sichtbar.</p>
</div>
<div class="btn-row" style="padding:0 20px 18px">
<button type="submit" class="btn"><?= $editList ? 'Änderungen speichern' : 'Erstellen' ?></button>
<a href="/staff/custom_lists.php" class="btn secondary">Abbrechen</a>
</div>
</form>
<?php ui_tab_assets('list'); ?>
<?php else: ?>
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px">
<h1 style="margin:0">Benutzerdefinierte Listen</h1>
<a href="/staff/custom_lists.php?new=1" class="btn">Neue Liste hinzufügen</a>
</div>
<p class="muted">Wiederverwendbare Auswahllisten für Ticket-Felder. Wähle in einem Ticket-Feld den Typ „Liste“ und verknüpfe eine dieser Listen.</p>
<div class="card">
<table>
<thead><tr><th>Name</th><th style="text-align:center">Einträge</th><th>Erstellt</th><th>Zuletzt aktualisiert</th><th></th></tr></thead>
<tbody>
<?php foreach ($lists as $l): ?>
<tr>
<td><a href="/staff/custom_lists.php?edit=<?= (int) $l['id'] ?>"><?= e($l['name']) ?></a></td>
<td style="text-align:center"><?= (int) $l['item_count'] ?></td>
<td class="muted" style="font-size:.82rem"><?= e(ui_date($l['created_at'] ?? null)) ?></td>
<td class="muted" style="font-size:.82rem"><?= e(ui_date($l['updated_at'] ?? null)) ?></td>
<td style="white-space:nowrap">
<a href="/staff/custom_lists.php?edit=<?= (int) $l['id'] ?>">Bearbeiten</a> ·
<form method="post" style="display:inline" onsubmit="return confirm('Liste wirklich löschen?')">
<?= csrf_field() ?>
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= (int) $l['id'] ?>">
<button type="submit" style="background:none;border:none;color:#dc2626;cursor:pointer;padding:0;font-size:.9rem">Löschen</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php if (!$lists): ?><tr><td colspan="5" class="muted">Noch keine Listen angelegt.</td></tr><?php endif; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php require __DIR__ . '/_footer.php'; ?>