161 lines
8.4 KiB
PHP
161 lines
8.4 KiB
PHP
<?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'; ?>
|