diff --git a/resources/js/src/database/events.ts b/resources/js/src/database/events.ts index 8123e937c4..50598aee52 100644 --- a/resources/js/src/database/events.ts +++ b/resources/js/src/database/events.ts @@ -15,11 +15,6 @@ AJAX.registerTeardown('database/events.js', function () { }); const DatabaseEvents = { - /** - * @var $ajaxDialog Query object containing the reference to the - * dialog that contains the editor - */ - $ajaxDialog: null, /** * @var syntaxHiglighter Reference to the codemirror editor */ @@ -176,24 +171,10 @@ const DatabaseEvents = { // We have successfully fetched the editor form ajaxRemoveMessage($msg); - /** - * @var buttonOptions Object containing options - * for jQueryUI dialog buttons - */ - var buttonOptions = { - [window.Messages.strGo]: { - text: window.Messages.strGo, - class: 'btn btn-primary', - }, - [window.Messages.strClose]: { - text: window.Messages.strClose, - class: 'btn btn-secondary', - }, - }; - // Now define the function that is called when - // the user presses the "Go" button - // @ts-ignore - buttonOptions[window.Messages.strGo].click = function () { + + let isEditMode = false; + + function eventsEditorModalSaveEventHandler () { // Move the data from the codemirror editor back to the // textarea, where it can be used in the form submission. if (typeof window.CodeMirror !== 'undefined') { @@ -221,10 +202,10 @@ const DatabaseEvents = { // Item created successfully ajaxRemoveMessage($msg); slidingMessage(data.message); - that.$ajaxDialog.dialog('close'); + window.bootstrap.Modal.getOrCreateInstance('#eventsEditorModal').hide(); // If we are in 'edit' mode, we must // remove the reference to the old row. - if (mode === 'edit' && $editRow !== null) { + if (isEditMode && $editRow !== null) { $editRow.remove(); } @@ -317,75 +298,61 @@ const DatabaseEvents = { } Navigation.reload(); - }); // end $.post() - } // end "if (that.validate())" - }; // end of function that handles the submission of the Editor - - // @ts-ignore - buttonOptions[window.Messages.strClose].click = function () { - $(this).dialog('close'); - }; - - /** - * Display the dialog to the user - */ - that.$ajaxDialog = $('
' + data.message + '
').dialog({ - classes: { - 'ui-dialog-titlebar-close': 'btn-close' - }, - height: 500, - width: '70%', - minWidth: 500, - // @ts-ignore - buttons: buttonOptions, - // Issue #15810 - use button titles for modals (eg: new procedure) - // Respect the order: title on href tag, href content, title sent in response - title: $this.attr('title') || $this.text() || $(data.title).text(), - modal: true, - open: function () { - $('#rteDialog').dialog('option', 'max-height', $(window).height()); - if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) { - $('#rteDialog').dialog('option', 'height', $(window).height()); - } - - $(this).find('input[name=item_name]').trigger('focus'); - $(this).find('input.datefield').each(function () { - addDatepicker($(this).css('width', '95%'), 'date'); }); - - $(this).find('input.datetimefield').each(function () { - addDatepicker($(this).css('width', '95%'), 'datetime'); - }); - - // @ts-ignore - $.datepicker.initialized = false; - }, - close: function () { - $(this).remove(); } - }); - - /** - * @var mode Used to remember whether the editor is in - * "Edit" or "Add" mode - */ - var mode = 'add'; - if ($('input[name=editor_process_edit]').length > 0) { - mode = 'edit'; } - // Attach syntax highlighted editor to the definition - /** - * @var elm jQuery object containing the reference to - * the Definition textarea. - */ - var $elm = $('textarea[name=item_definition]').last(); - var linterOptions = { - editorType: 'event', - }; - that.syntaxHiglighter = getSqlEditor($elm, {}, 'vertical', linterOptions); - window.codeMirrorEditor = that.syntaxHiglighter; - }); // end $.get() + const eventsEditorModal = document.getElementById('eventsEditorModal'); + + eventsEditorModal.addEventListener('shown.bs.modal', function () { + /** + * Issue #15810 - use button titles for modals (eg: new procedure) + * Respect the order: title on href tag, href content, title sent in response + */ + eventsEditorModal.querySelector('.modal-title').textContent = $this.attr('title') || $this.text() || $(data.title).text(); + eventsEditorModal.querySelector('.modal-body').innerHTML = data.message; + + const eventsEditorModalSaveButton = document.getElementById('eventsEditorModalSaveButton'); + eventsEditorModalSaveButton?.addEventListener('click', eventsEditorModalSaveEventHandler); + + $(this).find('input[name=item_name]').trigger('focus'); + $(this).find('input.datefield').each(function () { + addDatepicker($(this).css('width', '95%'), 'date'); + }); + + $(this).find('input.datetimefield').each(function () { + addDatepicker($(this).css('width', '95%'), 'datetime'); + }); + + // @ts-ignore + $.datepicker.initialized = false; + + if ($('input[name=editor_process_edit]').length > 0) { + isEditMode = true; + } + + // Attach syntax highlighted editor to the definition + /** + * @var elm jQuery object containing the reference to + * the Definition textarea. + */ + var $elm = $('textarea[name=item_definition]').last(); + var linterOptions = { + editorType: 'event', + }; + that.syntaxHiglighter = getSqlEditor($elm, {}, 'vertical', linterOptions); + window.codeMirrorEditor = that.syntaxHiglighter; + }); + + eventsEditorModal.addEventListener('hidden.bs.modal', function () { + const eventsEditorModalSaveButton = document.getElementById('eventsEditorModalSaveButton'); + eventsEditorModalSaveButton?.removeEventListener('click', eventsEditorModalSaveEventHandler); + document.getElementById('eventsEditorModal').querySelector('.modal-body').innerHTML = '
' + + '' + window.Messages.strLoading + '
'; + }); + + window.bootstrap.Modal.getOrCreateInstance(eventsEditorModal).show(); + }); }, dropDialog: function ($this) { @@ -561,9 +528,10 @@ const DatabaseEvents = { * to an element that is being validated */ var $elm = null; - if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') { + const eventsEditorModal = $('#eventsEditorModal'); + if (eventsEditorModal.find('select[name=item_type]').find(':selected').val() === 'RECURRING') { // The interval field must not be empty for recurring events - $elm = this.$ajaxDialog.find('input[name=item_interval_value]'); + $elm = eventsEditorModal.find('input[name=item_interval_value]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(window.Messages.strFormEmpty); @@ -572,7 +540,7 @@ const DatabaseEvents = { } } else { // The execute_at field must not be empty for "once off" events - $elm = this.$ajaxDialog.find('input[name=item_execute_at]'); + $elm = eventsEditorModal.find('input[name=item_execute_at]'); if ($elm.val() === '') { $elm.trigger('focus'); alert(window.Messages.strFormEmpty); diff --git a/resources/templates/database/events/index.twig b/resources/templates/database/events/index.twig index 8626bd09df..c91000b465 100644 --- a/resources/templates/database/events/index.twig +++ b/resources/templates/database/events/index.twig @@ -153,4 +153,24 @@ + + diff --git a/tests/unit/Controllers/Database/EventsControllerTest.php b/tests/unit/Controllers/Database/EventsControllerTest.php index b377e9d7bf..87bbbe27e1 100644 --- a/tests/unit/Controllers/Database/EventsControllerTest.php +++ b/tests/unit/Controllers/Database/EventsControllerTest.php @@ -181,6 +181,26 @@ final class EventsControllerTest extends AbstractTestCase + + HTML; @@ -307,6 +327,26 @@ HTML; + + HTML;