diff --git a/frontend-modern/src/components/Workloads/GuestDrawer.tsx b/frontend-modern/src/components/Workloads/GuestDrawer.tsx index 5054bf765..1e6e191ef 100644 --- a/frontend-modern/src/components/Workloads/GuestDrawer.tsx +++ b/frontend-modern/src/components/Workloads/GuestDrawer.tsx @@ -1,6 +1,6 @@ -import { Component, Show, Suspense } from 'solid-js'; +import { Component, Show, Suspense, createMemo } from 'solid-js'; import { DiscoveryTab } from '../Discovery/DiscoveryTab'; -import type { GuestDrawerProps } from './guestDrawerModel'; +import { getGuestDrawerHistoryFallbackMetrics, type GuestDrawerProps } from './guestDrawerModel'; import { useGuestDrawerState } from './useGuestDrawerState'; import { GuestDrawerHistory, GuestDrawerHistoryRangeSelect } from './GuestDrawerHistory'; import { GuestDrawerOverview } from './GuestDrawerOverview'; @@ -35,6 +35,9 @@ export const GuestDrawer: Component = (props) => { webInterfaceTargetLabel, } = useGuestDrawerState(props); const headingId = () => `guest-drawer-heading-${guestId()}`; + const historyFallbackMetrics = createMemo(() => + getGuestDrawerHistoryFallbackMetrics(props.guest), + ); return (
@@ -118,7 +121,11 @@ export const GuestDrawer: Component = (props) => { {hasHistorySupport() && activeTab() === 'history' && (
- +
)} diff --git a/frontend-modern/src/components/Workloads/guestDrawerModel.ts b/frontend-modern/src/components/Workloads/guestDrawerModel.ts index 2a42e3f26..344f3e3de 100644 --- a/frontend-modern/src/components/Workloads/guestDrawerModel.ts +++ b/frontend-modern/src/components/Workloads/guestDrawerModel.ts @@ -52,6 +52,38 @@ export interface GuestDrawerBackupPresentation { export const isGuestDrawerVM = (guest: Guest): boolean => resolveWorkloadType(guest) === 'vm'; +// Fallback current-value metrics for the guest drawer's history charts. +// Mirrors `getNodeDrawerHistoryFallbackMetrics` — supplies a single +// finite value per metric so `mergeFallbackHistoryMetrics` can synthesize +// a flat 2-point line, replacing the "Collecting history" placeholder +// when the metrics-store hasn't yet accumulated 2+ samples for that +// resource within the selected range. Keys must match the `metric` +// strings declared in `GUEST_DRAWER_HISTORY_GROUPS`. +export const getGuestDrawerHistoryFallbackMetrics = ( + guest: Guest, +): Record => { + const cpuRaw = typeof guest.cpu === 'number' ? guest.cpu : undefined; + const cpuPercent = + cpuRaw === undefined || !Number.isFinite(cpuRaw) + ? undefined + : cpuRaw <= 1.5 + ? cpuRaw * 100 + : cpuRaw; + const memUsage = guest.memory?.usage; + const diskUsage = guest.disk?.usage; + const finite = (value: number | undefined): number | undefined => + typeof value === 'number' && Number.isFinite(value) ? value : undefined; + return { + cpu: finite(cpuPercent), + memory: finite(memUsage), + disk: finite(diskUsage), + netin: finite(guest.networkIn), + netout: finite(guest.networkOut), + diskread: finite(guest.diskRead), + diskwrite: finite(guest.diskWrite), + }; +}; + export const GUEST_DRAWER_HISTORY_DEFAULT_RANGE: HistoryTimeRange = '24h'; export const GUEST_DRAWER_HISTORY_GROUPS: GuestDrawerHistoryGroupConfig[] = [