OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

ticket_new.php

9 KB
<?php $this->layout('layouts/portal', [
    'page_title' => 'Neues Ticket',
    'ssp_active' => 'tickets',
]);
$du = ($portal_address ?? 'du') !== 'sie';
?>
<a href="/portal/tickets" class="ssp-back"><i class="fas fa-arrow-left" aria-hidden="true"></i> <?= $this->te('Meine Tickets') ?></a>

<div class="ssp-hello">
    <h1><?= $this->te('Neues Ticket') ?></h1>
    <p><?= $du
        ? $this->te('Beschreibe dein Anliegen so konkret wie möglich – Screenshots helfen der IT bei der schnellen Bearbeitung.')
        : $this->te('Beschreiben Sie Ihr Anliegen so konkret wie möglich – Screenshots helfen der IT bei der schnellen Bearbeitung.') ?></p>
</div>

<?php if (!empty($known_issues)): ?>
<div class="ssp-card ssp-deflect">
    <h2><span class="ssp-card-icon"><i class="fas fa-exclamation-triangle" aria-hidden="true"></i></span> <?= $this->te('Bekannte Störung?') ?></h2>
    <p><?= $du
        ? $this->te('Zu folgenden Störungen arbeitet die IT bereits an einer Lösung. Bist du davon betroffen, melde dich einfach dazu – wir informieren dich, sobald es Neuigkeiten gibt. Ein eigenes Ticket ist dann nicht nötig.')
        : $this->te('Zu folgenden Störungen arbeitet die IT bereits an einer Lösung. Sind Sie davon betroffen, melden Sie sich einfach dazu – wir informieren Sie, sobald es Neuigkeiten gibt. Ein eigenes Ticket ist dann nicht nötig.') ?></p>
    <div class="ssp-deflect-list">
        <?php foreach ($known_issues as $issue): ?>
        <form method="POST" action="/portal/tickets/affected" class="ssp-deflect-item">
            <input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
            <input type="hidden" name="incident_id" value="<?= (int)$issue['id'] ?>">
            <span class="ssp-deflect-title"><?= $this->e($issue['title']) ?></span>
            <button type="submit" class="btn btn-sm btn-default" data-busy-label="Wird gemeldet …">
                <i class="fas fa-hand-paper" aria-hidden="true"></i> <?= $this->te('Ich bin auch betroffen') ?>
            </button>
        </form>
        <?php endforeach; ?>
    </div>
</div>
<?php endif; ?>

