fixe duploads and attachments now with colors tab and enhancements
This commit is contained in:
@@ -41,11 +41,11 @@ final class TicketShow extends Component
|
||||
/** @var array<int, TemporaryUploadedFile> */
|
||||
public array $attachments = [];
|
||||
|
||||
public ?int $status_id = null;
|
||||
public int|string|null $status_id = null;
|
||||
|
||||
public ?int $priority_id = null;
|
||||
public int|string|null $priority_id = null;
|
||||
|
||||
public ?int $agent_id = null;
|
||||
public int|string|null $agent_id = null;
|
||||
|
||||
public ?int $reply_parent_id = null;
|
||||
|
||||
@@ -225,10 +225,7 @@ final class TicketShow extends Component
|
||||
|
||||
$agentId = $this->normaliseNullableInt($this->agent_id);
|
||||
|
||||
validator(
|
||||
['agent_id' => $agentId],
|
||||
['agent_id' => ['nullable', 'integer', Rule::exists('users', 'id')]],
|
||||
)->validate();
|
||||
$this->validateAssignableAgent($agentId);
|
||||
|
||||
abort_unless(Schema::hasColumn('helpdesk_tickets', 'agent_id'), 500, 'The helpdesk_tickets.agent_id column is missing.');
|
||||
|
||||
@@ -310,6 +307,39 @@ final class TicketShow extends Component
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the selected agent exists and belongs to this ticket's company context.
|
||||
*/
|
||||
private function validateAssignableAgent(?int $agentId): void
|
||||
{
|
||||
if ($agentId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rule = Rule::exists('users', 'id');
|
||||
|
||||
if ($this->ticket->company_id !== null && Schema::hasColumn('users', 'company_id')) {
|
||||
$ticketCompanyId = (int) $this->ticket->company_id;
|
||||
$currentAgentId = $this->ticket->agent_id === null ? null : (int) $this->ticket->agent_id;
|
||||
|
||||
$rule->where(function ($query) use ($ticketCompanyId, $currentAgentId): void {
|
||||
$query->where(function ($tenantQuery) use ($ticketCompanyId): void {
|
||||
$tenantQuery->where('company_id', $ticketCompanyId)
|
||||
->orWhereNull('company_id');
|
||||
});
|
||||
|
||||
if ($currentAgentId !== null) {
|
||||
$query->orWhere('id', $currentAgentId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
validator(
|
||||
['agent_id' => $agentId],
|
||||
['agent_id' => ['nullable', 'integer', $rule]],
|
||||
)->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return assignable users for this ticket.
|
||||
*
|
||||
|
||||
@@ -202,10 +202,10 @@
|
||||
|
||||
@can('update', $ticket)
|
||||
<div class="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div class="mb-5 rounded-2xl bg-gradient-to-r from-blue-700 via-indigo-700 to-violet-700 px-4 py-4 text-white shadow-sm">
|
||||
<div class="mb-4 rounded-2xl bg-gradient-to-r from-blue-700 via-indigo-700 to-violet-700 px-4 py-3 text-white shadow-sm">
|
||||
<p class="text-xs font-black uppercase tracking-[0.24em] text-blue-100">Ticket controls</p>
|
||||
<h2 class="mt-1 text-lg font-black tracking-tight">Assignment, status and priority</h2>
|
||||
<p class="mt-1 text-sm font-semibold text-blue-100/90">Use the explicit update buttons below to save each change.</p>
|
||||
<h2 class="mt-1 text-base font-black tracking-tight">Assignment, status and priority</h2>
|
||||
<p class="mt-1 text-xs font-semibold text-blue-100/90">Choose a value, then save the specific change.</p>
|
||||
</div>
|
||||
|
||||
@if (session('ticket-action-updated'))
|
||||
@@ -214,9 +214,9 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form wire:submit.prevent="updateAgent" class="mb-6 space-y-3">
|
||||
<div class="mb-5 space-y-2">
|
||||
<label class="block text-sm font-bold text-zinc-700 dark:text-zinc-200" for="show_agent_id">Assigned agent</label>
|
||||
<select id="show_agent_id" wire:model.live="agent_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white p-3 text-sm font-bold text-zinc-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-dusk="ticket-show-agent">
|
||||
<select id="show_agent_id" wire:model="agent_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-dusk="ticket-show-agent">
|
||||
<option value="">Unassigned</option>
|
||||
@forelse ($agents as $agent)
|
||||
<option value="{{ $agent->id }}">{{ $agent->name }} · {{ $agent->email }}</option>
|
||||
@@ -225,42 +225,42 @@
|
||||
@endforelse
|
||||
</select>
|
||||
@error('agent_id') <p class="text-sm font-bold text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||
<button type="submit" dusk="update-agent" class="inline-flex w-full items-center justify-center rounded-xl bg-emerald-600 px-4 py-2.5 text-sm font-black text-white shadow-sm transition hover:bg-emerald-700 focus:outline-none focus:ring-2 focus:ring-emerald-400/70 disabled:cursor-not-allowed disabled:opacity-70" wire:loading.attr="disabled" wire:target="updateAgent">
|
||||
<button type="button" wire:click="updateAgent" dusk="update-agent" class="inline-flex w-full items-center justify-center rounded-lg bg-emerald-600 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-emerald-700 focus:outline-none focus:ring-2 focus:ring-emerald-400/70 disabled:cursor-not-allowed disabled:opacity-70" wire:loading.attr="disabled" wire:target="updateAgent">
|
||||
<i class="fa-solid fa-user-check mr-2" aria-hidden="true"></i>
|
||||
<span wire:loading.remove wire:target="updateAgent">Assign agent</span>
|
||||
<span wire:loading wire:target="updateAgent">Assigning...</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form wire:submit.prevent="updateStatus" class="mb-6 space-y-3">
|
||||
<div class="mb-5 space-y-2">
|
||||
<label class="block text-sm font-bold text-zinc-700 dark:text-zinc-200" for="show_status_id">Status</label>
|
||||
<select id="show_status_id" wire:model.live="status_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white p-3 text-sm font-bold text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-dusk="ticket-show-status">
|
||||
<select id="show_status_id" wire:model="status_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-dusk="ticket-show-status">
|
||||
@foreach ($statuses as $status)
|
||||
<option value="{{ $status->id }}">{{ $status->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('status_id') <p class="text-sm font-bold text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||
<button type="submit" dusk="update-status" class="inline-flex w-full items-center justify-center rounded-xl bg-blue-600 px-4 py-2.5 text-sm font-black text-white shadow-sm transition hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400/70 disabled:cursor-not-allowed disabled:opacity-70" wire:loading.attr="disabled" wire:target="updateStatus">
|
||||
<button type="button" wire:click="updateStatus" dusk="update-status" class="inline-flex w-full items-center justify-center rounded-lg bg-blue-600 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400/70 disabled:cursor-not-allowed disabled:opacity-70" wire:loading.attr="disabled" wire:target="updateStatus">
|
||||
<i class="fa-solid fa-circle-check mr-2" aria-hidden="true"></i>
|
||||
<span wire:loading.remove wire:target="updateStatus">Update status</span>
|
||||
<span wire:loading wire:target="updateStatus">Updating...</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form wire:submit.prevent="updatePriority" class="space-y-3">
|
||||
<div class="space-y-2">
|
||||
<label class="block text-sm font-bold text-zinc-700 dark:text-zinc-200" for="show_priority_id">Priority</label>
|
||||
<select id="show_priority_id" wire:model.live="priority_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white p-3 text-sm font-bold text-zinc-900 shadow-sm focus:border-amber-500 focus:ring-amber-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-dusk="ticket-show-priority">
|
||||
<select id="show_priority_id" wire:model="priority_id" class="hd-select block w-full rounded-xl border border-zinc-300 bg-white px-3 py-2 text-sm font-semibold text-zinc-900 shadow-sm focus:border-amber-500 focus:ring-amber-500 dark:border-zinc-700 dark:bg-zinc-950 dark:text-zinc-100" data-dusk="ticket-show-priority">
|
||||
@foreach ($priorities as $priority)
|
||||
<option value="{{ $priority->id }}">{{ $priority->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('priority_id') <p class="text-sm font-bold text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||
<button type="submit" dusk="update-priority" class="inline-flex w-full items-center justify-center rounded-xl bg-amber-500 px-4 py-2.5 text-sm font-black text-white shadow-sm transition hover:bg-amber-600 focus:outline-none focus:ring-2 focus:ring-amber-300/70 disabled:cursor-not-allowed disabled:opacity-70" wire:loading.attr="disabled" wire:target="updatePriority">
|
||||
<button type="button" wire:click="updatePriority" dusk="update-priority" class="inline-flex w-full items-center justify-center rounded-lg bg-amber-500 px-3 py-2 text-xs font-bold text-white shadow-sm transition hover:bg-amber-600 focus:outline-none focus:ring-2 focus:ring-amber-300/70 disabled:cursor-not-allowed disabled:opacity-70" wire:loading.attr="disabled" wire:target="updatePriority">
|
||||
<i class="fa-solid fa-flag mr-2" aria-hidden="true"></i>
|
||||
<span wire:loading.remove wire:target="updatePriority">Update priority</span>
|
||||
<span wire:loading wire:target="updatePriority">Updating...</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endcan
|
||||
</aside>
|
||||
|
||||
Reference in New Issue
Block a user