From 3bfa9062f93964b735c06fbb606f065f1eababf3 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Thu, 26 Feb 2026 00:43:13 +0300 Subject: [PATCH] Add autostart toggle button to dashboard target items Co-Authored-By: Claude Opus 4.6 --- .../wled_controller/static/css/dashboard.css | 25 +++++++++++++++++ server/src/wled_controller/static/js/app.js | 3 ++- .../static/js/features/dashboard.js | 27 ++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/server/src/wled_controller/static/css/dashboard.css b/server/src/wled_controller/static/css/dashboard.css index 996ee7e..083200a 100644 --- a/server/src/wled_controller/static/css/dashboard.css +++ b/server/src/wled_controller/static/css/dashboard.css @@ -186,6 +186,31 @@ gap: 4px; } +.dashboard-autostart-btn { + background: none; + border: none; + color: var(--text-muted); + font-size: 0.8rem; + width: 24px; + height: 24px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + border-radius: 4px; + transition: color 0.2s, background 0.2s; +} + +.dashboard-autostart-btn:hover { + color: var(--warning-color, #ffc107); + background: rgba(255, 193, 7, 0.1); +} + +.dashboard-autostart-btn.active { + color: var(--warning-color, #ffc107); +} + .dashboard-status-dot { font-size: 1rem; line-height: 1; diff --git a/server/src/wled_controller/static/js/app.js b/server/src/wled_controller/static/js/app.js index 34d09ca..88272d8 100644 --- a/server/src/wled_controller/static/js/app.js +++ b/server/src/wled_controller/static/js/app.js @@ -35,7 +35,7 @@ import { } from './features/devices.js'; import { loadDashboard, stopUptimeTimer, - dashboardToggleProfile, dashboardStartTarget, dashboardStopTarget, dashboardStopAll, + dashboardToggleProfile, dashboardStartTarget, dashboardStopTarget, dashboardToggleAutoStart, dashboardStopAll, toggleDashboardSection, changeDashboardPollInterval, } from './features/dashboard.js'; import { startEventsWS, stopEventsWS } from './core/events-ws.js'; @@ -186,6 +186,7 @@ Object.assign(window, { dashboardToggleProfile, dashboardStartTarget, dashboardStopTarget, + dashboardToggleAutoStart, dashboardStopAll, toggleDashboardSection, changeDashboardPollInterval, diff --git a/server/src/wled_controller/static/js/features/dashboard.js b/server/src/wled_controller/static/js/features/dashboard.js index 9fe5b59..7659bc7 100644 --- a/server/src/wled_controller/static/js/features/dashboard.js +++ b/server/src/wled_controller/static/js/features/dashboard.js @@ -21,6 +21,7 @@ let _fpsHistory = {}; // { targetId: number[] } — fps_actual let _fpsCurrentHistory = {}; // { targetId: number[] } — fps_current let _fpsCharts = {}; // { targetId: Chart } let _lastRunningIds = []; // sorted target IDs from previous render +let _lastAutoStartIds = ''; // comma-joined sorted auto-start IDs let _uptimeBase = {}; // { targetId: { seconds, timestamp } } let _uptimeTimer = null; let _uptimeElements = {}; // { targetId: HTMLElement } — cached DOM refs @@ -347,6 +348,7 @@ export async function loadDashboard(forceFullRender = false) { // Build dynamic HTML (targets, profiles) let dynamicHtml = ''; let runningIds = []; + let newAutoStartIds = ''; if (targets.length === 0 && profiles.length === 0) { dynamicHtml = `
${t('dashboard.no_targets')}
`; @@ -370,8 +372,9 @@ export async function loadDashboard(forceFullRender = false) { // Check if we can do an in-place metrics update (same targets, not first load) const newRunningIds = running.map(t => t.id).sort().join(','); const prevRunningIds = [..._lastRunningIds].sort().join(','); + newAutoStartIds = enriched.filter(t => t.auto_start).map(t => t.id).sort().join(','); const hasExistingDom = !!container.querySelector('.dashboard-perf-persistent'); - const structureUnchanged = hasExistingDom && newRunningIds === prevRunningIds; + const structureUnchanged = hasExistingDom && newRunningIds === prevRunningIds && newAutoStartIds === _lastAutoStartIds; if (structureUnchanged && !forceFullRender && running.length > 0) { _updateRunningMetrics(running); _cacheUptimeElements(); @@ -492,6 +495,7 @@ export async function loadDashboard(forceFullRender = false) { } } _lastRunningIds = runningIds; + _lastAutoStartIds = newAutoStartIds; _cacheUptimeElements(); await _initFpsCharts(runningIds); _startUptimeTimer(); @@ -577,6 +581,7 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
+
`; @@ -591,6 +596,7 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
+
`; @@ -699,6 +705,25 @@ export async function dashboardStopTarget(targetId) { } } +export async function dashboardToggleAutoStart(targetId, enable) { + try { + const response = await fetchWithAuth(`/picture-targets/${targetId}`, { + method: 'PUT', + body: JSON.stringify({ auto_start: enable }), + }); + if (response.ok) { + showToast(t(enable ? 'autostart.toggle.enabled' : 'autostart.toggle.disabled'), 'success'); + loadDashboard(); + } else { + const error = await response.json(); + showToast(`Failed: ${error.detail}`, 'error'); + } + } catch (error) { + if (error.isAuth) return; + showToast('Failed to toggle auto-start', 'error'); + } +} + export async function dashboardStopAll() { try { const targetsResp = await fetchWithAuth('/picture-targets');