app/assets/javascripts/headmin.js in headmin-0.3.4 vs app/assets/javascripts/headmin.js in headmin-0.4.0

- old
+ new

@@ -4960,10 +4960,206 @@ }; Controller.blessings = [ClassPropertiesBlessing, TargetPropertiesBlessing, ValuePropertiesBlessing]; Controller.targets = []; Controller.values = {}; +// app/assets/javascripts/headmin/controllers/autocomplete_controller.js +var autocomplete_controller_default = class extends Controller { + static get targets() { + return ["input", "dropdown", "dropdownItem"]; + } + static get values() { + return { + url: String + }; + } + connect() { + this.inputTarget.addEventListener("focus", (event) => { + this.show(); + }); + this.inputTarget.addEventListener("keydown", (event) => { + this.handleKeydown(event); + }); + document.addEventListener("click", (event) => { + this.handleOutsideClick(event); + }); + } + handleKeydown(event) { + this.show(); + const keyCode = parseInt(event.keyCode, 10); + if (this.isArrowKey(keyCode)) { + this.handleArrowKey(keyCode); + } else if (this.isEnterKey(keyCode)) { + this.selectActiveItem(); + } else { + this.handleTextKey(); + } + } + selectActiveItem() { + this.activeItem().click(); + } + isEnterKey(keyCode) { + return keyCode === 13; + } + handleArrowKey(keyCode) { + switch (keyCode) { + case 38: + this.handleArrowUp(); + break; + case 40: + this.handleArrowDown(); + break; + default: + } + } + handleArrowUp() { + this.selectPreviousItem(); + } + handleArrowDown() { + this.selectNextItem(); + } + selectNextItem() { + const next = this.nextItem(); + this.deselectAll(); + next.classList.add("active"); + } + nextItem() { + const current = this.activeItem(); + if (!this.hasSelectedItem()) { + return this.firstItem(); + } + if (this.isItemLast(current)) { + return this.firstItem(); + } else { + const index2 = this.itemIndex(current); + return this.itemAtIndex(index2 + 1); + } + } + selectPreviousItem() { + const previous = this.previousItem(); + this.deselectAll(); + previous.classList.add("active"); + } + previousItem() { + const current = this.activeItem(); + if (!this.hasSelectedItem()) { + return this.lastItem(); + } + if (this.isItemFirst(current)) { + return this.lastItem(); + } else { + const index2 = this.itemIndex(current); + return this.itemAtIndex(index2 - 1); + } + } + deselectAll() { + this.dropdownItemTargets.forEach((dropdownItem) => { + dropdownItem.classList.remove("active"); + }); + } + itemAtIndex(index2) { + return this.dropdownItemTargets[index2]; + } + firstItem() { + return this.itemAtIndex(0); + } + lastItem() { + return this.itemAtIndex(this.dropdownItemTargets.length - 1); + } + hasSelectedItem() { + return this.activeItem() !== void 0; + } + activeItem() { + return this.dropdownItemTargets.find((item) => { + return item.classList.contains("active"); + }); + } + isItemLast(item) { + return this.itemIndex(item) === this.dropdownItemTargets.length - 1; + } + isItemFirst(item) { + return this.itemIndex(item) === 0; + } + itemIndex(item) { + return Array.from(this.dropdownItemTargets).indexOf(item); + } + handleTextKey() { + this.fetchCollection().then((html) => { + this.renderCollection(html); + }).then(() => { + this.highlight(); + }); + } + show() { + if (this.isDropdownEmpty()) { + this.dropdownTarget.classList.remove("d-none"); + } else { + this.hide(); + } + } + hide() { + this.dropdownTarget.classList.add("d-none"); + } + isDropdownEmpty() { + return this.dropdownTarget.textContent.trim().length > 0; + } + isArrowKey(keyCode) { + const arrowKeyCodes = [37, 38, 39, 40]; + return arrowKeyCodes.includes(keyCode); + } + fetchCollection() { + if (this.isRemote()) { + return fetch(this.urlValue).then((response) => { + return response.text(); + }).catch((error2) => { + console.error("The URL you provided for the autocomplete collection didn't return a successful result", error2); + }); + } else { + return Promise.resolve(this.dropdownTarget.innerHTML); + } + } + renderCollection(html) { + this.dropdownTarget.innerHTML = html; + } + isRemote() { + return this.hasUrlValue; + } + highlight() { + const query = this.value(); + this.dropdownItemTargets.forEach((dropdownItem) => { + let text = dropdownItem.innerHTML; + text = text.replace(/<mark.*?>(.*?)<\/mark>/ig, "$1"); + const regex2 = new RegExp(`(${query})`, "gi"); + text = text.replace(regex2, "<mark>$1</mark>"); + dropdownItem.innerHTML = text; + }); + } + select(event) { + this.inputTarget.value = event.target.getAttribute("value"); + this.hide(); + } + value() { + return this.inputTarget.value; + } + numberOfCharacters() { + return this.value().length; + } + handleOutsideClick(event) { + if (!this.isClickedInside(event)) { + this.hide(); + } + } + isClickedInside(event) { + if (!event) { + return false; + } + const inInput = this.inputTarget.contains(event.target); + const inDropdown = this.dropdownTarget.contains(event.target); + return inInput || inDropdown; + } +}; + // node_modules/sortablejs/modular/sortable.esm.js function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); @@ -7140,11 +7336,11 @@ var blocks_controller_default = class extends Controller { static get targets() { return ["templateBlock", "block", "blocks", "templateEmpty", "button", "buttons"]; } connect() { - new sortable_esm_default(this.blocksTarget, { + sortable_esm_default.create(this.blocksTarget, { onEnd: () => { this.reorderPositions(); } }); this.toggleEmpty(); @@ -7169,11 +7365,10 @@ if (element) { element.insertAdjacentHTML("afterend", html); } else { this.blocksTarget.insertAdjacentHTML("afterbegin", html); } - this.blocksTarget.dispatchEvent(new CustomEvent("headmin:reinit", { bubbles: true })); this.reorderPositions(); this.toggleEmpty(); } remove(event) { event.preventDefault(); @@ -7188,23 +7383,22 @@ this.reorderPositions(); this.toggleEmpty(); } setPosition(html) { const position = this.retrieveLastPosition() + 1; - const regex = new RegExp("99999", "g"); - return html.replace(regex, position); + return html.replace(/99999/g, position); } retrieveLastPosition() { const blocks = Array.from(this.blockTargets); if (blocks.length < 1) { return 0; } const lastBlock = blocks.slice(-1)[0]; return parseInt(lastBlock.querySelector("[name*='position']").value); } reorderPositions() { - for (let [index2, block] of this.blockTargets.entries()) { + for (const [index2, block] of this.blockTargets.entries()) { this.changePositionInfo(block, index2); } } changePositionInfo(block, index2) { block.setAttribute("data-position", index2); @@ -7246,25 +7440,24 @@ var dropzone_controller_default = class extends Controller { static get targets() { return ["input"]; } connect() { - this.element.classList.add("h-dropzone"); this.inputTarget.addEventListener("dragover", (event) => { - this.element.classList.add("dragover"); + this.element.classList.add("focus"); }); this.inputTarget.addEventListener("dragleave", (event) => { - this.element.classList.remove("dragover"); + this.element.classList.remove("focus"); }); this.inputTarget.addEventListener("drop", (event) => { - this.element.classList.remove("dragover"); + this.element.classList.remove("focus"); }); this.inputTarget.addEventListener("focusin", (event) => { - this.element.classList.add("active"); + this.element.classList.add("focus"); }); this.inputTarget.addEventListener("focusout", (event) => { - this.element.classList.remove("active"); + this.element.classList.remove("focus"); }); } }; // app/assets/javascripts/headmin/controllers/file_preview_controller.js @@ -7360,11 +7553,11 @@ } } addThumbnails() { const files = this.inputFiles(); files.forEach((file) => { - let thumbnail = this.generateDummyThumbnail(); + const thumbnail = this.generateDummyThumbnail(); this.appendThumbnail(thumbnail); this.updateThumbnail(this.lastThumbnail(), file); }); } generateDummyThumbnail() { @@ -7405,11 +7598,11 @@ } updateThumbnailTitle(thumbnail, title) { thumbnail.title = title; } updateThumbnailBackground(thumbnail, url) { - let thumbnailBackground = thumbnail.querySelector(".h-thumbnail-bg"); + const thumbnailBackground = thumbnail.querySelector(".h-thumbnail-bg"); thumbnailBackground.style.backgroundImage = `url('${url}')`; } removeThumbnailIcon(thumbnail) { thumbnail.querySelector(".h-thumbnail-bg").innerHTML = ""; } @@ -7428,13 +7621,13 @@ spreadsheet: ["application/vnd.oasis.opendocument.spreadsheet"], richtext: ["application/vnd.oasis.opendocument.text"], zip: ["application/zip application/x-7z-compressed", "application/x-bzip application/x-bzip2 application/gzip application/vnd.rar"], pdf: ["application/pdf"] }; - const icon_name = Object.keys(typeMap).find((key) => typeMap[key].includes(mimeType)); - const full_icon_name = ["bi", "file", "earmark", icon_name].filter((e) => typeof e === "string" && e !== "").join("-"); - return `<i class="bi ${full_icon_name} h-thumbnail-icon"></i>`; + const iconName = Object.keys(typeMap).find((key) => typeMap[key].includes(mimeType)); + const fullIconName = ["bi", "file", "earmark", iconName].filter((e) => typeof e === "string" && e !== "").join("-"); + return `<i class="bi ${fullIconName} h-thumbnail-icon"></i>`; } isImage(file) { return file.type.match(/^image/) !== null; } fileToBase64(file) { @@ -7466,11 +7659,11 @@ var filter_controller_default = class extends Controller { static get targets() { return ["button", "popup"]; } connect() { - this.element["controller"] = this; + this.element.controller = this; document.addEventListener("click", (event) => { this.handleOutsideClick(event); }); } handleOutsideClick(event) { @@ -7522,11 +7715,10 @@ } createFilter(name) { let html = this.getTemplateHTML(name); html = this.replaceIdsWithTimestamps(html); this.listTarget.insertAdjacentHTML("beforeend", html); - this.menuItemTarget.dispatchEvent(new CustomEvent("headmin:reinit", { bubbles: true })); } remove(event) { const filter = event.currentTarget.closest(".h-filter"); filter.remove(); this.formTarget.submit(); @@ -7551,12 +7743,11 @@ return element.dataset.filterName === name; })[0]; return template.innerHTML; } replaceIdsWithTimestamps(html) { - const regex = new RegExp("template_id", "g"); - return html.replace(regex, new Date().getTime()); + return html.replace(/template_id/g, new Date().getTime()); } }; // node_modules/flatpickr/dist/esm/types/options.js var HOOKS = [ @@ -9744,11 +9935,11 @@ connect() { const options = { ...this.defaultOptions(), ...this.options() }; esm_default(this.inputTarget, options); } options() { - return JSON.parse(this.inputTarget.getAttribute("data-flatpickr-options")); + return JSON.parse(this.inputTarget.getAttribute("data-flatpickr")); } defaultOptions() { return { allowInput: true, dateFormat: "d/m/Y", @@ -14851,28 +15042,28 @@ this.closePopup(openPopup); } } open(event) { const button = event.target.closest('[data-popup-target="button"]'); - const popup = this.popupById(button.dataset["popupId"]); - const passThru = button.dataset["popupPassThru"]; + const popup = this.popupById(button.dataset.popupId); + const passThru = button.dataset.popupPassThru; if (passThru) { const passThruElement = popup.querySelector(passThru); passThruElement.click(); } else { createPopper3(button, popup); this.openPopup(popup); } } close(event) { const button = event.target.closest('[data-popup-target="button"]'); - const popup = this.popupById(button.dataset["popupId"]); + const popup = this.popupById(button.dataset.popupId); this.closePopup(popup); } popupById(id) { return this.popupTargets.find((popup) => { - return popup.dataset["popupId"] === id; + return popup.dataset.popupId === id; }); } openPopup(popup) { popup.classList.remove("closed"); } @@ -14882,17 +15073,35 @@ }; // app/assets/javascripts/headmin/controllers/redactorx_controller.js var redactorx_controller_default = class extends Controller { connect() { - if (typeof RedactorX == "undefined") { + this.initRedactor(); + } + initRedactor() { + if (typeof RedactorX === "undefined") { console.error("RedactorX is a paid module and is not included in Headmin. Please purchase it and import it as a JS module"); return false; } + const defaultOptions = { + editor: { + minHeight: "57px" + }, + subscribe: { + "app.start": () => { + this.stylize(); + } + } + }; const options = JSON.parse(this.element.getAttribute("data-redactor-options")); - RedactorX(this.element, options); + RedactorX(this.element, { ...defaultOptions, ...options }); } + stylize() { + const container = this.element.nextElementSibling; + const inputClasses = this.element.classList; + container.classList.add(...inputClasses); + } }; // app/assets/javascripts/headmin/controllers/repeater_controller.js var repeater_controller_default = class extends Controller { static get values() { @@ -14902,11 +15111,11 @@ } static get targets() { return ["repeater", "footer", "template", "row", "list", "empty", "addButton"]; } connect() { - new sortable_esm_default(this.listTarget, { + sortable_esm_default.create(this.listTarget, { animation: 150, ghostClass: "list-group-item-dark", draggable: ".repeater-row", handle: ".repeater-row-handle", onEnd: () => { @@ -14933,20 +15142,19 @@ } addRow(event) { event.preventDefault(); const button = event.target; const templateName = button.dataset.templateName; - let rowIndex = button.dataset.rowIndex; + const rowIndex = button.dataset.rowIndex; const template = this.getTemplate(templateName); const html = this.replaceIdsWithTimestamps(template); if (rowIndex) { const row = this.rowTargets[rowIndex]; row.insertAdjacentHTML("afterend", html); } else { this.footerTarget.insertAdjacentHTML("beforebegin", html); } - document.dispatchEvent(new CustomEvent("headmin:reinit", { bubbles: true })); this.resetIndices(); this.resetPositions(); this.toggleEmpty(); } removeRow(event) { @@ -15034,11 +15242,11 @@ } }; return defaultOptions[locale]; } hasTags() { - return this.element.dataset["tags"] === "true"; + return this.element.dataset.tags === "true"; } initTomSelect() { const defaultOptions = this.defaultOptions(i18n_default.locale); const options = { create: this.hasTags() }; new import_tom_select.default(this.element, { ...defaultOptions, ...options }); @@ -15150,11 +15358,11 @@ } static get targets() { return ["table", "body", "actions", "idCheckbox", "idsCheckbox", "row"]; } connect() { - new sortable_esm_default(this.bodyTarget, { + sortable_esm_default.create(this.bodyTarget, { handle: ".table-drag-sort-handle", onEnd: (event) => { this.submitPositions(); } }); @@ -15177,11 +15385,11 @@ return handles.map((handle) => { return handle.dataset.id; }); } idsFormData() { - let formData = new FormData(); + const formData = new FormData(); this.positions().forEach((id) => { formData.append("ids[]", id); }); return formData; } @@ -15245,11 +15453,12 @@ // app/assets/javascripts/headmin/index.js var Headmin = class { static start() { window.Stimulus = window.Stimulus || Application.start(); + Stimulus.register("autocomplete", autocomplete_controller_default); Stimulus.register("blocks", blocks_controller_default); - Stimulus.register("date_range", date_range_controller_default); + Stimulus.register("date-range", date_range_controller_default); Stimulus.register("dropzone", dropzone_controller_default); Stimulus.register("file-preview", file_preview_controller_default); Stimulus.register("filter", filter_controller_default); Stimulus.register("filters", filters_controller_default); Stimulus.register("flatpickr", flatpickr_controller_default);