diff --git a/Modules/Helpdesk/Livewire/TicketCreate.php b/Modules/Helpdesk/Livewire/TicketCreate.php index 216f0730..72a1ad73 100644 --- a/Modules/Helpdesk/Livewire/TicketCreate.php +++ b/Modules/Helpdesk/Livewire/TicketCreate.php @@ -102,6 +102,32 @@ final class TicketCreate extends Component return $this->redirectRoute('helpdesk.tickets.index', navigate: true); } + + /** + * Clear the create form, including Select2 and Flatpickr browser widgets. + */ + public function clearForm(): void + { + $this->resetErrorBag(); + $this->resetValidation(); + + $this->subject = ''; + $this->body = ''; + $this->company_id = null; + $this->board_id = null; + $this->priority_id = null; + $this->category_id = null; + $this->project_id = null; + $this->product_id = null; + $this->team_id = null; + $this->due_at = null; + $this->tag_ids = []; + $this->attachments = []; + + $this->dispatch('helpdesk-form-cleared'); + $this->dispatch('helpdesk-editor-reset', model: 'body'); + } + public function render(): View { return view('helpdesk::livewire.ticket-create', [ diff --git a/Modules/Helpdesk/Livewire/TicketEdit.php b/Modules/Helpdesk/Livewire/TicketEdit.php index 6bcf0719..a433be58 100644 --- a/Modules/Helpdesk/Livewire/TicketEdit.php +++ b/Modules/Helpdesk/Livewire/TicketEdit.php @@ -130,6 +130,34 @@ final class TicketEdit extends Component return redirect()->route('helpdesk.tickets.show', $fresh); } + + /** + * Clear the edit form, including Select2 and Flatpickr browser widgets. + */ + public function clearForm(): void + { + $this->authorize('update', $this->ticket); + $this->resetErrorBag(); + $this->resetValidation(); + + $this->subject = ''; + $this->body = ''; + $this->company_id = null; + $this->status_id = null; + $this->board_id = null; + $this->priority_id = null; + $this->category_id = null; + $this->project_id = null; + $this->product_id = null; + $this->team_id = null; + $this->agent_id = null; + $this->due_at = null; + $this->tag_ids = []; + + $this->dispatch('helpdesk-form-cleared'); + $this->dispatch('helpdesk-editor-reset', model: 'body'); + } + public function render(): View { return view('helpdesk::livewire.ticket-edit', [ diff --git a/Modules/Helpdesk/Resources/assets/css/app.css b/Modules/Helpdesk/Resources/assets/css/app.css index c908ab89..11ef032b 100644 --- a/Modules/Helpdesk/Resources/assets/css/app.css +++ b/Modules/Helpdesk/Resources/assets/css/app.css @@ -582,3 +582,61 @@ top: 50% !important; transform: translateY(-50%) !important; } + +/* Helpdesk Flatpickr date picker */ +.flatpickr-calendar { + border: 1px solid rgb(63 63 70); + background: rgb(24 24 27); + color: rgb(244 244 245); + box-shadow: 0 20px 45px rgb(0 0 0 / 0.35); +} + +.flatpickr-calendar.arrowTop::before, +.flatpickr-calendar.arrowTop::after, +.flatpickr-calendar.arrowBottom::before, +.flatpickr-calendar.arrowBottom::after { + border-bottom-color: rgb(24 24 27); + border-top-color: rgb(24 24 27); +} + +.flatpickr-months, +.flatpickr-months .flatpickr-month, +.flatpickr-current-month .flatpickr-monthDropdown-months, +.flatpickr-current-month input.cur-year { + background: rgb(24 24 27); + color: rgb(244 244 245); +} + +.flatpickr-weekday, +span.flatpickr-weekday { + color: rgb(161 161 170); +} + +.flatpickr-day { + color: rgb(228 228 231); +} + +.flatpickr-day:hover, +.flatpickr-day:focus { + border-color: rgb(59 130 246); + background: rgb(39 39 42); + color: rgb(255 255 255); +} + +.flatpickr-day.selected, +.flatpickr-day.startRange, +.flatpickr-day.endRange { + border-color: rgb(37 99 235); + background: rgb(37 99 235); + color: rgb(255 255 255); +} + +.flatpickr-day.today { + border-color: rgb(34 197 94); +} + +.flatpickr-day.flatpickr-disabled, +.flatpickr-day.prevMonthDay, +.flatpickr-day.nextMonthDay { + color: rgb(113 113 122); +} diff --git a/Modules/Helpdesk/Resources/assets/js/app.js b/Modules/Helpdesk/Resources/assets/js/app.js index ec2a020b..f801a102 100644 --- a/Modules/Helpdesk/Resources/assets/js/app.js +++ b/Modules/Helpdesk/Resources/assets/js/app.js @@ -1,30 +1,130 @@ import './bootstrap'; import $ from 'jquery'; +import select2 from 'select2/dist/js/select2.full.js'; +import flatpickr from 'flatpickr'; +import 'flatpickr/dist/flatpickr.css'; + window.$ = $; window.jQuery = $; -import select2 from 'select2/dist/js/select2.full.js'; + select2(window, $); -function initialiseHelpdeskSelects() -{ - console.log('initialising select2'); + +function livewireComponentFor(element) { + const componentRoot = element.closest('[wire\\:id]'); + + if (!componentRoot || ! window.Livewire) { + return null; + } + + return window.Livewire.find(componentRoot.getAttribute('wire:id')); +} + +function setLivewireProperty(element, model, value) { + const component = livewireComponentFor(element); + + if (!component || !model) { + return; + } + + component.set(model, value === '' ? null : value); +} + +function initialiseHelpdeskSelects() { $('[data-helpdesk-select2]').each(function () { - const $select = $(this); + const select = this; + const $select = $(select); + const placeholder = $select.data('placeholder') || $select.find('option[value=""]').first().text() || 'Select option'; + if ($select.hasClass('select2-hidden-accessible')) { return; } + + if (!$select.find('option[value=""]').length) { + $select.prepend(new Option('', '', false, false)); + } + $select.select2({ width: '100%', allowClear: true, + placeholder, + }); + + $select.on('change.helpdesk-select2', function () { + setLivewireProperty(select, $select.data('wire-model'), $select.val()); }); }); } -document.addEventListener('DOMContentLoaded', initialiseHelpdeskSelects); -document.addEventListener('livewire:navigated', initialiseHelpdeskSelects); -document.addEventListener('livewire:init', () => { +function clearHelpdeskSelects(root = document) { + $(root).find('[data-helpdesk-select2]').each(function () { + const $select = $(this); + + $select.val(null); + $select.trigger('change.select2'); + $select.trigger('change.helpdesk-select2'); + $select.trigger('change'); + }); +} + +function initialiseHelpdeskDatePickers() { + document.querySelectorAll('[data-helpdesk-flatpickr]').forEach((input) => { + if (input._helpdeskFlatpickr) { + return; + } + + input._helpdeskFlatpickr = flatpickr(input, { + allowInput: true, + altInput: true, + altFormat: 'd M Y', + dateFormat: 'Y-m-d', + disableMobile: false, + onChange: (_selectedDates, dateText) => { + setLivewireProperty(input, input.dataset.wireModel, dateText || null); + }, + onClose: (_selectedDates, dateText) => { + setLivewireProperty(input, input.dataset.wireModel, dateText || null); + }, + }); + }); +} + +function clearHelpdeskDatePickers(root = document) { + root.querySelectorAll('[data-helpdesk-flatpickr]').forEach((input) => { + if (input._helpdeskFlatpickr) { + input._helpdeskFlatpickr.clear(); + } + + input.value = ''; + setLivewireProperty(input, input.dataset.wireModel, null); + }); +} + +function initialiseHelpdeskFormControls() { initialiseHelpdeskSelects(); + initialiseHelpdeskDatePickers(); +} + +function clearHelpdeskFormControls() { + clearHelpdeskSelects(); + clearHelpdeskDatePickers(); +} + +window.initialiseHelpdeskFormControls = initialiseHelpdeskFormControls; +window.clearHelpdeskFormControls = clearHelpdeskFormControls; + +document.addEventListener('DOMContentLoaded', initialiseHelpdeskFormControls); +document.addEventListener('livewire:navigated', initialiseHelpdeskFormControls); +document.addEventListener('helpdesk-form-cleared', clearHelpdeskFormControls); + +document.addEventListener('livewire:init', () => { + initialiseHelpdeskFormControls(); + Livewire.hook('morphed', () => { - initialiseHelpdeskSelects(); + initialiseHelpdeskFormControls(); + }); + + Livewire.on('helpdesk-form-cleared', () => { + clearHelpdeskFormControls(); }); }); diff --git a/Modules/Helpdesk/Resources/views/components/date-picker.blade.php b/Modules/Helpdesk/Resources/views/components/date-picker.blade.php new file mode 100644 index 00000000..f514c6ed --- /dev/null +++ b/Modules/Helpdesk/Resources/views/components/date-picker.blade.php @@ -0,0 +1,33 @@ +@props([ + 'id', + 'model', + 'label' => null, + 'required' => false, + 'placeholder' => 'Select date', +]) + +