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
50 lines
1.2 KiB
Vue
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>
|