92 lines
2.8 KiB
PHP
92 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Helpdesk\Livewire;
|
|
|
|
use Illuminate\Contracts\View\View;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Livewire\Component;
|
|
use Modules\Helpdesk\Models\KanbanBoard as KanbanBoardModel;
|
|
use Modules\Helpdesk\Models\Status;
|
|
use Modules\Helpdesk\Models\Ticket;
|
|
use Modules\Helpdesk\Services\WorkflowNotificationService;
|
|
|
|
final class KanbanBoard extends Component
|
|
{
|
|
public ?int $board_id = null;
|
|
|
|
public function mount(): void
|
|
{
|
|
$this->board_id = KanbanBoardModel::query()
|
|
->where('is_default', true)
|
|
->orderBy('sort_order')
|
|
->value('id') ?: KanbanBoardModel::query()->orderBy('sort_order')->value('id');
|
|
}
|
|
|
|
/**
|
|
* Move a ticket to another workflow status.
|
|
*/
|
|
public function moveTicket(int|string $ticketId, int|string $statusId, WorkflowNotificationService $workflow): void
|
|
{
|
|
$ticket = Ticket::query()->visibleTo(Auth::user())->findOrFail((int) $ticketId);
|
|
$status = Status::query()->findOrFail((int) $statusId);
|
|
|
|
$this->authorize('update', $ticket);
|
|
|
|
$ticket->forceFill([
|
|
'status_id' => $status->id,
|
|
'completed_at' => $status->is_closed ? now() : null,
|
|
'last_activity_at' => now(),
|
|
])->save();
|
|
|
|
$workflow->dispatch(
|
|
$ticket->fresh(['owner', 'agent', 'status', 'priority', 'category', 'project', 'team']) ?? $ticket,
|
|
$status->is_closed ? 'ticket.closed' : 'ticket.updated',
|
|
Auth::user()
|
|
);
|
|
|
|
session()->flash('success', 'Ticket moved to ' . $status->name . '.');
|
|
}
|
|
|
|
/**
|
|
* Render the Kanban board.
|
|
*/
|
|
public function render(): View
|
|
{
|
|
$boards = KanbanBoardModel::query()
|
|
->with('statuses')
|
|
->orderBy('sort_order')
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
$board = $boards->firstWhere('id', $this->board_id) ?? $boards->first();
|
|
$statuses = $board?->statuses ?? Status::query()->orderBy('sort_order')->orderBy('name')->get();
|
|
|
|
return view('helpdesk::livewire.kanban-board', [
|
|
'boards' => $boards,
|
|
'board' => $board,
|
|
'statuses' => $statuses,
|
|
'ticketsByStatus' => $this->ticketsByStatus(),
|
|
])->layout('layouts.app');
|
|
}
|
|
|
|
/**
|
|
* Get visible tickets grouped by status.
|
|
*
|
|
* @return array<int, Collection<int, Ticket>>
|
|
*/
|
|
private function ticketsByStatus(): array
|
|
{
|
|
return Ticket::query()
|
|
->with(['owner', 'agent', 'status', 'priority', 'category', 'project', 'team'])
|
|
->visibleTo(Auth::user())
|
|
->latest('last_activity_at')
|
|
->limit(300)
|
|
->get()
|
|
->groupBy('status_id')
|
|
->all();
|
|
}
|
|
}
|