feat: add multi-server control panel and host-aware sync

This commit is contained in:
Luca Sacchi Ricciardi
2026-04-25 15:40:20 +02:00
parent 3ba6a9a41c
commit f60781bd7f
13 changed files with 641 additions and 41 deletions
+40 -8
View File
@@ -5,6 +5,8 @@
const API_BASE = "/api/v1";
const REFRESH_INTERVAL = 30000; // 30 secondi
let activeServerId = null;
let activeHost = null;
// Formattare bytes
function formatBytes(bytes) {
@@ -17,14 +19,19 @@ function formatBytes(bytes) {
// Recuperare health
async function fetchHealth() {
if (!activeHost) {
return null;
}
try {
const response = await fetch(`${API_BASE}/health`);
const response = await fetch(buildApiUrl(`${API_BASE}/health`));
if (response.ok) {
const data = await response.json();
return {
status: data.status,
ollama_status: data.ollama_status,
timestamp: new Date().toISOString()
timestamp: new Date().toISOString(),
serverId: activeServerId
};
}
} catch (error) {
@@ -35,8 +42,12 @@ async function fetchHealth() {
// Recuperare modelli
async function fetchModels() {
if (!activeHost) {
return null;
}
try {
const response = await fetch(`${API_BASE}/models`);
const response = await fetch(buildApiUrl(`${API_BASE}/models`));
if (!response.ok) throw new Error("Failed to load models");
const data = await response.json();
@@ -46,7 +57,8 @@ async function fetchModels() {
models,
total: models.length,
totalSize: formatBytes(models.reduce((sum, m) => sum + m.size, 0)),
timestamp: new Date().toISOString()
timestamp: new Date().toISOString(),
serverId: activeServerId
};
} catch (error) {
console.error("Error loading models:", error);
@@ -57,7 +69,7 @@ async function fetchModels() {
// Recuperare dettagli show per un modello
async function fetchModelShow(modelName) {
try {
const response = await fetch(`${API_BASE}/models/${encodeURIComponent(modelName)}/show`);
const response = await fetch(buildApiUrl(`${API_BASE}/models/${encodeURIComponent(modelName)}/show`));
if (!response.ok) {
return null;
}
@@ -89,6 +101,16 @@ async function fetchAllModelsShow(models) {
// Sincronizzare i dati
async function syncData() {
if (!activeHost) {
self.postMessage({
type: "DATA_UPDATED",
health: null,
modelsData: null,
serverId: activeServerId
});
return;
}
const health = await fetchHealth();
const modelsData = await fetchModels();
@@ -103,18 +125,28 @@ async function syncData() {
self.postMessage({
type: "DATA_UPDATED",
health,
modelsData
modelsData,
serverId: activeServerId
});
}
// Eseguire la sincronizzazione iniziale
syncData();
function buildApiUrl(path) {
const url = new URL(path, self.location.origin);
url.searchParams.set("host", activeHost);
return `${url.pathname}${url.search}`;
}
// Pianificare aggiornamenti periodici
setInterval(syncData, REFRESH_INTERVAL);
// Gestire messaggi dal main thread
self.onmessage = (event) => {
if (event.data.type === "SET_SERVER") {
activeServerId = event.data.serverId || null;
activeHost = event.data.host || null;
syncData();
}
if (event.data.type === "SYNC_NOW") {
syncData();
}