improve ux, moved functionality for better ui experience on app and extension.
This commit is contained in:
@@ -56,6 +56,7 @@ export const settingsApi = {
|
||||
getApiKey: () => api.get('/settings/api-key'),
|
||||
regenerateApiKey: () => api.post('/settings/api-key/regenerate'),
|
||||
getLogs: (params = {}) => api.get('/settings/logs', { params }),
|
||||
refreshStorageStats: () => api.post('/settings/storage-stats/refresh'),
|
||||
}
|
||||
|
||||
// Platforms API
|
||||
|
||||
@@ -208,8 +208,9 @@ const deleteDialog = ref(false)
|
||||
const deletePlatform = ref('')
|
||||
const verifyingPlatform = ref('')
|
||||
|
||||
onMounted(async () => {
|
||||
await loadData()
|
||||
onMounted(() => {
|
||||
// Don't block UI - load data in background
|
||||
loadData()
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
|
||||
@@ -82,12 +82,29 @@
|
||||
Retry All Failed ({{ failedCount }})
|
||||
</v-btn>
|
||||
<v-spacer />
|
||||
<div class="text-body-2 text-grey">
|
||||
<div class="text-body-2 text-grey d-flex align-center">
|
||||
<v-icon size="small" class="mr-1">mdi-harddisk</v-icon>
|
||||
Storage: {{ storageStats?.total_size_formatted || 'Calculating...' }}
|
||||
<span v-if="storageStats?.file_count" class="ml-2">
|
||||
({{ storageStats.file_count.toLocaleString() }} files)
|
||||
</span>
|
||||
<v-tooltip v-if="storageStats?.calculated_at" location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-icon v-bind="props" size="x-small" class="ml-2">mdi-information-outline</v-icon>
|
||||
</template>
|
||||
<span>Updated: {{ formatDate(storageStats.calculated_at) }}</span>
|
||||
</v-tooltip>
|
||||
<v-btn
|
||||
icon
|
||||
size="x-small"
|
||||
variant="text"
|
||||
class="ml-1"
|
||||
:loading="refreshingStorage"
|
||||
@click="refreshStorageStats"
|
||||
title="Refresh storage stats"
|
||||
>
|
||||
<v-icon size="small">mdi-refresh</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
@@ -270,6 +287,10 @@ const checkingAll = ref(false)
|
||||
const retryingAll = ref(false)
|
||||
const storageStats = ref(null)
|
||||
const runningDownloads = ref([])
|
||||
const loadingStats = ref(true)
|
||||
const loadingActivity = ref(true)
|
||||
const loadingStorage = ref(true)
|
||||
const refreshingStorage = ref(false)
|
||||
let refreshInterval = null
|
||||
|
||||
// Computed
|
||||
@@ -280,8 +301,9 @@ const sourcesWithErrors = computed(() =>
|
||||
)
|
||||
const failedCount = computed(() => stats.value?.failed || 0)
|
||||
|
||||
onMounted(async () => {
|
||||
await loadDashboardData()
|
||||
onMounted(() => {
|
||||
// Load data in background - DON'T await, let UI render immediately
|
||||
loadDashboardData()
|
||||
// Start auto-refresh for running downloads
|
||||
startAutoRefresh()
|
||||
})
|
||||
@@ -290,14 +312,23 @@ onUnmounted(() => {
|
||||
stopAutoRefresh()
|
||||
})
|
||||
|
||||
async function loadDashboardData() {
|
||||
await Promise.all([
|
||||
sourcesStore.fetchSources(),
|
||||
downloadsStore.fetchStats(),
|
||||
downloadsStore.fetchRecentActivity({ limit: 10 }),
|
||||
fetchRunningDownloads(),
|
||||
fetchStorageStats(),
|
||||
])
|
||||
function loadDashboardData() {
|
||||
// Fire off all requests in parallel, don't block UI
|
||||
// Each section handles its own loading state
|
||||
sourcesStore.fetchSources().catch(e => console.error('Failed to fetch sources:', e))
|
||||
|
||||
downloadsStore.fetchStats()
|
||||
.catch(e => console.error('Failed to fetch stats:', e))
|
||||
.finally(() => loadingStats.value = false)
|
||||
|
||||
downloadsStore.fetchRecentActivity({ limit: 10 })
|
||||
.catch(e => console.error('Failed to fetch recent activity:', e))
|
||||
.finally(() => loadingActivity.value = false)
|
||||
|
||||
fetchRunningDownloads()
|
||||
|
||||
// Storage stats can be slow - load independently
|
||||
fetchStorageStats()
|
||||
}
|
||||
|
||||
async function fetchRunningDownloads() {
|
||||
@@ -310,11 +341,29 @@ async function fetchRunningDownloads() {
|
||||
}
|
||||
|
||||
async function fetchStorageStats() {
|
||||
loadingStorage.value = true
|
||||
try {
|
||||
const response = await settingsApi.get()
|
||||
storageStats.value = response.data.storage_stats
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch storage stats:', e)
|
||||
} finally {
|
||||
loadingStorage.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshStorageStats() {
|
||||
refreshingStorage.value = true
|
||||
try {
|
||||
await settingsApi.refreshStorageStats()
|
||||
notifications.success('Storage stats refresh queued')
|
||||
// Wait a moment then fetch updated stats
|
||||
setTimeout(() => fetchStorageStats(), 3000)
|
||||
} catch (e) {
|
||||
console.error('Failed to refresh storage stats:', e)
|
||||
notifications.error('Failed to refresh storage stats')
|
||||
} finally {
|
||||
refreshingStorage.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,11 +241,10 @@ const headers = [
|
||||
{ title: 'Actions', key: 'actions', width: 100, sortable: false },
|
||||
]
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
loadDownloads(),
|
||||
sourcesStore.fetchSources(),
|
||||
])
|
||||
onMounted(() => {
|
||||
// Load data in background - don't block UI rendering
|
||||
loadDownloads()
|
||||
sourcesStore.fetchSources()
|
||||
})
|
||||
|
||||
watch([filterStatus, filterSourceId, filterFromDate, filterToDate], () => {
|
||||
|
||||
@@ -330,8 +330,9 @@ const apiHealthy = ref(true)
|
||||
const showApiKey = ref(false)
|
||||
const regenerateDialog = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
await loadAll()
|
||||
onMounted(() => {
|
||||
// Don't block UI - load data in background
|
||||
loadAll()
|
||||
})
|
||||
|
||||
async function loadAll() {
|
||||
|
||||
Reference in New Issue
Block a user