diff --git a/app/sovran_systemsos_web/server.py b/app/sovran_systemsos_web/server.py index 684ad0a..79dbf4e 100644 --- a/app/sovran_systemsos_web/server.py +++ b/app/sovran_systemsos_web/server.py @@ -1319,7 +1319,7 @@ async def api_credentials(unit: str): @app.get("/api/service-detail/{unit}") -async def api_service_detail(unit: str): +async def api_service_detail(unit: str, icon: str | None = None): """Return comprehensive details for a single service — status, credentials, port health, domain health, description, and IPs — in one API call.""" cfg = load_config() @@ -1335,8 +1335,12 @@ async def api_service_detail(unit: str): loop = asyncio.get_event_loop() overrides, nostr_npub = await loop.run_in_executor(None, _read_hub_overrides) - # Find the service config entry - entry = next((s for s in services if s.get("unit") == unit), None) + # Find the service config entry, preferring icon match when provided + entry = None + if icon: + entry = next((s for s in services if s.get("unit") == unit and s.get("icon") == icon), None) + if entry is None: + entry = next((s for s in services if s.get("unit") == unit), None) if entry is None: raise HTTPException(status_code=404, detail="Service not found") diff --git a/app/sovran_systemsos_web/static/app.js b/app/sovran_systemsos_web/static/app.js index ff246ce..3f19269 100644 --- a/app/sovran_systemsos_web/static/app.js +++ b/app/sovran_systemsos_web/static/app.js @@ -268,7 +268,7 @@ function buildTile(svc) { tile.style.cursor = "pointer"; tile.addEventListener("click", function() { - openServiceDetailModal(svc.unit, svc.name); + openServiceDetailModal(svc.unit, svc.name, svc.icon); }); return tile; @@ -383,14 +383,16 @@ function _attachCopyHandlers(container) { }); } -async function openServiceDetailModal(unit, name) { +async function openServiceDetailModal(unit, name, icon) { if (!$credsModal) return; if ($credsTitle) $credsTitle.textContent = name; if ($credsBody) $credsBody.innerHTML = '

Loading…

'; $credsModal.classList.add("open"); try { - var data = await apiFetch("/api/service-detail/" + encodeURIComponent(unit)); + var url = "/api/service-detail/" + encodeURIComponent(unit); + if (icon) url += "?icon=" + encodeURIComponent(icon); + var data = await apiFetch(url); var html = ""; // Section A: Description @@ -643,8 +645,8 @@ async function openServiceDetailModal(unit, name) { if (unit === "matrix-synapse.service") { var addBtn = document.getElementById("matrix-add-user-btn"); var changePwBtn = document.getElementById("matrix-change-pw-btn"); - if (addBtn) addBtn.addEventListener("click", function() { openMatrixCreateUserModal(unit, name); }); - if (changePwBtn) changePwBtn.addEventListener("click", function() { openMatrixChangePasswordModal(unit, name); }); + if (addBtn) addBtn.addEventListener("click", function() { openMatrixCreateUserModal(unit, name, icon); }); + if (changePwBtn) changePwBtn.addEventListener("click", function() { openMatrixChangePasswordModal(unit, name, icon); }); } if (data.feature) { @@ -695,7 +697,7 @@ async function openCredsModal(unit, name) { } } -function openMatrixCreateUserModal(unit, name) { +function openMatrixCreateUserModal(unit, name, icon) { if (!$credsBody) return; $credsBody.innerHTML = '
' + @@ -710,7 +712,7 @@ function openMatrixCreateUserModal(unit, name) { '
'; document.getElementById("matrix-create-back-btn").addEventListener("click", function() { - openServiceDetailModal(unit, name); + openServiceDetailModal(unit, name, icon); }); document.getElementById("matrix-create-submit-btn").addEventListener("click", async function() { @@ -750,7 +752,7 @@ function openMatrixCreateUserModal(unit, name) { }); } -function openMatrixChangePasswordModal(unit, name) { +function openMatrixChangePasswordModal(unit, name, icon) { if (!$credsBody) return; $credsBody.innerHTML = '
' + @@ -764,7 +766,7 @@ function openMatrixChangePasswordModal(unit, name) { '
'; document.getElementById("matrix-chpw-back-btn").addEventListener("click", function() { - openServiceDetailModal(unit, name); + openServiceDetailModal(unit, name, icon); }); document.getElementById("matrix-chpw-submit-btn").addEventListener("click", async function() {