www.spaceplanner.app

Web client to the spaceplanner API
git clone git://jacobedwards.org/www.spaceplanner.app
Log | Files | Refs

commit 71f55746d8ee42c3be4cd93fbf6c08cf7081bd19
parent d1f7c01c47857a2c667a5b3ba976b1dc6126dd0d
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Wed,  2 Oct 2024 10:44:56 -0700

Add page to change developer settings

Diffstat:
Afiles/dev/index.html | 25+++++++++++++++++++++++++
Afiles/dev/main.css | 7+++++++
Afiles/dev/main.js | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/files/dev/index.html b/files/dev/index.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> + <head> + <title>Spaceplanner Developer Settings</title> + <meta name="viewport" content="width=device-width"> + <script type="module" src="main.js"></script> + <link rel="stylesheet" type="text/css" href="/css/main.css"/> + <link rel="stylesheet" type="text/css" href="./main.css"/> + </head> + <body> + <header> + <h1>Developer Settings</h1> + <p>Settings to aid in development of the project.</p> + </header> + + <p>Changing these settings could result in unexpected + behavior, it's advisable to leave them alone if you + don't need them. Settings are stored in your device's + local storage so they should persist between sessions + (depending on your user agent and settings) and are + per-device.</p> + + <form id="settings"></form> + </body> +</html> diff --git a/files/dev/main.css b/files/dev/main.css @@ -0,0 +1,7 @@ +p { + max-width: 60ch; +} + +label.description { + display: block; +} diff --git a/files/dev/main.js b/files/dev/main.js @@ -0,0 +1,87 @@ +import * as dev from "/lib/dev.js" + +main() + +function main() { + let f = document.getElementById("settings") + + + for (let k in dev.settings) { + f.append(makeLabel(dev.settings[k])) + f.append(makeInput(dev.settings[k])) + f.append(makeDescription(dev.settings[k])) + f.append(document.createElement("br")) + } + let inputs = document.querySelectorAll("#settings > input") + + let reset = f.appendChild(document.createElement("input")) + reset.type = "button" + reset.value = "Restore" + reset.setAttribute("title", "Restore default settings") + reset.addEventListener("click", function(ev) { + inputs.forEach(function(i) { + if (dev.settings[i.id].type === "bool") { + i.checked = false + } else if (dev.settings[i.id].type === "string") { + i.value = "" + } else { + throw new Error("Invalid type") + } + dev.setting(i.id, null) + }) + }) +} + +function makeLabel(setting) { + let l = document.createElement("label") + + l.append(document.createTextNode(setting.name + ": ")) + l.setAttribute("for", setting.key) + l.setAttribute("title", setting.brief) + + return l +} + +function makeInput(setting) { + let c = document.createElement("input") + let i = c + + i.id = setting.key + i.setAttribute("title", setting.brief) + let v = dev.setting(setting.key) + if (setting.type === "bool") { + i.type = "checkbox" + if (v) { + i.setAttribute("checked", true) + } + } else if (setting.type === "string") { + i.value = v + } else { + throw new Error("Invalid type") + } + + i.addEventListener("change", inputChangeHandler) + + return c +} + +function makeDescription(setting) { + let l = document.createElement("label") + + l.classList.add("description") + l.setAttribute("for", setting.key) + l.append(document.createTextNode(setting.description ?? setting.brief)) + + return l +} + +function inputChangeHandler(ev) { + console.log("inputChangeHandler", ev.target.id, ev.target.value) + try { + dev.setting(ev.target.id, dev.settings[ev.target.id].type === "bool" ? ev.target.checked : ev.target.value) + } + catch(err) { + ev.target.setCustomValidity(err) + ev.target.reportValidity() + } +}