lib/super_settings/application/scripts.js in super_settings-1.0.2 vs lib/super_settings/application/scripts.js in super_settings-2.0.0

- old
+ new

@@ -13,12 +13,12 @@ return document.querySelectorAll("#settings-table tbody tr[data-edited=true]").length; } // Set the enabled status of the save button for submitting the form. function enableSaveButton() { - const saveButton = document.querySelector("#save-settings"); - const discardButton = document.querySelector("#discard-changes"); + const saveButton = document.querySelector("#super-settings-save-settings"); + const discardButton = document.querySelector("#super-settings-discard-changes"); if (saveButton) { const count = changesCount(); const countSpan = saveButton.querySelector(".count"); if (count === 0) { saveButton.disabled = true; @@ -115,10 +115,18 @@ row.querySelector(".super-settings-value-type .js-value-placeholder").innerText = setting.value_type; } if (setting.description !== null && setting.description !== undefined) { row.querySelector(".super-settings-description .js-value-placeholder").innerHTML = escapeHTML(setting.description).replaceAll("\n", "<br>"); } + if (setting.updated_at !== null && setting.updated_at !== undefined) { + const lastModified = new Date(Date.parse(setting.updated_at)); + const lastModifiedFormatter = new Intl.DateTimeFormat(navigator.language, {month: "short", day: "numeric", year: "numeric"}); + const lastModifiedString = lastModifiedFormatter.format(lastModified); + const lastModifiedElement = row.querySelector(".super-settings-last-modified .js-value-placeholder") + lastModifiedElement.innerText = lastModifiedString; + lastModifiedElement.title = dateFormatter().format(lastModified); + } return row } // Create an input element from a template depending on the value type. @@ -180,10 +188,11 @@ // Create a table row with form elements for editing a setting. function editSettingRow(setting) { const row = elementFromSettingTemplate(setting, "#setting-row-edit-template"); row.dataset.id = setting.id + row.dataset.key = setting.key row.querySelector(".super-settings-key input").value = setting.key; if (setting.description) { row.querySelector(".super-settings-description textarea").value = setting.description; } @@ -237,11 +246,11 @@ existingRow.replaceWith(row); } else { document.querySelector("#settings-table tbody").prepend(row); } bindSettingControlEvents(row); - filterSettings(document.querySelector("#filter").value); + filterSettings(document.querySelector("#super-settings-filter").value); row.scrollIntoView({block: "nearest"}); enableSaveButton(); return row; } @@ -299,11 +308,11 @@ }); } // Programatically apply the filter again to keep it up to date with other changes. function applyFilter(value) { - const filter = document.querySelector("#filter"); + const filter = document.querySelector("#super-settings-filter"); if (filter) { if (value) { filter.value = value; } } @@ -328,15 +337,15 @@ // Show a temporary message to give the user feedback that an operation has succeeded or not. function showFlash(message, success) { const flash = document.querySelector(".js-flash"); if (success) { - flash.classList.add("text-success"); - flash.classList.remove("text-danger"); + flash.classList.add("super-settings-text-success"); + flash.classList.remove("super-settings-text-danger"); } else { - flash.classList.add("text-danger"); - flash.classList.remove("text-success"); + flash.classList.add("tsuper-settings-ext-danger"); + flash.classList.remove("super-settings-text-success"); } flash.innerText = message; flash.style.display = "inline-block"; dismissFlash(); } @@ -376,11 +385,11 @@ rowsHTML += `<tr><td class="super-settings-text-nowrap">${escapeHTML(dateString)}</td><td>${escapeHTML(history.changed_by)}</td><td>${value}</td></tr>`; }); tbody.insertAdjacentHTML("beforeend", rowsHTML); if (payload.previous_page_params || payload.next_page_params) { - let paginationHTML = `<div class="align-center">`; + let paginationHTML = `<div class="super-settings-align-center">`; if (payload.previous_page_params) { paginationHTML += `<div style="float:left;"><a href="#" class="js-show-history" title="Newer" data-offset="${payload.previous_page_params.offset}" data-limit="${payload.previous_page_params.limit}" data-key="${payload.previous_page_params.key}")>&#8592; Newer</a></div>`; } if (payload.next_page_params) { paginationHTML += `<div style="float:right;"><a href="#" class="js-show-history" title="Older" data-offset="${payload.next_page_params.offset}" data-limit="${payload.next_page_params.limit}" data-key="${payload.next_page_params.key}")>Older &#8594;</a></div>`; @@ -391,11 +400,11 @@ addListener(parent.querySelectorAll(".js-show-history"), "click", showHistoryModal); } // Show a modal window overlayed on the page. function showModal() { - const modal = document.querySelector("#modal"); + const modal = document.querySelector("#super-settings-modal"); const content = document.querySelector(".super-settings-modal-content"); modal.style.display = "block"; modal.setAttribute("aria-hidden", "false"); modal.activator = document.activeElement; focusableElements(document).forEach(function(element) { @@ -407,11 +416,11 @@ document.querySelector("body").style.overflow = "hidden"; } // Hide the modal window overlayed on the page. function hideModal() { - const modal = document.querySelector("#modal"); + const modal = document.querySelector("#super-settings-modal"); const content = document.querySelector(".super-settings-modal-content"); modal.style.display = "none"; modal.setAttribute("aria-hidden", "true"); focusableElements(document).forEach(function(element) { const tabIndex = element.dataset.saveTabIndex; @@ -454,11 +463,11 @@ event.preventDefault(); if (!event.target.dataset) { return; } - const modal = document.querySelector("#modal"); + const modal = document.querySelector("#super-settings-modal"); const content = document.querySelector(".super-settings-modal-content"); let key = event.target.dataset.key; if (!key) { const row = event.target.closest("tr"); if (row) { @@ -590,11 +599,16 @@ event.target.disabled = true; const settingsData = []; document.querySelectorAll("#settings-table tbody tr[data-edited=true]").forEach(function(row) { const data = {}; settingsData.push(data); + data.key = row.querySelector(".js-setting-key").value; + if (data.key != row.dataset.key) { + data.key_was = row.dataset.key; + } + const deleted = row.querySelector(".js-setting-deleted"); if (deleted && deleted.value === "1") { data.deleted = true; } else { if (row.querySelector(".js-setting-value")) { @@ -633,11 +647,11 @@ // Listener for refresh page button. function refreshPage(event) { event.preventDefault(); let url = window.location.href.replace(/\?.*/, ""); - const filter = document.querySelector("#filter").value; + const filter = document.querySelector("#super-settings-filter").value; if (filter !== "") { url += "?filter=" + escape(filter); } window.location = url; } @@ -692,25 +706,87 @@ // Initialize the table with all the settings plus any changes from a failed form submission. function renderSettingsTable(settings) { const tbody = document.querySelector("#settings-table tbody"); tbody.innerHTML = ""; let count = settings.length; - settings.forEach(function(setting) { - const randomId = "setting" + Math.floor((Math.random() * 0xFFFFFFFFFFFFFF)).toString(16); + + sortSettings(settings).forEach(function(setting) { + const randomId = "setting" + Math.floor((Math.random() * 0xFFFFFFFFFFFFF)).toString(16); setting.id = (setting.id || randomId); const row = settingRow(setting); tbody.appendChild(row); bindSettingControlEvents(row); }); document.querySelector(".js-settings-count").textContent = `${count} ${count === 1 ? "Setting" : "Settings"}`; - const filter = document.querySelector("#filter"); + const filter = document.querySelector("#super-settings-filter"); if (filter) { filter.dispatchEvent(new Event("input")); } } + function sortOrder() { + const selectedSort = document.querySelector(".super-settings-sort-control[data-selected=true]"); + const field = selectedSort.dataset.field; + const order = selectedSort.dataset.order; + return {field: field, order: order}; + } + + // Sort settings by the selected sort option. + function sortSettings(settings) { + const sort = sortOrder(); + return settings.sort(function(a, b) { + let aValue = a[sort.field]; + let bValue = b[sort.field]; + if (sort.field == "updated_at") { + aValue = new Date(Date.parse(aValue)); + bValue = new Date(Date.parse(bValue)); + } + + if (aValue === bValue) { + return 0; + } else if (sort.order === "asc") { + return (aValue < bValue) ? -1 : 1; + } else { + return (aValue > bValue) ? -1 : 1; + } + }) + } + + function setSortOrder(event) { + event.preventDefault(); + + const target = event.target.closest(".super-settings-sort-control"); + let prevSelection = document.querySelector(".super-settings-sort-control[data-selected=true]"); + + if (prevSelection == target) { + selectSortElement(prevSelection, false); + target.querySelector(`[data-order=${target.dataset.order}]`).style.display = "none"; + target.dataset.order = (target.dataset.order === "asc" ? "desc" : "asc"); + target.querySelector(`[data-order=${target.dataset.order}]`).style.display = "inline-block"; + } else { + selectSortElement(prevSelection, false); + } + + selectSortElement(target, true); + + renderSettingsTable(activeSettings); + } + + function selectSortElement(element, selected) { + element.dataset.selected = selected; + + const svg = element.querySelector(`[data-order=${element.dataset.order}]`).querySelector("svg"); + if (selected) { + svg.style.backgroundColor = getComputedStyle(document.querySelector(".super-settings")).getPropertyValue("--primary-color"); + svg.style.fill = "white"; + } else { + svg.style.backgroundColor = null; + svg.style.fill = null; + } + } + function promptUnsavedChanges(event) { if (changesCount() > 0) { return "Are you sure you want to leave?"; } else { return undefined; @@ -738,17 +814,20 @@ let activeSettings = []; docReady(function() { storeAccessToken(); - addListener(document.querySelector("#filter"), "input", filterListener); - addListener(document.querySelector("#add-setting"), "click", addSetting); - addListener(document.querySelector("#discard-changes"), "click", refreshPage); - addListener(document.querySelector("#save-settings"), "click", updateSettings); - addListener(document.querySelector("#modal"), "click", closeModal); + addListener(document.querySelector("#super-settings-filter"), "input", filterListener); + addListener(document.querySelector("#super-settings-add-setting"), "click", addSetting); + addListener(document.querySelector("#super-settings-discard-changes"), "click", refreshPage); + addListener(document.querySelector("#super-settings-save-settings"), "click", updateSettings); + addListener(document.querySelector("#super-settings-modal"), "click", closeModal); + addListener(document.querySelectorAll(".super-settings-sort-control"), "click", setSortOrder); const queryParams = new URLSearchParams(window.location.search); applyFilter(queryParams.get("filter")); + + selectSortElement(document.querySelector(".super-settings-sort-control[data-selected=true]"), true); fetchActiveSettings(); window.onbeforeunload = promptUnsavedChanges; })