Add clone support for scene presets and update TODO
- Add clone_preset() to ScenePresetStore with deep copy of target snapshots
- Add POST /scene-presets/{id}/clone API endpoint
- Add clone button to scene preset cards in Automations tab
- Add i18n keys for clone feedback in all 3 locales
- Add TODO items for dashboard stats collapse and protocol badge review
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,7 +85,7 @@ import {
|
||||
} from './features/automations.js';
|
||||
import {
|
||||
openScenePresetCapture, editScenePreset, saveScenePreset, closeScenePresetEditor,
|
||||
activateScenePreset, recaptureScenePreset, deleteScenePreset,
|
||||
activateScenePreset, recaptureScenePreset, cloneScenePreset, deleteScenePreset,
|
||||
addSceneTarget, removeSceneTarget,
|
||||
} from './features/scene-presets.js';
|
||||
|
||||
@@ -325,6 +325,7 @@ Object.assign(window, {
|
||||
closeScenePresetEditor,
|
||||
activateScenePreset,
|
||||
recaptureScenePreset,
|
||||
cloneScenePreset,
|
||||
deleteScenePreset,
|
||||
addSceneTarget,
|
||||
removeSceneTarget,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { showToast, showConfirm } from '../core/ui.js';
|
||||
import { Modal } from '../core/modal.js';
|
||||
import { CardSection } from '../core/card-sections.js';
|
||||
import {
|
||||
ICON_SCENE, ICON_CAPTURE, ICON_START, ICON_EDIT, ICON_REFRESH, ICON_TARGET,
|
||||
ICON_SCENE, ICON_CAPTURE, ICON_START, ICON_EDIT, ICON_REFRESH, ICON_TARGET, ICON_CLONE,
|
||||
} from '../core/icons.js';
|
||||
import { scenePresetsCache } from '../core/state.js';
|
||||
import { cardColorStyle, cardColorButton } from '../core/card-colors.js';
|
||||
@@ -61,6 +61,7 @@ export function createSceneCard(preset) {
|
||||
${updated ? `<span class="stream-card-prop">${updated}</span>` : ''}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<button class="btn btn-icon btn-secondary" onclick="cloneScenePreset('${preset.id}')" title="${t('common.clone')}">${ICON_CLONE}</button>
|
||||
<button class="btn btn-icon btn-secondary" onclick="editScenePreset('${preset.id}')" title="${t('scenes.edit')}">${ICON_EDIT}</button>
|
||||
<button class="btn btn-icon btn-secondary" onclick="recaptureScenePreset('${preset.id}')" title="${t('scenes.recapture')}">${ICON_REFRESH}</button>
|
||||
<button class="btn btn-icon btn-success" onclick="activateScenePreset('${preset.id}')" title="${t('scenes.activate')}">${ICON_START}</button>
|
||||
@@ -304,6 +305,26 @@ export async function recaptureScenePreset(presetId) {
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Clone =====
|
||||
|
||||
export async function cloneScenePreset(presetId) {
|
||||
try {
|
||||
const resp = await fetchWithAuth(`/scene-presets/${presetId}/clone`, {
|
||||
method: 'POST',
|
||||
});
|
||||
if (resp.ok) {
|
||||
showToast(t('scenes.cloned'), 'success');
|
||||
_reloadScenesTab();
|
||||
} else {
|
||||
const err = await resp.json().catch(() => ({}));
|
||||
showToast(err.detail || t('scenes.error.clone_failed'), 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.isAuth) return;
|
||||
showToast(t('scenes.error.clone_failed'), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Delete =====
|
||||
|
||||
export async function deleteScenePreset(presetId) {
|
||||
|
||||
@@ -681,6 +681,8 @@
|
||||
"scenes.error.activate_failed": "Failed to activate scene",
|
||||
"scenes.error.recapture_failed": "Failed to recapture scene",
|
||||
"scenes.error.delete_failed": "Failed to delete scene",
|
||||
"scenes.cloned": "Scene cloned",
|
||||
"scenes.error.clone_failed": "Failed to clone scene",
|
||||
"time.hours_minutes": "{h}h {m}m",
|
||||
"time.minutes_seconds": "{m}m {s}s",
|
||||
"time.seconds": "{s}s",
|
||||
|
||||
@@ -681,6 +681,8 @@
|
||||
"scenes.error.activate_failed": "Не удалось активировать сцену",
|
||||
"scenes.error.recapture_failed": "Не удалось перезахватить сцену",
|
||||
"scenes.error.delete_failed": "Не удалось удалить сцену",
|
||||
"scenes.cloned": "Сцена клонирована",
|
||||
"scenes.error.clone_failed": "Не удалось клонировать сцену",
|
||||
"time.hours_minutes": "{h}ч {m}м",
|
||||
"time.minutes_seconds": "{m}м {s}с",
|
||||
"time.seconds": "{s}с",
|
||||
|
||||
@@ -681,6 +681,8 @@
|
||||
"scenes.error.activate_failed": "激活场景失败",
|
||||
"scenes.error.recapture_failed": "重新捕获场景失败",
|
||||
"scenes.error.delete_failed": "删除场景失败",
|
||||
"scenes.cloned": "场景已克隆",
|
||||
"scenes.error.clone_failed": "克隆场景失败",
|
||||
"time.hours_minutes": "{h}时 {m}分",
|
||||
"time.minutes_seconds": "{m}分 {s}秒",
|
||||
"time.seconds": "{s}秒",
|
||||
|
||||
Reference in New Issue
Block a user