fix: dashboard intl settings

This commit is contained in:
jialin
2024-06-30 13:49:44 +08:00
parent 9f4f28edaf
commit aa160da9f9
23 changed files with 270 additions and 202 deletions
+6 -17
View File
@@ -44,23 +44,12 @@ export default defineConfig({
minRatio: 0.8 minRatio: 0.8
} }
]); ]);
// config.module },
// .rule('images') terserOptions: {
// .test(/\.(png|jpe?g|gif|svg|ico)(\?.*)?$/) compress: {
// .use('url-loader') drop_console: true,
// .loader(require.resolve('url-loader')) drop_debugger: true
// .tap((options: any) => { }
// return {
// ...options,
// limit: 8192, // 小于8KB的图片会被转为base64
// fallback: {
// loader: require.resolve('file-loader'),
// options: {
// name: 'static/[name].[hash:8].[ext]' // 将所有图片输出到 static 目录
// }
// }
// };
// });
} }
} }
: {}), : {}),
-1
View File
@@ -1,6 +1,5 @@
.ant-pro-layout { .ant-pro-layout {
.ant-pro-sider { .ant-pro-sider {
padding: 10px;
// &.ant-layout-sider { // &.ant-layout-sider {
// background: var(--color-white-1); // background: var(--color-white-1);
// } // }
+7 -1
View File
@@ -1,5 +1,7 @@
import { Column } from '@ant-design/plots'; import { Column } from '@ant-design/plots';
import EmptyData from './empty-data';
interface BarChartProps { interface BarChartProps {
data: any[]; data: any[];
xField: string; xField: string;
@@ -99,7 +101,11 @@ const BarChart: React.FC<BarChartProps> = (props) => {
return ( return (
<> <>
<Column {...config} /> {data.length > 0 ? (
<Column {...config} />
) : (
<EmptyData height={height} title={title} />
)}
</> </>
); );
}; };
+32
View File
@@ -0,0 +1,32 @@
import { Empty } from 'antd';
import React from 'react';
const EmptyData: React.FC<{
height: string | number;
title: React.ReactNode;
}> = ({ height, title }) => {
return (
<div
style={{
width: '100%',
height: height || '100%'
}}
className="flex-center flex-column "
>
<h3
className="justify-center"
style={{ padding: '16px 0', marginBottom: 0 }}
>
{title}
</h3>
<div
className="flex-center justify-center flex-column"
style={{ height: '100%' }}
>
<Empty />
</div>
</div>
);
};
export default EmptyData;
+13 -4
View File
@@ -1,4 +1,5 @@
import { Bar } from '@ant-design/plots'; import { Bar } from '@ant-design/plots';
import EmptyData from './empty-data';
interface BarChartProps { interface BarChartProps {
data: any[]; data: any[];
@@ -11,6 +12,7 @@ interface BarChartProps {
seriesField?: string; seriesField?: string;
stack?: boolean; stack?: boolean;
legend?: any; legend?: any;
showYAxis?: boolean;
} }
const BarChart: React.FC<BarChartProps> = (props) => { const BarChart: React.FC<BarChartProps> = (props) => {
const { const {
@@ -23,6 +25,7 @@ const BarChart: React.FC<BarChartProps> = (props) => {
colorField, colorField,
seriesField, seriesField,
stack, stack,
showYAxis = true,
legend = undefined legend = undefined
} = props; } = props;
const config = { const config = {
@@ -57,9 +60,11 @@ const BarChart: React.FC<BarChartProps> = (props) => {
xAxis: true, xAxis: true,
tick: false tick: false
}, },
y: { y: showYAxis
tick: false ? {
} tick: false
}
: null
}, },
title: { title: {
title, title,
@@ -94,7 +99,11 @@ const BarChart: React.FC<BarChartProps> = (props) => {
return ( return (
<> <>
<Bar {...config} /> {data.length === 0 ? (
<EmptyData height={height} title={title} />
) : (
<Bar {...config} />
)}
</> </>
); );
}; };
+13 -2
View File
@@ -7,12 +7,22 @@ interface LineChartProps {
color?: string[]; color?: string[];
xField?: string; xField?: string;
yField?: string; yField?: string;
locale: string;
labelFormatter?: (v: any) => string; labelFormatter?: (v: any) => string;
slider?: any; slider?: any;
} }
const LineChart: React.FC<LineChartProps> = (props) => { const LineChart: React.FC<LineChartProps> = (props) => {
const { data, title, color, xField, yField, slider, height, labelFormatter } = const {
props; data,
title,
color,
xField,
locale,
yField,
slider,
height,
labelFormatter
} = props;
const config = { const config = {
title, title,
height, height,
@@ -56,6 +66,7 @@ const LineChart: React.FC<LineChartProps> = (props) => {
color: { color: {
layout: { justifyContent: 'center' } layout: { justifyContent: 'center' }
}, },
size: { size: {
itemLabelFontSize: 14, itemLabelFontSize: 14,
itemLabelFontWeight: 500 itemLabelFontWeight: 500
+1 -1
View File
@@ -16,7 +16,7 @@ const UitilBar: React.FC<UitilBarProps> = (props) => {
percent, percent,
steps = 10, steps = 10,
gapDegree = 170, gapDegree = 170,
strokeWidth = 12, strokeWidth = 10,
title, title,
size = 160, size = 160,
strokeColor, strokeColor,
+3 -1
View File
@@ -1,5 +1,6 @@
import apikeys from './en-US/apikeys'; import apikeys from './en-US/apikeys';
import common from './en-US/common'; import common from './en-US/common';
import dashboard from './en-US/dashboard';
import menu from './en-US/menu'; import menu from './en-US/menu';
import models from './en-US/models'; import models from './en-US/models';
import playground from './en-US/playground'; import playground from './en-US/playground';
@@ -13,5 +14,6 @@ export default {
...playground, ...playground,
...resources, ...resources,
...apikeys, ...apikeys,
...users ...users,
...dashboard
}; };
+24
View File
@@ -0,0 +1,24 @@
export default {
'dashboard.title': 'Dashboard',
'dashboard.workers': 'Workers',
'dashboard.models': 'Models',
'dashboard.totalgpus': 'Total GPUs',
'dashboard.allocategpus': 'Allocated GPUs',
'dashboard.instances': 'Instances',
'dashboard.systemload': 'System Load',
'dashboard.memory': 'Memory',
'dashboard.disk': 'Storage',
'dashboard.vram': 'VRAM',
'dashboard.cpuutilization': 'CPU Utilization',
'dashboard.memoryutilization': 'Memory Utilization',
'dashboard.diskutilization': 'Storage Utilization',
'dashboard.vramutilization': 'VRAM Utilization',
'dashboard.gpuutilization': 'GPU Utilization',
'dashboard.usage': 'Usage',
'dashboard.apirequest': 'API Request',
'dashboard.tokens': 'Tokens',
'dashboard.topusers': 'Top Users',
'dashboard.activeModels': 'Active Models',
'dashboard.runninginstances': 'Running Instances',
'dashboard.activeModels.name': 'Model Name'
};
+8 -1
View File
@@ -7,5 +7,12 @@ export default {
'resources.table.memory': 'Memory', 'resources.table.memory': 'Memory',
'resources.table.gpu': 'GPU', 'resources.table.gpu': 'GPU',
'resources.table.disk': 'Storage', 'resources.table.disk': 'Storage',
'resources.table.vram': 'VRAM' 'resources.table.vram': 'VRAM',
'resources.table.index': 'Index',
'resources.table.workername': 'Wroker Name',
'resources.table.vender': 'Vender',
'resources.table.temperature': 'Temperature',
'resources.table.core': 'Core',
'resources.table.gpuutilization': 'GPU Utilization',
'resources.table.vramutilization': 'VRAM Utilization'
}; };
+3 -1
View File
@@ -1,5 +1,6 @@
import apikeys from './zh-CN/apikeys'; import apikeys from './zh-CN/apikeys';
import common from './zh-CN/common'; import common from './zh-CN/common';
import dashboard from './zh-CN/dashboard';
import menu from './zh-CN/menu'; import menu from './zh-CN/menu';
import models from './zh-CN/models'; import models from './zh-CN/models';
import playground from './zh-CN/playground'; import playground from './zh-CN/playground';
@@ -13,5 +14,6 @@ export default {
...playground, ...playground,
...resources, ...resources,
...apikeys, ...apikeys,
...users ...users,
...dashboard
}; };
+24
View File
@@ -0,0 +1,24 @@
export default {
'dashboard.title': '概览',
'dashboard.workers': '节点',
'dashboard.models': '模型',
'dashboard.totalgpus': '总 GPU 数量',
'dashboard.allocategpus': '已分配 GPU 数量',
'dashboard.instances': '实例',
'dashboard.systemload': '系统负载',
'dashboard.memory': '内存',
'dashboard.disk': '磁盘',
'dashboard.vram': '显存',
'dashboard.cpuutilization': 'CPU 利用率',
'dashboard.memoryutilization': '内存利用率',
'dashboard.diskutilization': '磁盘利用率',
'dashboard.vramutilization': '显存利用率',
'dashboard.gpuutilization': 'GPU 利用率',
'dashboard.usage': '使用量',
'dashboard.apirequest': 'API 请求',
'dashboard.tokens': 'Tokens',
'dashboard.topusers': '用户排行',
'dashboard.activeModels': '活跃模型',
'dashboard.activeModels.name': '模型名称',
'dashboard.runninginstances': '运行实例'
};
+8 -1
View File
@@ -7,5 +7,12 @@ export default {
'resources.table.memory': '内存', 'resources.table.memory': '内存',
'resources.table.gpu': 'GPU', 'resources.table.gpu': 'GPU',
'resources.table.disk': '磁盘', 'resources.table.disk': '磁盘',
'resources.table.vram': '显存' 'resources.table.vram': '显存',
'resources.table.index': '序号',
'resources.table.workername': '节点名称',
'resources.table.vender': '厂商',
'resources.table.temperature': '温度',
'resources.table.core': '核数',
'resources.table.gpuutilization': 'GPU 利用率',
'resources.table.vramutilization': '显存利用率'
}; };
+36 -35
View File
@@ -1,44 +1,11 @@
import PageTools from '@/components/page-tools'; import PageTools from '@/components/page-tools';
import ProgressBar from '@/components/progress-bar'; import ProgressBar from '@/components/progress-bar';
import { useIntl } from '@umijs/max';
import { Col, Row, Table } from 'antd'; import { Col, Row, Table } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import { useContext } from 'react'; import { useContext } from 'react';
import { DashboardContext } from '../config/dashboard-context'; import { DashboardContext } from '../config/dashboard-context';
const modelColumns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name'
},
{
title: 'GPU Utilization',
dataIndex: 'gpu_utilization',
key: 'gpu_utilization',
render: (text: any, record: any) => (
<ProgressBar percent={_.round(text, 0)}></ProgressBar>
)
},
{
title: 'VRAM Utilization',
dataIndex: 'gpu_memory_utilization',
key: 'gpu_memory_utilization',
render: (text: any, record: any) => (
<ProgressBar percent={_.round(text, 0)}></ProgressBar>
)
},
{
title: 'Running Instances',
dataIndex: 'instance_count',
key: 'instance_count'
},
{
title: 'Tokens',
dataIndex: 'token_count',
key: 'token_count'
}
];
const projectColumns = [ const projectColumns = [
{ {
title: 'Name', title: 'Name',
@@ -102,7 +69,41 @@ const projectData = [
} }
]; ];
const ActiveTable = () => { const ActiveTable = () => {
const intl = useIntl();
const data = useContext(DashboardContext).active_models || []; const data = useContext(DashboardContext).active_models || [];
const modelColumns = [
{
title: intl.formatMessage({ id: 'dashboard.activeModels.name' }),
dataIndex: 'name',
key: 'name'
},
{
title: intl.formatMessage({ id: 'dashboard.gpuutilization' }),
dataIndex: 'gpu_utilization',
key: 'gpu_utilization',
render: (text: any, record: any) => (
<ProgressBar percent={_.round(text, 0)}></ProgressBar>
)
},
{
title: intl.formatMessage({ id: 'dashboard.vramutilization' }),
dataIndex: 'gpu_memory_utilization',
key: 'gpu_memory_utilization',
render: (text: any, record: any) => (
<ProgressBar percent={_.round(text, 0)}></ProgressBar>
)
},
{
title: intl.formatMessage({ id: 'dashboard.runninginstances' }),
dataIndex: 'instance_count',
key: 'instance_count'
},
{
title: 'Tokens',
dataIndex: 'token_count',
key: 'token_count'
}
];
return ( return (
<Row gutter={[20, 0]}> <Row gutter={[20, 0]}>
<Col xs={24} sm={24} md={24} lg={24} xl={24}> <Col xs={24} sm={24} md={24} lg={24} xl={24}>
@@ -112,7 +113,7 @@ const ActiveTable = () => {
<span <span
style={{ fontSize: 'var(--font-size-large)', padding: '9px 0' }} style={{ fontSize: 'var(--font-size-large)', padding: '9px 0' }}
> >
Active Models {intl.formatMessage({ id: 'dashboard.activeModels' })}
</span> </span>
} }
right={false} right={false}
+3 -1
View File
@@ -1,3 +1,4 @@
import { useIntl } from '@umijs/max';
import { Card, Col, Row, Space } from 'antd'; import { Card, Col, Row, Space } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import React, { useContext } from 'react'; import React, { useContext } from 'react';
@@ -26,6 +27,7 @@ const renderCardItem = (data: {
); );
}; };
const Overview: React.FC = () => { const Overview: React.FC = () => {
const intl = useIntl();
const data = useContext(DashboardContext).resource_counts || {}; const data = useContext(DashboardContext).resource_counts || {};
const renderValue = ( const renderValue = (
@@ -61,7 +63,7 @@ const Overview: React.FC = () => {
key={config.key} key={config.key}
> >
{renderCardItem({ {renderCardItem({
label: config.label, label: intl.formatMessage({ id: config.label }),
value: renderValue(_.get(data, config.key, 0)), value: renderValue(_.get(data, config.key, 0)),
bgColor: config.backgroundColor bgColor: config.backgroundColor
})} })}
@@ -1,32 +1,43 @@
import LineChart from '@/components/charts/line-chart'; import LineChart from '@/components/charts/line-chart';
import { getLocale, useIntl } from '@umijs/max';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import _ from 'lodash'; import _ from 'lodash';
import { useContext, useEffect, useState } from 'react'; import { useCallback, useContext, useEffect, useState } from 'react';
import { DashboardContext } from '../config/dashboard-context'; import { DashboardContext } from '../config/dashboard-context';
const TypeKeyMap = { const TypeKeyMap = {
cpu: { cpu: {
label: 'CPU', label: 'CPU',
type: 'CPU',
intl: false,
color: color:
'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)' 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)'
}, },
memory: { memory: {
label: 'Memory', label: 'dashboard.memory',
type: 'Memory',
intl: true,
color: color:
'linear-gradient(90deg,rgba(249, 248, 113,.8) 0%,rgba(255, 199, 92,0.7) 100%)' 'linear-gradient(90deg,rgba(249, 248, 113,.8) 0%,rgba(255, 199, 92,0.7) 100%)'
}, },
gpu: { gpu: {
label: 'GPU', label: 'GPU',
type: 'GPU',
intl: false,
color: 'rgba(84, 204, 152,0.8)' color: 'rgba(84, 204, 152,0.8)'
}, },
gpu_memory: { gpu_memory: {
label: 'VRAM', label: 'dashboard.vram',
type: 'VRAM',
intl: true,
color: color:
'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)' 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgba(0, 168, 143,.7) 100%)'
} }
}; };
const UtilizationOvertime: React.FC = () => { const UtilizationOvertime: React.FC = () => {
const intl = useIntl();
const locale = getLocale();
const data = useContext(DashboardContext)?.system_load?.history || {}; const data = useContext(DashboardContext)?.system_load?.history || {};
const [result, setResult] = useState< const [result, setResult] = useState<
{ time: string; value: number; type: string }[] { time: string; value: number; type: string }[]
@@ -52,30 +63,38 @@ const UtilizationOvertime: React.FC = () => {
const labelFormatter = (value: any) => { const labelFormatter = (value: any) => {
return `${value}%`; return `${value}%`;
}; };
const generateData = () => { const generateData = useCallback(() => {
const list: { value: number; time: string; type: string }[] = []; const list: { value: number; time: string; type: string }[] = [];
_.each(typeList, (type: any) => { _.each(typeList, (type: any) => {
const dataList = _.map(_.get(data, type, []), (item: any) => { const dataList = _.map(_.get(data, type, []), (item: any) => {
const value = _.get(item, 'value', 0);
const time = dayjs(item.timestamp * 1000).format('HH:mm:ss');
const itemtype = _.get(TypeKeyMap, [type, 'intl'], false)
? intl.formatMessage({
id: _.get(TypeKeyMap, [type, 'label'], '')
})
: _.get(TypeKeyMap, [type, 'label'], '');
return { return {
value: _.round(item.value, 2) || 0, value,
time: dayjs(item.timestamp * 1000).format('HH:mm:ss'), time,
type: _.get(TypeKeyMap, [type, 'label'], ''), type: itemtype,
color: 'red' color: 'red'
}; };
}); });
list.push(...dataList); list.push(...dataList);
}); });
setResult(list); setResult(list);
}; }, [data, locale]);
useEffect(() => { useEffect(() => {
generateData(); generateData();
}, [data]); }, [data, locale]);
return ( return (
<> <>
<LineChart <LineChart
data={result} data={result}
locale={locale}
labelFormatter={labelFormatter} labelFormatter={labelFormatter}
slider={sliderConfig} slider={sliderConfig}
/> />
+15 -5
View File
@@ -2,6 +2,7 @@ import CardWrapper from '@/components/card-wrapper';
import PageTools from '@/components/page-tools'; import PageTools from '@/components/page-tools';
import breakpoints from '@/config/breakpoints'; import breakpoints from '@/config/breakpoints';
import useWindowResize from '@/hooks/use-window-resize'; import useWindowResize from '@/hooks/use-window-resize';
import { useIntl } from '@umijs/max';
import { Col, DatePicker, Row } from 'antd'; import { Col, DatePicker, Row } from 'antd';
import _ from 'lodash'; import _ from 'lodash';
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect, useState } from 'react';
@@ -15,6 +16,7 @@ const SystemLoad = () => {
'linear-gradient(90deg, rgba(255, 214, 102,.8) 0%, rgba(255, 214, 102,0.5) 50%, rgba(255, 214, 102,.8) 100%)', 'linear-gradient(90deg, rgba(255, 214, 102,.8) 0%, rgba(255, 214, 102,0.5) 50%, rgba(255, 214, 102,.8) 100%)',
'linear-gradient(90deg, rgba(255, 120, 117,.8) 0%, rgba(255, 120, 117,0.5) 50%, rgba(255, 120, 117,.8) 100%)' 'linear-gradient(90deg, rgba(255, 120, 117,.8) 0%, rgba(255, 120, 117,0.5) 50%, rgba(255, 120, 117,.8) 100%)'
]; ];
const intl = useIntl();
const data = useContext(DashboardContext)?.system_load?.current || {}; const data = useContext(DashboardContext)?.system_load?.current || {};
const { size } = useWindowResize(); const { size } = useWindowResize();
const [paddingRight, setPaddingRight] = useState<string>('20px'); const [paddingRight, setPaddingRight] = useState<string>('20px');
@@ -40,7 +42,7 @@ const SystemLoad = () => {
style={{ margin: '32px 8px' }} style={{ margin: '32px 8px' }}
left={ left={
<span style={{ fontSize: 'var(--font-size-large)' }}> <span style={{ fontSize: 'var(--font-size-large)' }}>
System Load {intl.formatMessage({ id: 'dashboard.systemload' })}
</span> </span>
} }
right={ right={
@@ -65,25 +67,33 @@ const SystemLoad = () => {
<Row style={{ height: largeChartHeight, width: '100%' }}> <Row style={{ height: largeChartHeight, width: '100%' }}>
<Col span={12} style={{ height: smallChartHeight }}> <Col span={12} style={{ height: smallChartHeight }}>
<UitilBar <UitilBar
title="GPU Utilization" title={intl.formatMessage({
id: 'dashboard.gpuutilization'
})}
percent={_.round(data.gpu?.utilization_rate || 0, 1)} percent={_.round(data.gpu?.utilization_rate || 0, 1)}
></UitilBar> ></UitilBar>
</Col> </Col>
<Col span={12} style={{ height: smallChartHeight }}> <Col span={12} style={{ height: smallChartHeight }}>
<UitilBar <UitilBar
title="VRAM Utilization" title={intl.formatMessage({
id: 'dashboard.vramutilization'
})}
percent={_.round(data.gpu_memory?.utilization_rate || 0, 1)} percent={_.round(data.gpu_memory?.utilization_rate || 0, 1)}
></UitilBar> ></UitilBar>
</Col> </Col>
<Col span={12} style={{ height: smallChartHeight }}> <Col span={12} style={{ height: smallChartHeight }}>
<UitilBar <UitilBar
title="CPU Utilization" title={intl.formatMessage({
id: 'dashboard.cpuutilization'
})}
percent={_.round(data.cpu?.utilization_rate || 0, 1)} percent={_.round(data.cpu?.utilization_rate || 0, 1)}
></UitilBar> ></UitilBar>
</Col> </Col>
<Col span={12} style={{ height: smallChartHeight }}> <Col span={12} style={{ height: smallChartHeight }}>
<UitilBar <UitilBar
title="CPU Memory Utilization" title={intl.formatMessage({
id: 'dashboard.memoryutilization'
})}
percent={_.round(data.memory?.utilization_rate || 0, 1)} percent={_.round(data.memory?.utilization_rate || 0, 1)}
></UitilBar> ></UitilBar>
</Col> </Col>
+15 -8
View File
@@ -5,6 +5,7 @@ import PageTools from '@/components/page-tools';
import breakpoints from '@/config/breakpoints'; import breakpoints from '@/config/breakpoints';
import useWindowResize from '@/hooks/use-window-resize'; import useWindowResize from '@/hooks/use-window-resize';
import { generateRandomArray } from '@/utils'; import { generateRandomArray } from '@/utils';
import { useIntl } from '@umijs/max';
import { Col, DatePicker, Row } from 'antd'; import { Col, DatePicker, Row } from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import _ from 'lodash'; import _ from 'lodash';
@@ -93,6 +94,7 @@ const tokenUsage = TokensData.map((val, i) => {
}); });
const Usage = () => { const Usage = () => {
const intl = useIntl();
const { size } = useWindowResize(); const { size } = useWindowResize();
const [paddingRight, setPaddingRight] = useState<string>('20px'); const [paddingRight, setPaddingRight] = useState<string>('20px');
const [requestData, setRequestData] = useState< const [requestData, setRequestData] = useState<
@@ -125,14 +127,14 @@ const Usage = () => {
_.each(data.api_request_history, (item: any) => { _.each(data.api_request_history, (item: any) => {
requestList.push({ requestList.push({
time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD'), time: dayjs(item.timestamp * 1000).format('YYYY-MM'),
value: item.value value: item.value
}); });
}); });
_.each(data.completion_token_history, (item: any) => { _.each(data.completion_token_history, (item: any) => {
tokenList.push({ tokenList.push({
time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD'), time: dayjs(item.timestamp * 1000).format('YYYY-MM'),
name: 'completion_token', name: 'completion_token',
color: 'rgba(84, 204, 152,0.8)', color: 'rgba(84, 204, 152,0.8)',
value: item.value value: item.value
@@ -140,7 +142,7 @@ const Usage = () => {
}); });
_.each(data.prompt_token_history, (item: any) => { _.each(data.prompt_token_history, (item: any) => {
tokenList.push({ tokenList.push({
time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD'), time: dayjs(item.timestamp * 1000).format('YYYY-MM'),
name: 'prompt_token', name: 'prompt_token',
color: 'rgba(0, 170, 173, 0.8)', color: 'rgba(0, 170, 173, 0.8)',
value: item.value value: item.value
@@ -183,7 +185,11 @@ const Usage = () => {
<> <>
<PageTools <PageTools
style={{ margin: '32px 8px' }} style={{ margin: '32px 8px' }}
left={<span style={{ fontSize: 'var(--font-size-large)' }}>Usage</span>} left={
<span style={{ fontSize: 'var(--font-size-large)' }}>
{intl.formatMessage({ id: 'dashboard.usage' })}
</span>
}
right={ right={
<RangePicker onChange={handleSelectDate} style={{ width: 300 }} /> <RangePicker onChange={handleSelectDate} style={{ width: 300 }} />
} }
@@ -201,7 +207,7 @@ const Usage = () => {
<Row style={{ width: '100%' }}> <Row style={{ width: '100%' }}>
<Col span={12}> <Col span={12}>
<ColumnBar <ColumnBar
title="API Request" title={intl.formatMessage({ id: 'dashboard.apirequest' })}
data={requestData} data={requestData}
xField="time" xField="time"
yField="value" yField="value"
@@ -210,7 +216,7 @@ const Usage = () => {
</Col> </Col>
<Col span={12}> <Col span={12}>
<ColumnBar <ColumnBar
title="Tokens" title={intl.formatMessage({ id: 'dashboard.tokens' })}
data={tokenData} data={tokenData}
group={false} group={false}
colorField="name" colorField="name"
@@ -227,11 +233,12 @@ const Usage = () => {
<Col xs={24} sm={24} md={24} lg={24} xl={8}> <Col xs={24} sm={24} md={24} lg={24} xl={8}>
<CardWrapper> <CardWrapper>
<HBar <HBar
title="Top Users" title={intl.formatMessage({ id: 'dashboard.topusers' })}
data={userData} data={userData}
colorField="type"
stack={true} stack={true}
legend={false} legend={false}
showYAxis={false}
colorField="type"
xField="name" xField="name"
yField="value" yField="value"
height={360} height={360}
+5 -5
View File
@@ -1,31 +1,31 @@
export const overviewConfigs = [ export const overviewConfigs = [
{ {
key: 'workworker_count', key: 'workworker_count',
label: 'Workers', label: 'dashboard.workers',
// backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))' // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
backgroundColor: 'var(--color-white-1)' backgroundColor: 'var(--color-white-1)'
}, },
{ {
key: 'gpu_count', key: 'gpu_count',
label: 'Total GPUs', label: 'dashboard.totalgpus',
backgroundColor: 'var(--color-white-1)' backgroundColor: 'var(--color-white-1)'
// backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))' // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
}, },
{ {
key: 'allocatedGpus', key: 'allocatedGpus',
label: 'Allocated GPUs', label: 'dashboard.allocategpus',
backgroundColor: 'var(--color-white-1)' backgroundColor: 'var(--color-white-1)'
// backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))' // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
}, },
{ {
key: 'model_count', key: 'model_count',
label: 'Models', label: 'dashboard.models',
backgroundColor: 'var(--color-white-1)' backgroundColor: 'var(--color-white-1)'
// backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))' // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
}, },
{ {
key: 'model_instance_count', key: 'model_instance_count',
label: 'Instances', label: 'dashboard.instances',
backgroundColor: 'var(--color-white-1)' backgroundColor: 'var(--color-white-1)'
// backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))' // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
} }
+1 -4
View File
@@ -372,10 +372,7 @@ const Models: React.FC = () => {
useEffect(() => { useEffect(() => {
fetchData(); fetchData();
setTimeout(() => { createModelsChunkRequest();
createModelsChunkRequest();
}, 1000);
return () => { return () => {
chunkRequedtRef.current?.current?.cancel?.(); chunkRequedtRef.current?.current?.cancel?.();
}; };
+3 -4
View File
@@ -76,10 +76,9 @@ const PasswordForm: React.FC = () => {
{ {
required: true, required: true,
pattern: PasswordReg, pattern: PasswordReg,
message: intl.formatMessage( message: intl.formatMessage({
{ id: 'common.form.rule.input' }, id: 'users.form.rule.password'
{ name: intl.formatMessage({ id: 'users.form.newpassword' }) } })
)
} }
]} ]}
> >
+21 -100
View File
@@ -12,97 +12,6 @@ import { queryGpuDevicesList } from '../apis';
import { GPUDeviceItem } from '../config/types'; import { GPUDeviceItem } from '../config/types';
const { Column } = Table; const { Column } = Table;
const dataSource: GPUDeviceItem[] = [
{
id: 1,
name: 'bj-web-service-1',
address: '183.14.31.136',
hostname: 'bj-web-service-1',
labels: {},
resources: {
capacity: {
cpu: 4,
gpu: 2,
memory: '64 GiB',
gram: '24 Gib'
},
allocable: {
cpu: 2.5,
gpu: 1.6,
memory: '64',
gram: '24 Gib'
}
},
state: 'ACTIVE'
},
{
id: 2,
name: 'bj-db-service-2',
address: '172.24.1.36',
hostname: 'bj-db-service-2',
labels: {},
resources: {
capacity: {
cpu: 4,
gpu: 2,
memory: '64 GiB',
gram: '24 Gib'
},
allocable: {
cpu: 2,
gpu: 1.5,
memory: '32 GiB',
gram: '12 Gib'
}
},
state: 'ACTIVE'
},
{
id: 3,
name: 'guangzhou-computed-node-2',
address: '170.10.2.10',
hostname: 'guangzhou-computed-node-2',
labels: {},
resources: {
capacity: {
cpu: 8,
gpu: 4,
memory: '64 GiB',
gram: '24 Gib'
},
allocable: {
cpu: 2,
gpu: 1.5,
memory: '32 GiB',
gram: '12 Gib'
}
},
state: 'ACTIVE'
},
{
id: 4,
name: 'hangzhou-cache-node-1',
address: '115.2.21.10',
hostname: 'hangzhou-cache-node-1',
labels: {},
resources: {
capacity: {
cpu: 8,
gpu: 4,
memory: '64 GiB',
gram: '24 Gib'
},
allocable: {
cpu: 4,
gpu: 2.5,
memory: '40 GiB',
gram: '16 Gib'
}
},
state: 'ACTIVE'
}
];
const Models: React.FC = () => { const Models: React.FC = () => {
const intl = useIntl(); const intl = useIntl();
const rowSelection = useTableRowSelection(); const rowSelection = useTableRowSelection();
@@ -205,20 +114,32 @@ const Models: React.FC = () => {
onChange: handlePageChange onChange: handlePageChange
}} }}
> >
<Column title="Name" dataIndex="name" key="name" />
<Column <Column
title="Index" title={intl.formatMessage({ id: 'common.table.name' })}
dataIndex="name"
key="name"
/>
<Column
title={intl.formatMessage({ id: 'resources.table.index' })}
dataIndex="index" dataIndex="index"
key="index" key="index"
render={(text, record: GPUDeviceItem) => { render={(text, record: GPUDeviceItem) => {
return <span>{record.index}</span>; return <span>{record.index}</span>;
}} }}
/> />
<Column title="Worker Name" dataIndex="worker_name" key="worker_name" /> <Column
<Column title="Vendor" dataIndex="vendor" key="vendor" /> title={intl.formatMessage({ id: 'resources.table.workername' })}
dataIndex="worker_name"
key="worker_name"
/>
<Column
title={intl.formatMessage({ id: 'resources.table.vender' })}
dataIndex="vendor"
key="vendor"
/>
<Column <Column
title="Temperature(˚C)" title={`${intl.formatMessage({ id: 'resources.table.temperature' })} (°C)`}
dataIndex="temperature" dataIndex="temperature"
key="Temperature" key="Temperature"
render={(text, record: GPUDeviceItem) => { render={(text, record: GPUDeviceItem) => {
@@ -226,7 +147,7 @@ const Models: React.FC = () => {
}} }}
/> />
<Column <Column
title="Core" title={intl.formatMessage({ id: 'resources.table.core' })}
dataIndex="core" dataIndex="core"
key="Core" key="Core"
render={(text, record: GPUDeviceItem) => { render={(text, record: GPUDeviceItem) => {
@@ -234,7 +155,7 @@ const Models: React.FC = () => {
}} }}
/> />
<Column <Column
title="GPU Utilization" title={intl.formatMessage({ id: 'resources.table.gpuutilization' })}
dataIndex="gpuUtil" dataIndex="gpuUtil"
key="gpuUtil" key="gpuUtil"
render={(text, record: GPUDeviceItem) => { render={(text, record: GPUDeviceItem) => {
@@ -247,8 +168,8 @@ const Models: React.FC = () => {
/> />
<Column <Column
title="VRAM" title={intl.formatMessage({ id: 'resources.table.vramutilization' })}
dataIndex="GRAM" dataIndex="VRAM"
key="VRAM" key="VRAM"
render={(text, record: GPUDeviceItem) => { render={(text, record: GPUDeviceItem) => {
return ( return (
+1 -1
View File
@@ -13,7 +13,7 @@ export const requestConfig: RequestConfig = {
errorHandler: (error: any, opts: any) => { errorHandler: (error: any, opts: any) => {
const { message: errorMessage, response } = error; const { message: errorMessage, response } = error;
const errMsg = response?.data?.message || errorMessage; const errMsg = response?.data?.message || errorMessage;
if (!opts?.skipErrorHandler) { if (!opts?.skipErrorHandler && response?.status) {
message.error(errMsg); message.error(errMsg);
} }
console.log('errorHandler+++++++++++++++', error, opts); console.log('errorHandler+++++++++++++++', error, opts);