style: model list buttons
This commit is contained in:
@@ -101,12 +101,14 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
if (backend === backendOptionsMap.llamaBox) {
|
||||
return {
|
||||
backend: 'llama-box',
|
||||
releases: 'https://github.com/gpustack/llama-box/releases',
|
||||
link: 'https://github.com/gpustack/llama-box?tab=readme-ov-file#usage'
|
||||
};
|
||||
}
|
||||
if (backend === backendOptionsMap.vllm) {
|
||||
return {
|
||||
backend: 'vLLM',
|
||||
releases: 'https://github.com/vllm-project/vllm/releases',
|
||||
link: 'https://docs.vllm.ai/en/stable/serving/openai_compatible_server.html#command-line-arguments-for-the-server'
|
||||
};
|
||||
}
|
||||
@@ -327,6 +329,25 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
description={intl.formatMessage({
|
||||
id: 'models.form.backendVersion.tips'
|
||||
})}
|
||||
labelExtra={
|
||||
backendParamsTips?.releases && (
|
||||
<span
|
||||
style={{
|
||||
marginLeft: 5
|
||||
}}
|
||||
>
|
||||
(
|
||||
<Typography.Link
|
||||
style={{ lineHeight: 1 }}
|
||||
href={backendParamsTips?.releases}
|
||||
target="_blank"
|
||||
>
|
||||
{intl.formatMessage({ id: 'models.form.releases' })}
|
||||
</Typography.Link>
|
||||
)
|
||||
</span>
|
||||
)
|
||||
}
|
||||
></SealInput.Input>
|
||||
</Form.Item>
|
||||
|
||||
@@ -346,19 +367,20 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||
dataList={form.getFieldValue('backend_parameters') || []}
|
||||
onChange={handleBackendParametersChange}
|
||||
options={paramsConfig}
|
||||
description={
|
||||
backendParamsTips && (
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
{ id: 'models.form.backend_parameters.vllm.tips' },
|
||||
{ backend: backendParamsTips.backend || '' }
|
||||
)}{' '}
|
||||
labelExtra={
|
||||
backendParamsTips?.link && (
|
||||
<span style={{ marginLeft: 2 }}>
|
||||
(
|
||||
<Typography.Link
|
||||
href={backendParamsTips.link}
|
||||
style={{ lineHeight: 1 }}
|
||||
href={backendParamsTips?.link}
|
||||
target="_blank"
|
||||
>
|
||||
{intl.formatMessage({ id: 'common.text.here' })}
|
||||
{intl.formatMessage({
|
||||
id: 'models.form.moreparameters'
|
||||
})}
|
||||
</Typography.Link>
|
||||
)
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import AutoTooltip from '@/components/auto-tooltip';
|
||||
import DropdownButtons from '@/components/drop-down-buttons';
|
||||
import IconFont from '@/components/icon-font';
|
||||
import RowChildren from '@/components/seal-table/components/row-children';
|
||||
import SimpleTabel from '@/components/simple-table';
|
||||
import SimpleTabel, { ColumnProps } from '@/components/simple-table';
|
||||
import StatusTag from '@/components/status-tag';
|
||||
import { HandlerOptions } from '@/hooks/use-chunk-fetch';
|
||||
import useDownloadStream from '@/hooks/use-download-stream';
|
||||
@@ -12,7 +12,8 @@ import {
|
||||
DeleteOutlined,
|
||||
DownloadOutlined,
|
||||
HddFilled,
|
||||
InfoCircleOutlined
|
||||
InfoCircleOutlined,
|
||||
ThunderboltFilled
|
||||
} from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import {
|
||||
@@ -27,17 +28,48 @@ import {
|
||||
} from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { MODEL_INSTANCE_API } from '../apis';
|
||||
import { InstanceStatusMap, InstanceStatusMapValue, status } from '../config';
|
||||
import { ModelInstanceListItem } from '../config/types';
|
||||
import '../style/instance-item.less';
|
||||
|
||||
const WorkerInfo = (props: {
|
||||
title: React.ReactNode;
|
||||
defaultOpen: boolean;
|
||||
}) => {
|
||||
const [open, setOpen] = React.useState(props.defaultOpen);
|
||||
useEffect(() => {
|
||||
if (props.defaultOpen) {
|
||||
setTimeout(() => {
|
||||
setOpen(false);
|
||||
}, 1000);
|
||||
}
|
||||
}, [props.defaultOpen]);
|
||||
return (
|
||||
<span className="server-info-wrapper">
|
||||
<Tooltip
|
||||
open={open}
|
||||
onOpenChange={setOpen}
|
||||
title={props.title}
|
||||
overlayInnerStyle={{
|
||||
width: 'max-content',
|
||||
maxWidth: '400px'
|
||||
}}
|
||||
>
|
||||
<span className="server-info">
|
||||
<InfoCircleOutlined />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
interface InstanceItemProps {
|
||||
instanceData: ModelInstanceListItem;
|
||||
workerList: WorkerListItem[];
|
||||
modelData?: any;
|
||||
defaultOpenId: string;
|
||||
handleChildSelect: (val: string, item: ModelInstanceListItem) => void;
|
||||
}
|
||||
|
||||
@@ -76,7 +108,7 @@ const childActionList = [
|
||||
}
|
||||
];
|
||||
|
||||
const distributeCols = [
|
||||
const distributeCols: ColumnProps[] = [
|
||||
{
|
||||
title: 'Worker',
|
||||
key: 'worker_name'
|
||||
@@ -84,7 +116,7 @@ const distributeCols = [
|
||||
{
|
||||
title: 'IP',
|
||||
key: 'worker_ip',
|
||||
render: ({ row }: { row: ModelInstanceListItem }) => {
|
||||
render: ({ row }) => {
|
||||
return row.port ? `${row.worker_ip}:${row.port}` : row.worker_ip;
|
||||
}
|
||||
},
|
||||
@@ -94,9 +126,21 @@ const distributeCols = [
|
||||
key: 'gpu_index'
|
||||
},
|
||||
{
|
||||
title: 'resources.table.memory',
|
||||
title: 'resources.table.vram',
|
||||
locale: true,
|
||||
key: 'ram'
|
||||
key: 'vram',
|
||||
rowSpan: ({ row, rowIndex, colIndex, dataIndex, dataList }) => {
|
||||
return rowIndex === 0 ? dataList.length : 0;
|
||||
},
|
||||
render: ({ rowIndex, dataList }) => {
|
||||
if (rowIndex === 0) {
|
||||
return convertFileSize(
|
||||
_.sumBy(dataList, (item: any) => item.vram),
|
||||
2
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@@ -153,6 +197,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
||||
instanceData,
|
||||
workerList,
|
||||
modelData,
|
||||
defaultOpenId,
|
||||
handleChildSelect
|
||||
}) => {
|
||||
const [api, contextHolder] = notification.useNotification({
|
||||
@@ -224,55 +269,32 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
||||
? `${instanceData.worker_ip}:${instanceData.port}`
|
||||
: instanceData.worker_ip;
|
||||
}
|
||||
let backend = modelData?.backend || '';
|
||||
if (modelData.backend_version) {
|
||||
backend += ` (${modelData.backend_version})`;
|
||||
}
|
||||
const vrams = instanceData.computed_resource_claim?.vram || {};
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 5 }}>
|
||||
<div>{instanceData.worker_name}</div>
|
||||
<div className="flex-center">
|
||||
<HddFilled className="m-r-5" />
|
||||
{instanceData.worker_name}
|
||||
{workerIp}
|
||||
</div>
|
||||
<div className="flex m-b-6 gap-6">
|
||||
<InfoItem label="IP" value={workerIp} width={180}></InfoItem>
|
||||
<InfoItem
|
||||
width={90}
|
||||
label={intl.formatMessage({ id: 'models.form.backend' })}
|
||||
value={backend}
|
||||
></InfoItem>
|
||||
<div className="flex-center">
|
||||
<IconFont type="icon-filled-gpu" className="m-r-5" />
|
||||
{intl.formatMessage({ id: 'models.table.gpuindex' })}: [
|
||||
{_.join(instanceData.gpu_indexes?.sort?.(), ',')}]
|
||||
</div>
|
||||
<div className="flex gap-6">
|
||||
<InfoItem
|
||||
width={180}
|
||||
label={intl.formatMessage({ id: 'models.table.gpuindex' })}
|
||||
value={Object.keys(vrams)
|
||||
?.sort?.()
|
||||
.map((index) => {
|
||||
return (
|
||||
<span className="flex-1" key={index}>
|
||||
<span className="index">
|
||||
[{index}] {''}
|
||||
</span>
|
||||
{convertFileSize(vrams?.[index], 0)}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
></InfoItem>
|
||||
<InfoItem
|
||||
width={90}
|
||||
label={intl.formatMessage({ id: 'resources.table.memory' })}
|
||||
value={convertFileSize(
|
||||
instanceData.computed_resource_claim?.ram,
|
||||
0
|
||||
)}
|
||||
></InfoItem>
|
||||
<div className="flex-center">
|
||||
<ThunderboltFilled className="m-r-5" />
|
||||
{intl.formatMessage({ id: 'models.form.backend' })}:{' '}
|
||||
{modelData?.backend || ''}
|
||||
{modelData.backend_version ? `(${modelData.backend_version})` : ''}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}, [modelData, instanceData, intl]);
|
||||
|
||||
const calcTotalVram = (vram: Record<string, number>) => {
|
||||
return _.sum(_.values(vram));
|
||||
};
|
||||
|
||||
const renderDistributedServer = useCallback(
|
||||
(severList: any[]) => {
|
||||
const list = _.map(severList, (item: any) => {
|
||||
@@ -281,20 +303,35 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
||||
worker_name: data?.name,
|
||||
worker_ip: data?.ip,
|
||||
port: '',
|
||||
ram: convertFileSize(item.computed_resource_claim?.ram, 0),
|
||||
gpu_index: displayGPUs(item.computed_resource_claim?.vram || {})
|
||||
vram: calcTotalVram(item.computed_resource_claim?.vram || {}),
|
||||
gpu_index: _.keys(item.computed_resource_claim?.vram).join(',')
|
||||
};
|
||||
});
|
||||
|
||||
// const list = [
|
||||
// {
|
||||
// worker_name: 'worker1',
|
||||
// worker_ip: '192.168.50.23',
|
||||
// port: '',
|
||||
// vram: 21555525632,
|
||||
// gpu_index: '0,1'
|
||||
// },
|
||||
// {
|
||||
// worker_name: 'worker2',
|
||||
// worker_ip: '192.168.50.25',
|
||||
// port: '',
|
||||
// vram: 21555525632,
|
||||
// gpu_index: '2,3'
|
||||
// }
|
||||
// ];
|
||||
|
||||
const mainWorker = [
|
||||
{
|
||||
worker_name: `${instanceData.worker_name} (main)`,
|
||||
worker_name: `${instanceData.worker_name}`,
|
||||
worker_ip: `${instanceData.worker_ip}`,
|
||||
port: '',
|
||||
ram: convertFileSize(instanceData.computed_resource_claim?.ram, 0),
|
||||
gpu_index: displayGPUs(
|
||||
instanceData.computed_resource_claim?.vram || {}
|
||||
)
|
||||
vram: calcTotalVram(instanceData.computed_resource_claim?.vram || {}),
|
||||
gpu_index: `${instanceData.gpu_indexes?.join?.(',')}(main)`
|
||||
}
|
||||
];
|
||||
|
||||
@@ -443,18 +480,12 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
||||
<AutoTooltip title={instanceData.name} ghost>
|
||||
<span className="m-r-5">{instanceData.name}</span>
|
||||
</AutoTooltip>
|
||||
<Tooltip
|
||||
title={renderWorkerInfo}
|
||||
overlayInnerStyle={{
|
||||
width: 'max-content',
|
||||
maxWidth: '400px'
|
||||
}}
|
||||
>
|
||||
<span className="server-info">
|
||||
<InfoCircleOutlined className="m-r-2" />{' '}
|
||||
{intl.formatMessage({ id: 'common.button.moreInfo' })}
|
||||
</span>
|
||||
</Tooltip>
|
||||
{!!instanceData.worker_id && (
|
||||
<WorkerInfo
|
||||
title={renderWorkerInfo}
|
||||
defaultOpen={defaultOpenId === instanceData.name}
|
||||
></WorkerInfo>
|
||||
)}
|
||||
</span>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
@@ -468,10 +499,9 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
||||
>
|
||||
{renderOffloadInfo}
|
||||
{renderDistributionInfo(
|
||||
instanceData.distributed_servers?.rpc_servers || []
|
||||
)}
|
||||
{renderDistributionInfo(
|
||||
instanceData.distributed_servers?.ray_actors || []
|
||||
instanceData.distributed_servers?.rpc_servers ||
|
||||
instanceData.distributed_servers?.ray_actors ||
|
||||
[]
|
||||
)}
|
||||
</span>
|
||||
</Col>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
||||
import { Space } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { ModelInstanceListItem } from '../config/types';
|
||||
import '../style/instance-item.less';
|
||||
import InstanceItem from './instance-item';
|
||||
@@ -10,6 +10,7 @@ interface InstanceItemProps {
|
||||
list: ModelInstanceListItem[];
|
||||
workerList: WorkerListItem[];
|
||||
modelData?: any;
|
||||
currentExpanded?: string;
|
||||
handleChildSelect: (val: string, item: ModelInstanceListItem) => void;
|
||||
}
|
||||
|
||||
@@ -17,8 +18,26 @@ const Instances: React.FC<InstanceItemProps> = ({
|
||||
list,
|
||||
workerList,
|
||||
modelData,
|
||||
currentExpanded,
|
||||
handleChildSelect
|
||||
}) => {
|
||||
const [firstLoad, setFirstLoad] = React.useState(true);
|
||||
|
||||
const defaultOpenId = useMemo(() => {
|
||||
if (!currentExpanded) {
|
||||
return '';
|
||||
}
|
||||
const current = _.find(
|
||||
list,
|
||||
(item: ModelInstanceListItem) => item.worker_id
|
||||
);
|
||||
return current ? current.name : '';
|
||||
}, [currentExpanded, list]);
|
||||
|
||||
useEffect(() => {
|
||||
setFirstLoad(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Space size={16} direction="vertical" style={{ width: '100%' }}>
|
||||
{_.map(list, (item: ModelInstanceListItem, index: number) => {
|
||||
@@ -28,6 +47,7 @@ const Instances: React.FC<InstanceItemProps> = ({
|
||||
modelData={modelData}
|
||||
workerList={workerList}
|
||||
instanceData={item}
|
||||
defaultOpenId={firstLoad ? defaultOpenId : ''}
|
||||
handleChildSelect={handleChildSelect}
|
||||
></InstanceItem>
|
||||
);
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
SyncOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { Access, useAccess, useIntl, useNavigate } from '@umijs/max';
|
||||
import { useAccess, useIntl, useNavigate } from '@umijs/max';
|
||||
import {
|
||||
Button,
|
||||
Dropdown,
|
||||
@@ -68,7 +68,6 @@ import {
|
||||
} from '../config';
|
||||
import { FormData, ListItem, ModelInstanceListItem } from '../config/types';
|
||||
import { useGenerateFormEditInitialValues } from '../hooks';
|
||||
import DeployDropdown from './deploy-dropdown';
|
||||
import DeployModal from './deploy-modal';
|
||||
import Instances from './instances';
|
||||
import ModelTag from './model-tag';
|
||||
@@ -120,7 +119,7 @@ const ActionList = [
|
||||
{
|
||||
label: 'common.button.start',
|
||||
key: 'start',
|
||||
icon: <IconFont type="icon-playcircle"></IconFont>
|
||||
icon: <IconFont type="icon-outline-play"></IconFont>
|
||||
},
|
||||
{
|
||||
label: 'common.button.delete',
|
||||
@@ -132,6 +131,27 @@ const ActionList = [
|
||||
}
|
||||
];
|
||||
|
||||
const ButtonList = [
|
||||
{
|
||||
label: 'common.button.start',
|
||||
key: 'start',
|
||||
icon: <IconFont type="icon-outline-play"></IconFont>
|
||||
},
|
||||
{
|
||||
label: 'common.button.stop',
|
||||
key: 'stop',
|
||||
icon: <IconFont type="icon-stop1"></IconFont>
|
||||
},
|
||||
{
|
||||
label: 'common.button.delete',
|
||||
key: 'delete',
|
||||
icon: <DeleteOutlined />,
|
||||
props: {
|
||||
danger: true
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const generateSource = (record: ListItem) => {
|
||||
if (record.source === modelSourceMap.modelscope_value) {
|
||||
return `${modelSourceMap.modelScope}/${record.model_scope_model_id}`;
|
||||
@@ -327,6 +347,12 @@ const Models: React.FC<ModelsProps> = ({
|
||||
}, []);
|
||||
|
||||
const sourceOptions = [
|
||||
{
|
||||
label: intl.formatMessage({ id: 'menu.models.modelCatalog' }),
|
||||
value: 'catalog',
|
||||
key: 'catalog',
|
||||
icon: <IconFont type="icon-catalog"></IconFont>
|
||||
},
|
||||
{
|
||||
label: 'Hugging Face',
|
||||
value: modelSourceMap.huggingface_value,
|
||||
@@ -345,12 +371,6 @@ const Models: React.FC<ModelsProps> = ({
|
||||
key: 'modelscope',
|
||||
icon: <IconFont type="icon-tu2"></IconFont>
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage({ id: 'menu.models.modelCatalog' }),
|
||||
value: 'catalog',
|
||||
key: 'catalog',
|
||||
icon: <IconFont type="icon-catalog"></IconFont>
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage({ id: 'models.form.localPath' }),
|
||||
value: modelSourceMap.local_path_value,
|
||||
@@ -659,11 +679,12 @@ const Models: React.FC<ModelsProps> = ({
|
||||
);
|
||||
|
||||
const renderChildren = useCallback(
|
||||
(list: any, parent?: any) => {
|
||||
(list: any, options: { parent?: any; [key: string]: any }) => {
|
||||
return (
|
||||
<Instances
|
||||
list={list}
|
||||
modelData={parent}
|
||||
currentExpanded={options.currentExpanded}
|
||||
modelData={options.parent}
|
||||
workerList={workerList}
|
||||
handleChildSelect={handleChildSelect}
|
||||
></Instances>
|
||||
@@ -739,6 +760,18 @@ const Models: React.FC<ModelsProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleActionSelect = (val: any) => {
|
||||
if (val === 'delete') {
|
||||
handleDeleteBatch();
|
||||
}
|
||||
if (val === 'start') {
|
||||
handleStartBatch();
|
||||
}
|
||||
if (val === 'stop') {
|
||||
handleStopBatch();
|
||||
}
|
||||
};
|
||||
|
||||
const columns: SealColumnProps[] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
@@ -939,12 +972,6 @@ const Models: React.FC<ModelsProps> = ({
|
||||
onClick: handleClickDropdown
|
||||
}}
|
||||
trigger={['hover']}
|
||||
dropdownRender={() => (
|
||||
<DeployDropdown
|
||||
items={sourceOptions}
|
||||
onSelect={handleClickDropdown}
|
||||
></DeployDropdown>
|
||||
)}
|
||||
placement="bottomRight"
|
||||
>
|
||||
<Button
|
||||
@@ -955,7 +982,19 @@ const Models: React.FC<ModelsProps> = ({
|
||||
{intl?.formatMessage?.({ id: 'models.button.deploy' })}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
<Button
|
||||
<DropdownButtons
|
||||
items={ButtonList}
|
||||
extra={
|
||||
rowSelection.selectedRowKeys.length > 0 && (
|
||||
<span>({rowSelection.selectedRowKeys.length})</span>
|
||||
)
|
||||
}
|
||||
size="large"
|
||||
showText={true}
|
||||
disabled={!rowSelection.selectedRowKeys.length}
|
||||
onSelect={handleActionSelect}
|
||||
/>
|
||||
{/* <Button
|
||||
icon={<IconFont type="icon-outline-play"></IconFont>}
|
||||
onClick={handleStartBatch}
|
||||
disabled={!rowSelection.selectedRows.length}
|
||||
@@ -993,7 +1032,7 @@ const Models: React.FC<ModelsProps> = ({
|
||||
)}
|
||||
</span>
|
||||
</Button>
|
||||
</Access>
|
||||
</Access> */}
|
||||
</Space>
|
||||
}
|
||||
></PageTools>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import AutoTooltip from '@/components/auto-tooltip';
|
||||
import PageTools from '@/components/page-tools';
|
||||
import ProgressBar from '@/components/progress-bar';
|
||||
import InfoColumn from '@/components/simple-table/info-column';
|
||||
import useTableSort from '@/hooks/use-table-sort';
|
||||
import { convertFileSize } from '@/utils';
|
||||
import { SyncOutlined } from '@ant-design/icons';
|
||||
@@ -12,6 +13,33 @@ import { queryGpuDevicesList } from '../apis';
|
||||
import { GPUDeviceItem } from '../config/types';
|
||||
const { Column } = Table;
|
||||
|
||||
const fieldList = [
|
||||
{
|
||||
label: 'resources.table.total',
|
||||
key: 'total',
|
||||
locale: true,
|
||||
render: (val: any) => {
|
||||
return convertFileSize(val, 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'resources.table.used',
|
||||
key: 'used',
|
||||
locale: true,
|
||||
render: (val: any) => {
|
||||
return convertFileSize(val, 0);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'resources.table.allocated',
|
||||
key: 'allocated',
|
||||
locale: true,
|
||||
render: (val: any) => {
|
||||
return convertFileSize(val, 0);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const GPUList: React.FC = () => {
|
||||
console.log('GPUList======');
|
||||
const intl = useIntl();
|
||||
@@ -228,19 +256,10 @@ const GPUList: React.FC = () => {
|
||||
) * 100
|
||||
}
|
||||
label={
|
||||
<span className="flex-column">
|
||||
<span>
|
||||
{intl.formatMessage({ id: 'resources.table.total' })}:{' '}
|
||||
{convertFileSize(record.memory?.total, 0)}
|
||||
</span>
|
||||
<span>
|
||||
{intl.formatMessage({ id: 'resources.table.used' })}:{' '}
|
||||
{convertFileSize(
|
||||
record.memory?.used || record.memory?.allocated,
|
||||
0
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
<InfoColumn
|
||||
fieldList={fieldList}
|
||||
data={record.memory}
|
||||
></InfoColumn>
|
||||
}
|
||||
></ProgressBar>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user