diff --git a/webui/static/stats-automations.js b/webui/static/stats-automations.js index 7e52a709..320113e5 100644 --- a/webui/static/stats-automations.js +++ b/webui/static/stats-automations.js @@ -386,8 +386,9 @@ let _autoSyncScheduleState = { playlists: [], automations: [], playlistSchedules: {}, - automationManaged: [], + automationPipelines: [], }; +let _autoSyncActiveTab = 'schedule'; /** * Fire-and-forget helper: send parsed playlist data to be mirrored on the backend. @@ -637,25 +638,26 @@ function autoSyncIsScheduleOwned(auto) { function buildAutoSyncScheduleState(playlists, automations) { const playlistSchedules = {}; - const automationManaged = []; - automations.filter(autoSyncIsPipelineAutomation).forEach(auto => { + const automationPipelines = []; + const pipelineAutomations = automations.filter(autoSyncIsPipelineAutomation); + pipelineAutomations.forEach(auto => { const playlistId = autoSyncPlaylistIdFromAutomation(auto); const hours = auto.trigger_type === 'schedule' ? autoSyncHoursFromTrigger(auto.trigger_config || {}) : null; - if (playlistId && hours) { + if (playlistId && hours && autoSyncIsScheduleOwned(auto)) { playlistSchedules[playlistId] = { automation_id: auto.id, automation_name: auto.name, hours, enabled: auto.enabled !== false && auto.enabled !== 0, - owned: autoSyncIsScheduleOwned(auto), + owned: true, next_run: auto.next_run, trigger_config: auto.trigger_config || {}, }; } else { - automationManaged.push(auto); + automationPipelines.push(auto); } }); - return { playlists, automations, playlistSchedules, automationManaged }; + return { playlists, automations, playlistSchedules, automationPipelines }; } async function openAutoSyncScheduleModal() { @@ -679,7 +681,7 @@ async function openAutoSyncScheduleModal() { `; overlay.style.display = 'flex'; - overlay.addEventListener('click', e => { if (e.target === overlay) closeAutoSyncScheduleModal(); }, { once: true }); + overlay.onclick = e => { if (e.target === overlay) closeAutoSyncScheduleModal(); }; await refreshAutoSyncScheduleModal(); } @@ -719,7 +721,49 @@ function renderAutoSyncScheduleModal() { const overlay = document.getElementById('auto-sync-schedule-modal'); if (!overlay) return; - const { playlists, playlistSchedules, automationManaged } = _autoSyncScheduleState; + const { playlists, playlistSchedules, automationPipelines } = _autoSyncScheduleState; + const scheduledCount = Object.keys(playlistSchedules).length; + const enabledCount = Object.values(playlistSchedules).filter(s => s.enabled).length; + const pipelineCount = automationPipelines.length; + const totalTracks = playlists.reduce((sum, p) => sum + (parseInt(p.track_count, 10) || 0), 0); + const scheduleActive = _autoSyncActiveTab === 'schedule'; + const automationsActive = _autoSyncActiveTab === 'automations'; + + const schedulePanel = renderAutoSyncSchedulePanel(playlists, playlistSchedules); + const automationPanel = renderAutoSyncAutomationPanel(automationPipelines, playlists); + + overlay.innerHTML = ` +
Schedule mirrored playlists through the same playlist-pipeline engine used by Automations.
+Drag mirrored playlists into an interval. Each placement creates or updates a matching playlist-pipeline automation.
-