summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--web/app.js79
1 files changed, 44 insertions, 35 deletions
diff --git a/web/app.js b/web/app.js
index a661fe7..a2b0ea9 100644
--- a/web/app.js
+++ b/web/app.js
@@ -1079,6 +1079,7 @@ let taskCache = new Map();
let lastServerUpdate = null;
let pollTimeout = null;
let lastUserInteraction = Date.now();
+let lastHistoryFetch = 0;
function getActiveTab() {
const active = document.querySelector('.tab.active');
@@ -1096,13 +1097,52 @@ async function fetchHealth() {
return res.json();
}
+function renderActiveTab(allTasks) {
+ const activeTab = getActiveTab();
+ switch (activeTab) {
+ case 'queue':
+ renderQueuePanel(allTasks);
+ break;
+ case 'interrupted':
+ renderInterruptedPanel(allTasks);
+ break;
+ case 'ready':
+ renderReadyPanel(allTasks);
+ break;
+ case 'running':
+ renderRunningView(allTasks);
+ if (Date.now() - lastHistoryFetch > 60_000) {
+ lastHistoryFetch = Date.now();
+ fetchRecentExecutions(BASE_PATH, fetch)
+ .then(execs => renderRunningHistory(execs))
+ .catch(() => {
+ const histEl = document.querySelector('.running-history');
+ if (histEl) histEl.innerHTML = '<p class="task-meta">Could not load execution history.</p>';
+ });
+ }
+ break;
+ case 'all':
+ renderAllPanel(allTasks);
+ break;
+ case 'stats':
+ fetchRecentExecutions(BASE_PATH, fetch)
+ .then(execs => renderStatsPanel(allTasks, execs))
+ .catch(() => {});
+ break;
+ case 'settings':
+ renderSettingsPanel();
+ break;
+ }
+}
+
async function poll() {
try {
const health = await fetchHealth();
const serverUpdate = health.last_updated;
- // If server says nothing changed, we skip fetching tasks.
+ // If server says nothing changed, skip fetching but still render (e.g. tab was just switched).
if (lastServerUpdate && serverUpdate <= lastServerUpdate && taskCache.size > 0) {
+ renderActiveTab(Array.from(taskCache.values()));
return;
}
@@ -1118,39 +1158,7 @@ async function poll() {
const allTasks = Array.from(taskCache.values());
updateTabBadges(allTasks);
-
- const activeTab = getActiveTab();
- switch (activeTab) {
- case 'queue':
- renderQueuePanel(allTasks);
- break;
- case 'interrupted':
- renderInterruptedPanel(allTasks);
- break;
- case 'ready':
- renderReadyPanel(allTasks);
- break;
- case 'running':
- renderRunningView(allTasks);
- fetchRecentExecutions(BASE_PATH, fetch)
- .then(execs => renderRunningHistory(execs))
- .catch(() => {
- const histEl = document.querySelector('.running-history');
- if (histEl) histEl.innerHTML = '<p class="task-meta">Could not load execution history.</p>';
- });
- break;
- case 'all':
- renderAllPanel(allTasks);
- break;
- case 'stats':
- fetchRecentExecutions(BASE_PATH, fetch)
- .then(execs => renderStatsPanel(allTasks, execs))
- .catch(() => {});
- break;
- case 'settings':
- renderSettingsPanel();
- break;
- }
+ renderActiveTab(allTasks);
} catch (err) {
console.error('Polling failed:', err);
const panel = document.querySelector('[data-panel="queue"] .panel-task-list');
@@ -2106,7 +2114,8 @@ function renderRunningView(tasks) {
// Update elapsed spans in place if the same tasks are still running.
const existingCards = currentEl.querySelectorAll('[data-task-id]');
const existingIds = new Set([...existingCards].map(c => c.dataset.taskId));
- const unchanged = running.length === existingCards.length &&
+ const unchanged = running.length > 0 &&
+ running.length === existingCards.length &&
running.every(t => existingIds.has(t.id));
if (unchanged) {