<div class="ssp-card ssp-form">
    <form method="POST" action="/portal/tickets" enctype="multipart/form-data">
        <input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
        <div class="form-group">
            <label for="ssp-subject"><?= $this->te('Betreff') ?> <span class="text-danger">*</span></label>
            <input type="text" id="ssp-subject" name="subject" class="form-control" required maxlength="500"
                   value="<?= $this->e($draft_subject ?? '') ?>" autocomplete="off"
                   placeholder="<?= $du ? $this->te('Worum geht es? (kurz und knapp)') : $this->te('Worum geht es? (kurz und knapp)') ?>">
            <div id="ssp-kb-hits" class="ssp-kb-hits" hidden>
                <p class="ssp-kb-hits-head"><i class="fas fa-lightbulb" aria-hidden="true"></i>
                    <?= $du ? $this->te('Vielleicht hilft dir das schon weiter:') : $this->te('Vielleicht hilft Ihnen das schon weiter:') ?></p>
                <ul id="ssp-kb-hits-list"></ul>
            </div>
        </div>
        <div class="form-group">
            <label for="ssp-body"><?= $this->te('Beschreibung') ?> <span class="text-danger">*</span></label>
            <textarea id="ssp-body" name="body" class="form-control" rows="7" required
                      placeholder="<?= $du
                          ? $this->te('Was ist passiert? Seit wann? Was hast du schon versucht?')
                          : $this->te('Was ist passiert? Seit wann? Was haben Sie schon versucht?') ?>"><?= $this->e($draft_body ?? '') ?></textarea>
        </div>
        <div class="ssp-form-row">
            <?php if (!empty($categories)): ?>
            <div class="form-group">
                <label for="ssp-category"><?= $this->te('Kategorie') ?></label>
                <select id="ssp-category" name="category_id" class="form-control">
                    <option value=""><?= $this->te('– Bitte wählen (optional) –') ?></option>
                    <?php foreach ($categories as $cat): ?>
                    <option value="<?= (int)$cat['id'] ?>"><?= str_repeat('&nbsp;&nbsp;&nbsp;', (int)($cat['_depth'] ?? 0)) ?><?= $this->e($cat['name']) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <?php endif; ?>
            <?php if (!empty($locations)): ?>
            <div class="form-group">
                <label for="ssp-location"><?= $this->te('Standort') ?></label>
                <select id="ssp-location" name="location_id" class="form-control">
                    <option value=""><?= $this->te('– Bitte wählen (optional) –') ?></option>
                    <?php foreach ($locations as $loc): ?>
                    <option value="<?= (int)$loc['id'] ?>"><?= str_repeat('&nbsp;&nbsp;&nbsp;', (int)($loc['_depth'] ?? 0)) ?><?= $this->e($loc['name']) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <?php endif; ?>
        </div>
        <?php if (!empty($my_assets)): ?>
        <div class="form-group">
            <label for="ssp-asset"><?= $this->te('Betroffenes Gerät') ?></label>
            <select id="ssp-asset" name="asset_id" class="form-control">
                <option value=""><?= $this->te('– Kein Gerät (optional) –') ?></option>
                <?php foreach ($my_assets as $a):
                    $label = trim(($a['manufacturer_name'] ?? '') . ' ' . ($a['type_name'] ?? ''));
                    $label = $a['inventory_number'] . ($a['name'] ? ' · ' . $a['name'] : '') . ($label !== '' ? ' (' . $label . ')' : '');
                ?>
                <option value="<?= (int)$a['id'] ?>" <?= (int)($prefill_asset ?? 0) === (int)$a['id'] ? 'selected' : '' ?>><?= $this->e($label) ?></option>
                <?php endforeach; ?>
            </select>
            <span class="ssp-form-hint"><?= $du ? $this->te('Deine zugewiesenen Geräte – hilft der IT bei der Zuordnung.') : $this->te('Ihre zugewiesenen Geräte – hilft der IT bei der Zuordnung.') ?></span>
        </div>
        <?php endif; ?>
        <div class="form-group">
            <label class="ssp-att-label" for="ssp-tn-att"><i class="fas fa-paperclip" aria-hidden="true"></i> <?= $this->te('Anhänge (optional)') ?></label>
            <input type="file" id="ssp-tn-att" name="attachments[]" class="form-control" multiple>
            <span class="ssp-form-hint"><?= $this->te('z.&nbsp;B. Screenshots oder Fehlermeldungen – Bilder, PDFs und gängige Dokumente.') ?></span>
        </div>
        <button type="submit" class="btn btn-primary" data-busy-label="Wird erstellt …"><i class="fas fa-paper-plane" aria-hidden="true"></i> <?= $this->te('Ticket absenden') ?></button>
    </form>
</div>

<script>
// Selbsthilfe-Vorschläge während der Eingabe: schlägt freigegebene
// Artikel zum Betreff vor, damit einfache Fragen ohne Ticket gelöst
// werden können. Rein additiv – das Formular bleibt ohne JS nutzbar.
(function () {
    var input = document.getElementById('ssp-subject');
    var box   = document.getElementById('ssp-kb-hits');
    var list  = document.getElementById('ssp-kb-hits-list');
    if (!input || !box || !list) return;

    var timer = null;
    var lastQuery = '';

    function render(items) {
        list.innerHTML = '';
        if (!items.length) { box.setAttribute('hidden', ''); return; }
        items.forEach(function (a) {
            var li = document.createElement('li');
            var link = document.createElement('a');
            // Der Zusatz hält fest, dass der Artikel aus einem Vorschlag beim
            // Melden geöffnet wurde – daraus entsteht die Kennzahl, wie oft die
            // Selbsthilfe eine Meldung erübrigt.
            link.href = '/portal/hilfe/' + a.id + '?von=melden';
            link.target = '_blank';
            link.rel = 'noopener';
            link.textContent = a.title;
            var topic = document.createElement('span');
            topic.className = 'ssp-kb-hit-topic';
            topic.textContent = a.topic;
            li.appendChild(link);
            li.appendChild(topic);
            list.appendChild(li);
        });
        box.removeAttribute('hidden');
    }

    input.addEventListener('input', function () {
        clearTimeout(timer);
        var q = input.value.trim();
        if (q.length < 3) { box.setAttribute('hidden', ''); return; }
        timer = setTimeout(function () {
            if (q === lastQuery) return;
            lastQuery = q;
            fetch('/portal/hilfe/vorschlaege?q=' + encodeURIComponent(q), {
                headers: { 'X-Requested-With': 'XMLHttpRequest' }
            })
            .then(function (r) { return r.ok ? r.json() : []; })
            .then(function (items) { render(Array.isArray(items) ? items : []); })
            .catch(function () { box.setAttribute('hidden', ''); });
        }, 350);
    });
})();
</script>