OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

custom_fields.php

15 KB
<?php $this->layout('layouts/admin', [
    'page_title'         => $page_title,
    'current_admin_page' => 'assets',
]); ?>

<div class="mb-3">
    <a href="<?= $this->e($back_url) ?>" class="btn btn-default"><i class="fas fa-arrow-left"></i> <?= $this->te('Zur&uuml;ck') ?></a>
</div>

<!-- Info -->
<div class="card card-outline card-primary mb-3">
    <div class="card-header">
        <h3 class="card-title"><i class="fas fa-wrench"></i> <?= $this->te('Benutzerdefinierte Felder') ?></h3>
        <p class="text-muted small mb-0">
            <?= $entity_type === 'category' ? 'Kategorie' : 'Modell / Typ' ?>:
            <strong><?= $this->e($entity['name']) ?></strong>
            <?php if ($entity_type === 'type' && !empty($entity['manufacturer_name'])): ?>
                <span class="text-muted"> (<?= $this->e($entity['manufacturer_name']) ?>)</span>
            <?php endif; ?>
        </p>
    </div>
</div>

<!-- Neues Feld anlegen -->
<div class="card card-outline card-primary mb-3">
    <div class="card-header">
        <h3 class="card-title"><i class="fas fa-plus"></i> <?= $this->te('Neues Feld anlegen') ?></h3>
        <p class="text-muted small mb-0"><?= $this->te('Freitext oder Dropdown mit vorgegebenen Werten.') ?></p>
    </div>
    <div class="card-body">
            <form action="<?= $this->e($base_url) ?>" method="POST" class="form" id="newFieldForm">
                <input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
                <div class="settings-grid" style="grid-template-columns:1fr 1fr 1fr;">
                    <div class="form-group">
                        <label><?= $this->te('Feldbezeichnung *') ?></label>
                        <input type="text" name="field_label" class="form-control" placeholder="<?= $this->te('z.B. CPU, RAM, Seriennummer') ?>" required maxlength="255">
                    </div>
                    <div class="form-group">
                        <label for="newFieldType"><?= $this->te('Feldtyp') ?></label>
                        <select name="field_type" class="form-control" id="newFieldType" onchange="toggleDropdownOptions('new')">
                            <option value="text"><?= $this->te('Freitext') ?></option>
                            <option value="dropdown"><?= $this->te('Dropdown') ?></option>
                        </select>
                    </div>
                    <div class="form-group">
                        <label for="f-c7b0-sort_order"><?= $this->te('Reihenfolge') ?></label>
                        <input id="f-c7b0-sort_order" type="number" name="sort_order" class="form-control" value="0" min="0">
                    </div>
                    <div class="form-group" id="newDropdownOptions" style="grid-column:1/-1;display:none;">
                        <label><?= $this->te('Dropdown-Optionen') ?> <small style="font-weight:400;color:var(--gray-500);"><?= $this->te('(eine Option pro Zeile)') ?></small></label>
                        <textarea name="dropdown_options" class="form-control" rows="4" placeholder="<?= $this->te('Option 1&#10;Option 2&#10;Option 3') ?>"></textarea>
                    </div>
                    <div class="form-group" id="newDefaultValue">
                        <label><?= $this->te('Standard-Wert') ?> <small style="font-weight:400;color:var(--gray-500);"><?= $this->te('(wird beim neuen Asset vorausgefüllt)') ?></small></label>
                        <input type="text" name="default_value" class="form-control" placeholder="<?= $this->te('z.B. 16 GB DDR4') ?>">
                    </div>
                    <div class="form-group" style="justify-content:center;padding-top:1.5rem;">
                        <label class="checkbox-label" style="display:flex;align-items:center;gap:0.5rem;cursor:pointer;">
                            <input type="checkbox" name="is_required" value="1">
                            <?= $this->te('Pflichtfeld') ?>
                        </label>
                    </div>
                    <div class="form-group" style="align-self:flex-end;">
                        <button type="submit" class="btn btn-primary"><?= $this->te('Feld anlegen') ?></button>
                    </div>
                </div>
            </form>
        </div>
</div>

