// views/remotes.js — connector-tile grid of configured remotes with CRUD.
import { post } from "../rc.js?v=persist-all-jobs-1";
import { getState, setState, toast } from "../state.js?v=persist-all-jobs-1";
import { t } from "../i18n.js?v=persist-all-jobs-1";
export async function renderRemotes() {
const app = document.getElementById("app");
if (!app) return;
app.innerHTML = `
`;
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, "'");
}