Skip to content

Commit 9fe6e3c

Browse files
committed
Clarify workload cost metrics
1 parent 769f0d7 commit 9fe6e3c

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

web/src/components/cost/WorkloadCostTab.tsx

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useMemo, useState } from 'react'
22
import { clsx } from 'clsx'
3-
import { AlertCircle, DollarSign, Loader2, TrendingUp } from 'lucide-react'
3+
import { AlertCircle, DollarSign, HelpCircle, Loader2, TrendingUp } from 'lucide-react'
44
import {
55
useOpenCostWorkload,
66
useOpenCostWorkloadTrend,
@@ -11,6 +11,7 @@ import {
1111
type OpenCostWorkloadDetailResponse,
1212
type OpenCostWorkloadTrendResponse,
1313
} from '../../api/client'
14+
import { Tooltip } from '../ui/Tooltip'
1415
import { formatCostAxis } from './format'
1516

1617
const TIME_RANGES: { value: CostTimeRange; label: string }[] = [
@@ -108,7 +109,12 @@ export function WorkloadCostTab({ kind, namespace, name }: WorkloadCostTabProps)
108109
<div className="flex items-center gap-2">
109110
<TrendingUp className="h-4 w-4 text-theme-text-tertiary" />
110111
<div>
111-
<div className="text-sm font-semibold text-theme-text-primary">Historical compute cost</div>
112+
<div className="flex items-center gap-1.5">
113+
<div className="text-sm font-semibold text-theme-text-primary">Historical compute cost</div>
114+
<MetricInfoTooltip
115+
content="Dollars are based on OpenCost CPU and memory allocation over time, not raw utilization. Efficiency compares actual usage against that allocated cost."
116+
/>
117+
</div>
112118
<div className="text-xs text-theme-text-tertiary">CPU and memory allocation attributed by workload ownership</div>
113119
</div>
114120
</div>
@@ -179,6 +185,7 @@ export function WorkloadCostTab({ kind, namespace, name }: WorkloadCostTabProps)
179185
label="Efficiency"
180186
value={hasCurrent ? (current?.efficiency ? `${current.efficiency.toFixed(0)}%` : '0%') : '—'}
181187
subvalue={hasCurrent ? `${formatCost(current?.idleCost ?? 0)}/hr idle` : 'Current allocation unavailable'}
188+
tooltip="Actual CPU and memory usage divided by allocated CPU and memory cost for the last hour. Low efficiency usually means requested capacity is sitting idle."
182189
/>
183190
<MetricTile
184191
label="Monthly projection"
@@ -190,7 +197,10 @@ export function WorkloadCostTab({ kind, namespace, name }: WorkloadCostTabProps)
190197
<section className="rounded-lg border border-theme-border bg-theme-surface/50 p-4">
191198
<div className="mb-3 flex items-center justify-between gap-3">
192199
<div>
193-
<div className="text-sm font-semibold text-theme-text-primary">Current cost split</div>
200+
<div className="flex items-center gap-1.5">
201+
<div className="text-sm font-semibold text-theme-text-primary">Current cost split</div>
202+
<MetricInfoTooltip content="Last-hour allocated CPU and memory cost for this workload. This is the cost of reserved/requested capacity, not only what the containers used." />
203+
</div>
194204
<div className="text-xs text-theme-text-tertiary">Last 1h OpenCost allocation window</div>
195205
</div>
196206
<div className="text-sm font-medium text-theme-text-primary tabular-nums">{hasCurrent ? `${formatCost(splitTotal)}/hr` : '—'}</div>
@@ -299,16 +309,27 @@ function MetricBlock({ label, value, subvalue }: { label: string; value: string;
299309
)
300310
}
301311

302-
function MetricTile({ label, value, subvalue }: { label: string; value: string; subvalue?: string }) {
312+
function MetricTile({ label, value, subvalue, tooltip }: { label: string; value: string; subvalue?: string; tooltip?: string }) {
303313
return (
304314
<div className="rounded-lg border border-theme-border bg-theme-surface/50 p-4">
305-
<div className="text-xs font-medium uppercase text-theme-text-tertiary">{label}</div>
315+
<div className="flex items-center gap-1.5">
316+
<div className="text-xs font-medium uppercase text-theme-text-tertiary">{label}</div>
317+
{tooltip && <MetricInfoTooltip content={tooltip} />}
318+
</div>
306319
<div className="mt-1 text-lg font-semibold text-theme-text-primary tabular-nums">{value}</div>
307320
{subvalue && <div className="mt-1 text-xs text-theme-text-tertiary">{subvalue}</div>}
308321
</div>
309322
)
310323
}
311324

325+
function MetricInfoTooltip({ content }: { content: string }) {
326+
return (
327+
<Tooltip content={content} className="max-w-[280px] whitespace-normal text-left" delay={150}>
328+
<HelpCircle className="h-3.5 w-3.5 cursor-help text-theme-text-tertiary transition-colors hover:text-theme-text-secondary" />
329+
</Tooltip>
330+
)
331+
}
332+
312333
function LegendItem({ colorClass, label, value }: { colorClass: string; label: string; value: string }) {
313334
return (
314335
<div className="flex items-center justify-between gap-3 rounded-md bg-theme-base px-2.5 py-2">

0 commit comments

Comments
 (0)