feat(downloads): front-and-center "active now" panel with live elapsed timers
New ActiveDownloadsPanel pinned at the top of the Downloads tab shows what's running (pulsing dot + live mm:ss timer counting from started_at) and what's queued, so the operator can see activity at a glance without the running filter. Backed by store.loadActive() which fetches running + pending independent of the feed filter; refreshed every 4s by the existing live poll. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,10 @@ export const useDownloadsStore = defineStore('downloads', () => {
|
||||
const stats = ref({ pending: 0, running: 0, ok: 0, error: 0, skipped: 0 })
|
||||
const activity = ref({ hours: 24, buckets: [] })
|
||||
const failing = ref([])
|
||||
// Running + queued events, fetched independent of the feed's filter so
|
||||
// the "active now" panel always reflects what's happening regardless of
|
||||
// how the operator has filtered the historical list below.
|
||||
const activeEvents = ref([])
|
||||
|
||||
function _params(extra = {}) {
|
||||
const out = { limit: 50, ...extra }
|
||||
@@ -75,10 +79,19 @@ export const useDownloadsStore = defineStore('downloads', () => {
|
||||
return failing.value
|
||||
}
|
||||
|
||||
async function loadActive() {
|
||||
const [running, pending] = await Promise.all([
|
||||
api.get('/api/downloads', { params: { status: 'running', limit: 50 } }),
|
||||
api.get('/api/downloads', { params: { status: 'pending', limit: 50 } }),
|
||||
])
|
||||
activeEvents.value = [...running, ...pending]
|
||||
return activeEvents.value
|
||||
}
|
||||
|
||||
return {
|
||||
events, cursor, hasMore, filter, selected, loading, error, stats,
|
||||
activity, failing,
|
||||
activity, failing, activeEvents,
|
||||
loadFirst, loadMore, loadOne, applyFilter, closeDetail, loadStats,
|
||||
loadActivity, loadFailing,
|
||||
loadActivity, loadFailing, loadActive,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user