98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
|
|
/**
|
||
|
|
* Shared formatting helpers for channel monitor views (admin + user).
|
||
|
|
*
|
||
|
|
* Centralises:
|
||
|
|
* - status / provider label + badge class lookups
|
||
|
|
* - latency / availability / percent number formatting
|
||
|
|
*
|
||
|
|
* i18n keys live under `monitorCommon.*` so admin and user views share the
|
||
|
|
* same translation source.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { useI18n } from 'vue-i18n'
|
||
|
|
import type { MonitorStatus, Provider } from '@/api/admin/channelMonitor'
|
||
|
|
import {
|
||
|
|
PROVIDER_OPENAI,
|
||
|
|
PROVIDER_ANTHROPIC,
|
||
|
|
PROVIDER_GEMINI,
|
||
|
|
STATUS_OPERATIONAL,
|
||
|
|
STATUS_DEGRADED,
|
||
|
|
STATUS_FAILED,
|
||
|
|
STATUS_ERROR,
|
||
|
|
} from '@/constants/channelMonitor'
|
||
|
|
|
||
|
|
const NEUTRAL_BADGE = 'bg-gray-100 text-gray-800 dark:bg-dark-700 dark:text-gray-300'
|
||
|
|
|
||
|
|
export interface AvailabilityRow {
|
||
|
|
primary_status: MonitorStatus | ''
|
||
|
|
availability_7d: number | null | undefined
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useChannelMonitorFormat() {
|
||
|
|
const { t } = useI18n()
|
||
|
|
|
||
|
|
function statusLabel(s: MonitorStatus | ''): string {
|
||
|
|
if (!s) return t('monitorCommon.status.unknown')
|
||
|
|
return t(`monitorCommon.status.${s}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
function statusBadgeClass(s: MonitorStatus | ''): string {
|
||
|
|
switch (s) {
|
||
|
|
case STATUS_OPERATIONAL:
|
||
|
|
return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300'
|
||
|
|
case STATUS_DEGRADED:
|
||
|
|
return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300'
|
||
|
|
case STATUS_FAILED:
|
||
|
|
return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300'
|
||
|
|
case STATUS_ERROR:
|
||
|
|
default:
|
||
|
|
return NEUTRAL_BADGE
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function providerLabel(p: Provider | string): string {
|
||
|
|
if (p === PROVIDER_OPENAI || p === PROVIDER_ANTHROPIC || p === PROVIDER_GEMINI) {
|
||
|
|
return t(`monitorCommon.providers.${p}`)
|
||
|
|
}
|
||
|
|
return p || '-'
|
||
|
|
}
|
||
|
|
|
||
|
|
function providerBadgeClass(p: Provider | string): string {
|
||
|
|
switch (p) {
|
||
|
|
case PROVIDER_OPENAI:
|
||
|
|
return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300'
|
||
|
|
case PROVIDER_ANTHROPIC:
|
||
|
|
return 'bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300'
|
||
|
|
case PROVIDER_GEMINI:
|
||
|
|
return 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300'
|
||
|
|
default:
|
||
|
|
return NEUTRAL_BADGE
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatLatency(ms: number | null | undefined): string {
|
||
|
|
if (ms == null) return t('monitorCommon.latencyEmpty')
|
||
|
|
return String(Math.round(ms))
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatPercent(v: number | null | undefined): string {
|
||
|
|
if (v == null || Number.isNaN(v)) return '-'
|
||
|
|
return `${v.toFixed(2)}%`
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatAvailability(row: AvailabilityRow): string {
|
||
|
|
if (!row.primary_status) return '-'
|
||
|
|
return formatPercent(row.availability_7d)
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
statusLabel,
|
||
|
|
statusBadgeClass,
|
||
|
|
providerLabel,
|
||
|
|
providerBadgeClass,
|
||
|
|
formatLatency,
|
||
|
|
formatPercent,
|
||
|
|
formatAvailability,
|
||
|
|
}
|
||
|
|
}
|