Add autostart toggle button to dashboard target items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -186,6 +186,31 @@
|
|||||||
gap: 4px;
|
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 {
|
.dashboard-status-dot {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import {
|
|||||||
} from './features/devices.js';
|
} from './features/devices.js';
|
||||||
import {
|
import {
|
||||||
loadDashboard, stopUptimeTimer,
|
loadDashboard, stopUptimeTimer,
|
||||||
dashboardToggleProfile, dashboardStartTarget, dashboardStopTarget, dashboardStopAll,
|
dashboardToggleProfile, dashboardStartTarget, dashboardStopTarget, dashboardToggleAutoStart, dashboardStopAll,
|
||||||
toggleDashboardSection, changeDashboardPollInterval,
|
toggleDashboardSection, changeDashboardPollInterval,
|
||||||
} from './features/dashboard.js';
|
} from './features/dashboard.js';
|
||||||
import { startEventsWS, stopEventsWS } from './core/events-ws.js';
|
import { startEventsWS, stopEventsWS } from './core/events-ws.js';
|
||||||
@@ -186,6 +186,7 @@ Object.assign(window, {
|
|||||||
dashboardToggleProfile,
|
dashboardToggleProfile,
|
||||||
dashboardStartTarget,
|
dashboardStartTarget,
|
||||||
dashboardStopTarget,
|
dashboardStopTarget,
|
||||||
|
dashboardToggleAutoStart,
|
||||||
dashboardStopAll,
|
dashboardStopAll,
|
||||||
toggleDashboardSection,
|
toggleDashboardSection,
|
||||||
changeDashboardPollInterval,
|
changeDashboardPollInterval,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ let _fpsHistory = {}; // { targetId: number[] } — fps_actual
|
|||||||
let _fpsCurrentHistory = {}; // { targetId: number[] } — fps_current
|
let _fpsCurrentHistory = {}; // { targetId: number[] } — fps_current
|
||||||
let _fpsCharts = {}; // { targetId: Chart }
|
let _fpsCharts = {}; // { targetId: Chart }
|
||||||
let _lastRunningIds = []; // sorted target IDs from previous render
|
let _lastRunningIds = []; // sorted target IDs from previous render
|
||||||
|
let _lastAutoStartIds = ''; // comma-joined sorted auto-start IDs
|
||||||
let _uptimeBase = {}; // { targetId: { seconds, timestamp } }
|
let _uptimeBase = {}; // { targetId: { seconds, timestamp } }
|
||||||
let _uptimeTimer = null;
|
let _uptimeTimer = null;
|
||||||
let _uptimeElements = {}; // { targetId: HTMLElement } — cached DOM refs
|
let _uptimeElements = {}; // { targetId: HTMLElement } — cached DOM refs
|
||||||
@@ -347,6 +348,7 @@ export async function loadDashboard(forceFullRender = false) {
|
|||||||
// Build dynamic HTML (targets, profiles)
|
// Build dynamic HTML (targets, profiles)
|
||||||
let dynamicHtml = '';
|
let dynamicHtml = '';
|
||||||
let runningIds = [];
|
let runningIds = [];
|
||||||
|
let newAutoStartIds = '';
|
||||||
|
|
||||||
if (targets.length === 0 && profiles.length === 0) {
|
if (targets.length === 0 && profiles.length === 0) {
|
||||||
dynamicHtml = `<div class="dashboard-no-targets">${t('dashboard.no_targets')}</div>`;
|
dynamicHtml = `<div class="dashboard-no-targets">${t('dashboard.no_targets')}</div>`;
|
||||||
@@ -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)
|
// 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 newRunningIds = running.map(t => t.id).sort().join(',');
|
||||||
const prevRunningIds = [..._lastRunningIds].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 hasExistingDom = !!container.querySelector('.dashboard-perf-persistent');
|
||||||
const structureUnchanged = hasExistingDom && newRunningIds === prevRunningIds;
|
const structureUnchanged = hasExistingDom && newRunningIds === prevRunningIds && newAutoStartIds === _lastAutoStartIds;
|
||||||
if (structureUnchanged && !forceFullRender && running.length > 0) {
|
if (structureUnchanged && !forceFullRender && running.length > 0) {
|
||||||
_updateRunningMetrics(running);
|
_updateRunningMetrics(running);
|
||||||
_cacheUptimeElements();
|
_cacheUptimeElements();
|
||||||
@@ -492,6 +495,7 @@ export async function loadDashboard(forceFullRender = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_lastRunningIds = runningIds;
|
_lastRunningIds = runningIds;
|
||||||
|
_lastAutoStartIds = newAutoStartIds;
|
||||||
_cacheUptimeElements();
|
_cacheUptimeElements();
|
||||||
await _initFpsCharts(runningIds);
|
await _initFpsCharts(runningIds);
|
||||||
_startUptimeTimer();
|
_startUptimeTimer();
|
||||||
@@ -577,6 +581,7 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dashboard-target-actions">
|
<div class="dashboard-target-actions">
|
||||||
|
<button class="dashboard-autostart-btn${target.auto_start ? ' active' : ''}" onclick="dashboardToggleAutoStart('${target.id}', ${!target.auto_start})" title="${target.auto_start ? t('autostart.toggle.enabled') : t('autostart.toggle.disabled')}">★</button>
|
||||||
<button class="btn btn-icon btn-warning" onclick="dashboardStopTarget('${target.id}')" title="${t('device.button.stop')}">${ICON_STOP_PLAIN}</button>
|
<button class="btn btn-icon btn-warning" onclick="dashboardStopTarget('${target.id}')" title="${t('device.button.stop')}">${ICON_STOP_PLAIN}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -591,6 +596,7 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
|
|||||||
</div>
|
</div>
|
||||||
<div class="dashboard-target-metrics"></div>
|
<div class="dashboard-target-metrics"></div>
|
||||||
<div class="dashboard-target-actions">
|
<div class="dashboard-target-actions">
|
||||||
|
<button class="dashboard-autostart-btn${target.auto_start ? ' active' : ''}" onclick="dashboardToggleAutoStart('${target.id}', ${!target.auto_start})" title="${target.auto_start ? t('autostart.toggle.enabled') : t('autostart.toggle.disabled')}">★</button>
|
||||||
<button class="btn btn-icon btn-success" onclick="dashboardStartTarget('${target.id}')" title="${t('device.button.start')}">▶</button>
|
<button class="btn btn-icon btn-success" onclick="dashboardStartTarget('${target.id}')" title="${t('device.button.start')}">▶</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@@ -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() {
|
export async function dashboardStopAll() {
|
||||||
try {
|
try {
|
||||||
const targetsResp = await fetchWithAuth('/picture-targets');
|
const targetsResp = await fetchWithAuth('/picture-targets');
|
||||||
|
|||||||
Reference in New Issue
Block a user