Validation now runs only when Create Ticket is clicked.

* Removed the live body binding causing premature $commit.
* Details editor still syncs before submit.
* Added duplicate-submit guard.
* Should no longer need clicking Save/Create twice.
* Append-only changelog.
* module.json version 1.9.42.
This commit is contained in:
Mark Gregory
2026-06-23 11:13:54 +01:00
parent 7c4a94b5ea
commit 4ee0b8e604
6 changed files with 92 additions and 39 deletions
+61 -33
View File
@@ -8,7 +8,6 @@ use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
use Livewire\WithFileUploads;
@@ -25,44 +24,65 @@ final class TicketCreate extends Component
{
use WithFileUploads;
#[Validate('nullable|integer')]
public ?int $company_id = null;
#[Validate('required|string|max:200')]
public string $subject = '';
#[Validate('required|string|min:10')]
public string $body = '';
#[Validate('nullable|integer|exists:helpdesk_kanban_boards,id')]
public ?int $board_id = null;
#[Validate('required|integer|exists:helpdesk_priorities,id')]
public ?int $priority_id = null;
#[Validate('nullable|integer|exists:helpdesk_categories,id')]
public ?int $category_id = null;
#[Validate('nullable|integer|exists:helpdesk_projects,id')]
public ?int $project_id = null;
#[Validate('nullable|integer|exists:helpdesk_products,id')]
public ?int $product_id = null;
#[Validate('nullable|integer|exists:helpdesk_teams,id')]
public ?int $team_id = null;
#[Validate('nullable|date')]
public ?string $due_at = null;
/** @var array<int, int> */
#[Validate('array')]
public array $tag_ids = [];
/** @var array<int, TemporaryUploadedFile> */
#[Validate('array')]
public array $attachments = [];
public bool $isSaving = false;
/**
* Validation rules are intentionally evaluated only when the user submits
* the form, not while rich-text/select widgets are synchronising.
*
* @return array<string, mixed>
*/
protected function rules(): array
{
return [
'company_id' => ['nullable', 'integer'],
'subject' => ['required', 'string', 'max:200'],
'body' => ['required', 'string', 'min:10'],
'board_id' => ['nullable', 'integer', 'exists:helpdesk_kanban_boards,id'],
'priority_id' => ['required', 'integer', 'exists:helpdesk_priorities,id'],
'category_id' => ['nullable', 'integer', 'exists:helpdesk_categories,id'],
'project_id' => ['nullable', 'integer', 'exists:helpdesk_projects,id'],
'product_id' => ['nullable', 'integer', 'exists:helpdesk_products,id'],
'team_id' => ['nullable', 'integer', 'exists:helpdesk_teams,id'],
'due_at' => ['nullable', 'date'],
'tag_ids' => ['array'],
'tag_ids.*' => ['integer', 'exists:helpdesk_tags,id'],
'attachments' => ['array'],
'attachments.*' => [
'file',
'max:'.config('helpdesk.max_upload_kb'),
'mimes:'.implode(',', config('helpdesk.allowed_mimes')),
],
];
}
/**
* Initialise configured Helpdesk defaults for a new ticket.
*/
@@ -76,29 +96,37 @@ final class TicketCreate extends Component
*/
public function save(TicketService $tickets)
{
$this->validate();
$this->validate([
'attachments.*' => 'file|max:'.config('helpdesk.max_upload_kb').'|mimes:'.implode(',', config('helpdesk.allowed_mimes')),
'tag_ids.*' => 'integer|exists:helpdesk_tags,id',
]);
if ($this->isSaving) {
return null;
}
$ticket = $tickets->create(Auth::user(), [
'company_id' => $this->company_id,
'subject' => $this->subject,
'body' => $this->body,
'board_id' => $this->board_id,
'priority_id' => $this->priority_id,
'category_id' => $this->category_id,
'project_id' => $this->project_id,
'product_id' => $this->product_id,
'team_id' => $this->team_id,
'due_at' => $this->due_at,
'tag_ids' => $this->tag_ids,
], $this->attachments);
$this->isSaving = true;
session()->flash('success', 'Ticket '.$ticket->reference.' has been created.');
try {
$this->body = trim($this->body);
return $this->redirectRoute('helpdesk.tickets.index', navigate: true);
$this->validate();
$ticket = $tickets->create(Auth::user(), [
'company_id' => $this->company_id,
'subject' => $this->subject,
'body' => $this->body,
'board_id' => $this->board_id,
'priority_id' => $this->priority_id,
'category_id' => $this->category_id,
'project_id' => $this->project_id,
'product_id' => $this->product_id,
'team_id' => $this->team_id,
'due_at' => $this->due_at,
'tag_ids' => $this->tag_ids,
], $this->attachments);
session()->flash('success', 'Ticket '.$ticket->reference.' has been created.');
return $this->redirectRoute('helpdesk.tickets.index', navigate: true);
} finally {
$this->isSaving = false;
}
}
/**