2021-11-28 19:41:57 +00:00
|
|
|
// Retrieve elements from the DOM.
|
2021-11-27 15:50:05 +00:00
|
|
|
var showConfig = document.getElementById("show-config");
|
2021-11-28 00:17:15 +00:00
|
|
|
var configForm = document.getElementById("config-form");
|
2021-11-28 19:41:57 +00:00
|
|
|
var regenerateButton = document.getElementById("config-regenerate");
|
2021-11-28 02:47:56 +00:00
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
// Global variables.
|
|
|
|
var rawConfig = {};
|
2021-11-28 02:47:56 +00:00
|
|
|
var emptyValueDefault = "🖊️";
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
/**
|
|
|
|
* Fetch the existing config file.
|
|
|
|
*/
|
2021-11-28 00:17:15 +00:00
|
|
|
fetch("/config")
|
|
|
|
.then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
rawConfig = data;
|
|
|
|
configForm.style.display = "block";
|
|
|
|
processChildren(configForm, data);
|
|
|
|
|
|
|
|
var submitButton = document.createElement("button");
|
|
|
|
submitButton.type = "submit";
|
|
|
|
submitButton.innerHTML = "update";
|
|
|
|
configForm.appendChild(submitButton);
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
// The config form's submit handler.
|
2021-11-28 00:17:15 +00:00
|
|
|
configForm.addEventListener("submit", (event) => {
|
|
|
|
event.preventDefault();
|
2021-11-28 16:12:26 +00:00
|
|
|
console.log(rawConfig);
|
2021-11-28 01:36:03 +00:00
|
|
|
const response = fetch("/config", {
|
|
|
|
method: "POST",
|
|
|
|
credentials: "same-origin",
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
body: JSON.stringify(rawConfig)
|
|
|
|
}).then(response => response.json())
|
|
|
|
.then((data) => console.log(data));
|
2021-11-27 15:50:05 +00:00
|
|
|
});
|
2021-11-27 16:14:49 +00:00
|
|
|
});
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
/**
|
|
|
|
* The click handler for the Regenerate button.
|
|
|
|
*/
|
2021-11-28 18:28:22 +00:00
|
|
|
regenerateButton.addEventListener("click", (event) => {
|
|
|
|
event.preventDefault();
|
2021-11-28 18:45:00 +00:00
|
|
|
regenerateButton.style.cursor = "progress";
|
|
|
|
regenerateButton.disabled = true;
|
2021-11-28 18:28:22 +00:00
|
|
|
fetch("/regenerate")
|
|
|
|
.then(response => response.json())
|
2021-11-28 19:29:16 +00:00
|
|
|
.then(data => {
|
|
|
|
regenerateButton.style.cursor = "pointer";
|
|
|
|
regenerateButton.disabled = false;
|
|
|
|
console.log(data);
|
|
|
|
});
|
2021-11-28 18:28:22 +00:00
|
|
|
})
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
/**
|
|
|
|
* Adds config elements to the DOM representing the sub-components
|
|
|
|
* of one of the fields in the raw config file.
|
|
|
|
* @param {the parent element} element
|
|
|
|
* @param {the data to be rendered for this element and its children} data
|
|
|
|
*/
|
2021-11-27 16:14:49 +00:00
|
|
|
function processChildren(element, data) {
|
|
|
|
for (let key in data) {
|
|
|
|
var child = document.createElement("div");
|
|
|
|
child.id = key;
|
2021-11-27 19:39:05 +00:00
|
|
|
child.className = "config-element";
|
2021-11-27 16:14:49 +00:00
|
|
|
child.appendChild(document.createTextNode(key + ": "));
|
2021-11-28 01:36:03 +00:00
|
|
|
if (data[key] === Object(data[key]) && !Array.isArray(data[key])) {
|
2021-11-28 02:47:56 +00:00
|
|
|
child.className+=" config-title";
|
2021-11-27 16:14:49 +00:00
|
|
|
processChildren(child, data[key]);
|
|
|
|
} else {
|
2021-11-28 02:47:56 +00:00
|
|
|
child.appendChild(createValueNode(data, key));
|
2021-11-27 16:14:49 +00:00
|
|
|
}
|
|
|
|
element.appendChild(child);
|
|
|
|
}
|
2021-11-27 23:00:47 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
/**
|
|
|
|
* Takes an element, and replaces it with an editable
|
|
|
|
* element with the same data in place.
|
|
|
|
* @param {the original element to be replaced} original
|
|
|
|
* @param {the source data to be rendered for the new element} data
|
|
|
|
* @param {the key for this input in the source data} key
|
|
|
|
*/
|
2021-11-28 00:17:15 +00:00
|
|
|
function makeElementEditable(original, data, key) {
|
2021-11-28 01:36:03 +00:00
|
|
|
original.addEventListener("click", () => {
|
2021-11-27 23:00:47 +00:00
|
|
|
var inputNewText = document.createElement("input");
|
|
|
|
inputNewText.type = "text";
|
2021-11-28 00:17:15 +00:00
|
|
|
inputNewText.className = "config-element-edit";
|
|
|
|
inputNewText.value = original.textContent;
|
|
|
|
fixInputOnFocusOut(inputNewText, data, key);
|
|
|
|
original.parentNode.replaceChild(inputNewText, original);
|
|
|
|
inputNewText.focus();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
/**
|
|
|
|
* Creates a node corresponding to the value of a config element.
|
|
|
|
* @param {the source data} data
|
|
|
|
* @param {the key corresponding to this node's data} key
|
|
|
|
* @returns A new element which corresponds to the value in some field.
|
|
|
|
*/
|
2021-11-28 02:47:56 +00:00
|
|
|
function createValueNode(data, key) {
|
|
|
|
var valueElement = document.createElement("span");
|
|
|
|
valueElement.className = "config-element-value";
|
|
|
|
valueElement.textContent = !data[key] ? emptyValueDefault : data[key];
|
|
|
|
makeElementEditable(valueElement, data, key);
|
|
|
|
return valueElement;
|
|
|
|
}
|
|
|
|
|
2021-11-28 19:41:57 +00:00
|
|
|
/**
|
|
|
|
* Replaces an existing input element with an element with the same data, which is not an input.
|
|
|
|
* If the input data for this element was changed, update the corresponding data in the raw config.
|
|
|
|
* @param {the original element to be replaced} original
|
|
|
|
* @param {the source data} data
|
|
|
|
* @param {the key corresponding to this node's data} key
|
|
|
|
*/
|
2021-11-28 00:17:15 +00:00
|
|
|
function fixInputOnFocusOut(original, data, key) {
|
|
|
|
original.addEventListener("blur", () => {
|
2021-11-28 02:47:56 +00:00
|
|
|
data[key] = (!!data[key] && original.value != emptyValueDefault) ? original.value : "";
|
|
|
|
original.parentNode.replaceChild(createValueNode(data, key), original);
|
2021-11-27 23:00:47 +00:00
|
|
|
})
|
2021-11-28 00:17:15 +00:00
|
|
|
}
|