diff --git a/app/assets/javascripts/alchemy/admin.js b/app/assets/javascripts/alchemy/admin.js index 768ecf0433..3e2dce2ab4 100644 --- a/app/assets/javascripts/alchemy/admin.js +++ b/app/assets/javascripts/alchemy/admin.js @@ -19,7 +19,6 @@ //= require alchemy/alchemy.dialog //= require alchemy/alchemy.char_counter //= require alchemy/alchemy.confirm_dialog -//= require alchemy/alchemy.dirty //= require alchemy/alchemy.dragndrop //= require alchemy/alchemy.element_editors //= require alchemy/alchemy.elements_window diff --git a/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee b/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee deleted file mode 100644 index b554a6943c..0000000000 --- a/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +++ /dev/null @@ -1,59 +0,0 @@ -window.Alchemy = {} if typeof (window.Alchemy) is "undefined" - -$.extend Alchemy, - - ElementDirtyObserver: (selector) -> - $(selector).find('input[type="text"], select').change (e) => - $content = $(e.target) - $content.addClass('dirty') - @setElementDirty $content.closest(".element-editor") - return - - setElementDirty: (element) -> - $element = $(element) - $element.addClass('dirty') - window.onbeforeunload = @pageUnload - - pageUnload: -> - Alchemy.t('page_dirty_notice') - - setElementClean: (element) -> - $element = $(element) - $element.removeClass('dirty') - $element.find('> .element-body .dirty').removeClass('dirty') - window.onbeforeunload = undefined - - isPageDirty: -> - $('#element_area').find('.element-editor.dirty').length > 0 - - isElementDirty: (element) -> - $(element).hasClass('dirty') - - checkPageDirtyness: (element) -> - callback = undefined - if $(element).is("form") - callback = -> - $form = $("
") - $form.append $(element).find("input") - $form.appendTo "body" - Alchemy.pleaseWaitOverlay() - $form.submit() - else if $(element).is("a") - callback = -> - Turbo.visit(element.pathname) - if Alchemy.isPageDirty() - Alchemy.openConfirmDialog Alchemy.t('page_dirty_notice'), - title: Alchemy.t('warning') - ok_label: Alchemy.t('ok') - cancel_label: Alchemy.t('cancel') - on_ok: -> - window.onbeforeunload = undefined - callback() - false - else - true - - PageLeaveObserver: -> - $('#main_navi a').click (event) -> - unless Alchemy.checkPageDirtyness(event.currentTarget) - event.preventDefault() diff --git a/app/javascript/alchemy_admin.js b/app/javascript/alchemy_admin.js index 179ee0c9a9..18c511ce96 100644 --- a/app/javascript/alchemy_admin.js +++ b/app/javascript/alchemy_admin.js @@ -1,6 +1,7 @@ import "@hotwired/turbo-rails" import translate from "alchemy_admin/i18n" +import Dirty from "alchemy_admin/dirty" import translationData from "alchemy_admin/translations" import fileEditors from "alchemy_admin/file_editors" import IngredientAnchorLink from "alchemy_admin/ingredient_anchor_link" @@ -19,8 +20,8 @@ if (typeof window.Alchemy === "undefined") { // Enhance the global Alchemy object with imported features Object.assign(Alchemy, { - // Global utility method for translating a given string - t: translate, + ...Dirty, + t: translate, // Global utility method for translating a given string translations: Object.assign(Alchemy.translations || {}, translationData), fileEditors, pictureEditors, diff --git a/app/javascript/alchemy_admin/datepicker.js b/app/javascript/alchemy_admin/datepicker.js index 50b6bc4c66..6ad0c2b08e 100644 --- a/app/javascript/alchemy_admin/datepicker.js +++ b/app/javascript/alchemy_admin/datepicker.js @@ -23,9 +23,7 @@ export default function Datepicker(scope = document) { noCalendar: type === "time", time_24hr: Alchemy.t("formats.time_24hr"), onValueUpdate(_selectedDates, _dateStr, instance) { - return Alchemy.setElementDirty( - instance.element.closest(".element-editor") - ) + Alchemy.setElementDirty(instance.element.closest(".element-editor")) } } flatpickr(input, options) diff --git a/app/javascript/alchemy_admin/dirty.js b/app/javascript/alchemy_admin/dirty.js new file mode 100644 index 0000000000..1a47abf7b0 --- /dev/null +++ b/app/javascript/alchemy_admin/dirty.js @@ -0,0 +1,79 @@ +function ElementDirtyObserver(selector) { + $(selector) + .find('input[type="text"], select') + .change(function (event) { + const $content = $(event.target) + $content.addClass("dirty") + setElementDirty($content.closest(".element-editor")) + }) +} + +function setElementDirty(element) { + $(element).addClass("dirty") + window.onbeforeunload = Alchemy.t("page_dirty_notice") +} + +function setElementClean(element) { + const $element = $(element) + $element.removeClass("dirty") + $element.find("> .element-body .dirty").removeClass("dirty") + window.onbeforeunload = () => {} +} + +function isPageDirty() { + return $("#element_area").find(".element-editor.dirty").length > 0 +} + +function isElementDirty(element) { + return $(element).hasClass("dirty") +} + +function checkPageDirtyness(element) { + let callback = () => {} + + if ($(element).is("form")) { + callback = function () { + const $form = $( + `` + ) + $form.append($(element).find("input")) + $form.appendTo("body") + + Alchemy.pleaseWaitOverlay() + $form.submit() + } + } else if ($(element).is("a")) { + callback = () => Turbo.visit(element.pathname) + } + + if (isPageDirty()) { + Alchemy.openConfirmDialog(Alchemy.t("page_dirty_notice"), { + title: Alchemy.t("warning"), + ok_label: Alchemy.t("ok"), + cancel_label: Alchemy.t("cancel"), + on_ok: function () { + window.onbeforeunload = void 0 + callback() + } + }) + return false + } + return true +} + +function PageLeaveObserver() { + $("#main_navi a").click(function (event) { + if (!checkPageDirtyness(event.currentTarget)) { + event.preventDefault() + } + }) +} + +export default { + ElementDirtyObserver, + setElementDirty, + setElementClean, + isElementDirty, + checkPageDirtyness, + PageLeaveObserver +}