diff --git a/server/src/wled_controller/static/js/core/ui.js b/server/src/wled_controller/static/js/core/ui.js index 4b8b58e..b24e0a7 100644 --- a/server/src/wled_controller/static/js/core/ui.js +++ b/server/src/wled_controller/static/js/core/ui.js @@ -292,3 +292,13 @@ export function hideOverlaySpinner() { const overlay = document.getElementById('overlay-spinner'); if (overlay) overlay.remove(); } + +export function formatUptime(seconds) { + if (!seconds || seconds <= 0) return '-'; + const h = Math.floor(seconds / 3600); + const m = Math.floor((seconds % 3600) / 60); + const s = Math.floor(seconds % 60); + if (h > 0) return t('time.hours_minutes', { h, m }); + if (m > 0) return t('time.minutes_seconds', { m, s }); + return t('time.seconds', { s }); +} diff --git a/server/src/wled_controller/static/js/features/dashboard.js b/server/src/wled_controller/static/js/features/dashboard.js index 286f1a1..224bd1d 100644 --- a/server/src/wled_controller/static/js/features/dashboard.js +++ b/server/src/wled_controller/static/js/features/dashboard.js @@ -5,7 +5,7 @@ import { apiKey, _dashboardLoading, set_dashboardLoading, dashboardPollInterval, setDashboardPollInterval } from '../core/state.js'; import { API_BASE, getHeaders, fetchWithAuth, escapeHtml } from '../core/api.js'; import { t } from '../core/i18n.js'; -import { showToast } from '../core/ui.js'; +import { showToast, formatUptime } from '../core/ui.js'; import { renderPerfSection, initPerfCharts, startPerfPolling, stopPerfPolling } from './perf-charts.js'; import { startAutoRefresh } from './tabs.js'; @@ -292,16 +292,6 @@ function _sectionContent(sectionKey, itemsHtml) { return `
`; } -function formatUptime(seconds) { - if (!seconds || seconds <= 0) return '-'; - const h = Math.floor(seconds / 3600); - const m = Math.floor((seconds % 3600) / 60); - const s = Math.floor(seconds % 60); - if (h > 0) return t('time.hours_minutes', { h, m }); - if (m > 0) return t('time.minutes_seconds', { m, s }); - return t('time.seconds', { s }); -} - export async function loadDashboard(forceFullRender = false) { if (_dashboardLoading) return; set_dashboardLoading(true); @@ -356,12 +346,18 @@ export async function loadDashboard(forceFullRender = false) { const structureUnchanged = hasExistingDom && newRunningIds === prevRunningIds; if (structureUnchanged && !forceFullRender && running.length > 0) { _updateRunningMetrics(running); + _cacheUptimeElements(); + _startUptimeTimer(); + startPerfPolling(); set_dashboardLoading(false); return; } if (structureUnchanged && forceFullRender) { if (running.length > 0) _updateRunningMetrics(running); _updateProfilesInPlace(profiles); + _cacheUptimeElements(); + _startUptimeTimer(); + startPerfPolling(); set_dashboardLoading(false); return; } diff --git a/server/src/wled_controller/static/js/features/kc-targets.js b/server/src/wled_controller/static/js/features/kc-targets.js index 1fd9b8d..97dac04 100644 --- a/server/src/wled_controller/static/js/features/kc-targets.js +++ b/server/src/wled_controller/static/js/features/kc-targets.js @@ -12,7 +12,7 @@ import { } from '../core/state.js'; import { API_BASE, getHeaders, fetchWithAuth, escapeHtml } from '../core/api.js'; import { t } from '../core/i18n.js'; -import { lockBody, showToast, showConfirm } from '../core/ui.js'; +import { lockBody, showToast, showConfirm, formatUptime } from '../core/ui.js'; import { Modal } from '../core/modal.js'; class KCEditorModal extends Modal { @@ -116,6 +116,10 @@ export function createKCTargetCard(target, sourceMap, patternTemplateMap) {