johnandersen777.bsky.social/atlibs-socialweb-computer-requester
socialweb.computer market requester and policy modules for atlibs, with its web pages and lexicons
0
0
import { templated } from 'atlibs/component/index.js'
const Base = await templated(new URL('./swc-sessions.html', import.meta.url));
const names = (form) => new FormData(form).getAll("sessions");
// Login and module sessions, and the agent features. Emits login {username, names},
// set-sessions {names}, announce, allow-agent-requests {allow}. Renders {ui, compute}.
customElements.define('swc-sessions', class extends Base {
connectedCallback() {
super.connectedCallback();
const emit = (type, detail) => this.dispatchEvent(new CustomEvent(type, { bubbles: true, detail }));
this.querySelector(".login-form").onsubmit = (e) => {
e.preventDefault();
emit("login", { username: e.target.username.value, names: names(e.target) });
};
this.querySelector(".sessions-form").onsubmit = (e) => {
e.preventDefault();
emit("set-sessions", { names: names(e.target) });
};
this.querySelector(".announce-button").onclick = () => emit("announce");
this.querySelector(".allow").onchange = (e) => emit("allow-agent-requests", { allow: e.target.checked });
}
// One checkbox per policy session, in both forms; login ticks them all.
setPolicy(policy) {
for (const fieldset of this.querySelectorAll(".choices")) {
fieldset.replaceChildren(...Object.entries(policy.sessions).map(([name, { label, scope }]) => {
const choice = Base.templates.choice.content.cloneNode(true);
Object.assign(choice.querySelector("input"), { value: name, checked: true });
choice.querySelector(".label").textContent = label ?? name;
choice.querySelector("label").title = scope;
return choice;
}));
}
this.policy = policy;
}
render({ ui, compute }, previous) {
this.querySelector(".login").style.display = ui.session === "signed-out" ? "block" : "none";
this.querySelector(".panel").style.display = ui.session === "signed-in" ? "block" : "none";
this.querySelector(".login-button").toggleAttribute("aria-busy", ui.login.busy);
this.querySelector(".login .error").textContent = ui.login.error ?? "";
if (previous?.ui.granted !== ui.granted) {
for (const input of this.querySelectorAll(".sessions-form input")) input.checked = ui.granted.includes(input.value);
}
const on = ui.features.includes("agents");
const requires = this.policy?.features.agents.requires.join(" + ") ?? "";
this.querySelector(".feature").textContent = on ? `on (${requires})` : `off: needs ${requires}`;
const announce = this.querySelector(".announce-button");
announce.disabled = !on || !compute.receipt;
announce.toggleAttribute("aria-busy", ui.announce.status === "busy");
const allow = this.querySelector(".allow");
allow.disabled = !on;
allow.checked = ui.allowAgentRequests;
this.querySelector(".announce").textContent = ui.announce.error ?? (ui.announce.status === "done" ? "posted" : on && !compute.receipt ? "Find a guest (below) to announce it." : "");
}
});