v1.1.4
- Configurable ticket numbering (Admin > Konfiguracja > Ogólne): admin-set prefix and minimum zero-padded length for the ticket number. - "Ukryj kolejność zgłoszeń": an opt-in mode that displays a stable, HMAC-derived checksum instead of the sequential ticket number, so it gives no indication of ticket volume or creation order. Ticket URLs switch to the same checksum when this is on, so a link and the number on the page it points to always match. The REST API is unaffected — pinned to `id` regardless of this setting. Search now also matches by checksum. - Fixed: attachments no longer show an inline image thumbnail in the message thread — every attachment (images included) shows as just its filename, opening in a new tab on click. - Docs: README/ARCHITECTURE/wiki updated for all of the above. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -617,6 +617,21 @@ $tabGroups = [
|
||||
</select>
|
||||
</div>
|
||||
<label class="radio"><input type="checkbox" wire:model="systemConfig.autoAssignByCategory" style="position:static;opacity:1;width:auto;height:auto">Automatyczne przypisywanie do zespołu wg kategorii</label>
|
||||
|
||||
<div class="hr"></div>
|
||||
|
||||
<div class="field">
|
||||
<label>Prefiks numeru zgłoszenia</label>
|
||||
<input class="input" maxlength="20" placeholder="#" wire:model.live="systemConfig.ticketNumberPrefix">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Minimalna długość numeru (uzupełniana zerami z przodu)</label>
|
||||
<input class="input" type="number" min="1" max="10" wire:model.live="systemConfig.ticketNumberMinLength">
|
||||
</div>
|
||||
<label class="radio"><input type="checkbox" wire:model.live="systemConfig.ticketNumberObfuscate" style="position:static;opacity:1;width:auto;height:auto">Ukryj kolejność zgłoszeń (numer wyświetlany jako suma kontrolna zamiast kolejnego numeru)</label>
|
||||
<div class="text-muted" style="font-size:12px">
|
||||
ID z bazy: {{ $this->ticketNumberPreview['id'] }} → podgląd numeru: {{ $this->ticketNumberPreview['formatted'] }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="padding:20px;gap:14px">
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
@foreach (($tab === 'current' ? $this->currentTickets : $this->archiveTickets) as $ticket)
|
||||
<a href="{{ route('client.ticket', $ticket) }}" wire:navigate class="card elev-sm" style="padding:16px;cursor:pointer;flex-direction:row;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;text-decoration:none;color:inherit">
|
||||
<div>
|
||||
<div style="font-weight:500">#{{ $ticket->number }} — {{ $ticket->subject }}</div>
|
||||
<div style="font-weight:500">{{ $ticket->displayNumber() }} — {{ $ticket->subject }}</div>
|
||||
<div class="card-meta">{{ $ticket->categoryLabel() }} · {{ \App\Support\Rel::format($ticket->updated_at) }}</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:6px">
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
@endphp
|
||||
|
||||
<div class="card" style="padding:22px;gap:10px">
|
||||
<div class="card-kicker">Zgłoszenie #{{ $ticket->number }}</div>
|
||||
<div class="card-kicker">Zgłoszenie {{ $ticket->displayNumber() }}</div>
|
||||
<h2 style="margin:2px 0 0">{{ $ticket->subject }}</h2>
|
||||
<div class="card-meta">{{ $ticket->categoryLabel() }} · utworzono {{ \App\Support\Rel::format($ticket->created_at) }}</div>
|
||||
<div style="white-space:pre-wrap;font-size:14px;margin-top:4px">{{ $ticket->body }}</div>
|
||||
@@ -168,7 +168,7 @@
|
||||
<div class="card-kicker">Inne Twoje zgłoszenia</div>
|
||||
@forelse ($this->otherTickets as $ot)
|
||||
<a href="{{ route('client.ticket', $ot) }}" wire:navigate style="display:flex;justify-content:space-between;align-items:center;gap:8px;cursor:pointer;text-decoration:none;color:inherit">
|
||||
<span style="font-size:13px">#{{ $ot->number }} — {{ $ot->subject }}</span>
|
||||
<span style="font-size:13px">{{ $ot->displayNumber() }} — {{ $ot->subject }}</span>
|
||||
<span style="{{ $ot->statusStyle() }};flex:none">{{ $ot->statusLabel() }}</span>
|
||||
</a>
|
||||
@empty
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
@if ($this->submittedTicket)
|
||||
<div class="card elev-md" style="padding:32px;gap:14px;text-align:left">
|
||||
<span class="tag tag-accent" style="align-self:flex-start">Zgłoszenie przyjęte</span>
|
||||
<h2 style="margin:0">Zgłoszenie #{{ $this->submittedTicket->number }} zostało utworzone</h2>
|
||||
<h2 style="margin:0">Zgłoszenie {{ $this->submittedTicket->displayNumber() }} zostało utworzone</h2>
|
||||
<p class="text-muted" style="margin:0">Zapisz numer zgłoszenia i adres e-mail — będziesz mógł/mogła sprawdzić status, kontaktując się z zespołem wsparcia. Aktualizacje będziemy wysyłać na Twój adres e-mail.</p>
|
||||
<div class="hr"></div>
|
||||
<div style="display:flex;flex-direction:column;gap:4px;font-size:14px">
|
||||
<div><strong>Numer zgłoszenia:</strong> #{{ $this->submittedTicket->number }}</div>
|
||||
<div><strong>Numer zgłoszenia:</strong> {{ $this->submittedTicket->displayNumber() }}</div>
|
||||
<div><strong>Temat:</strong> {{ $this->submittedTicket->subject }}</div>
|
||||
<div><strong>Kategoria:</strong> {{ $this->submittedTicket->categoryLabel() }}</div>
|
||||
<div><strong>Zgłaszający:</strong> {{ $this->submittedTicket->email }}</div>
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
<tr wire:key="ticket-{{ $t->id }}">
|
||||
<td class="td-select"><input type="checkbox" @checked(in_array($t->id, $selectedIds)) wire:click="toggleSelect({{ $t->id }})"></td>
|
||||
@if (in_array('number', $visibleColumns))
|
||||
<td data-label="Numer" class="td-title"><a href="{{ route('operator.ticket', $t) }}" wire:navigate style="color:inherit;text-decoration:none;cursor:pointer">{{ $t->number }}</a></td>
|
||||
<td data-label="Numer" class="td-title"><a href="{{ route('operator.ticket', $t) }}" wire:navigate style="color:inherit;text-decoration:none;cursor:pointer">{{ $t->displayNumber() }}</a></td>
|
||||
@endif
|
||||
@if (in_array('subject', $visibleColumns))
|
||||
<td data-label="Temat" class="td-title"><a href="{{ route('operator.ticket', $t) }}" wire:navigate style="color:inherit;text-decoration:none;cursor:pointer;white-space:nowrap">{{ $t->subject }}</a></td>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<div class="main-col" style="display:flex;flex-direction:column;gap:16px">
|
||||
<div class="card" style="padding:20px;gap:8px">
|
||||
<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:8px">
|
||||
<div class="card-kicker">Zgłoszenie #{{ $ticket->number }}</div>
|
||||
<div class="card-kicker">Zgłoszenie {{ $ticket->displayNumber() }}</div>
|
||||
@unless ($editingDetails)
|
||||
<button type="button" class="btn btn-ghost" style="padding:0" wire:click="toggleEditDetails">Edytuj</button>
|
||||
@endunless
|
||||
@@ -456,7 +456,7 @@
|
||||
<div class="dialog-backdrop">
|
||||
<div class="dialog" style="max-width:400px">
|
||||
<div class="dialog-title">Potwierdź usunięcie</div>
|
||||
<div class="dialog-body">Czy na pewno usunąć zgłoszenie #{{ $ticket->number }}?</div>
|
||||
<div class="dialog-body">Czy na pewno usunąć zgłoszenie {{ $ticket->displayNumber() }}?</div>
|
||||
<div class="dialog-actions">
|
||||
<button type="button" class="btn btn-secondary" wire:click="cancelDeleteTicket">Anuluj</button>
|
||||
<button type="button" class="btn btn-primary" wire:click="confirmDeleteTicket">Usuń</button>
|
||||
|
||||
Reference in New Issue
Block a user