feat(workers): add tooltip hint on VRAM index, merge index+bar trigger

Blue dashed underline on the VRAM GPU index; index and ProgressBar share one Tooltip trigger showing the memory detail.
This commit is contained in:
jialin
2026-07-20 15:55:39 +08:00
committed by jialin
parent b3b819a080
commit ae06ad7aae
@@ -26,7 +26,7 @@ import { Tooltip } from 'antd';
import { ColumnsType } from 'antd/lib/table'; import { ColumnsType } from 'antd/lib/table';
import { useAtom, useAtomValue } from 'jotai'; import { useAtom, useAtomValue } from 'jotai';
import _ from 'lodash'; import _ from 'lodash';
import { useMemo } from 'react'; import { useEffect, useMemo, useState } from 'react';
import semverCoerce from 'semver/functions/coerce'; import semverCoerce from 'semver/functions/coerce';
import semverGt from 'semver/functions/gt'; import semverGt from 'semver/functions/gt';
import { status, WorkerStatusMap, WorkerStatusMapValue } from '../config'; import { status, WorkerStatusMap, WorkerStatusMapValue } from '../config';
@@ -143,15 +143,57 @@ const GPUCell = ({ devices }: { devices: GPUDeviceItem[] }) => (
</span> </span>
); );
// index + ProgressBar
const VRAMItem = ({
item,
autoOpen
}: {
item: GPUDeviceItem;
autoOpen: boolean;
}) => {
const [open, setOpen] = useState(false);
useEffect(() => {
setOpen(autoOpen);
}, [autoOpen]);
const percent = item.memory?.used
? _.round(item.memory?.utilization_rate, 0)
: _.round((item.memory?.allocated / item.memory?.total) * 100, 0);
return (
<Tooltip
title={<InfoColumn fieldList={fieldList} data={item.memory} />}
open={open}
onOpenChange={setOpen}
>
<span className="flex-center" style={{ cursor: 'pointer' }}>
<span
className="m-r-5"
style={{ display: 'flex', width: 25, lineHeight: 1.2 }}
>
<span
style={{
paddingBottom: 2,
borderBottom: '1px dashed var(--ant-blue-6)'
}}
>
[{item.index}]
</span>
</span>
<ProgressBar percent={percent} />
</span>
</Tooltip>
);
};
const VRAMCell = ({ const VRAMCell = ({
devices, devices,
intl,
rIndex, rIndex,
loadend, loadend,
firstLoad firstLoad
}: { }: {
devices: GPUDeviceItem[]; devices: GPUDeviceItem[];
intl: any;
rIndex: number; rIndex: number;
loadend: boolean; loadend: boolean;
firstLoad: boolean; firstLoad: boolean;
@@ -160,36 +202,11 @@ const VRAMCell = ({
{_.map( {_.map(
_.sortBy(devices || [], ['index']), _.sortBy(devices || [], ['index']),
(item: GPUDeviceItem, index: number) => ( (item: GPUDeviceItem, index: number) => (
<span key={index} className="flex-center"> <VRAMItem
<span key={index}
className="m-r-5" item={item}
style={{ display: 'flex', width: 25, lineHeight: 1 }} autoOpen={rIndex === 0 && index === 0 && loadend && firstLoad}
> />
[{item.index}]
</span>
<ProgressBar
defaultOpen={rIndex === 0 && index === 0 && loadend && firstLoad}
percent={
item.memory?.used
? _.round(item.memory?.utilization_rate, 0)
: _.round(
(item.memory?.allocated / item.memory?.total) * 100,
0
)
}
label={<InfoColumn fieldList={fieldList} data={item.memory} />}
/>
{item.memory.is_unified_memory && (
<Tooltip
title={intl.formatMessage({ id: 'resources.table.unified' })}
>
<InfoCircleOutlined
className="m-l-5"
style={{ color: 'var(--ant-blue-5)' }}
/>
</Tooltip>
)}
</span>
) )
)} )}
</span> </span>
@@ -498,6 +515,7 @@ const useWorkerColumns = ({
{ {
title: 'GPU', title: 'GPU',
dataIndex: 'gpu', dataIndex: 'gpu',
minWidth: 100,
render: (_, record) => render: (_, record) =>
statusAvailable(record) ? ( statusAvailable(record) ? (
<GPUCell devices={record?.status?.gpu_devices} /> <GPUCell devices={record?.status?.gpu_devices} />
@@ -508,11 +526,11 @@ const useWorkerColumns = ({
{ {
title: intl.formatMessage({ id: 'resources.table.vram' }), title: intl.formatMessage({ id: 'resources.table.vram' }),
dataIndex: 'vram', dataIndex: 'vram',
minWidth: 100,
render: (_, record, rIndex) => render: (_, record, rIndex) =>
statusAvailable(record) ? ( statusAvailable(record) ? (
<VRAMCell <VRAMCell
devices={record?.status?.gpu_devices} devices={record?.status?.gpu_devices}
intl={intl}
rIndex={rIndex} rIndex={rIndex}
loadend={loadend} loadend={loadend}
firstLoad={firstLoad} firstLoad={firstLoad}
@@ -524,6 +542,7 @@ const useWorkerColumns = ({
{ {
title: intl.formatMessage({ id: 'resources.table.disk' }), title: intl.formatMessage({ id: 'resources.table.disk' }),
dataIndex: 'storage', dataIndex: 'storage',
minWidth: 100,
render: (_, record) => ( render: (_, record) => (
<span className="flex-center flex-full"> <span className="flex-center flex-full">
{statusAvailable(record) ? ( {statusAvailable(record) ? (