From 70f16ef1e36b11f1c34f6017f3c3c1981196e6d8 Mon Sep 17 00:00:00 2001 From: librelad Date: Mon, 22 Jun 2026 14:41:36 +0100 Subject: [PATCH] fix(webui/tasks): auto-expand opens one row, not all of them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit autoExpandTask (the monitorTask path) opened its row directly without collapsing the others and never set highlightedTaskId — unlike every other opener (toggleTaskDetails, selectTask), which enforce a single open row. So a burst of monitored task creations, e.g. a multi-app first install, stacked every panel open at once. Wait for the row to render, then delegate to selectTask, which collapses any other open panel, sets highlightedTaskId, attaches the right log view (live stream vs snapshot) and scrolls into view. Setting highlightedTaskId also makes monitorTask's own guard trip after the first task, so the running-task auto-follow takes over from there. Co-Authored-By: Claude Opus 4.8 Signed-off-by: librelad --- .../components/tasks/js/tasks-row-expand.js | 70 +++++-------------- 1 file changed, 18 insertions(+), 52 deletions(-) diff --git a/containers/libreportal/frontend/components/tasks/js/tasks-row-expand.js b/containers/libreportal/frontend/components/tasks/js/tasks-row-expand.js index e4e4d39..0e5475f 100644 --- a/containers/libreportal/frontend/components/tasks/js/tasks-row-expand.js +++ b/containers/libreportal/frontend/components/tasks/js/tasks-row-expand.js @@ -197,63 +197,29 @@ Object.assign(TasksManager.prototype, { window.removeEventListener('taskCompleted', onComplete); }); }, - // Auto-expand a task when it's created - async autoExpandTask(taskId) { - - // Wait for task to be rendered + // Auto-expand a task when it's created/started. Waits for its row to land in + // the DOM, then hands off to selectTask, which collapses any other open panel + // first. Opening the row directly here (as this used to) skipped that + // collapse and never set highlightedTaskId, so a burst of monitored tasks — + // e.g. a multi-app first install — stacked every panel open instead of + // showing just the active one. + autoExpandTask(taskId) { let attempts = 0; const maxAttempts = 10; - - const tryExpand = async () => { + + const tryExpand = () => { attempts++; - - // Check if task element exists - const taskElement = document.querySelector(`[data-task-id="${taskId}"]`); - if (!taskElement) { - if (attempts < maxAttempts) { - setTimeout(tryExpand, 500); // Try again in 500ms - } else { - console.warn(`⚠️ Could not find task element for ${taskId} after ${maxAttempts} attempts`); - } - return; + // selectTask returns false until the row exists; once it succeeds it has + // also attached the right log view (live stream vs snapshot), set + // highlightedTaskId and scrolled the row into view — nothing more to do. + if (this.selectTask(taskId)) return; + if (attempts < maxAttempts) { + setTimeout(tryExpand, 500); + } else { + console.warn(`⚠️ Could not find task element for ${taskId} after ${maxAttempts} attempts`); } - - - // Get the details element - const details = document.getElementById(`details-${taskId}`); - if (!details) { - if (attempts < maxAttempts) { - setTimeout(tryExpand, 500); - } else { - console.warn(`⚠️ Could not find details element for ${taskId}`); - } - return; - } - - - // Expand the task details - details.style.display = 'block'; - details.classList.add('task-details-open'); - - // Update toggle button - const toggleBtn = document.querySelector(`.task-btn.toggle-details[onclick*="toggleTaskDetails('${taskId}')"]`); - if (toggleBtn) { - toggleBtn.classList.add('expanded'); - } - - // Scroll to the task - taskElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); - - // Load the output if task is completed - const task = await this.taskManager.getTask(taskId); - if (task && (task.status === 'completed' || task.status === 'failed')) { - setTimeout(() => { - this.loadTaskOutput(taskId); - }, 1000); - } - }; - + tryExpand(); }, });