fix in planner

This commit is contained in:
Mateusz Gruszczyński
2026-06-16 22:57:29 +02:00
parent 03ce088d24
commit 48f68cf125
5 changed files with 5 additions and 4 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
export const profileListSource = " function markActiveProfileRow(id){\n // Note: Keeps the active rTorrent profile frame in sync immediately after switching, before diagnostics refresh finishes.\n const activeId=String(id||'');\n document.querySelectorAll('#profileList .profile-row').forEach(row=>{\n const isActive=String(row.dataset.profileId||'')===activeId;\n row.classList.toggle('active', isActive);\n row.setAttribute('aria-current', isActive ? 'true' : 'false');\n const badge=row.querySelector('[data-active-profile-badge]');\n if(badge) badge.classList.toggle('d-none', !isActive);\n });\n }\n function profileDiagnosticStatusClass(status){\n // Note: rTorrent profile badges reuse Bootstrap colors and the same normal/slow/error idea as the poller panel.\n const value=String(status||'unknown').toLowerCase();\n if(value==='normal' || value==='online') return 'success';\n if(value==='slow' || value==='slowdown') return 'warning';\n if(value==='error' || value==='recovery') return 'danger';\n return 'secondary';\n }\n function profileDiagnosticStatusLabel(status){\n const value=String(status||'unknown').toLowerCase();\n return value==='online' ? 'normal' : value;\n }\n async function refreshProfiles(){\n const j=await (await fetch('/api/profiles')).json();\n profileCache=new Map((j.profiles||[]).map(p=>[String(p.id),p]));\n const active=String(j.active?.id ?? activeProfileId ?? '');\n const rows=j.profiles||[];\n const statusMap=new Map();\n try{ const d=await (await fetch('/api/profiles/diagnostics')).json(); (d.diagnostics||[]).forEach(x=>statusMap.set(String(x.profile_id), x)); }catch(e){}\n $('profileList').innerHTML=rows.map(p=>{\n const d=statusMap.get(String(p.id))||{};\n const st=profileDiagnosticStatusLabel(d.status || 'unknown');\n const cls=profileDiagnosticStatusClass(st);\n const response=d.response_time_ms?` \u00b7 ${esc(d.response_time_ms)} ms`:'';\n const threshold=d.slow_threshold_ms?` \u00b7 slow > ${esc(d.slow_threshold_ms)} ms`:'';\n const isActive=String(p.id)===active;\n const backupIcon=p.profile_backup_enabled?`<span class=\"profile-backup-icon\" title=\"Automatic profile backup enabled\" aria-label=\"Automatic profile backup enabled\"><i class=\"fa-solid fa-floppy-disk\"></i></span>`:'';\n return `<div class=\"profile-row ${isActive?'active':''}\" data-profile-id=\"${esc(p.id)}\" aria-current=\"${isActive?'true':'false'}\"><b><span class=\"profile-id-badge\">#${esc(p.id)}</span> ${esc(p.name)} <span data-active-profile-badge class='badge text-bg-primary ms-1 ${isActive?'':'d-none'}'>active</span> ${p.is_remote?\"<span class='badge text-bg-secondary ms-1'>remote</span>\":''} <span class=\"badge text-bg-${cls}\">${esc(st)}</span></b><span>ID ${esc(p.id)} \u00b7 ${esc(p.scgi_url)} \u00b7 heavy ${esc(p.max_parallel_jobs||5)} \u00b7 light ${esc(p.light_parallel_jobs||4)} \u00b7 poll ${esc(p.polling_min_interval_seconds||'-')}s${response}${threshold}</span><div class=\"profile-actions\"><button class=\"btn btn-xs btn-outline-primary\" data-use-profile=\"${p.id}\"><i class=\"fa-solid fa-plug-circle-check\"></i> use</button>${backupIcon}<button class=\"btn btn-xs btn-outline-info\" data-test-saved-profile=\"${p.id}\" title=\"Diagnostics\"><i class=\"fa-solid fa-stethoscope\"></i></button><button class=\"btn btn-xs btn-outline-secondary\" data-edit-profile=\"${p.id}\" title=\"Edit\"><i class=\"fa-solid fa-pen-to-square\"></i></button><button class=\"btn btn-xs btn-outline-danger\" data-del-profile=\"${p.id}\" title=\"Delete\"><i class=\"fa-solid fa-trash-can\"></i> Remove</button></div></div>`;\n }).join('')||'No profiles.';\n }\n";
export const profileListSource = " function markActiveProfileRow(id){\n // Note: Keeps the active rTorrent profile frame in sync immediately after switching, before diagnostics refresh finishes.\n const activeId=String(id||'');\n document.querySelectorAll('#profileList .profile-row').forEach(row=>{\n const isActive=String(row.dataset.profileId||'')===activeId;\n row.classList.toggle('active', isActive);\n row.setAttribute('aria-current', isActive ? 'true' : 'false');\n const badge=row.querySelector('[data-active-profile-badge]');\n if(badge) badge.classList.toggle('d-none', !isActive);\n });\n }\n function profileDiagnosticStatusClass(status){\n // Note: rTorrent profile badges reuse Bootstrap colors and the same normal/slow/error idea as the poller panel.\n const value=String(status||'unknown').toLowerCase();\n if(value==='normal' || value==='online') return 'success';\n if(value==='slow' || value==='slowdown') return 'warning';\n if(value==='error' || value==='recovery') return 'danger';\n return 'secondary';\n }\n function profileDiagnosticStatusLabel(status){\n const value=String(status||'unknown').toLowerCase();\n return value==='online' ? 'normal' : value;\n }\n async function refreshProfiles(){\n const j=await (await fetch('/api/profiles')).json();\n profileCache=new Map((j.profiles||[]).map(p=>[String(p.id),p]));\n const active=String(j.active?.id ?? activeProfileId ?? '');\n const rows=j.profiles||[];\n const statusMap=new Map();\n try{ const d=await (await fetch('/api/profiles/diagnostics')).json(); (d.diagnostics||[]).forEach(x=>statusMap.set(String(x.profile_id), x)); }catch(e){}\n $('profileList').innerHTML=rows.map(p=>{\n const d=statusMap.get(String(p.id))||{};\n const st=profileDiagnosticStatusLabel(d.status || 'unknown');\n const cls=profileDiagnosticStatusClass(st);\n const response=d.response_time_ms?` \u00b7 ${esc(d.response_time_ms)} ms`:'';\n const threshold=d.slow_threshold_ms?` \u00b7 slow > ${esc(d.slow_threshold_ms)} ms`:'';\n const isActive=String(p.id)===active;\n const backupIcon=p.profile_backup_enabled?`<span class=\"profile-backup-icon\" title=\"Automatic profile backup enabled\" aria-label=\"Automatic profile backup enabled\"><i class=\"fa-solid fa-floppy-disk\"></i></span>`:'';\n return `<div class=\"profile-row ${isActive?'active':''}\" data-profile-id=\"${esc(p.id)}\" aria-current=\"${isActive?'true':'false'}\"><b><span class=\"profile-id-badge\">#${esc(p.id)}</span> ${esc(p.name)} <span data-active-profile-badge class='badge text-bg-primary ms-1 ${isActive?'':'d-none'}'>active</span> ${p.is_remote?\"<span class='badge text-bg-secondary ms-1'>remote</span>\":''} <span class=\"badge text-bg-${cls}\">${esc(st)}</span></b><span>ID ${esc(p.id)} \u00b7 ${esc(p.scgi_url)} \u00b7 heavy ${esc(p.max_parallel_jobs||5)} \u00b7 light ${esc(p.light_parallel_jobs||4)} \u00b7 poll ${esc(p.polling_min_interval_seconds||'-')}s${response}${threshold}</span><div class=\"profile-actions\">${backupIcon}<button class=\"btn btn-xs btn-outline-primary\" data-use-profile=\"${p.id}\"><i class=\"fa-solid fa-plug-circle-check\"></i> use</button><button class=\"btn btn-xs btn-outline-info\" data-test-saved-profile=\"${p.id}\" title=\"Diagnostics\"><i class=\"fa-solid fa-stethoscope\"></i></button><button class=\"btn btn-xs btn-outline-secondary\" data-edit-profile=\"${p.id}\" title=\"Edit\"><i class=\"fa-solid fa-pen-to-square\"></i></button><button class=\"btn btn-xs btn-outline-danger\" data-del-profile=\"${p.id}\" title=\"Delete\"><i class=\"fa-solid fa-trash-can\"></i> Remove</button></div></div>`;\n }).join('')||'No profiles.';\n }\n";