v1.1.3
- Triggers (Admin > Wyzwalacze): event-driven rules that fire immediately on a ticket lifecycle event (created/updated/status/priority/assignee/team/ category changed, new reply), with AND-conditions and ordered actions (set status/priority/team/assignee, send e-mail). Ships its own dedicated, freely add/edit/delete-able e-mail templates, kept separate from the fixed system templates. - Ticket watching: operators can star/"Obserwuj" any ticket to follow it regardless of assignment/team. - Real-time notification bell (private per-user broadcast channel, 30s fallback poll) with an opt-in in-tab browser push notification. - Per-user notification preferences (/settings/notifications): scope (mine/unassigned/watched/all) and e-mail toggle per event category. - Admin > Integracje: new tab for LDAP/AD + BookStack config, split out of Konfiguracja. - Operator queue: Podkategoria/Zespół/Utworzono columns (off by default). - Obserwuj button moved next to the auto-refresh countdown; trigger condition builder shows subcategory/zgłaszający as name dropdowns instead of raw IDs; /settings/notifications got a back link, full-width push card, and a bordered table container; admin panel tab and operator queue view now persist across a plain page refresh. - Docs: README/ARCHITECTURE/wiki updated for all of the above. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ $tabGroups = [
|
||||
['key' => 'reply-quick-actions', 'label' => 'Szybkie akcje odpowiedzi', 'icon' => 'bolt'],
|
||||
['key' => 'response-templates', 'label' => 'Szablony odpowiedzi', 'icon' => 'chat'],
|
||||
['key' => 'automation-rules', 'label' => 'Automatyzacja SLA', 'icon' => 'bolt'],
|
||||
['key' => 'triggers', 'label' => 'Wyzwalacze', 'icon' => 'rule'],
|
||||
],
|
||||
'Zespół' => [
|
||||
['key' => 'users', 'label' => 'Użytkownicy', 'icon' => 'group'],
|
||||
@@ -16,8 +17,10 @@ $tabGroups = [
|
||||
],
|
||||
'Ustawienia' => [
|
||||
['key' => 'templates', 'label' => 'Szablony e-mail', 'icon' => 'mail'],
|
||||
['key' => 'email', 'label' => 'E-MAIL', 'icon' => 'forward_to_inbox'],
|
||||
['key' => 'branding', 'label' => 'Wygląd i branding', 'icon' => 'palette'],
|
||||
['key' => 'config', 'label' => 'Konfiguracja', 'icon' => 'settings'],
|
||||
['key' => 'integrations', 'label' => 'Integracje', 'icon' => 'hub'],
|
||||
['key' => 'api-keys', 'label' => 'Klucze API', 'icon' => 'vpn_key'],
|
||||
['key' => 'about', 'label' => 'O aplikacji', 'icon' => 'info'],
|
||||
],
|
||||
@@ -356,6 +359,11 @@ $tabGroups = [
|
||||
@endif
|
||||
@endif
|
||||
|
||||
{{-- ================= TRIGGERS ================= --}}
|
||||
@if ($tab === 'triggers')
|
||||
<livewire:admin.triggers />
|
||||
@endif
|
||||
|
||||
{{-- ================= STATUSES ================= --}}
|
||||
@if ($tab === 'statuses')
|
||||
<h3 style="margin:0 0 6px">Statusy</h3>
|
||||
@@ -435,6 +443,27 @@ $tabGroups = [
|
||||
|
||||
{{-- ================= EMAIL TEMPLATES ================= --}}
|
||||
@if ($tab === 'templates')
|
||||
<h3 style="margin:0 0 6px">Powiadomienia e-mail</h3>
|
||||
<p class="text-muted" style="font-size:12.5px;margin:0 0 14px">Każde zdarzenie ma stały, przypisany na stałe szablon — możesz go dowolnie edytować, ale nie zmienić na inny. Wyłącz przełącznik, żeby dana wiadomość nigdy nie była wysyłana.</p>
|
||||
<div class="table-wrap">
|
||||
<table class="table">
|
||||
<thead><tr><th>Zdarzenie</th><th>Odbiorca</th><th>Wysyłane</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($this->notificationSettings as $ns)
|
||||
<tr>
|
||||
<td style="white-space:nowrap">{{ $ns->trigger_label }}</td>
|
||||
<td><span class="tag tag-outline">{{ $ns->recipient === 'operator' ? 'Operator' : 'Zgłaszający' }}</span></td>
|
||||
<td><input type="checkbox" @checked($ns->enabled) wire:click="toggleNotificationEnabled({{ $ns->id }})"></td>
|
||||
<td><button type="button" class="btn btn-ghost" wire:click="editEmailTemplate({{ $ns->email_template_id }})">Edytuj szablon</button></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- ================= E-MAIL ================= --}}
|
||||
@if ($tab === 'email')
|
||||
<h3 style="margin:0 0 6px">Wygląd wiadomości e-mail</h3>
|
||||
<p class="text-muted" style="font-size:12.5px;margin:0 0 14px">Każde powiadomienie wysyłane jest w stałym „pudełku” (nazwa firmy, ramka, treść zdarzenia) — tu edytujesz tylko jego stopkę. Po prawej — podgląd na żywo na przykładowym zgłoszeniu.</p>
|
||||
|
||||
@@ -454,23 +483,45 @@ $tabGroups = [
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 style="margin:0 0 6px">Powiadomienia e-mail</h3>
|
||||
<p class="text-muted" style="font-size:12.5px;margin:0 0 14px">Każde zdarzenie ma stały, przypisany na stałe szablon — możesz go dowolnie edytować, ale nie zmienić na inny. Wyłącz przełącznik, żeby dana wiadomość nigdy nie była wysyłana.</p>
|
||||
<div class="table-wrap">
|
||||
<table class="table">
|
||||
<thead><tr><th>Zdarzenie</th><th>Odbiorca</th><th>Wysyłane</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($this->notificationSettings as $ns)
|
||||
<tr>
|
||||
<td style="white-space:nowrap">{{ $ns->trigger_label }}</td>
|
||||
<td><span class="tag tag-outline">{{ $ns->recipient === 'operator' ? 'Operator' : 'Zgłaszający' }}</span></td>
|
||||
<td><input type="checkbox" @checked($ns->enabled) wire:click="toggleNotificationEnabled({{ $ns->id }})"></td>
|
||||
<td><button type="button" class="btn btn-ghost" wire:click="editEmailTemplate({{ $ns->email_template_id }})">Edytuj szablon</button></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h3 style="margin:0 0 14px">E-mail (SMTP)</h3>
|
||||
<form wire:submit="saveMailConfig" class="card" style="padding:20px;gap:14px;max-width:480px">
|
||||
<div class="field"><label>Adres nadawcy</label><input class="input" type="email" placeholder="wsparcie@firma.pl" wire:model="mailConfig.fromAddress"></div>
|
||||
<div class="field"><label>Nazwa nadawcy</label><input class="input" placeholder="Zespół Wsparcia" wire:model="mailConfig.fromName"></div>
|
||||
|
||||
<div class="hr"></div>
|
||||
|
||||
<label class="radio"><input type="checkbox" wire:model="mailConfig.smtpEnabled" style="position:static;opacity:1;width:auto;height:auto"><strong>Włącz wysyłkę przez własny serwer SMTP</strong></label>
|
||||
<span class="text-muted" style="font-size:11.5px;margin-top:-8px">Bez włączenia aplikacja wysyła pocztę zgodnie z konfiguracją środowiska (.env).</span>
|
||||
|
||||
@if ($mailConfig['smtpEnabled'])
|
||||
<div class="field"><label>Host SMTP</label><input class="input" placeholder="smtp.example.com" wire:model="mailConfig.smtpHost"></div>
|
||||
<div style="display:flex;gap:10px">
|
||||
<div class="field" style="flex:1"><label>Port</label><input class="input" type="number" placeholder="587" wire:model="mailConfig.smtpPort"></div>
|
||||
<div class="field" style="flex:1">
|
||||
<label>Szyfrowanie</label>
|
||||
<select class="input" wire:model="mailConfig.smtpEncryption">
|
||||
<option value="none">Brak</option>
|
||||
<option value="tls">STARTTLS</option>
|
||||
<option value="ssl">SSL/TLS</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field"><label>Użytkownik</label><input class="input" wire:model="mailConfig.smtpUsername"></div>
|
||||
<div class="field"><label>Hasło</label><input class="input" type="password" placeholder="(bez zmian jeśli puste)" wire:model="mailConfig.smtpPassword"></div>
|
||||
|
||||
<div style="display:flex;gap:10px;margin-top:8px;align-items:center;flex-wrap:wrap">
|
||||
<button type="button" class="btn btn-secondary" wire:click="testMailConnection">Wyślij testową wiadomość</button>
|
||||
<button type="submit" class="btn btn-primary">Zapisz</button>
|
||||
@if ($mailTestResult === 'ok')
|
||||
<div style="display:flex;align-items:center;gap:6px;color:var(--color-success)"><span class="material-symbols-outlined" style="font-size:18px">check_circle</span>Wysłano na Twój adres</div>
|
||||
@elseif ($mailTestResult === 'error')
|
||||
<div style="display:flex;align-items:center;gap:6px;color:var(--color-danger)"><span class="material-symbols-outlined" style="font-size:18px">error</span>Błąd wysyłki</div>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<button type="submit" class="btn btn-primary" style="align-self:flex-start">Zapisz</button>
|
||||
@endif
|
||||
</form>
|
||||
@endif
|
||||
|
||||
{{-- ================= BRANDING ================= --}}
|
||||
@@ -615,46 +666,14 @@ $tabGroups = [
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form wire:submit="saveMailConfig" class="card" style="padding:20px;gap:14px">
|
||||
<h4 style="margin:0">E-mail (SMTP)</h4>
|
||||
<div class="field"><label>Adres nadawcy</label><input class="input" type="email" placeholder="wsparcie@firma.pl" wire:model="mailConfig.fromAddress"></div>
|
||||
<div class="field"><label>Nazwa nadawcy</label><input class="input" placeholder="Zespół Wsparcia" wire:model="mailConfig.fromName"></div>
|
||||
<p class="text-muted" style="font-size:11.5px;margin:-4px 0 0">Stopka wiadomości e-mail edytowana jest w zakładce „Szablony e-mail”.</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="hr"></div>
|
||||
{{-- ================= INTEGRATIONS ================= --}}
|
||||
@if ($tab === 'integrations')
|
||||
<h3 style="margin:0 0 16px">Integracje</h3>
|
||||
|
||||
<label class="radio"><input type="checkbox" wire:model="mailConfig.smtpEnabled" style="position:static;opacity:1;width:auto;height:auto"><strong>Włącz wysyłkę przez własny serwer SMTP</strong></label>
|
||||
<span class="text-muted" style="font-size:11.5px;margin-top:-8px">Bez włączenia aplikacja wysyła pocztę zgodnie z konfiguracją środowiska (.env).</span>
|
||||
|
||||
@if ($mailConfig['smtpEnabled'])
|
||||
<div class="field"><label>Host SMTP</label><input class="input" placeholder="smtp.example.com" wire:model="mailConfig.smtpHost"></div>
|
||||
<div style="display:flex;gap:10px">
|
||||
<div class="field" style="flex:1"><label>Port</label><input class="input" type="number" placeholder="587" wire:model="mailConfig.smtpPort"></div>
|
||||
<div class="field" style="flex:1">
|
||||
<label>Szyfrowanie</label>
|
||||
<select class="input" wire:model="mailConfig.smtpEncryption">
|
||||
<option value="none">Brak</option>
|
||||
<option value="tls">STARTTLS</option>
|
||||
<option value="ssl">SSL/TLS</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field"><label>Użytkownik</label><input class="input" wire:model="mailConfig.smtpUsername"></div>
|
||||
<div class="field"><label>Hasło</label><input class="input" type="password" placeholder="(bez zmian jeśli puste)" wire:model="mailConfig.smtpPassword"></div>
|
||||
|
||||
<div style="display:flex;gap:10px;margin-top:8px;align-items:center;flex-wrap:wrap">
|
||||
<button type="button" class="btn btn-secondary" wire:click="testMailConnection">Wyślij testową wiadomość</button>
|
||||
<button type="submit" class="btn btn-primary">Zapisz</button>
|
||||
@if ($mailTestResult === 'ok')
|
||||
<div style="display:flex;align-items:center;gap:6px;color:var(--color-success)"><span class="material-symbols-outlined" style="font-size:18px">check_circle</span>Wysłano na Twój adres</div>
|
||||
@elseif ($mailTestResult === 'error')
|
||||
<div style="display:flex;align-items:center;gap:6px;color:var(--color-danger)"><span class="material-symbols-outlined" style="font-size:18px">error</span>Błąd wysyłki</div>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<button type="submit" class="btn btn-primary" style="align-self:flex-start">Zapisz</button>
|
||||
@endif
|
||||
</form>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));gap:20px;align-items:start">
|
||||
|
||||
<form wire:submit="saveLdapConfig" class="card" style="padding:20px;gap:14px">
|
||||
<h4 style="margin:0">LDAP / Active Directory</h4>
|
||||
|
||||
Reference in New Issue
Block a user