feat: add dashboard health actions
This commit is contained in:
@@ -46,6 +46,8 @@ const emptySummary = (): AdminFileSummary => ({
|
||||
expiringSoonCount: 0,
|
||||
storageIssueCount: 0,
|
||||
neverRetrievedCount: 0,
|
||||
healthyCount: 0,
|
||||
permanentCount: 0,
|
||||
storageUsed: 0,
|
||||
usedCount: 0
|
||||
})
|
||||
@@ -219,7 +221,12 @@ export function useAdminFiles() {
|
||||
{
|
||||
value: 'healthy',
|
||||
label: t('fileManage.healthFilters.healthy'),
|
||||
count: Math.max(summary.value.totalFiles - summary.value.healthAttentionCount, 0)
|
||||
count: summary.value.healthyCount
|
||||
},
|
||||
{
|
||||
value: 'permanent',
|
||||
label: t('fileManage.healthFilters.permanent'),
|
||||
count: summary.value.permanentCount
|
||||
}
|
||||
])
|
||||
|
||||
@@ -305,6 +312,8 @@ export function useAdminFiles() {
|
||||
neverRetrievedCount: files.filter((file) =>
|
||||
file.statusInsightReasons.includes('never_retrieved')
|
||||
).length,
|
||||
healthyCount: files.filter((file) => file.statusInsightSeverity === 'success').length,
|
||||
permanentCount: files.filter((file) => file.statusInsightState === 'permanent').length,
|
||||
storageUsed: files.reduce((totalSize, file) => totalSize + normalizeCount(file.size), 0),
|
||||
usedCount: files.reduce(
|
||||
(totalUsed, file) => totalUsed + normalizeCount(file.usedCount ?? file.used_count),
|
||||
@@ -312,6 +321,40 @@ export function useAdminFiles() {
|
||||
)
|
||||
})
|
||||
|
||||
const normalizeSummary = (
|
||||
rawSummary: Partial<AdminFileSummary> | undefined,
|
||||
files: AdminFileViewItem[],
|
||||
total: number
|
||||
): AdminFileSummary => {
|
||||
const fallback = buildFallbackSummary(files, total)
|
||||
if (!rawSummary) return fallback
|
||||
|
||||
return {
|
||||
totalFiles: normalizeCount(rawSummary.totalFiles ?? fallback.totalFiles),
|
||||
activeCount: normalizeCount(rawSummary.activeCount ?? fallback.activeCount),
|
||||
expiredCount: normalizeCount(rawSummary.expiredCount ?? fallback.expiredCount),
|
||||
textCount: normalizeCount(rawSummary.textCount ?? fallback.textCount),
|
||||
fileCount: normalizeCount(rawSummary.fileCount ?? fallback.fileCount),
|
||||
chunkedCount: normalizeCount(rawSummary.chunkedCount ?? fallback.chunkedCount),
|
||||
healthAttentionCount: normalizeCount(
|
||||
rawSummary.healthAttentionCount ?? fallback.healthAttentionCount
|
||||
),
|
||||
healthDangerCount: normalizeCount(rawSummary.healthDangerCount ?? fallback.healthDangerCount),
|
||||
healthWarningCount: normalizeCount(
|
||||
rawSummary.healthWarningCount ?? fallback.healthWarningCount
|
||||
),
|
||||
expiringSoonCount: normalizeCount(rawSummary.expiringSoonCount ?? fallback.expiringSoonCount),
|
||||
storageIssueCount: normalizeCount(rawSummary.storageIssueCount ?? fallback.storageIssueCount),
|
||||
neverRetrievedCount: normalizeCount(
|
||||
rawSummary.neverRetrievedCount ?? fallback.neverRetrievedCount
|
||||
),
|
||||
healthyCount: normalizeCount(rawSummary.healthyCount ?? fallback.healthyCount),
|
||||
permanentCount: normalizeCount(rawSummary.permanentCount ?? fallback.permanentCount),
|
||||
storageUsed: normalizeCount(rawSummary.storageUsed ?? fallback.storageUsed),
|
||||
usedCount: normalizeCount(rawSummary.usedCount ?? fallback.usedCount)
|
||||
}
|
||||
}
|
||||
|
||||
const normalizeInsightSeverity = (
|
||||
severity: AdminFileInsightSeverity | undefined
|
||||
): AdminFileInsightSeverity => {
|
||||
@@ -684,7 +727,7 @@ export function useAdminFiles() {
|
||||
|
||||
tableData.value = res.detail.data.map(createFileViewItem)
|
||||
params.value.total = res.detail.total
|
||||
summary.value = res.detail.summary || buildFallbackSummary(tableData.value, res.detail.total)
|
||||
summary.value = normalizeSummary(res.detail.summary, tableData.value, res.detail.total)
|
||||
syncSelectedFilesWithCurrentPage()
|
||||
} catch (error) {
|
||||
hasLoadError.value = true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { computed, ref, reactive } from 'vue'
|
||||
import { StatsService } from '@/services'
|
||||
import type { DashboardViewData } from '@/types'
|
||||
import type { DashboardData, DashboardHealthSummary, DashboardViewData } from '@/types'
|
||||
import { formatFileSize, getErrorMessage } from '@/utils/common'
|
||||
|
||||
type UseDashboardStatsOptions = {
|
||||
@@ -27,6 +27,14 @@ const emptyDashboardData = (): DashboardViewData => ({
|
||||
openUpload: 0,
|
||||
enableChunk: 0,
|
||||
maxSaveSeconds: 0,
|
||||
healthAttentionCount: 0,
|
||||
healthDangerCount: 0,
|
||||
healthWarningCount: 0,
|
||||
expiringSoonCount: 0,
|
||||
storageIssueCount: 0,
|
||||
neverRetrievedCount: 0,
|
||||
healthyCount: 0,
|
||||
permanentCount: 0,
|
||||
topSuffixes: [],
|
||||
recentFiles: [],
|
||||
storageUsedText: '0 Bytes',
|
||||
@@ -37,6 +45,8 @@ const emptyDashboardData = (): DashboardViewData => ({
|
||||
activeRatio: 0,
|
||||
textRatio: 0,
|
||||
fileRatio: 0,
|
||||
healthyRatio: 0,
|
||||
healthAttentionRatio: 0,
|
||||
todaySizeRatio: 0
|
||||
})
|
||||
|
||||
@@ -62,6 +72,34 @@ const normalizeRecentFiles = (recentFiles: DashboardViewData['recentFiles']) =>
|
||||
usedCount: toNumber(file.usedCount)
|
||||
}))
|
||||
|
||||
const healthSummaryKeys: (keyof DashboardHealthSummary)[] = [
|
||||
'healthAttentionCount',
|
||||
'healthDangerCount',
|
||||
'healthWarningCount',
|
||||
'expiringSoonCount',
|
||||
'storageIssueCount',
|
||||
'neverRetrievedCount',
|
||||
'healthyCount',
|
||||
'permanentCount'
|
||||
]
|
||||
|
||||
const normalizeHealthSummary = (detail: DashboardData): DashboardHealthSummary => ({
|
||||
healthAttentionCount: toNumber(
|
||||
detail.healthSummary?.healthAttentionCount ?? detail.healthAttentionCount
|
||||
),
|
||||
healthDangerCount: toNumber(detail.healthSummary?.healthDangerCount ?? detail.healthDangerCount),
|
||||
healthWarningCount: toNumber(
|
||||
detail.healthSummary?.healthWarningCount ?? detail.healthWarningCount
|
||||
),
|
||||
expiringSoonCount: toNumber(detail.healthSummary?.expiringSoonCount ?? detail.expiringSoonCount),
|
||||
storageIssueCount: toNumber(detail.healthSummary?.storageIssueCount ?? detail.storageIssueCount),
|
||||
neverRetrievedCount: toNumber(
|
||||
detail.healthSummary?.neverRetrievedCount ?? detail.neverRetrievedCount
|
||||
),
|
||||
healthyCount: toNumber(detail.healthSummary?.healthyCount ?? detail.healthyCount),
|
||||
permanentCount: toNumber(detail.healthSummary?.permanentCount ?? detail.permanentCount)
|
||||
})
|
||||
|
||||
export function useDashboardStats(options: UseDashboardStatsOptions = {}) {
|
||||
const dashboardData = reactive<DashboardViewData>(emptyDashboardData())
|
||||
const isLoading = ref(false)
|
||||
@@ -103,6 +141,10 @@ export function useDashboardStats(options: UseDashboardStatsOptions = {}) {
|
||||
dashboardData.openUpload = toNumber(detail.openUpload)
|
||||
dashboardData.enableChunk = toNumber(detail.enableChunk)
|
||||
dashboardData.maxSaveSeconds = toNumber(detail.maxSaveSeconds)
|
||||
const healthSummary = normalizeHealthSummary(detail)
|
||||
healthSummaryKeys.forEach((key) => {
|
||||
dashboardData[key] = healthSummary[key]
|
||||
})
|
||||
dashboardData.topSuffixes = detail.topSuffixes || []
|
||||
dashboardData.recentFiles = normalizeRecentFiles(detail.recentFiles || [])
|
||||
|
||||
@@ -120,6 +162,12 @@ export function useDashboardStats(options: UseDashboardStatsOptions = {}) {
|
||||
dashboardData.fileRatio = dashboardData.totalFiles
|
||||
? clampRatio((dashboardData.fileCount / dashboardData.totalFiles) * 100)
|
||||
: 0
|
||||
dashboardData.healthyRatio = dashboardData.totalFiles
|
||||
? clampRatio((dashboardData.healthyCount / dashboardData.totalFiles) * 100)
|
||||
: 0
|
||||
dashboardData.healthAttentionRatio = dashboardData.totalFiles
|
||||
? clampRatio((dashboardData.healthAttentionCount / dashboardData.totalFiles) * 100)
|
||||
: 0
|
||||
dashboardData.todaySizeRatio = dashboardData.uploadSizeLimit
|
||||
? clampRatio((dashboardData.todaySize / dashboardData.uploadSizeLimit) * 100)
|
||||
: 0
|
||||
|
||||
Reference in New Issue
Block a user