<!-- Feldliste -->
<div class="card card-outline card-primary mb-3">
    <div class="card-header">
        <h3 class="card-title"><i class="fas fa-list"></i> <?= $this->t('Definierte Felder') ?> (<?= count($fields) ?>)</h3>
    </div>
    <div class="card-body table-responsive p-0">
            <?php if (empty($fields)): ?>
                <div style="padding:2rem;text-align:center;color:var(--gray-400);"><?= $this->te('Noch keine Felder definiert.') ?></div>
            <?php else: ?>
            <div class="admin-table-wrap">
                <table style="width:100%;border-collapse:collapse;font-size:0.875rem;">
                    <thead>
                        <tr>
                            <?php
                            $thStyle = 'padding:0.65rem 1rem;text-align:left;font-size:0.72rem;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;color:var(--gray-500);background:var(--gray-50);border-bottom:2px solid var(--gray-200);';
                            ?>
                            <th scope="col" style="<?= $thStyle ?>"><?= $this->te('Bezeichnung') ?></th>
                            <th scope="col" style="<?= $thStyle ?>"><?= $this->te('Typ') ?></th>
                            <th scope="col" style="<?= $thStyle ?>"><?= $this->te('Optionen') ?></th>
                            <th scope="col" style="<?= $thStyle ?>"><?= $this->te('Standard-Wert') ?></th>
                            <th scope="col" style="<?= $thStyle ?>"><?= $this->te('Reihenfolge') ?></th>
                            <th scope="col" style="<?= $thStyle ?>"><?= $this->te('Pflicht') ?></th>
                            <th scope="col" style="<?= $thStyle ?>;width:120px;"></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($fields as $field): ?>
                        <?php
                            $tdStyle = 'padding:0.65rem 1rem;border-bottom:1px solid var(--gray-100);vertical-align:middle;';
                            $options = [];
                            if ($field['dropdown_options']) {
                                $options = json_decode($field['dropdown_options'], true) ?: [];
                            }
                        ?>
                        <tr id="fieldRow-<?= $field['id'] ?>">
                            <td style="<?= $tdStyle ?>">
                                <strong><?= $this->e($field['field_label']) ?></strong>
                                <br><small style="color:var(--gray-400);font-size:0.75rem;"><?= $this->e($field['field_name']) ?></small>
                            </td>
                            <td style="<?= $tdStyle ?>">
                                <?php if ($field['field_type'] === 'dropdown'): ?>
                                    <span style="background:var(--violet-100);color:var(--violet-600);padding:0.15rem 0.5rem;border-radius:0.25rem;font-size:0.78rem;font-weight:600;"><?= $this->te('Dropdown') ?></span>
                                <?php else: ?>
                                    <span style="background:var(--sky-100);color:var(--sky-700);padding:0.15rem 0.5rem;border-radius:0.25rem;font-size:0.78rem;font-weight:600;"><?= $this->te('Freitext') ?></span>
                                <?php endif; ?>
                            </td>
                            <td style="<?= $tdStyle ?>;font-size:0.8rem;color:var(--gray-500);">
                                <?php if (!empty($options)): ?>
                                    <?= implode(', ', array_map([$this, 'e'], $options)) ?>
                                <?php else: ?>
                                    —
                                <?php endif; ?>
                            </td>
                            <td style="<?= $tdStyle ?>;font-size:0.85rem;color:var(--gray-700);">
                                <?= $field['default_value'] !== null && $field['default_value'] !== ''
                                    ? '<code style="font-size:0.8rem;background:var(--gray-100);padding:0.1rem 0.35rem;border-radius:0.2rem;">' . $this->e($field['default_value']) . '</code>'
                                    : '<span style="color:var(--gray-300);">—</span>' ?>
                            </td>
                            <td style="<?= $tdStyle ?>"><?= (int)$field['sort_order'] ?></td>
                            <td style="<?= $tdStyle ?>">
                                <?= $field['is_required'] ? '✅' : '—' ?>
                            </td>
                            <td style="<?= $tdStyle ?>">
                                <button onclick="toggleFieldEdit(<?= $field['id'] ?>)" class="btn btn-sm btn-secondary"><?= $this->te('Bearbeiten') ?></button>
                                <form method="POST" action="<?= $this->e($base_url) ?>/<?= $field['id'] ?>/delete" style="display:inline;"
                                      onsubmit="return confirm('Feld \'<?= $this->e(addslashes($field['field_label'])) ?>\' löschen?')">
                                    <input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
                                    <button aria-label="<?= $this->te('Löschen') ?>" type="submit" class="btn btn-sm btn-danger-outline">✕</button>
                                </form>
                            </td>
                        </tr>
                        <!-- Inline Edit Row -->
                        <tr id="fieldEdit-<?= $field['id'] ?>" style="display:none;background:var(--sky-50);">
                            <td colspan="7" style="padding:1rem 1.25rem;border-bottom:1px solid var(--gray-200);">
                                <form method="POST" action="<?= $this->e($base_url) ?>/<?= $field['id'] ?>" style="display:flex;gap:0.75rem;flex-wrap:wrap;align-items:flex-end;">
                                    <input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
                                    <input type="hidden" name="_method" value="PUT">

                                    <div style="display:flex;flex-direction:column;gap:0.25rem;min-width:180px;">
                                        <label style="font-size:0.75rem;font-weight:700;color:var(--gray-700);"><?= $this->te('Bezeichnung') ?></label>
                                        <input type="text" name="field_label" value="<?= $this->e($field['field_label']) ?>" class="form-control" required>
                                    </div>
                                    <div style="display:flex;flex-direction:column;gap:0.25rem;">
                                        <label for="editFieldType-                   " style="font-size:0.75rem;font-weight:700;color:var(--gray-700);"><?= $this->te('Typ') ?></label>
                                        <select name="field_type" class="form-control" id="editFieldType-<?= $field['id'] ?>"
                                                onchange="toggleDropdownOptions('edit-<?= $field['id'] ?>')">
                                            <option value="text" <?= $field['field_type'] === 'text' ? 'selected' : '' ?>><?= $this->te('Freitext') ?></option>
                                            <option value="dropdown" <?= $field['field_type'] === 'dropdown' ? 'selected' : '' ?>><?= $this->te('Dropdown') ?></option>
                                        </select>
                                    </div>
                                    <div id="editDropdownOptions-<?= $field['id'] ?>" style="display:<?= $field['field_type'] === 'dropdown' ? 'flex' : 'none' ?>;flex-direction:column;gap:0.25rem;min-width:220px;">
                                        <label style="font-size:0.75rem;font-weight:700;color:var(--gray-700);"><?= $this->te('Optionen (eine pro Zeile)') ?></label>
                                        <textarea name="dropdown_options" class="form-control" rows="3"><?= $this->e(implode("\n", $options)) ?></textarea>
                                    </div>
                                    <div style="display:flex;flex-direction:column;gap:0.25rem;">
                                        <label style="font-size:0.75rem;font-weight:700;color:var(--gray-700);"><?= $this->te('Reihenfolge') ?></label>
                                        <input type="number" name="sort_order" value="<?= (int)$field['sort_order'] ?>" class="form-control" style="width:80px;">
                                    </div>
                                    <div style="display:flex;flex-direction:column;gap:0.25rem;min-width:160px;">
                                        <label style="font-size:0.75rem;font-weight:700;color:var(--gray-700);"><?= $this->te('Standard-Wert') ?></label>
                                        <input type="text" name="default_value" value="<?= $this->e($field['default_value'] ?? '') ?>" class="form-control" placeholder="<?= $this->te('Leer = kein Standard') ?>">
                                    </div>
                                    <label style="display:flex;align-items:center;gap:0.4rem;font-size:0.8rem;cursor:pointer;padding-bottom:0.2rem;">
                                        <input type="checkbox" name="is_required" value="1" <?= $field['is_required'] ? 'checked' : '' ?>>
                                        <?= $this->te('Pflichtfeld') ?>
                                    </label>
                                    <button type="submit" class="btn btn-primary" style="white-space:nowrap;"><?= $this->te('💾 Speichern') ?></button>
                                    <button type="button" onclick="toggleFieldEdit(<?= $field['id'] ?>)" class="btn btn-secondary"><?= $this->te('Abbrechen') ?></button>
                                </form>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
            <?php endif; ?>
        </div>
</div>

<script>
function toggleDropdownOptions(prefix) {
    var select  = document.getElementById(prefix === 'new' ? 'newFieldType' : 'editFieldType-' + prefix.replace('edit-', ''));
    var wrapper = document.getElementById(prefix === 'new' ? 'newDropdownOptions' : 'editDropdownOptions-' + prefix.replace('edit-', ''));
    if (!select || !wrapper) return;
    wrapper.style.display = select.value === 'dropdown' ? 'flex' : 'none';
}

function toggleFieldEdit(id) {
    var row = document.getElementById('fieldEdit-' + id);
    row.style.display = row.style.display === 'none' ? '' : 'none';
}
</script>