Files
FabledCurator/frontend/src/views/DownloadsView.vue
T
2026-05-20 20:46:48 -04:00

71 lines
2.2 KiB
Vue

<template>
<v-container fluid class="py-6">
<FilterPills v-model="pill" />
<v-alert v-if="store.error" type="error" variant="tonal" closable class="my-4">
{{ String(store.error) }}
</v-alert>
<div v-if="store.loading && store.events.length === 0" class="fc-dl__loading">
<v-progress-circular indeterminate color="accent" size="36" />
</div>
<div v-else-if="store.events.length === 0" class="fc-dl__empty">
<p>No download events yet. Trigger a check from /subscriptions.</p>
</div>
<div v-else>
<DownloadEventRow
v-for="e in store.events" :key="e.id" :event="e"
@open="openDetail"
/>
<div class="fc-dl__sentinel">
<v-btn v-if="store.hasMore" variant="text" @click="store.loadMore()" :loading="store.loading">
Load more
</v-btn>
<span v-else class="text-caption" style="opacity: 0.5">No more events.</span>
</div>
</div>
<DownloadDetailModal
:event="store.selected"
@close="store.closeDetail()"
/>
</v-container>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'
import { useDownloadsStore } from '../stores/downloads.js'
import FilterPills from '../components/downloads/FilterPills.vue'
import DownloadEventRow from '../components/downloads/DownloadEventRow.vue'
import DownloadDetailModal from '../components/downloads/DownloadDetailModal.vue'
const store = useDownloadsStore()
const pill = ref('all')
onMounted(() => store.loadFirst())
watch(pill, async (v) => {
// 'quarantined' has no API filter yet — defer until the API grows
// (a metadata.run_stats.quarantined_count > 0 filter, FC-3d territory).
// For now route it the same as 'all' but keep the chip for discoverability.
const statusMap = { all: null, running: 'running', error: 'error', quarantined: null }
await store.applyFilter({ status: statusMap[v] })
})
async function openDetail(id) {
await store.loadOne(id)
}
</script>
<style scoped>
.fc-dl__loading, .fc-dl__empty {
display: flex; justify-content: center; padding: 3rem 0;
color: rgb(var(--v-theme-on-surface-variant));
}
.fc-dl__sentinel {
display: flex; justify-content: center; padding: 1rem 0;
}
</style>