// views/remotes.js — connector-tile grid of configured remotes with CRUD. import { post } from "../rc.js"; import { getState, setState, toast } from "../state.js"; import { t } from "../i18n.js"; export async function renderRemotes() { const app = document.getElementById("app"); if (!app) return; app.innerHTML = `

${t("remotes.title")}

${t("remotes.subtitle")}

${t("remotes.new_remote")}

${t("remotes.loading")}

`; const grid = document.getElementById("remote-grid"); try { const [listRes, dumpRes] = await Promise.all([ post("config/listremotes"), post("config/dump"), ]); const names = (listRes && listRes.remotes) || []; const dump = dumpRes || {}; const remotes = names.map((name) => ({ name, type: (dump[name] && dump[name].type) || "unknown", })); setState({ remotes }); if (remotes.length === 0) { grid.innerHTML = `

${t("remotes.empty_title")}

${t("remotes.empty_body")}

`; return; } grid.innerHTML = remotes .map( (r) => ` ${escapeHtml(r.name)} ${escapeHtml(r.type)}
`, ) .join(""); grid.querySelectorAll("[data-edit]").forEach((btn) => { btn.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); location.hash = `#/configure/edit/${encodeURIComponent(btn.dataset.edit)}`; }); }); grid.querySelectorAll("[data-delete]").forEach((btn) => { btn.addEventListener("click", async (e) => { e.preventDefault(); e.stopPropagation(); const name = btn.dataset.delete; if (!confirm(t("remotes.delete_confirm", name))) return; try { await post("config/delete", { name }); toast(t("remotes.deleted", name), "success"); await renderRemotes(); } catch (err) { toast(`${t("remotes.delete_failed")}: ${err.message}`, "error"); } }); }); } catch (e) { grid.innerHTML = `

${t("error.couldnt_reach")}

${escapeHtml(e.message)}

`; toast(`${t("remotes.load_failed")}: ${e.message}`, "error"); } } function escapeHtml(s) { return String(s) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }