class ServersPage { constructor() { this.form = document.getElementById("server-form"); this.serverIdInput = document.getElementById("server-id"); this.serverNameInput = document.getElementById("server-name"); this.serverHostInput = document.getElementById("server-host"); this.clearFormBtn = document.getElementById("clear-form-btn"); this.serversList = document.getElementById("servers-list"); this.serversCount = document.getElementById("servers-count"); this.init(); } init() { this.form?.addEventListener("submit", (event) => { event.preventDefault(); this.saveServer(); }); this.clearFormBtn?.addEventListener("click", () => this.resetForm()); this.renderServers(); } saveServer() { const name = this.serverNameInput?.value.trim() || ""; const host = normalizeHost(this.serverHostInput?.value || ""); if (!name || !host) { return; } const existingId = this.serverIdInput?.value || ""; const servers = loadServers(); if (existingId) { const index = servers.findIndex((server) => server.id === existingId); if (index >= 0) { servers[index] = { ...servers[index], name, host }; } saveServers(servers); setActiveServerId(existingId); } else { const newServer = { id: generateServerId(), name, host }; servers.push(newServer); saveServers(servers); setActiveServerId(newServer.id); } this.resetForm(); this.renderServers(); } editServer(serverId) { const server = getServerById(serverId); if (!server) { return; } this.serverIdInput.value = server.id; this.serverNameInput.value = server.name; this.serverHostInput.value = server.host; } deleteServer(serverId) { const servers = loadServers().filter((server) => server.id !== serverId); saveServers(servers); clearServerCaches(serverId); const activeServerId = getActiveServerId(); if (activeServerId === serverId) { if (servers.length > 0) { setActiveServerId(servers[0].id); } else { localStorage.removeItem(ACTIVE_SERVER_KEY); } } this.renderServers(); } selectServer(serverId) { setActiveServerId(serverId); this.renderServers(); } openAvailable(serverId) { window.location.href = buildServerUrl("/models-available", serverId); } openRunning(serverId) { window.location.href = buildServerUrl("/models-running", serverId); } resetForm() { this.serverIdInput.value = ""; this.serverNameInput.value = ""; this.serverHostInput.value = ""; } renderServers() { const servers = loadServers(); const activeServerId = getActiveServerId(); if (this.serversCount) { this.serversCount.textContent = `${servers.length} server${servers.length === 1 ? "" : "s"}`; } if (!this.serversList) { return; } if (servers.length === 0) { this.serversList.innerHTML = `
No servers configured yet. Add your first Ollama endpoint in the control panel.
`; return; } this.serversList.innerHTML = servers .map((server) => { const isActive = server.id === activeServerId; return `

${this.escapeHtml(server.name)}

${this.escapeHtml(server.host)}

`; }) .join(""); this.bindServerActions(); } bindServerActions() { this.serversList.querySelectorAll("button[data-action]").forEach((button) => { button.addEventListener("click", () => { const action = button.getAttribute("data-action"); const serverId = button.getAttribute("data-server-id") || ""; if (!serverId) { return; } if (action === "select") this.selectServer(serverId); if (action === "available") this.openAvailable(serverId); if (action === "running") this.openRunning(serverId); if (action === "edit") this.editServer(serverId); if (action === "delete") this.deleteServer(serverId); }); }); } escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } } document.addEventListener("DOMContentLoaded", () => { window.serversPage = new ServersPage(); });