mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-09 10:57:03 +08:00
feat(admin): add paginated API key usage leaderboard
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<TimeRangePicker
|
||||
:model-value="timeRange"
|
||||
:show-granularity="false"
|
||||
:preset-options="timeRangePresetOptions"
|
||||
@update:model-value="$emit('update:timeRange', $event)"
|
||||
/>
|
||||
|
||||
<Select
|
||||
:model-value="metric"
|
||||
@update:model-value="emitMetric"
|
||||
>
|
||||
<SelectTrigger class="h-8 text-xs w-28">
|
||||
<SelectValue placeholder="指标" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="requests">
|
||||
请求数
|
||||
</SelectItem>
|
||||
<SelectItem value="tokens">
|
||||
Tokens
|
||||
</SelectItem>
|
||||
<SelectItem value="cost">
|
||||
成本
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TimeRangePicker } from '@/components/common'
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue
|
||||
} from '@/components/ui'
|
||||
import type { DateRangeParams } from '@/features/usage/types'
|
||||
|
||||
type LeaderboardMetric = 'requests' | 'tokens' | 'cost'
|
||||
type LeaderboardTimeRangePreset = 'today' | 'yesterday' | 'last7days' | 'last30days' | 'last90days' | 'custom'
|
||||
|
||||
defineProps<{
|
||||
metric: LeaderboardMetric
|
||||
timeRange: DateRangeParams
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:metric', value: LeaderboardMetric): void
|
||||
(e: 'update:timeRange', value: DateRangeParams): void
|
||||
}>()
|
||||
|
||||
const timeRangePresetOptions: LeaderboardTimeRangePreset[] = [
|
||||
'today',
|
||||
'yesterday',
|
||||
'last7days',
|
||||
'last30days',
|
||||
'last90days',
|
||||
'custom'
|
||||
]
|
||||
|
||||
function emitMetric(value: string) {
|
||||
if (value === 'requests' || value === 'tokens' || value === 'cost') {
|
||||
emit('update:metric', value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,26 +1,28 @@
|
||||
<template>
|
||||
<TableCard :title="title">
|
||||
<template #actions>
|
||||
<Select
|
||||
v-if="showMetricSelect"
|
||||
:model-value="metric"
|
||||
@update:model-value="emitMetric"
|
||||
>
|
||||
<SelectTrigger class="h-8 text-xs w-28">
|
||||
<SelectValue placeholder="指标" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="requests">
|
||||
请求数
|
||||
</SelectItem>
|
||||
<SelectItem value="tokens">
|
||||
Tokens
|
||||
</SelectItem>
|
||||
<SelectItem value="cost">
|
||||
成本
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<slot name="actions">
|
||||
<Select
|
||||
v-if="showMetricSelect"
|
||||
:model-value="metric"
|
||||
@update:model-value="emitMetric"
|
||||
>
|
||||
<SelectTrigger class="h-8 text-xs w-28">
|
||||
<SelectValue placeholder="指标" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="requests">
|
||||
请求数
|
||||
</SelectItem>
|
||||
<SelectItem value="tokens">
|
||||
Tokens
|
||||
</SelectItem>
|
||||
<SelectItem value="cost">
|
||||
成本
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</slot>
|
||||
</template>
|
||||
|
||||
<div
|
||||
@@ -77,6 +79,8 @@
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
<slot name="pagination" />
|
||||
</TableCard>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export { default as ActivityHeatmap } from './ActivityHeatmap.vue'
|
||||
export { default as LeaderboardControls } from './LeaderboardControls.vue'
|
||||
export { default as LeaderboardTable } from './LeaderboardTable.vue'
|
||||
export { default as CostForecastChart } from './CostForecastChart.vue'
|
||||
export { default as QuotaProgressCard } from './QuotaProgressCard.vue'
|
||||
|
||||
Reference in New Issue
Block a user