Files
admin-web/src/modules/self-operated/pages/CollectionView.vue
T

57 lines
3.0 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import '@/styles/adminDensity.css'
import { computed, onActivated, onDeactivated, onMounted, onUnmounted, ref } from 'vue'
import AdminPage from '@/shared/components/AdminPage.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
import { analyticsApi } from '../api/analytics'
import type { Overview } from '../types'
import { RequestFence, RuntimePoller, hasActiveTask } from '../state'
import CollectionAccountMonitor from '../components/CollectionAccountMonitor.vue'
const access = useAccessPreviewStore()
const permitted = computed(() => access.can('platform:self-operated-analytics:list'))
const overview = ref<Overview | null>(null)
const error = ref<ApiErrorDetails | null>(null)
const loading = ref(false)
const visible = ref(!document.hidden)
const fence = new RequestFence()
let active = false
function busy() {
const tasks = [overview.value?.accountActivity, ...(overview.value?.warehouses.flatMap(w => [...(w.activeTasks ?? []), w.currentTask, w.sharedUpstream]) ?? [])].filter(t => t != null)
return hasActiveTask(tasks) || tasks.some(t => ['READY', 'APPLYING', 'WAITING', 'QUEUED'].includes(t.taskStatus))
}
async function read() {
if (!active || !visible.value || !permitted.value) return false
const request = fence.begin()
loading.value = true
try {
const result = await analyticsApi.overview('lingxing-primary', undefined, request.signal)
if (!request.current()) return false
overview.value = result; error.value = null
} catch (cause) {
if (request.current()) error.value = getApiErrorDetails(cause, '采集状态更新失败,请重试')
} finally { if (request.current()) loading.value = false }
return busy()
}
const poller = new RuntimePoller(read, () => fence.cancel())
function visibility() { visible.value = !document.hidden; poller.setVisible(visible.value) }
function resume() { if (active) return; active = true; visibility(); poller.start() }
function suspend() { active = false; visible.value = false; poller.stop(); loading.value = false }
onMounted(() => { resume(); document.addEventListener('visibilitychange', visibility) })
onActivated(resume)
onDeactivated(suspend)
onUnmounted(() => { suspend(); document.removeEventListener('visibilitychange', visibility) })
</script>
<template>
<AdminPage class="admin-density">
<p v-if="!permitted" role="alert">没有采集状态查看权限。</p>
<template v-else>
<LoadErrorState v-if="error" title="采集状态更新失败" :message="error.message" :loading="loading" compact @retry="read"><template #details><ApiErrorMeta :details="error" /></template></LoadErrorState>
<CollectionAccountMonitor :overview="overview" :loading="loading" :stale="Boolean(error)" :visible="visible" @refresh="read" />
</template>
</AdminPage>
</template>