Fix: Pass icon to disambiguate Bitcoin node modals sharing bitcoind.service unit

Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/ca5a66cc-4b7d-4d26-9a65-3d0c9de4a279

Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-04 22:57:12 +00:00
committed by GitHub
parent e40b0bd188
commit 6b0da2f7cd
2 changed files with 18 additions and 12 deletions

View File

@@ -1319,7 +1319,7 @@ async def api_credentials(unit: str):
@app.get("/api/service-detail/{unit}") @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, """Return comprehensive details for a single service — status, credentials,
port health, domain health, description, and IPs — in one API call.""" port health, domain health, description, and IPs — in one API call."""
cfg = load_config() cfg = load_config()
@@ -1335,7 +1335,11 @@ async def api_service_detail(unit: str):
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
overrides, nostr_npub = await loop.run_in_executor(None, _read_hub_overrides) overrides, nostr_npub = await loop.run_in_executor(None, _read_hub_overrides)
# Find the service config entry # 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) entry = next((s for s in services if s.get("unit") == unit), None)
if entry is None: if entry is None:
raise HTTPException(status_code=404, detail="Service not found") raise HTTPException(status_code=404, detail="Service not found")

View File

@@ -268,7 +268,7 @@ function buildTile(svc) {
tile.style.cursor = "pointer"; tile.style.cursor = "pointer";
tile.addEventListener("click", function() { tile.addEventListener("click", function() {
openServiceDetailModal(svc.unit, svc.name); openServiceDetailModal(svc.unit, svc.name, svc.icon);
}); });
return tile; return tile;
@@ -383,14 +383,16 @@ function _attachCopyHandlers(container) {
}); });
} }
async function openServiceDetailModal(unit, name) { async function openServiceDetailModal(unit, name, icon) {
if (!$credsModal) return; if (!$credsModal) return;
if ($credsTitle) $credsTitle.textContent = name; if ($credsTitle) $credsTitle.textContent = name;
if ($credsBody) $credsBody.innerHTML = '<p class="creds-loading">Loading…</p>'; if ($credsBody) $credsBody.innerHTML = '<p class="creds-loading">Loading…</p>';
$credsModal.classList.add("open"); $credsModal.classList.add("open");
try { 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 = ""; var html = "";
// Section A: Description // Section A: Description
@@ -643,8 +645,8 @@ async function openServiceDetailModal(unit, name) {
if (unit === "matrix-synapse.service") { if (unit === "matrix-synapse.service") {
var addBtn = document.getElementById("matrix-add-user-btn"); var addBtn = document.getElementById("matrix-add-user-btn");
var changePwBtn = document.getElementById("matrix-change-pw-btn"); var changePwBtn = document.getElementById("matrix-change-pw-btn");
if (addBtn) addBtn.addEventListener("click", function() { openMatrixCreateUserModal(unit, name); }); if (addBtn) addBtn.addEventListener("click", function() { openMatrixCreateUserModal(unit, name, icon); });
if (changePwBtn) changePwBtn.addEventListener("click", function() { openMatrixChangePasswordModal(unit, name); }); if (changePwBtn) changePwBtn.addEventListener("click", function() { openMatrixChangePasswordModal(unit, name, icon); });
} }
if (data.feature) { if (data.feature) {
@@ -695,7 +697,7 @@ async function openCredsModal(unit, name) {
} }
} }
function openMatrixCreateUserModal(unit, name) { function openMatrixCreateUserModal(unit, name, icon) {
if (!$credsBody) return; if (!$credsBody) return;
$credsBody.innerHTML = $credsBody.innerHTML =
'<div class="matrix-form-group"><label class="matrix-form-label" for="matrix-new-username">Username</label>' + '<div class="matrix-form-group"><label class="matrix-form-label" for="matrix-new-username">Username</label>' +
@@ -710,7 +712,7 @@ function openMatrixCreateUserModal(unit, name) {
'<div class="matrix-form-result" id="matrix-create-result"></div>'; '<div class="matrix-form-result" id="matrix-create-result"></div>';
document.getElementById("matrix-create-back-btn").addEventListener("click", function() { 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() { 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; if (!$credsBody) return;
$credsBody.innerHTML = $credsBody.innerHTML =
'<div class="matrix-form-group"><label class="matrix-form-label" for="matrix-chpw-username">Username (localpart only, e.g. <em>alice</em>)</label>' + '<div class="matrix-form-group"><label class="matrix-form-label" for="matrix-chpw-username">Username (localpart only, e.g. <em>alice</em>)</label>' +
@@ -764,7 +766,7 @@ function openMatrixChangePasswordModal(unit, name) {
'<div class="matrix-form-result" id="matrix-chpw-result"></div>'; '<div class="matrix-form-result" id="matrix-chpw-result"></div>';
document.getElementById("matrix-chpw-back-btn").addEventListener("click", function() { 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() { document.getElementById("matrix-chpw-submit-btn").addEventListener("click", async function() {