Replace profile targets with scene activation and searchable scene selector
Profiles now activate scene presets instead of individual targets, with configurable deactivation behavior (none/revert/fallback scene). The target checklist UI is replaced by a searchable combobox for scene selection that scales well with many scenes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import { startAutoRefresh, updateTabBadge } from './tabs.js';
|
||||
import {
|
||||
getTargetTypeIcon,
|
||||
ICON_TARGET, ICON_PROFILE, ICON_CLOCK, ICON_WARNING, ICON_OK,
|
||||
ICON_STOP, ICON_STOP_PLAIN, ICON_START, ICON_AUTOSTART, ICON_HELP,
|
||||
ICON_STOP, ICON_STOP_PLAIN, ICON_START, ICON_AUTOSTART, ICON_HELP, ICON_SCENE,
|
||||
} from '../core/icons.js';
|
||||
import { loadScenePresets, renderScenePresetsSection } from './scene-presets.js';
|
||||
|
||||
@@ -269,12 +269,6 @@ function _updateProfilesInPlace(profiles) {
|
||||
badge.textContent = t('profiles.status.inactive');
|
||||
}
|
||||
}
|
||||
const metricVal = card.querySelector('.dashboard-metric-value');
|
||||
if (metricVal) {
|
||||
const cnt = p.target_ids.length;
|
||||
const active = (p.active_target_ids || []).length;
|
||||
metricVal.textContent = p.is_active ? `${active}/${cnt}` : `${cnt}`;
|
||||
}
|
||||
const btn = card.querySelector('.dashboard-target-actions .dashboard-action-btn');
|
||||
if (btn) {
|
||||
btn.className = `dashboard-action-btn ${p.enabled ? 'stop' : 'start'}`;
|
||||
@@ -490,7 +484,8 @@ export async function loadDashboard(forceFullRender = false) {
|
||||
const activeProfiles = profiles.filter(p => p.is_active);
|
||||
const inactiveProfiles = profiles.filter(p => !p.is_active);
|
||||
updateTabBadge('profiles', activeProfiles.length);
|
||||
const profileItems = [...activeProfiles, ...inactiveProfiles].map(p => renderDashboardProfile(p)).join('');
|
||||
const sceneMap = new Map(scenePresets.map(s => [s.id, s]));
|
||||
const profileItems = [...activeProfiles, ...inactiveProfiles].map(p => renderDashboardProfile(p, sceneMap)).join('');
|
||||
|
||||
dynamicHtml += `<div class="dashboard-section">
|
||||
${_sectionHeader('profiles', t('dashboard.section.profiles'), profiles.length)}
|
||||
@@ -669,7 +664,7 @@ function renderDashboardTarget(target, isRunning, devicesMap = {}, cssSourceMap
|
||||
}
|
||||
}
|
||||
|
||||
function renderDashboardProfile(profile) {
|
||||
function renderDashboardProfile(profile, sceneMap = new Map()) {
|
||||
const isActive = profile.is_active;
|
||||
const isDisabled = !profile.enabled;
|
||||
|
||||
@@ -693,9 +688,9 @@ function renderDashboardProfile(profile) {
|
||||
? `<span class="dashboard-badge-active">${t('profiles.status.active')}</span>`
|
||||
: `<span class="dashboard-badge-stopped">${t('profiles.status.inactive')}</span>`;
|
||||
|
||||
const targetCount = profile.target_ids.length;
|
||||
const activeCount = (profile.active_target_ids || []).length;
|
||||
const targetsInfo = isActive ? `${activeCount}/${targetCount}` : `${targetCount}`;
|
||||
// Scene info
|
||||
const scene = profile.scene_preset_id ? sceneMap.get(profile.scene_preset_id) : null;
|
||||
const sceneName = scene ? escapeHtml(scene.name) : t('profiles.scene.none_selected');
|
||||
|
||||
return `<div class="dashboard-target dashboard-profile dashboard-card-link" data-profile-id="${profile.id}" onclick="if(!event.target.closest('button')){navigateToCard('profiles',null,'profiles','data-profile-id','${profile.id}')}">
|
||||
<div class="dashboard-target-info">
|
||||
@@ -703,15 +698,10 @@ function renderDashboardProfile(profile) {
|
||||
<div>
|
||||
<div class="dashboard-target-name">${escapeHtml(profile.name)}</div>
|
||||
${condSummary ? `<div class="dashboard-target-subtitle">${escapeHtml(condSummary)}</div>` : ''}
|
||||
<div class="dashboard-target-subtitle">${ICON_SCENE} ${sceneName}</div>
|
||||
</div>
|
||||
${statusBadge}
|
||||
</div>
|
||||
<div class="dashboard-target-metrics">
|
||||
<div class="dashboard-metric">
|
||||
<div class="dashboard-metric-value">${targetsInfo}</div>
|
||||
<div class="dashboard-metric-label">${t('dashboard.targets')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-target-actions">
|
||||
<button class="dashboard-action-btn ${profile.enabled ? 'stop' : 'start'}" onclick="dashboardToggleProfile('${profile.id}', ${!profile.enabled})" title="${profile.enabled ? t('profiles.action.disable') : t('profiles.status.active')}">
|
||||
${profile.enabled ? ICON_STOP_PLAIN : ICON_START}
|
||||
|
||||
Reference in New Issue
Block a user