import { templated } from 'atlibs/component/index.js' const Base = await templated(new URL('./agents-list.html', import.meta.url)); // The launch records, one row each. Emits refresh, status {rkey}, shutdown {rkey, delete}. // Renders the AgentsCubit state. customElements.define('agents-list', class extends Base { connectedCallback() { super.connectedCallback(); this.querySelector(".refresh").onclick = () => this.dispatchEvent(new CustomEvent("refresh", { bubbles: true })); } render(agents, previous) { this.querySelector(".panel").style.display = agents.session === "signed-in" ? "block" : "none"; this.querySelector(".error").textContent = agents.error ?? ""; if (previous && ["agents", "busy", "results"].every((k) => previous[k] === agents[k])) return; const emit = (type, detail) => this.dispatchEvent(new CustomEvent(type, { bubbles: true, detail })); this.querySelector(".agents").replaceChildren(...agents.agents.map(({ rkey, record }) => { const row = Base.templates.agent.content.cloneNode(true); const busy = agents.busy[rkey]; row.querySelector(".status").textContent = record.status; row.querySelector(".subhandle").textContent = record.subhandle ?? record.name; row.querySelector(".rkey").textContent = rkey; row.querySelector(".detail").textContent = busy ? `${busy}...` : [record.receipt?.uri, record.error].filter(Boolean).join(" | "); const status = row.querySelector(".status-button"); const shutdown = row.querySelector(".shutdown-button"); for (const b of [status, shutdown]) b.disabled = Boolean(busy); status.toggleAttribute("aria-busy", busy === "status"); shutdown.toggleAttribute("aria-busy", busy === "shutdown"); shutdown.disabled ||= record.status === "stopped"; status.onclick = () => emit("status", { rkey }); const remove = row.querySelector(".delete"); shutdown.onclick = () => emit("shutdown", { rkey, delete: remove.checked }); const result = agents.results[rkey]; row.querySelector(".result").textContent = result ? JSON.stringify(result, null, 1) : ""; return row; })); } });