From 918dbad88f50c38c2e064feb3d3f7c603efd1f5b Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Sat, 7 Mar 2026 11:27:53 -0800 Subject: [PATCH] reorganize automations page. --- webui/static/script.js | 58 ++++++++++++++++++++++++++++++----- webui/static/style.css | 68 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/webui/static/script.js b/webui/static/script.js index 9e964ab4..3619b1c1 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -43332,10 +43332,42 @@ const _autoIcons = { clear_quarantine: '\uD83D\uDDD1\uFE0F', cleanup_wishlist: '\uD83E\uDDF9', update_discovery_pool: '\uD83E\uDDED', start_quality_scan: '\uD83D\uDCCA', backup_database: '\uD83D\uDCBE', + refresh_beatport_cache: '\uD83C\uDFB5', + clean_search_history: '\uD83D\uDDD1\uFE0F', + clean_completed_downloads: '\u2705', }; // --- Load & Render List --- +function _buildAutomationSection(id, label, automations, useGrid) { + const section = document.createElement('div'); + section.className = 'automations-section'; + section.id = id; + const collapsed = localStorage.getItem('auto_section_' + id) === '1'; + if (collapsed) section.classList.add('collapsed'); + const header = document.createElement('div'); + header.className = 'automations-section-header'; + header.innerHTML = ` + + ${label} + ${automations.length} + + `; + header.onclick = () => { + section.classList.toggle('collapsed'); + localStorage.setItem('auto_section_' + id, section.classList.contains('collapsed') ? '1' : '0'); + }; + const body = document.createElement('div'); + body.className = 'automations-section-body'; + const container = document.createElement('div'); + container.className = useGrid ? 'automations-grid' : 'automations-user-list'; + automations.forEach(a => container.appendChild(renderAutomationCard(a))); + body.appendChild(container); + section.appendChild(header); + section.appendChild(body); + return section; +} + async function loadAutomations() { const list = document.getElementById('automations-list'); const empty = document.getElementById('automations-empty'); @@ -43352,18 +43384,27 @@ async function loadAutomations() { } empty.style.display = 'none'; list.innerHTML = ''; - automations.forEach(a => list.appendChild(renderAutomationCard(a))); + + const systemAutos = automations.filter(a => a.is_system); + const userAutos = automations.filter(a => !a.is_system); + + if (systemAutos.length) { + list.appendChild(_buildAutomationSection('auto-section-system', 'System', systemAutos, true)); + } + if (userAutos.length) { + list.appendChild(_buildAutomationSection('auto-section-custom', 'My Automations', userAutos, false)); + } + // Stats summary bar if (statsBar) { const total = automations.length; const active = automations.filter(a => a.enabled).length; - const scheduled = automations.filter(a => a.enabled && a.trigger_type === 'schedule').length; - const eventBased = automations.filter(a => a.enabled && a.trigger_type !== 'schedule').length; + const sys = systemAutos.length; + const custom = userAutos.length; statsBar.innerHTML = ` - ${total} Total ${active} Active - ${scheduled} Scheduled - ${eventBased} Event-Based + ${sys} System + ${custom} Custom `; } // Catch up on current automation progress @@ -43389,7 +43430,6 @@ function renderAutomationCard(a) { const thenItems = a.then_actions || []; const actionDelay = a.action_config && a.action_config.delay ? a.action_config.delay : 0; const metaParts = []; - if (a.is_system) metaParts.push('System'); if (a.last_run) metaParts.push('Last: ' + _autoTimeAgo(a.last_run)); const _timerTriggers = ['schedule', 'daily_time', 'weekly_time']; if (a.next_run && a.enabled && _timerTriggers.includes(a.trigger_type)) metaParts.push('Next: ' + _autoTimeUntil(a.next_run)); @@ -43463,7 +43503,9 @@ function _autoFormatAction(type) { start_database_update: 'Update Database', run_duplicate_cleaner: 'Run Duplicate Cleaner', clear_quarantine: 'Clear Quarantine', cleanup_wishlist: 'Clean Up Wishlist', update_discovery_pool: 'Update Discovery', start_quality_scan: 'Run Quality Scan', - backup_database: 'Backup Database' }; + backup_database: 'Backup Database', + refresh_beatport_cache: 'Refresh Beatport Cache', clean_search_history: 'Clean Search History', + clean_completed_downloads: 'Clean Completed Downloads' }; return labels[type] || type || 'Unknown'; } function _autoFormatNotify(type) { diff --git a/webui/static/style.css b/webui/static/style.css index e257f3cf..32f34b9f 100644 --- a/webui/static/style.css +++ b/webui/static/style.css @@ -28820,6 +28820,72 @@ body { .automations-container { padding: 20px 24px; } .automations-list { display: flex; flex-direction: column; gap: 0; } +/* --- Section Headers (System / My Automations) --- */ +.automations-section { + margin-bottom: 8px; +} +.automations-section:last-child { margin-bottom: 0; } +.automations-section-header { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 2px 10px; + cursor: pointer; + user-select: none; + -webkit-user-select: none; +} +.automations-section-header:hover .section-label { color: rgba(255,255,255,0.85); } +.section-chevron { + font-size: 11px; + color: rgba(255,255,255,0.3); + transition: transform 0.25s ease; + width: 14px; + text-align: center; + flex-shrink: 0; +} +.automations-section.collapsed .section-chevron { transform: rotate(-90deg); } +.section-label { + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 1px; + color: rgba(255,255,255,0.4); + transition: color 0.2s ease; +} +.section-count { + font-size: 10px; + color: rgba(255,255,255,0.25); + padding: 1px 8px; + border-radius: 8px; + background: rgba(255,255,255,0.04); + border: 1px solid rgba(255,255,255,0.06); +} +.section-line { + flex: 1; + height: 1px; + background: rgba(255,255,255,0.06); +} +.automations-section-body { + overflow: hidden; + transition: max-height 0.3s ease, opacity 0.25s ease; + max-height: 2000px; + opacity: 1; +} +.automations-section.collapsed .automations-section-body { + max-height: 0; + opacity: 0; +} + +/* --- System Automations 2-Column Grid --- */ +.automations-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 6px; +} +@media (max-width: 800px) { + .automations-grid { grid-template-columns: 1fr; } +} + /* --- New Automation Button --- */ .auto-new-btn { background: linear-gradient(135deg, rgb(var(--accent-rgb)) 0%, rgb(var(--accent-light-rgb)) 100%); @@ -28892,7 +28958,7 @@ body { .automation-card.disabled { opacity: 0.55; } .automation-card.disabled:hover { opacity: 0.75; } .automation-card.disabled .automation-name { color: rgba(255,255,255,0.5); } -.automation-card.system { border-left: 3px solid var(--accent, #6366f1); } +.automation-card.system { border-left: none; padding: 8px 12px; } .system-badge { display: inline-block; font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; padding: 1px 5px; border-radius: 6px; background: rgba(99,102,241,0.2); color: #818cf8; vertical-align: middle; } .automation-status { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }