import { templated } from 'atlibs/component/index.js' const Base = await templated(new URL('./requester-actions.html', import.meta.url)); // The requester module's module.json actions as forms. Emits run-entry {entry, input}; empty // fields are left out, values go as text (the cubit types them by module.json). customElements.define('requester-actions', class extends Base { setActions(actions) { this.querySelector(".actions").replaceChildren(...actions.map(({ entry, label, description, fields }) => { const action = Base.templates.action.content.cloneNode(true); action.querySelector(".label").textContent = label; action.querySelector(".description").textContent = description; action.querySelector(".fields").replaceChildren(...fields.map(({ key, label }) => { const field = Base.templates.field.content.cloneNode(true); field.querySelector(".label").textContent = label; field.querySelector("textarea").name = key; return field; })); const form = action.querySelector("form"); form.dataset.entry = entry; form.onsubmit = (e) => { e.preventDefault(); const input = Object.fromEntries([...new FormData(form)].filter(([, v]) => v.trim()).map(([k, v]) => [k, v.trim()])); this.dispatchEvent(new CustomEvent("run-entry", { bubbles: true, detail: { entry, input } })); }; return action; })); } render(state, previous) { this.querySelector(".panel").style.display = state.session === "signed-in" ? "block" : "none"; if (previous?.results === state.results && previous?.running === state.running) return; for (const form of this.querySelectorAll("form[data-entry]")) { const { entry } = form.dataset; form.querySelector(".run").toggleAttribute("aria-busy", state.running === entry); form.querySelector(".result").textContent = entry in state.results ? JSON.stringify(state.results[entry], null, 1) : ""; } } });