';
for (const p of profiles) {
- html += createProfileCard(p);
+ html += createProfileCard(p, runningTargetIds);
}
html += `
+
@@ -57,7 +73,7 @@ function renderProfiles(profiles) {
});
}
-function createProfileCard(profile) {
+function createProfileCard(profile, runningTargetIds = new Set()) {
const statusClass = !profile.enabled ? 'disabled' : profile.is_active ? 'active' : 'inactive';
const statusText = !profile.enabled ? t('profiles.status.disabled') : profile.is_active ? t('profiles.status.active') : t('profiles.status.inactive');
@@ -104,7 +120,15 @@ function createProfileCard(profile) {
${condPills}
-
@@ -361,6 +385,33 @@ export async function saveProfileEditor() {
}
}
+export async function toggleProfileTargets(profileId) {
+ try {
+ const profileResp = await fetchWithAuth(`/profiles/${profileId}`);
+ if (!profileResp.ok) throw new Error('Failed to load profile');
+ const profile = await profileResp.json();
+ // Fetch actual processing state for each target in this profile
+ const stateResults = await Promise.all(
+ profile.target_ids.map(id =>
+ fetchWithAuth(`/picture-targets/${id}/state`)
+ .then(r => r.ok ? r.json() : null)
+ .catch(() => null)
+ )
+ );
+ const runningSet = new Set(
+ profile.target_ids.filter((_, i) => stateResults[i]?.processing)
+ );
+ const shouldStop = profile.target_ids.some(id => runningSet.has(id));
+ await Promise.all(profile.target_ids.map(id =>
+ fetchWithAuth(`/picture-targets/${id}/${shouldStop ? 'stop' : 'start'}`, { method: 'POST' }).catch(() => {})
+ ));
+ loadProfiles();
+ } catch (e) {
+ if (e.isAuth) return;
+ showToast(e.message, 'error');
+ }
+}
+
export async function toggleProfileEnabled(profileId, enable) {
try {
const action = enable ? 'enable' : 'disable';
diff --git a/server/src/wled_controller/static/locales/en.json b/server/src/wled_controller/static/locales/en.json
index e827824..3f95519 100644
--- a/server/src/wled_controller/static/locales/en.json
+++ b/server/src/wled_controller/static/locales/en.json
@@ -516,6 +516,7 @@
"profiles.status.active": "Active",
"profiles.status.inactive": "Inactive",
"profiles.status.disabled": "Disabled",
+ "profiles.action.disable": "Disable",
"profiles.last_activated": "Last activated",
"profiles.logic.and": " AND ",
"profiles.logic.or": " OR ",
@@ -525,6 +526,8 @@
"profiles.created": "Profile created",
"profiles.deleted": "Profile deleted",
"profiles.error.name_required": "Name is required",
+ "profiles.toggle_all.start": "Start all targets",
+ "profiles.toggle_all.stop": "Stop all targets",
"time.hours_minutes": "{h}h {m}m",
"time.minutes_seconds": "{m}m {s}s",
"time.seconds": "{s}s",
diff --git a/server/src/wled_controller/static/locales/ru.json b/server/src/wled_controller/static/locales/ru.json
index a5d2693..bd9cd4a 100644
--- a/server/src/wled_controller/static/locales/ru.json
+++ b/server/src/wled_controller/static/locales/ru.json
@@ -516,6 +516,7 @@
"profiles.status.active": "Активен",
"profiles.status.inactive": "Неактивен",
"profiles.status.disabled": "Отключён",
+ "profiles.action.disable": "Отключить",
"profiles.last_activated": "Последняя активация",
"profiles.logic.and": " И ",
"profiles.logic.or": " ИЛИ ",
@@ -525,6 +526,8 @@
"profiles.created": "Профиль создан",
"profiles.deleted": "Профиль удалён",
"profiles.error.name_required": "Введите название",
+ "profiles.toggle_all.start": "Запустить все цели",
+ "profiles.toggle_all.stop": "Остановить все цели",
"time.hours_minutes": "{h}ч {m}м",
"time.minutes_seconds": "{m}м {s}с",
"time.seconds": "{s}с",