mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2024-11-29 19:53:40 +01:00
9d408a62bf
These new samplers will be hidden when diffusers is disabled. Also, samplers that aren't implemented in diffusers yet will be disabled when using diffusers
659 lines
23 KiB
JavaScript
659 lines
23 KiB
JavaScript
/**
|
|
* Enum of parameter types
|
|
* @readonly
|
|
* @enum {string}
|
|
*/
|
|
var ParameterType = {
|
|
checkbox: "checkbox",
|
|
select: "select",
|
|
select_multiple: "select_multiple",
|
|
slider: "slider",
|
|
custom: "custom",
|
|
}
|
|
|
|
/**
|
|
* JSDoc style
|
|
* @typedef {object} Parameter
|
|
* @property {string} id
|
|
* @property {keyof ParameterType} type
|
|
* @property {string | (parameter: Parameter) => (HTMLElement | string)} label
|
|
* @property {string | (parameter: Parameter) => (HTMLElement | string) | undefined} note
|
|
* @property {(parameter: Parameter) => (HTMLElement | string) | undefined} render
|
|
* @property {string | undefined} icon
|
|
* @property {number|boolean|string} default
|
|
* @property {boolean?} saveInAppConfig
|
|
*/
|
|
|
|
/** @type {Array.<Parameter>} */
|
|
var PARAMETERS = [
|
|
{
|
|
id: "theme",
|
|
type: ParameterType.select,
|
|
label: "Theme",
|
|
default: "theme-default",
|
|
note: "customize the look and feel of the ui",
|
|
options: [
|
|
// Note: options expanded dynamically
|
|
{
|
|
value: "theme-default",
|
|
label: "Default",
|
|
},
|
|
],
|
|
icon: "fa-palette",
|
|
},
|
|
{
|
|
id: "save_to_disk",
|
|
type: ParameterType.checkbox,
|
|
label: "Auto-Save Images",
|
|
note: "automatically saves images to the specified location",
|
|
icon: "fa-download",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "diskPath",
|
|
type: ParameterType.custom,
|
|
label: "Save Location",
|
|
render: (parameter) => {
|
|
return `<input id="${parameter.id}" name="${parameter.id}" size="30" disabled>`
|
|
},
|
|
},
|
|
{
|
|
id: "metadata_output_format",
|
|
type: ParameterType.select,
|
|
label: "Metadata format",
|
|
note: "will be saved to disk in this format",
|
|
default: "txt",
|
|
options: [
|
|
{
|
|
value: "none",
|
|
label: "none",
|
|
},
|
|
{
|
|
value: "txt",
|
|
label: "txt",
|
|
},
|
|
{
|
|
value: "json",
|
|
label: "json",
|
|
},
|
|
{
|
|
value: "embed",
|
|
label: "embed",
|
|
},
|
|
{
|
|
value: "embed,txt",
|
|
label: "embed & txt",
|
|
},
|
|
{
|
|
value: "embed,json",
|
|
label: "embed & json",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: "block_nsfw",
|
|
type: ParameterType.checkbox,
|
|
label: "Block NSFW images",
|
|
note: "blurs out NSFW images",
|
|
icon: "fa-land-mine-on",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "sound_toggle",
|
|
type: ParameterType.checkbox,
|
|
label: "Enable Sound",
|
|
note: "plays a sound on task completion",
|
|
icon: "fa-volume-low",
|
|
default: true,
|
|
},
|
|
{
|
|
id: "process_order_toggle",
|
|
type: ParameterType.checkbox,
|
|
label: "Process newest jobs first",
|
|
note: "reverse the normal processing order",
|
|
icon: "fa-arrow-down-short-wide",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "ui_open_browser_on_start",
|
|
type: ParameterType.checkbox,
|
|
label: "Open browser on startup",
|
|
note: "starts the default browser on startup",
|
|
icon: "fa-window-restore",
|
|
default: true,
|
|
saveInAppConfig: true,
|
|
},
|
|
{
|
|
id: "vram_usage_level",
|
|
type: ParameterType.select,
|
|
label: "GPU Memory Usage",
|
|
note:
|
|
"Faster performance requires more GPU memory (VRAM)<br/><br/>" +
|
|
"<b>Balanced:</b> nearly as fast as High, much lower VRAM usage<br/>" +
|
|
"<b>High:</b> fastest, maximum GPU memory usage</br>" +
|
|
"<b>Low:</b> slowest, recommended for GPUs with 3 to 4 GB memory",
|
|
icon: "fa-forward",
|
|
default: "balanced",
|
|
options: [
|
|
{ value: "balanced", label: "Balanced" },
|
|
{ value: "high", label: "High" },
|
|
{ value: "low", label: "Low" },
|
|
],
|
|
},
|
|
{
|
|
id: "use_cpu",
|
|
type: ParameterType.checkbox,
|
|
label: "Use CPU (not GPU)",
|
|
note: "warning: this will be *very* slow",
|
|
icon: "fa-microchip",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "auto_pick_gpus",
|
|
type: ParameterType.checkbox,
|
|
label: "Automatically pick the GPUs (experimental)",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "use_gpus",
|
|
type: ParameterType.select_multiple,
|
|
label: "GPUs to use (experimental)",
|
|
note: "to process in parallel",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "auto_save_settings",
|
|
type: ParameterType.checkbox,
|
|
label: "Auto-Save Settings",
|
|
note: "restores settings on browser load",
|
|
icon: "fa-gear",
|
|
default: true,
|
|
},
|
|
{
|
|
id: "confirm_dangerous_actions",
|
|
type: ParameterType.checkbox,
|
|
label: "Confirm dangerous actions",
|
|
note:
|
|
"Actions that might lead to data loss must either be clicked with the shift key pressed, or confirmed in an 'Are you sure?' dialog",
|
|
icon: "fa-check-double",
|
|
default: true,
|
|
},
|
|
{
|
|
id: "listen_to_network",
|
|
type: ParameterType.checkbox,
|
|
label: "Make Stable Diffusion available on your network. Please restart the program after changing this.",
|
|
note: "Other devices on your network can access this web page",
|
|
icon: "fa-network-wired",
|
|
default: true,
|
|
saveInAppConfig: true,
|
|
},
|
|
{
|
|
id: "listen_port",
|
|
type: ParameterType.custom,
|
|
label: "Network port",
|
|
note: "Port that this server listens to. The '9000' part in 'http://localhost:9000'. Please restart the program after changing this.",
|
|
icon: "fa-anchor",
|
|
render: (parameter) => {
|
|
return `<input id="${parameter.id}" name="${parameter.id}" size="6" value="9000" onkeypress="preventNonNumericalInput(event)">`
|
|
},
|
|
saveInAppConfig: true,
|
|
},
|
|
{
|
|
id: "use_beta_channel",
|
|
type: ParameterType.checkbox,
|
|
label: "Beta channel",
|
|
note:
|
|
"Get the latest features immediately (but could be less stable). Please restart the program after changing this.",
|
|
icon: "fa-fire",
|
|
default: false,
|
|
},
|
|
{
|
|
id: "test_diffusers",
|
|
type: ParameterType.checkbox,
|
|
label: "Test Diffusers",
|
|
note:
|
|
"<b>Experimental! Can have bugs!</b> Use upcoming features (like LoRA) in our new engine. Please press Save, then restart the program after changing this.",
|
|
icon: "fa-bolt",
|
|
default: false,
|
|
saveInAppConfig: true,
|
|
},
|
|
]
|
|
|
|
function getParameterSettingsEntry(id) {
|
|
let parameter = PARAMETERS.filter((p) => p.id === id)
|
|
if (parameter.length === 0) {
|
|
return
|
|
}
|
|
return parameter[0].settingsEntry
|
|
}
|
|
|
|
function sliderUpdate(event) {
|
|
if (event.srcElement.id.endsWith("-input")) {
|
|
let slider = document.getElementById(event.srcElement.id.slice(0, -6))
|
|
slider.value = event.srcElement.value
|
|
slider.dispatchEvent(new Event("change"))
|
|
} else {
|
|
let field = document.getElementById(event.srcElement.id + "-input")
|
|
field.value = event.srcElement.value
|
|
field.dispatchEvent(new Event("change"))
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {Parameter} parameter
|
|
* @returns {string | HTMLElement}
|
|
*/
|
|
function getParameterElement(parameter) {
|
|
switch (parameter.type) {
|
|
case ParameterType.checkbox:
|
|
var is_checked = parameter.default ? " checked" : ""
|
|
return `<input id="${parameter.id}" name="${parameter.id}"${is_checked} type="checkbox">`
|
|
case ParameterType.select:
|
|
case ParameterType.select_multiple:
|
|
var options = (parameter.options || [])
|
|
.map((option) => `<option value="${option.value}">${option.label}</option>`)
|
|
.join("")
|
|
var multiple = parameter.type == ParameterType.select_multiple ? "multiple" : ""
|
|
return `<select id="${parameter.id}" name="${parameter.id}" ${multiple}>${options}</select>`
|
|
case ParameterType.slider:
|
|
return `<input id="${parameter.id}" name="${parameter.id}" class="editor-slider" type="range" value="${parameter.default}" min="${parameter.slider_min}" max="${parameter.slider_max}" oninput="sliderUpdate(event)"> <input id="${parameter.id}-input" name="${parameter.id}-input" size="4" value="${parameter.default}" pattern="^[0-9\.]+$" onkeypress="preventNonNumericalInput(event)" oninput="sliderUpdate(event)"> ${parameter.slider_unit}`
|
|
case ParameterType.custom:
|
|
return parameter.render(parameter)
|
|
default:
|
|
console.error(`Invalid type ${parameter.type} for parameter ${parameter.id}`)
|
|
return "ERROR: Invalid Type"
|
|
}
|
|
}
|
|
|
|
let parametersTable = document.querySelector("#system-settings .parameters-table")
|
|
/**
|
|
* fill in the system settings popup table
|
|
* @param {Array<Parameter> | undefined} parameters
|
|
* */
|
|
function initParameters(parameters) {
|
|
parameters.forEach((parameter) => {
|
|
const element = getParameterElement(parameter)
|
|
const elementWrapper = createElement("div")
|
|
if (element instanceof Node) {
|
|
elementWrapper.appendChild(element)
|
|
} else {
|
|
elementWrapper.innerHTML = element
|
|
}
|
|
|
|
const note = typeof parameter.note === "function" ? parameter.note(parameter) : parameter.note
|
|
const noteElements = []
|
|
if (note) {
|
|
const noteElement = createElement("small")
|
|
if (note instanceof Node) {
|
|
noteElement.appendChild(note)
|
|
} else {
|
|
noteElement.innerHTML = note || ""
|
|
}
|
|
noteElements.push(noteElement)
|
|
}
|
|
|
|
const icon = parameter.icon ? [createElement("i", undefined, ["fa", parameter.icon])] : []
|
|
|
|
const label = typeof parameter.label === "function" ? parameter.label(parameter) : parameter.label
|
|
const labelElement = createElement("label", { for: parameter.id })
|
|
if (label instanceof Node) {
|
|
labelElement.appendChild(label)
|
|
} else {
|
|
labelElement.innerHTML = label
|
|
}
|
|
|
|
const newrow = createElement(
|
|
"div",
|
|
{ "data-setting-id": parameter.id, "data-save-in-app-config": parameter.saveInAppConfig },
|
|
undefined,
|
|
[
|
|
createElement("div", undefined, undefined, icon),
|
|
createElement("div", undefined, undefined, [labelElement, ...noteElements]),
|
|
elementWrapper,
|
|
]
|
|
)
|
|
parametersTable.appendChild(newrow)
|
|
parameter.settingsEntry = newrow
|
|
})
|
|
}
|
|
|
|
initParameters(PARAMETERS)
|
|
|
|
// listen to parameters from plugins
|
|
PARAMETERS.addEventListener("push", (...items) => {
|
|
initParameters(items)
|
|
|
|
if (items.find((item) => item.saveInAppConfig)) {
|
|
console.log(
|
|
"Reloading app config for new parameters",
|
|
items.map((p) => p.id)
|
|
)
|
|
getAppConfig()
|
|
}
|
|
})
|
|
|
|
let vramUsageLevelField = document.querySelector("#vram_usage_level")
|
|
let useCPUField = document.querySelector("#use_cpu")
|
|
let autoPickGPUsField = document.querySelector("#auto_pick_gpus")
|
|
let useGPUsField = document.querySelector("#use_gpus")
|
|
let saveToDiskField = document.querySelector("#save_to_disk")
|
|
let diskPathField = document.querySelector("#diskPath")
|
|
let metadataOutputFormatField = document.querySelector("#metadata_output_format")
|
|
let listenToNetworkField = document.querySelector("#listen_to_network")
|
|
let listenPortField = document.querySelector("#listen_port")
|
|
let useBetaChannelField = document.querySelector("#use_beta_channel")
|
|
let uiOpenBrowserOnStartField = document.querySelector("#ui_open_browser_on_start")
|
|
let confirmDangerousActionsField = document.querySelector("#confirm_dangerous_actions")
|
|
let testDiffusers = document.querySelector("#test_diffusers")
|
|
|
|
let saveSettingsBtn = document.querySelector("#save-system-settings-btn")
|
|
|
|
async function changeAppConfig(configDelta) {
|
|
try {
|
|
let res = await fetch("/app_config", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(configDelta),
|
|
})
|
|
res = await res.json()
|
|
|
|
console.log("set config status response", res)
|
|
} catch (e) {
|
|
console.log("set config status error", e)
|
|
}
|
|
}
|
|
|
|
async function getAppConfig() {
|
|
try {
|
|
let res = await fetch("/get/app_config")
|
|
const config = await res.json()
|
|
|
|
applySettingsFromConfig(config)
|
|
|
|
// custom overrides
|
|
if (config.update_branch === "beta") {
|
|
useBetaChannelField.checked = true
|
|
document.querySelector("#updateBranchLabel").innerText = "(beta)"
|
|
} else {
|
|
getParameterSettingsEntry("test_diffusers").style.display = "none"
|
|
}
|
|
if (config.ui && config.ui.open_browser_on_start === false) {
|
|
uiOpenBrowserOnStartField.checked = false
|
|
}
|
|
if (config.net && config.net.listen_to_network === false) {
|
|
listenToNetworkField.checked = false
|
|
}
|
|
if (config.net && config.net.listen_port !== undefined) {
|
|
listenPortField.value = config.net.listen_port
|
|
}
|
|
|
|
const testDiffusersEnabled = config.test_diffusers && config.update_branch !== "main"
|
|
testDiffusers.checked = testDiffusersEnabled
|
|
|
|
if (!testDiffusersEnabled) {
|
|
document.querySelector("#lora_model_container").style.display = "none"
|
|
document.querySelector("#lora_alpha_container").style.display = "none"
|
|
|
|
document.querySelectorAll("#sampler_name option.diffusers-only").forEach(option => {
|
|
option.style.display = "none"
|
|
})
|
|
} else {
|
|
document.querySelector("#lora_model_container").style.display = ""
|
|
document.querySelector("#lora_alpha_container").style.display = loraModelField.value ? "" : "none"
|
|
|
|
document.querySelectorAll("#sampler_name option.k_diffusion-only").forEach(option => {
|
|
option.disabled = true
|
|
})
|
|
}
|
|
|
|
console.log("get config status response", config)
|
|
|
|
return config
|
|
} catch (e) {
|
|
console.log("get config status error", e)
|
|
|
|
return {}
|
|
}
|
|
}
|
|
|
|
function applySettingsFromConfig(config) {
|
|
Array.from(parametersTable.children).forEach((parameterRow) => {
|
|
if (parameterRow.dataset.settingId in config && parameterRow.dataset.saveInAppConfig === "true") {
|
|
const configValue = config[parameterRow.dataset.settingId]
|
|
const parameterElement =
|
|
document.getElementById(parameterRow.dataset.settingId) ||
|
|
parameterRow.querySelector("input") ||
|
|
parameterRow.querySelector("select")
|
|
|
|
switch (parameterElement?.tagName) {
|
|
case "INPUT":
|
|
if (parameterElement.type === "checkbox") {
|
|
parameterElement.checked = configValue
|
|
} else {
|
|
parameterElement.value = configValue
|
|
}
|
|
parameterElement.dispatchEvent(new Event("change"))
|
|
break
|
|
case "SELECT":
|
|
if (Array.isArray(configValue)) {
|
|
Array.from(parameterElement.options).forEach((option) => {
|
|
if (configValue.includes(option.value || option.text)) {
|
|
option.selected = true
|
|
}
|
|
})
|
|
} else {
|
|
parameterElement.value = configValue
|
|
}
|
|
parameterElement.dispatchEvent(new Event("change"))
|
|
break
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
saveToDiskField.addEventListener("change", function(e) {
|
|
diskPathField.disabled = !this.checked
|
|
metadataOutputFormatField.disabled = !this.checked
|
|
})
|
|
|
|
function getCurrentRenderDeviceSelection() {
|
|
let selectedGPUs = $("#use_gpus").val()
|
|
|
|
if (useCPUField.checked && !autoPickGPUsField.checked) {
|
|
return "cpu"
|
|
}
|
|
if (autoPickGPUsField.checked || selectedGPUs.length == 0) {
|
|
return "auto"
|
|
}
|
|
|
|
return selectedGPUs.join(",")
|
|
}
|
|
|
|
useCPUField.addEventListener("click", function() {
|
|
let gpuSettingEntry = getParameterSettingsEntry("use_gpus")
|
|
let autoPickGPUSettingEntry = getParameterSettingsEntry("auto_pick_gpus")
|
|
if (this.checked) {
|
|
gpuSettingEntry.style.display = "none"
|
|
autoPickGPUSettingEntry.style.display = "none"
|
|
autoPickGPUsField.setAttribute("data-old-value", autoPickGPUsField.checked)
|
|
autoPickGPUsField.checked = false
|
|
} else if (useGPUsField.options.length >= MIN_GPUS_TO_SHOW_SELECTION) {
|
|
gpuSettingEntry.style.display = ""
|
|
autoPickGPUSettingEntry.style.display = ""
|
|
let oldVal = autoPickGPUsField.getAttribute("data-old-value")
|
|
if (oldVal === null || oldVal === undefined) {
|
|
// the UI started with CPU selected by default
|
|
autoPickGPUsField.checked = true
|
|
} else {
|
|
autoPickGPUsField.checked = oldVal === "true"
|
|
}
|
|
gpuSettingEntry.style.display = autoPickGPUsField.checked ? "none" : ""
|
|
}
|
|
})
|
|
|
|
useGPUsField.addEventListener("click", function() {
|
|
let selectedGPUs = $("#use_gpus").val()
|
|
autoPickGPUsField.checked = selectedGPUs.length === 0
|
|
})
|
|
|
|
autoPickGPUsField.addEventListener("click", function() {
|
|
if (this.checked) {
|
|
$("#use_gpus").val([])
|
|
}
|
|
|
|
let gpuSettingEntry = getParameterSettingsEntry("use_gpus")
|
|
gpuSettingEntry.style.display = this.checked ? "none" : ""
|
|
})
|
|
|
|
async function setDiskPath(defaultDiskPath, force = false) {
|
|
var diskPath = getSetting("diskPath")
|
|
if (force || diskPath == "" || diskPath == undefined || diskPath == "undefined") {
|
|
setSetting("diskPath", defaultDiskPath)
|
|
}
|
|
}
|
|
|
|
function setDeviceInfo(devices) {
|
|
let cpu = devices.all.cpu.name
|
|
let allGPUs = Object.keys(devices.all).filter((d) => d != "cpu")
|
|
let activeGPUs = Object.keys(devices.active)
|
|
|
|
function ID_TO_TEXT(d) {
|
|
let info = devices.all[d]
|
|
if ("mem_free" in info && "mem_total" in info) {
|
|
return `${info.name} <small>(${d}) (${info.mem_free.toFixed(1)}Gb free / ${info.mem_total.toFixed(
|
|
1
|
|
)} Gb total)</small>`
|
|
} else {
|
|
return `${info.name} <small>(${d}) (no memory info)</small>`
|
|
}
|
|
}
|
|
|
|
allGPUs = allGPUs.map(ID_TO_TEXT)
|
|
activeGPUs = activeGPUs.map(ID_TO_TEXT)
|
|
|
|
let systemInfoEl = document.querySelector("#system-info")
|
|
systemInfoEl.querySelector("#system-info-cpu").innerText = cpu
|
|
systemInfoEl.querySelector("#system-info-gpus-all").innerHTML = allGPUs.join("</br>")
|
|
systemInfoEl.querySelector("#system-info-rendering-devices").innerHTML = activeGPUs.join("</br>")
|
|
}
|
|
|
|
function setHostInfo(hosts) {
|
|
let port = listenPortField.value
|
|
hosts = hosts.map((addr) => `http://${addr}:${port}/`).map((url) => `<div><a href="${url}">${url}</a></div>`)
|
|
document.querySelector("#system-info-server-hosts").innerHTML = hosts.join("")
|
|
}
|
|
|
|
async function getSystemInfo() {
|
|
try {
|
|
const res = await SD.getSystemInfo()
|
|
let devices = res["devices"]
|
|
|
|
let allDeviceIds = Object.keys(devices["all"]).filter((d) => d !== "cpu")
|
|
let activeDeviceIds = Object.keys(devices["active"]).filter((d) => d !== "cpu")
|
|
|
|
if (activeDeviceIds.length === 0) {
|
|
useCPUField.checked = true
|
|
}
|
|
|
|
if (allDeviceIds.length < MIN_GPUS_TO_SHOW_SELECTION || useCPUField.checked) {
|
|
let gpuSettingEntry = getParameterSettingsEntry("use_gpus")
|
|
gpuSettingEntry.style.display = "none"
|
|
let autoPickGPUSettingEntry = getParameterSettingsEntry("auto_pick_gpus")
|
|
autoPickGPUSettingEntry.style.display = "none"
|
|
}
|
|
|
|
if (allDeviceIds.length === 0) {
|
|
useCPUField.checked = true
|
|
useCPUField.disabled = true // no compatible GPUs, so make the CPU mandatory
|
|
}
|
|
|
|
autoPickGPUsField.checked = devices["config"] === "auto"
|
|
|
|
useGPUsField.innerHTML = ""
|
|
allDeviceIds.forEach((device) => {
|
|
let deviceName = devices["all"][device]["name"]
|
|
let deviceOption = `<option value="${device}">${deviceName} (${device})</option>`
|
|
useGPUsField.insertAdjacentHTML("beforeend", deviceOption)
|
|
})
|
|
|
|
if (autoPickGPUsField.checked) {
|
|
let gpuSettingEntry = getParameterSettingsEntry("use_gpus")
|
|
gpuSettingEntry.style.display = "none"
|
|
} else {
|
|
$("#use_gpus").val(activeDeviceIds)
|
|
}
|
|
|
|
setDeviceInfo(devices)
|
|
setHostInfo(res["hosts"])
|
|
let force = false
|
|
if (res["enforce_output_dir"] !== undefined) {
|
|
force = res["enforce_output_dir"]
|
|
if (force == true) {
|
|
saveToDiskField.checked = true
|
|
metadataOutputFormatField.disabled = false
|
|
}
|
|
saveToDiskField.disabled = force
|
|
diskPathField.disabled = force
|
|
}
|
|
setDiskPath(res["default_output_dir"], force)
|
|
} catch (e) {
|
|
console.log("error fetching devices", e)
|
|
}
|
|
}
|
|
|
|
saveSettingsBtn.addEventListener("click", function() {
|
|
if (listenPortField.value == "") {
|
|
alert("The network port field must not be empty.")
|
|
return
|
|
}
|
|
if (listenPortField.value < 1 || listenPortField.value > 65535) {
|
|
alert("The network port must be a number from 1 to 65535")
|
|
return
|
|
}
|
|
const updateBranch = useBetaChannelField.checked ? "beta" : "main"
|
|
|
|
const updateAppConfigRequest = {
|
|
render_devices: getCurrentRenderDeviceSelection(),
|
|
update_branch: updateBranch,
|
|
}
|
|
|
|
Array.from(parametersTable.children).forEach((parameterRow) => {
|
|
if (parameterRow.dataset.saveInAppConfig === "true") {
|
|
const parameterElement =
|
|
document.getElementById(parameterRow.dataset.settingId) ||
|
|
parameterRow.querySelector("input") ||
|
|
parameterRow.querySelector("select")
|
|
|
|
switch (parameterElement?.tagName) {
|
|
case "INPUT":
|
|
if (parameterElement.type === "checkbox") {
|
|
updateAppConfigRequest[parameterRow.dataset.settingId] = parameterElement.checked
|
|
} else {
|
|
updateAppConfigRequest[parameterRow.dataset.settingId] = parameterElement.value
|
|
}
|
|
break
|
|
case "SELECT":
|
|
if (parameterElement.multiple) {
|
|
updateAppConfigRequest[parameterRow.dataset.settingId] = Array.from(parameterElement.options)
|
|
.filter((option) => option.selected)
|
|
.map((option) => option.value || option.text)
|
|
} else {
|
|
updateAppConfigRequest[parameterRow.dataset.settingId] = parameterElement.value
|
|
}
|
|
break
|
|
default:
|
|
console.error(
|
|
`Setting parameter ${parameterRow.dataset.settingId} couldn't be saved to app.config - element #${parameter.id} is a <${parameterElement?.tagName} /> instead of a <input /> or a <select />!`
|
|
)
|
|
break
|
|
}
|
|
}
|
|
})
|
|
|
|
const savePromise = changeAppConfig(updateAppConfigRequest)
|
|
saveSettingsBtn.classList.add("active")
|
|
Promise.all([savePromise, asyncDelay(300)]).then(() => saveSettingsBtn.classList.remove("active"))
|
|
})
|