Centralize icon resolution into core/icons.js, fix auto-start row alignment
- Create core/icons.js with type-resolution getters and icon constants - Replace inline emoji literals across 11 feature files with imports - Remove duplicate icon maps (getEngineIcon, _vsTypeIcons, typeIcons, etc.) - Fix dashboard auto-start row missing metrics placeholder div Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,11 @@ import { t } from '../core/i18n.js';
|
||||
import { showToast, formatUptime } from '../core/ui.js';
|
||||
import { renderPerfSection, initPerfCharts, startPerfPolling, stopPerfPolling } from './perf-charts.js';
|
||||
import { startAutoRefresh, updateTabBadge } from './tabs.js';
|
||||
import {
|
||||
getTargetTypeIcon,
|
||||
ICON_TARGET, ICON_PROFILE, ICON_CLOCK, ICON_WARNING, ICON_OK,
|
||||
ICON_STOP, ICON_STOP_PLAIN, ICON_AUTOSTART,
|
||||
} from '../core/icons.js';
|
||||
|
||||
const DASHBOARD_COLLAPSED_KEY = 'dashboard_collapsed';
|
||||
const MAX_FPS_SAMPLES = 120;
|
||||
@@ -53,7 +58,7 @@ function _startUptimeTimer() {
|
||||
if (!el) continue;
|
||||
const seconds = _getInterpolatedUptime(id);
|
||||
if (seconds != null) {
|
||||
el.textContent = `🕐 ${formatUptime(seconds)}`;
|
||||
el.textContent = `${ICON_CLOCK} ${formatUptime(seconds)}`;
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
@@ -184,7 +189,7 @@ function _updateRunningMetrics(enrichedRunning) {
|
||||
if (fpsEl) fpsEl.innerHTML = `${fpsActual}<span class="dashboard-fps-target">/${fpsTarget}</span>`;
|
||||
|
||||
const errorsEl = cached?.errors || document.querySelector(`[data-errors-text="${target.id}"]`);
|
||||
if (errorsEl) errorsEl.textContent = `${errors > 0 ? '⚠️' : '✅'} ${errors}`;
|
||||
if (errorsEl) errorsEl.textContent = `${errors > 0 ? ICON_WARNING : ICON_OK} ${errors}`;
|
||||
|
||||
// Update health dot
|
||||
const isLed = target.target_type === 'led' || target.target_type === 'wled';
|
||||
@@ -228,7 +233,7 @@ function _updateProfilesInPlace(profiles) {
|
||||
if (btn) {
|
||||
btn.className = `btn btn-icon ${p.enabled ? 'btn-warning' : 'btn-success'}`;
|
||||
btn.setAttribute('onclick', `dashboardToggleProfile('${p.id}', ${!p.enabled})`);
|
||||
btn.textContent = p.enabled ? '⏹' : '▶';
|
||||
btn.textContent = p.enabled ? ICON_STOP_PLAIN : '▶';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,21 +374,22 @@ export async function loadDashboard(forceFullRender = false) {
|
||||
const isRunning = !!(target.state && target.state.processing);
|
||||
const device = devicesMap[target.device_id];
|
||||
const deviceName = device ? device.name : '';
|
||||
const typeIcon = target.target_type === 'key_colors' ? '🎨' : '💡';
|
||||
const typeIcon = getTargetTypeIcon(target.target_type);
|
||||
const statusBadge = isRunning
|
||||
? `<span class="dashboard-badge-active">${t('profiles.status.active')}</span>`
|
||||
: `<span class="dashboard-badge-stopped">${t('profiles.status.inactive')}</span>`;
|
||||
return `<div class="dashboard-target dashboard-autostart" data-target-id="${target.id}">
|
||||
<div class="dashboard-target-info">
|
||||
<span class="dashboard-target-icon">⭐</span>
|
||||
<span class="dashboard-target-icon">${ICON_AUTOSTART}</span>
|
||||
<div>
|
||||
<div class="dashboard-target-name">${escapeHtml(target.name)} ${statusBadge}</div>
|
||||
${deviceName ? `<div class="dashboard-target-subtitle">${typeIcon} ${escapeHtml(deviceName)}</div>` : `<div class="dashboard-target-subtitle">${typeIcon}</div>`}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-target-metrics"></div>
|
||||
<div class="dashboard-target-actions">
|
||||
<button class="btn btn-icon ${isRunning ? 'btn-warning' : 'btn-success'}" onclick="${isRunning ? `dashboardStopTarget('${target.id}')` : `dashboardStartTarget('${target.id}')`}" title="${isRunning ? t('device.stop') : t('device.start')}">
|
||||
${isRunning ? '⏹' : '▶'}
|
||||
${isRunning ? ICON_STOP_PLAIN : '▶'}
|
||||
</button>
|
||||
</div>
|
||||
</div>`;
|
||||
@@ -412,7 +418,7 @@ export async function loadDashboard(forceFullRender = false) {
|
||||
|
||||
if (running.length > 0) {
|
||||
runningIds = running.map(t => t.id);
|
||||
const stopAllBtn = `<button class="btn btn-sm btn-danger dashboard-stop-all" onclick="event.stopPropagation(); dashboardStopAll()" title="${t('dashboard.stop_all')}">⏹️ ${t('dashboard.stop_all')}</button>`;
|
||||
const stopAllBtn = `<button class="btn btn-sm btn-danger dashboard-stop-all" onclick="event.stopPropagation(); dashboardStopAll()" title="${t('dashboard.stop_all')}">${ICON_STOP} ${t('dashboard.stop_all')}</button>`;
|
||||
const runningItems = running.map(target => renderDashboardTarget(target, true, devicesMap, cssSourceMap)).join('');
|
||||
|
||||
targetsInner += `<div class="dashboard-subsection">
|
||||
@@ -472,7 +478,7 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
|
||||
const state = target.state || {};
|
||||
const metrics = target.metrics || {};
|
||||
const isLed = target.target_type === 'led' || target.target_type === 'wled';
|
||||
const icon = '⚡';
|
||||
const icon = ICON_TARGET;
|
||||
const typeLabel = isLed ? t('dashboard.type.led') : t('dashboard.type.kc');
|
||||
|
||||
let subtitleParts = [typeLabel];
|
||||
@@ -530,14 +536,14 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-metric" title="${t('dashboard.uptime')}">
|
||||
<div class="dashboard-metric-value" data-uptime-text="${target.id}">🕐 ${uptime}</div>
|
||||
<div class="dashboard-metric-value" data-uptime-text="${target.id}">${ICON_CLOCK} ${uptime}</div>
|
||||
</div>
|
||||
<div class="dashboard-metric" title="${t('dashboard.errors')}">
|
||||
<div class="dashboard-metric-value" data-errors-text="${target.id}">${errors > 0 ? '⚠️' : '✅'} ${errors}</div>
|
||||
<div class="dashboard-metric-value" data-errors-text="${target.id}">${errors > 0 ? ICON_WARNING : ICON_OK} ${errors}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-target-actions">
|
||||
<button class="btn btn-icon btn-warning" onclick="dashboardStopTarget('${target.id}')" title="${t('device.button.stop')}">⏹</button>
|
||||
<button class="btn btn-icon btn-warning" onclick="dashboardStopTarget('${target.id}')" title="${t('device.button.stop')}">${ICON_STOP_PLAIN}</button>
|
||||
</div>
|
||||
</div>`;
|
||||
} else {
|
||||
@@ -587,7 +593,7 @@ function renderDashboardProfile(profile) {
|
||||
|
||||
return `<div class="dashboard-target dashboard-profile" data-profile-id="${profile.id}">
|
||||
<div class="dashboard-target-info">
|
||||
<span class="dashboard-target-icon">📋</span>
|
||||
<span class="dashboard-target-icon">${ICON_PROFILE}</span>
|
||||
<div>
|
||||
<div class="dashboard-target-name">${escapeHtml(profile.name)}</div>
|
||||
${condSummary ? `<div class="dashboard-target-subtitle">${escapeHtml(condSummary)}</div>` : ''}
|
||||
@@ -602,7 +608,7 @@ function renderDashboardProfile(profile) {
|
||||
</div>
|
||||
<div class="dashboard-target-actions">
|
||||
<button class="btn btn-icon ${profile.enabled ? 'btn-warning' : 'btn-success'}" onclick="dashboardToggleProfile('${profile.id}', ${!profile.enabled})" title="${profile.enabled ? t('profiles.action.disable') : t('profiles.status.active')}">
|
||||
${profile.enabled ? '⏹' : '▶'}
|
||||
${profile.enabled ? ICON_STOP_PLAIN : '▶'}
|
||||
</button>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
Reference in New Issue
Block a user