Files
sub2api/frontend/src/components/user/monitor/MonitorAvailabilityRow.vue
erio a1425b457d feat(channel-monitor): redesign user dashboard as card grid
Reference check-cx UI: INTELLIGENCE MONITOR hero + 3-column card grid
with 60-point timeline bars.

Backend:
- Add PrimaryPingLatencyMs + Timeline[60] to UserMonitorView
- ListRecentHistoryForMonitors: batch CTE + ROW_NUMBER() window query
- indexLatestByModel / indexAvailabilityByModel helpers

Frontend:
- 7 new components: ProviderIcon, MonitorMetricPair, MonitorAvailabilityRow,
  MonitorTimeline, MonitorHero, MonitorCard, MonitorCardGrid
- ChannelStatusView 381→~180 lines (delegated to subcomponents)
- AbortController reload concurrency protection
- HSL 0-120° availability color mapping
- Replace emoji with Icon component (bolt / globe)
- i18n: monitorCommon.* shared namespace, channelStatus.hero.*

Bump VERSION to 0.1.114.24
2026-04-20 23:38:59 +08:00

50 lines
1.2 KiB
Vue

<template>
<div class="mt-3 flex items-end justify-between">
<div class="text-[11px] uppercase tracking-widest text-gray-400">
{{ windowLabel }}
</div>
<div class="flex items-baseline gap-0.5">
<span
class="text-3xl font-bold tabular-nums leading-none"
:style="colorStyle"
>
{{ displayValue }}
</span>
<span
class="text-base font-semibold leading-none"
:style="colorStyle"
>%</span>
</div>
</div>
<div
v-if="samplesLabel"
class="mt-1 text-[11px] text-gray-400 text-right"
>
{{ samplesLabel }}
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { hslForPct } from '@/composables/useChannelMonitorFormat'
const props = defineProps<{
windowLabel: string
value: number | null
samplesLabel?: string
}>()
const { t } = useI18n()
const displayValue = computed(() => {
if (props.value === null || Number.isNaN(props.value)) return t('monitorCommon.latencyEmpty')
return props.value.toFixed(2)
})
const colorStyle = computed(() => {
const colour = hslForPct(props.value)
return colour ? { color: colour } : { color: 'rgb(156 163 175)' }
})
</script>