Remove all migration logic, scroll tutorial targets into view, mock URL uses device ID

- Remove legacy migration code: profiles→automations key fallbacks, segments array
  fallback, standby_interval compat, profile_id compat, wled→led type mapping,
  legacy calibration field, audio CSS migration, default template migration,
  loadTargets alias, wled sub-tab mapping
- Scroll tutorial step targets into view when off-screen
- Mock device URL changed from mock://{led_count} to mock://{device_id},
  hide mock URL badge on device cards

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 18:31:41 +03:00
parent 39b31aec34
commit 0eb0f44ddb
12 changed files with 26 additions and 172 deletions

View File

@@ -93,7 +93,7 @@ import {
showAddDevice, closeAddDeviceModal, scanForDevices, handleAddDevice,
} from './features/device-discovery.js';
import {
loadTargetsTab, loadTargets, switchTargetSubTab,
loadTargetsTab, switchTargetSubTab,
showTargetEditor, closeTargetEditorModal, forceCloseTargetEditorModal, saveTargetEditor,
startTargetProcessing, stopTargetProcessing,
startTargetOverlay, stopTargetOverlay, deleteTarget,
@@ -330,7 +330,6 @@ Object.assign(window, {
// targets
loadTargetsTab,
loadTargets,
switchTargetSubTab,
expandAllTargetSections, collapseAllTargetSections,
showTargetEditor,

View File

@@ -337,8 +337,7 @@ export async function handleAddDevice(event) {
let url;
if (isMockDevice(deviceType)) {
const ledCount = document.getElementById('device-led-count')?.value || '60';
url = `mock://${ledCount}`;
url = 'mock://';
} else if (isSerialDevice(deviceType)) {
url = document.getElementById('device-serial-port').value;
} else {

View File

@@ -31,8 +31,8 @@ class DeviceSettingsModal extends Modal {
_getUrl() {
if (isMockDevice(this.deviceType)) {
const ledCount = this.$('settings-led-count')?.value || '60';
return `mock://${ledCount}`;
const deviceId = this.$('settings-device-id')?.value || '';
return `mock://${deviceId}`;
}
if (isSerialDevice(this.deviceType)) {
return this.$('settings-serial-port').value;
@@ -83,7 +83,7 @@ export function createDeviceCard(device) {
<div class="card-title">
<span class="health-dot ${healthClass}" title="${healthTitle}"></span>
${device.name || device.id}
${device.url && device.url.startsWith('http') ? `<a class="device-url-badge" href="${device.url}" target="_blank" rel="noopener" title="${t('device.button.webui')}"><span class="device-url-text">${escapeHtml(device.url.replace(/^https?:\/\//, ''))}</span><span class="device-url-icon">${ICON_WEB}</span></a>` : (device.url && !device.url.startsWith('http') ? `<span class="device-url-badge"><span class="device-url-text">${escapeHtml(device.url)}</span></span>` : '')}
${device.url && device.url.startsWith('http') ? `<a class="device-url-badge" href="${device.url}" target="_blank" rel="noopener" title="${t('device.button.webui')}"><span class="device-url-text">${escapeHtml(device.url.replace(/^https?:\/\//, ''))}</span><span class="device-url-icon">${ICON_WEB}</span></a>` : (device.url && !device.url.startsWith('mock://') && !device.url.startsWith('http') ? `<span class="device-url-badge"><span class="device-url-text">${escapeHtml(device.url)}</span></span>` : '')}
${healthLabel}
</div>
</div>

View File

@@ -438,11 +438,6 @@ export async function saveTargetEditor() {
// ===== TARGETS TAB (WLED devices + targets combined) =====
export async function loadTargets() {
// Alias for backward compatibility
await loadTargetsTab();
}
export function switchTargetSubTab(tabKey) {
document.querySelectorAll('.target-sub-tab-btn').forEach(btn =>
btn.classList.toggle('active', btn.dataset.targetSubTab === tabKey)
@@ -572,9 +567,7 @@ export async function loadTargetsTab() {
const runningCount = targetsWithState.filter(t => t.state && t.state.processing).length;
updateTabBadge('targets', runningCount);
// Backward compat: map stored "wled" sub-tab to "led"
let activeSubTab = localStorage.getItem('activeTargetSubTab') || 'led';
if (activeSubTab === 'wled') activeSubTab = 'led';
const activeSubTab = localStorage.getItem('activeTargetSubTab') || 'led';
const subTabs = [
{ key: 'led', icon: getTargetTypeIcon('led'), titleKey: 'targets.subtab.led', count: ledDevices.length + Object.keys(colorStripSourceMap).length + ledTargets.length },

View File

@@ -249,6 +249,12 @@ function showTutorialStep(index, direction = 1) {
target.classList.add('tutorial-target');
if (isFixed) target.style.zIndex = '10001';
// Scroll target into view if off-screen
const preRect = target.getBoundingClientRect();
if (preRect.bottom > window.innerHeight || preRect.top < 0) {
target.scrollIntoView({ behavior: 'instant', block: 'center' });
}
const targetRect = target.getBoundingClientRect();
const pad = 6;
let x, y, w, h;