From cb19cd2476e280465b2c0d0c7416d66533e2a79d Mon Sep 17 00:00:00 2001 From: jialin Date: Wed, 17 Jun 2026 20:07:49 +0800 Subject: [PATCH] fix: show cpu only spec info --- .../instances/utils/render-instance-type.tsx | 34 ++++++++++++++++--- .../tables/use-instances-columns.tsx | 26 ++++++++++---- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/pages/gpu-service/instances/utils/render-instance-type.tsx b/src/pages/gpu-service/instances/utils/render-instance-type.tsx index 24d6fc28..7824d6a3 100644 --- a/src/pages/gpu-service/instances/utils/render-instance-type.tsx +++ b/src/pages/gpu-service/instances/utils/render-instance-type.tsx @@ -85,6 +85,9 @@ const formatResources = ( }; }; +// Spec popover categories, in render order. +type SpecCategory = 'gpu' | 'cpu' | 'ram' | 'disk'; + export const renderInstanceType = ( record: ListItem, options: { @@ -92,22 +95,31 @@ export const renderInstanceType = ( // name → capacity (e.g. "20Gi") for referenced persistent volumes, so the // Disk → Persistent row can show the size instead of just the PV name. pvCapacityByName?: Record; + // Limit the spec popover to these categories (default: all). The Instance + // Types breakdown only wants CPU + RAM, for example. + categories?: SpecCategory[]; + // Override the primary label (default: derived " x " / + // "CPU Only"). The Instance Types breakdown keeps its plain product name. + title?: string; } ) => { - const { intl, pvCapacityByName } = options; + const { intl, pvCapacityByName, categories } = options; const description = parseJsonSafe(record?.description || '{}', {}).spec || {}; const resources = formatResources({ spec: description }, record); const accelerator = record.spec?.resources?.accelerator; - const title = description.acceleratable - ? `${description.product} x ${accelerator}` - : 'CPU Only'; + const title = + options.title ?? + (description.acceleratable + ? `${description.product} x ${accelerator}` + : 'CPU Only'); const volume = (record.spec as any)?.volume; // Spec popover grouped by category (GPU / CPU / Memory / Disk), mirroring // the Deployments instance info icon: dark tooltip, per-category icon, // instance name as the title. Rows with no value are dropped. type Section = { + key: SpecCategory; icon: string; name: string; rows: [string | null, string | undefined][]; @@ -115,6 +127,7 @@ export const renderInstanceType = ( const sections: Section[] = []; if (description.acceleratable) { sections.push({ + key: 'gpu', icon: 'icon-gpu', name: 'GPU', rows: [ @@ -134,16 +147,19 @@ export const renderInstanceType = ( }); } sections.push({ + key: 'cpu', icon: 'icon-cpu', name: 'CPU', rows: [[null, resources.cpu]] }); sections.push({ + key: 'ram', icon: 'icon-ram-02', name: intl.formatMessage({ id: 'gpuservice.instance.ram' }), rows: [[null, resources.ram]] }); sections.push({ + key: 'disk', icon: 'icon-hard-disk', name: intl.formatMessage({ id: 'gpuservice.instance.disk' }), rows: [ @@ -170,8 +186,16 @@ export const renderInstanceType = ( ] }); + const visibleSections = categories + ? sections.filter((s) => categories.includes(s.key)) + : sections; + return ( - + ); }; diff --git a/src/pages/usage/instances-tab/tables/use-instances-columns.tsx b/src/pages/usage/instances-tab/tables/use-instances-columns.tsx index 40b22d99..8e505ae3 100644 --- a/src/pages/usage/instances-tab/tables/use-instances-columns.tsx +++ b/src/pages/usage/instances-tab/tables/use-instances-columns.tsx @@ -36,18 +36,30 @@ const useInstancesColumns = (groupKey: GroupKey) => { render: (v: number) => (v ?? 0).toFixed(2) } ]; - // Instance Types breakdown: just the pretty product name (or flavor slug - // for older rows) — no spec sub-line. CPU-only flavors (no GPU cards) show - // "CPU Only", matching the canonical GPU Instances renderer. + // Instance Types breakdown: the pretty product name (or flavor slug for + // older rows; "CPU Only" when no GPU cards) plus a CPU + RAM spec popover — + // rendered through the canonical renderer so the formatting matches the GPU + // Instances list, but limited to the CPU/RAM categories. const instanceTypeColType = { title: intl.formatMessage({ id: 'usage.table.instanceType' }), dataIndex: 'gpu_type', key: 'gpu_type', render: (_v: string, row: ResourceBreakdownItem) => - (row.gpu_count ?? 0) > 0 ? ( - instanceTypeLabel(row) - ) : ( - CPU Only + renderInstanceType( + buildInstanceTypeRecordFromMiB({ + name: row.instance_name, + product: row.product || row.gpu_type, + gpuCount: row.gpu_count, + unitCpuMilli: row.unit_cpu_milli, + unitMemoryMib: row.unit_memory_mib, + vramMib: row.vram_mib + }), + { + intl, + categories: ['cpu', 'ram'], + title: + (row.gpu_count ?? 0) > 0 ? instanceTypeLabel(row) : 'CPU Only' + } ) }; // Instances breakdown: render through the canonical GPU Instances list