166 lines
5.0 KiB
PHP
Executable File
166 lines
5.0 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Helpdesk\Livewire;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
|
use Illuminate\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Livewire\Attributes\Url;
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
use Modules\Helpdesk\Models\Ticket;
|
|
|
|
final class ArchivedTicketIndex extends Component
|
|
{
|
|
use AuthorizesRequests;
|
|
use WithPagination;
|
|
|
|
#[Url]
|
|
public string $search = '';
|
|
|
|
public bool $deleteModalOpen = false;
|
|
public ?int $pendingDeleteTicketId = null;
|
|
public ?string $pendingDeleteTicketReference = null;
|
|
public ?string $pendingDeleteTicketSubject = null;
|
|
|
|
public function updatedSearch(): void
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function restoreTicket(int $ticketId): void
|
|
{
|
|
$ticket = $this->archivedTicket($ticketId);
|
|
$this->authorize('delete', $ticket);
|
|
|
|
$reference = $ticket->reference;
|
|
|
|
$ticket->restore();
|
|
$ticket->forceFill(['archived_at' => null])->save();
|
|
|
|
$this->resetPage();
|
|
|
|
$this->dispatch(
|
|
'thredary:toast',
|
|
type: 'success',
|
|
title: 'Ticket restored',
|
|
message: "Ticket {$reference} was restored to the active ticket list.",
|
|
);
|
|
}
|
|
|
|
public function askToDeletePermanently(int $ticketId): void
|
|
{
|
|
$ticket = $this->archivedTicket($ticketId);
|
|
$this->authorize('delete', $ticket);
|
|
|
|
$this->pendingDeleteTicketId = $ticket->id;
|
|
$this->pendingDeleteTicketReference = $ticket->reference;
|
|
$this->pendingDeleteTicketSubject = $ticket->subject;
|
|
$this->deleteModalOpen = true;
|
|
}
|
|
|
|
public function cancelPermanentDelete(): void
|
|
{
|
|
$this->resetDeleteState();
|
|
}
|
|
|
|
public function deletePermanently(): void
|
|
{
|
|
if ($this->pendingDeleteTicketId === null) {
|
|
$this->resetDeleteState();
|
|
return;
|
|
}
|
|
|
|
$ticket = $this->archivedTicket($this->pendingDeleteTicketId);
|
|
$this->authorize('delete', $ticket);
|
|
$reference = $ticket->reference;
|
|
|
|
DB::transaction(static function () use ($ticket): void {
|
|
$attachments = $ticket->attachments()->get(['id', 'disk', 'path']);
|
|
|
|
foreach ($attachments as $attachment) {
|
|
if (filled($attachment->disk) && filled($attachment->path)) {
|
|
Storage::disk($attachment->disk)->delete($attachment->path);
|
|
}
|
|
}
|
|
|
|
$ticket->forceDelete();
|
|
});
|
|
|
|
$this->resetDeleteState();
|
|
$this->resetPage();
|
|
|
|
$this->dispatch(
|
|
'thredary:toast',
|
|
type: 'success',
|
|
title: 'Ticket permanently deleted',
|
|
message: "Ticket {$reference} and its archived data were permanently deleted.",
|
|
);
|
|
}
|
|
|
|
public function render(): View
|
|
{
|
|
return view('modules.helpdesk.livewire.archived-ticket-index', [
|
|
'tickets' => $this->tickets(),
|
|
])->layout('layouts.app');
|
|
}
|
|
|
|
private function archivedTicket(int $ticketId): Ticket
|
|
{
|
|
return Ticket::query()
|
|
->onlyTrashed()
|
|
->visibleTo(Auth::user())
|
|
->findOrFail($ticketId);
|
|
}
|
|
|
|
/** @return LengthAwarePaginator<int, Ticket> */
|
|
private function tickets(): LengthAwarePaginator
|
|
{
|
|
$user = Auth::user();
|
|
$search = trim($this->search);
|
|
|
|
return Ticket::query()
|
|
->onlyTrashed()
|
|
->without('user')
|
|
->select('helpdesk_tickets.*')
|
|
->addSelect([
|
|
'requester_name' => User::query()
|
|
->select('name')
|
|
->whereColumn('users.id', 'helpdesk_tickets.user_id')
|
|
->limit(1),
|
|
'agent_name' => User::query()
|
|
->select('name')
|
|
->whereColumn('users.id', 'helpdesk_tickets.agent_id')
|
|
->limit(1),
|
|
])
|
|
->with(['status', 'priority', 'category', 'project', 'team'])
|
|
->withCount('attachments')
|
|
->visibleTo($user)
|
|
->when($search !== '', static function (Builder $query) use ($search): Builder {
|
|
return $query->where(static function (Builder $subQuery) use ($search): void {
|
|
$subQuery->where('reference', 'like', '%'.$search.'%')
|
|
->orWhere('subject', 'like', '%'.$search.'%')
|
|
->orWhere('body', 'like', '%'.$search.'%');
|
|
});
|
|
})
|
|
->orderByDesc('archived_at')
|
|
->orderByDesc('deleted_at')
|
|
->paginate(15);
|
|
}
|
|
|
|
private function resetDeleteState(): void
|
|
{
|
|
$this->deleteModalOpen = false;
|
|
$this->pendingDeleteTicketId = null;
|
|
$this->pendingDeleteTicketReference = null;
|
|
$this->pendingDeleteTicketSubject = null;
|
|
}
|
|
}
|