diff --git a/Modules/Helpdesk/Resources/views/components/html-editor.blade.php b/Modules/Helpdesk/Resources/views/components/html-editor.blade.php index 1491907c..6e8a4218 100644 --- a/Modules/Helpdesk/Resources/views/components/html-editor.blade.php +++ b/Modules/Helpdesk/Resources/views/components/html-editor.blade.php @@ -14,29 +14,49 @@
whereDoesntStartWith('wire:model')->merge(['class' => 'space-y-2']) }} @if ($model) data-helpdesk-editor-model="{{ $model }}" @endif x-on:helpdesk-editor-reset.window="if ($event.detail.model === model) clear()" - x-on:helpdesk-editor-sync.window="if ($event.detail.model === model) sync()" x-data="{ + x-on:helpdesk-editor-sync.window="if ($event.detail.model === model) syncToLivewire()" + x-data="{ model: @js($model), value: @js($initialValue), - sync() { + submitHandler: null, + readEditor() { this.value = this.$refs.editor.innerHTML; + + return this.value; + }, + syncToHiddenInput() { + this.readEditor(); + }, + syncToLivewire(live = false) { + this.readEditor(); + if (this.model) { - this.$wire.set(this.model, this.value); + this.$wire.set(this.model, this.value, live); } }, command(action, value = null) { this.$refs.editor.focus(); document.execCommand(action, false, value); - this.sync(); + this.syncToHiddenInput(); }, clear() { this.value = ''; this.$refs.editor.innerHTML = ''; + if (this.model) { - this.$wire.set(this.model, ''); + this.$wire.set(this.model, '', false); } }, init() { this.$refs.editor.innerHTML = this.value || ''; + + this.submitHandler = () => this.syncToLivewire(false); + this.$root.closest('form')?.addEventListener('submit', this.submitHandler, { capture: true }); + }, + destroy() { + if (this.submitHandler) { + this.$root.closest('form')?.removeEventListener('submit', this.submitHandler, { capture: true }); + } } }"> @@ -66,16 +86,15 @@ class="rounded-lg px-2 py-1 text-sm hover:bg-zinc-200 dark:hover:bg-zinc-800">Clear
-
-

- Browser spellcheck is enabled for this rich editor. Use your browser or operating-system spelling menu for suggestions. + Browser spellcheck is enabled for this rich editor. Misspelled words are checked by the browser/operating system while typing.

@if ($model) diff --git a/Modules/Helpdesk/Resources/views/livewire/ticket-create.blade.php b/Modules/Helpdesk/Resources/views/livewire/ticket-create.blade.php index f3ffdcf5..32b2db16 100644 --- a/Modules/Helpdesk/Resources/views/livewire/ticket-create.blade.php +++ b/Modules/Helpdesk/Resources/views/livewire/ticket-create.blade.php @@ -7,7 +7,7 @@ 'Raise a new support request with priority, product/service, project, category, team and full details.', ]) -
+

Ticket details

diff --git a/Modules/Helpdesk/Tests/Feature/TicketCreateEditorSyncFilesTest.php b/Modules/Helpdesk/Tests/Feature/TicketCreateEditorSyncFilesTest.php index 6dd16e76..d7a04b45 100644 --- a/Modules/Helpdesk/Tests/Feature/TicketCreateEditorSyncFilesTest.php +++ b/Modules/Helpdesk/Tests/Feature/TicketCreateEditorSyncFilesTest.php @@ -9,23 +9,35 @@ use Tests\TestCase; final class TicketCreateEditorSyncFilesTest extends TestCase { /** - * The ticket create editor must bind the details body through Livewire - * without eager live validation while the user is typing. + * The ticket create editor must not send Livewire requests while typing. + * Eager key/input sync causes disabled submit states, random content + * replacement, and prevents native spellcheck from settling. */ - public function test_ticket_create_editor_pushes_details_body_to_livewire_before_validation(): void + public function test_ticket_create_editor_does_not_sync_livewire_on_keypress_or_input(): void + { + $editor = file_get_contents(base_path('Modules/Helpdesk/Resources/views/components/html-editor.blade.php')); + + $this->assertIsString($editor); + $this->assertStringNotContainsString('x-on:input', $editor); + $this->assertStringNotContainsString('x-on:keyup', $editor); + $this->assertStringContainsString('contenteditable="true"', $editor); + $this->assertStringContainsString('spellcheck="true"', $editor); + $this->assertStringContainsString('this.$wire.set(this.model, this.value, live)', $editor); + $this->assertStringContainsString('syncToLivewire(false)', $editor); + } + + /** + * The create form must push the rich editor body to the Livewire property + * during submit capture, before the save action validates the body field. + */ + public function test_ticket_create_form_syncs_body_before_submit_validation(): void { $view = file_get_contents(base_path('Modules/Helpdesk/Resources/views/livewire/ticket-create.blade.php')); $this->assertIsString($view); $this->assertStringContainsString('wire:model="body"', $view); + $this->assertStringContainsString('x-on:submit.capture', $view); + $this->assertStringContainsString('helpdesk-editor-sync', $view); $this->assertStringNotContainsString('wire:model.live="body"', $view); - $this->assertStringContainsString('submit', $view); - $this->assertTrue( - str_contains($view, 'Livewire') - || str_contains($view, '$wire') - || str_contains($view, '@this') - || str_contains($view, 'wire:model="body"'), - 'Ticket create editor must keep the body field synchronised with Livewire before validation.' - ); } } diff --git a/Modules/Helpdesk/changelog.yaml b/Modules/Helpdesk/changelog.yaml index 07d4484e..5cdd517c 100644 --- a/Modules/Helpdesk/changelog.yaml +++ b/Modules/Helpdesk/changelog.yaml @@ -228,3 +228,11 @@ - Mirrored manual time-log entries into helpdesk_ticket_time_logs when the timer history table is present so the ticket detail modal stays current. - Updated TicketTimeLogTest to use authorised Helpdesk fixture users and lookup data instead of ad-hoc users that fail the ticket update policy. - Kept the pricing-free dashboard test baseline and preserved append-only changelog history. + +- version: 1.9.52 + date: 2026-06-24 + changes: + - Fixed ticket create rich editor Livewire synchronisation so typing no longer fires keypress/input requests. + - Restored native browser spellcheck on the contenteditable editor by allowing typed text to remain stable in the DOM. + - Added submit-capture body synchronisation before validation so tickets can be created reliably. + - Added regression assertions for editor spellcheck, keypress sync prevention, and submit-time body sync. diff --git a/Modules/Helpdesk/module.json b/Modules/Helpdesk/module.json index 2eb95df9..5d826b68 100644 --- a/Modules/Helpdesk/module.json +++ b/Modules/Helpdesk/module.json @@ -22,5 +22,5 @@ "Modules\\Helpdesk\\Providers\\HelpdeskServiceProvider" ], "files": [], - "version": "1.9.50" + "version": "1.9.52" }