chore: dashbord ui

main
jialin 2 years ago
parent 8d35ce0380
commit 246d203e36

@ -7,7 +7,7 @@ const DeleteCssPlugin = require('./plugins/delete-css-plugin');
import proxy from './proxy';
import routes from './routes';
const env = process.env.NODE_ENV;
const isProduction = env === 'production';
const isProduction = env === 'production1';
export default defineConfig({
proxy: {
@ -48,11 +48,11 @@ export default defineConfig({
ignoreOrder: true
}
]);
config.plugin('delete-css').use(DeleteCssPlugin, [
{
outputPath: path.resolve(__dirname, '../', 'dist')
}
]);
// config.plugin('delete-css').use(DeleteCssPlugin, [
// {
// outputPath: path.resolve(__dirname, '../', 'dist')
// }
// ]);
config.output
.filename('js/[name].[contenthash:8].js')
.chunkFilename('js/[name].[contenthash:8].chunk.js');

@ -13,7 +13,6 @@ const BarChart: React.FC<BarChartProps> = (props) => {
data,
xField,
yField,
title,
// colorField: 'name',
direction: 'vertical',
height,
@ -31,7 +30,12 @@ const BarChart: React.FC<BarChartProps> = (props) => {
xAxis: true
}
},
title: {
title,
style: {
align: 'center'
}
},
split: {
type: 'line',
line: {
@ -44,7 +48,7 @@ const BarChart: React.FC<BarChartProps> = (props) => {
},
style: {
fill: '#2fbf85',
fill: '#54cc98',
radiusTopLeft: 8,
radiusTopRight: 8,
width: 30

@ -0,0 +1,47 @@
import { Gauge } from '@ant-design/plots';
import React from 'react';
interface GaugeChartProps {
target: number;
total: number;
width?: number;
height?: number;
title?: string;
thresholds: number[];
rangColor: string[];
}
const GaugeChart: React.FC<GaugeChartProps> = (props) => {
const { target, total, width, height, thresholds, rangColor, title } = props;
const config = {
width,
height,
autoFit: true,
data: {
target,
total,
name: 'score',
thresholds
},
legend: false,
scale: {
color: {
range: rangColor
}
},
title: {
titleFontSize: 14,
style: {
align: 'center'
}
},
style: {
textContent: (target: number, total: number) => {
return `${(target / total) * 100}%`;
}
}
};
return <Gauge {...config} />;
};
export default GaugeChart;

@ -13,7 +13,6 @@ const BarChart: React.FC<BarChartProps> = (props) => {
data,
xField,
yField,
title,
// colorField: 'name',
direction: 'vertical',
height,
@ -31,7 +30,12 @@ const BarChart: React.FC<BarChartProps> = (props) => {
xAxis: true
}
},
title: {
title,
style: {
align: 'center'
}
},
split: {
type: 'line',
line: {
@ -44,7 +48,7 @@ const BarChart: React.FC<BarChartProps> = (props) => {
},
style: {
fill: '#2fbf85',
fill: '#54cc98',
radiusTopLeft: 8,
radiusTopRight: 8,
height: 30

@ -0,0 +1,58 @@
import { Line } from '@ant-design/plots';
interface LineChartProps {
title?: string;
height?: number;
data: any[];
color?: string[];
xField?: string;
yField?: string;
slider?: boolean;
}
const LineChart: React.FC<LineChartProps> = (props) => {
const { data, title, color, xField, yField, slider, height } = props;
const config = {
title,
height,
xField: xField || 'time',
yField: yField || 'value',
color: color || ['red', 'blue', 'green'],
colorField: 'type',
autoFit: true,
slider,
shapeField: 'smooth',
axis: {
x: {
textStyle: {
autoRoate: true
}
}
},
point: {
shapeField: 'circle',
sizeField: 2
},
style: {
lineWidth: 1.5
},
legend: {
itemMarker: {
symbol: 'circle'
},
color: {
layout: { justifyContent: 'center' }
}
},
tooltip: {
title: 'time',
items: [{ channel: 'y' }]
}
};
return (
<>
<Line data={data} {...config} />
</>
);
};
export default LineChart;

@ -26,6 +26,9 @@ html {
--ant-table-row-selected-bg: #f0fff6;
--ant-table-row-selected-hover-bg: #d8f2e4;
--ant-table-row-hover-bg: #e6e6e6;
--color-chart-red: #ff7875;
--color-chart-green: #54cc98;
--color-chart-glod: #ffd666;
// --color-text-1: #000;
--seal-transition-func: cubic-bezier(0, 0, 1, 1);

@ -0,0 +1,161 @@
import ContentWrapper from '@/components/content-wrapper';
import { Col, Row, Table } from 'antd';
const modelColumns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name'
},
{
title: 'Allocated GPUs',
dataIndex: 'allocated',
key: 'allocated',
render: (text: any, record: any) => <span>{record.gpu.allocated}</span>
},
{
title: 'GPU Utilization',
dataIndex: 'utilization',
key: 'utilization',
render: (text: any, record: any) => <span>{record.gpu.utilization}</span>
},
{
title: 'Running Instances',
dataIndex: 'running',
key: 'running',
render: (text: any, record: any) => <span>{record.instances.running}</span>
},
{
title: 'Pending Instances',
dataIndex: 'pending',
key: 'pending',
render: (text: any, record: any) => <span>{record.instances.pending}</span>
}
];
const projectColumns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name'
},
{
title: 'Token Quota',
dataIndex: 'quota',
key: 'quota'
},
{
title: 'Token Utilization',
dataIndex: 'utilization',
key: 'utilization'
},
{
title: 'Members',
dataIndex: 'members',
key: 'members'
}
];
const modelData = [
{
id: 1,
name: 'qwen2',
gpu: { allocated: 4, utilization: '50%' },
instances: { running: 1, pending: 0 }
},
{
id: 2,
name: 'llama3:70b',
gpu: { allocated: 3, utilization: '70%' },
instances: { running: 1, pending: 0 }
},
{
id: 3,
name: 'llama3',
gpu: { allocated: 5, utilization: '20%' },
instances: { running: 1, pending: 0 }
},
{
id: 4,
name: 'gemma',
gpu: { allocated: 1, utilization: '25%' },
instances: { running: 1, pending: 0 }
},
{
id: 5,
name: 'phi3',
gpu: { allocated: 2, utilization: '46%' },
instances: { running: 1, pending: 0 }
}
];
const projectData = [
{
id: 1,
name: 'copilot-dev',
quota: 100,
utilization: 50,
members: 4
},
{
id: 2,
name: 'rag-wiki',
quota: 200,
utilization: 70,
members: 3
},
{
id: 3,
name: 'smart-auto-agent',
quota: 100,
utilization: 20,
members: 5
},
{
id: 4,
name: 'office-auto-docs',
quota: 100,
utilization: 25,
members: 1
},
{
id: 5,
name: 'smart-customer-service',
quota: 100,
utilization: 46,
members: 2
}
];
const ActiveTable = () => {
return (
<Row>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Active Models</span>}
>
<Table
columns={modelColumns}
dataSource={modelData}
pagination={false}
rowKey="id"
/>
</ContentWrapper>
</Col>
<Col span={12}>
<ContentWrapper
title={<span style={{ lineHeight: '48px' }}>Active Projects</span>}
>
<Table
columns={projectColumns}
dataSource={projectData}
pagination={false}
rowKey="id"
/>
</ContentWrapper>
</Col>
</Row>
);
};
export default ActiveTable;

@ -1,6 +1,5 @@
import PageTools from '@/components/page-tools';
import LineChart from '@/components/charts/line-chart';
import { generateRandomArray } from '@/utils';
import { Line } from '@ant-design/plots';
import _ from 'lodash';
const mockData = {
@ -43,50 +42,10 @@ const UtilizationOvertime: React.FC = () => {
};
const data = generateData();
const handleSelectDate = (date: string) => {
console.log('dateString============', date);
};
const config = {
// title: 'Resource Utilization',
xField: 'time',
yField: 'value',
color: ['red', 'blue', 'green'],
colorField: 'type',
autoFit: true,
slider: false,
shapeField: 'smooth',
axis: {
x: {
textStyle: {
autoRoate: true
}
}
},
point: {
shapeField: 'circle',
sizeField: 2
},
style: {
lineWidth: 1.4
},
legend: {
color: {
layout: { justifyContent: 'center' }
}
},
tooltip: {
title: 'time',
items: [{ channel: 'y' }]
}
// label: {
// autoRotate: true
// }
};
// <DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
return (
<>
<PageTools marginBottom={10} marginTop={0} left={false} right={false} />
<Line height={400} data={data} {...config} />
<LineChart height={400} data={data} />
</>
);
};

@ -0,0 +1,68 @@
import GaugeChart from '@/components/charts/gauge';
import PageTools from '@/components/page-tools';
import { Col, DatePicker, Row } from 'antd';
import ResourceUtilization from './resource-utilization';
const SystemLoad = () => {
const handleSelectDate = (date: string) => {
console.log('dateString============', date);
};
return (
<div className="system-load">
<PageTools
marginBottom={10}
marginTop={0}
left={false}
right={
<DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
}
/>
<ResourceUtilization />
<Row style={{ width: '100%' }}>
<Col span={6}>
<GaugeChart
title="GPU Compute Utilization"
total={100}
target={20}
// height={320}
thresholds={[50, 70, 100]}
rangColor={['#54cc98', '#ffd666', '#ff7875']}
></GaugeChart>
</Col>
<Col span={6}>
<GaugeChart
title="GPU Memory Utilization"
total={100}
target={30}
// height={320}
thresholds={[50, 70, 100]}
rangColor={['#54cc98', '#ffd666', '#ff7875']}
></GaugeChart>
</Col>
<Col span={6}>
<GaugeChart
title="CPU Compute Utilization"
total={100}
target={40}
// height={320}
thresholds={[50, 70, 100]}
rangColor={['#54cc98', '#ffd666', '#ff7875']}
></GaugeChart>
</Col>
<Col span={6}>
<GaugeChart
title="CPU Memory Utilization"
total={100}
target={70}
// height={320}
thresholds={[50, 70, 100]}
rangColor={['#54cc98', '#ffd666', '#ff7875']}
></GaugeChart>
</Col>
</Row>
</div>
);
};
export default SystemLoad;

@ -0,0 +1,156 @@
import ColumnBar from '@/components/charts/column-bar';
import HBar from '@/components/charts/h-bar';
import PageTools from '@/components/page-tools';
import { generateRandomArray } from '@/utils';
import { PageContainer } from '@ant-design/pro-components';
import { Col, DatePicker, Row } from 'antd';
const times = [
'june 1',
'june 2',
'june 3',
'june 4',
'june 5',
'june 6',
'june 7'
];
const users = ['Jim', 'Lucy', 'Lily', 'Tom', 'Jack', 'Rose', 'Jerry'];
const projects = [
'copilot-dev',
'rag-wiki',
'smart-auto-agent',
'office-auto-docs',
'smart-customer-service'
];
const APIRequestData = generateRandomArray({
length: times.length,
max: 100,
min: 0,
offset: 10
});
const TokensData = generateRandomArray({
length: times.length,
max: 2000,
min: 200,
offset: 200
});
const usersData = generateRandomArray({
length: users.length,
max: 100,
min: 0,
offset: 10
});
const projectsData = generateRandomArray({
length: projects.length,
max: 100,
min: 0,
offset: 10
});
const userDataList = usersData
.map((val, i) => {
return {
time: users[i],
value: val
};
})
.sort((a, b) => b.value - a.value);
const projectDataList = projectsData
.map((val, i) => {
return {
time: projects[i],
value: val
};
})
.sort((a, b) => b.value - a.value);
const dataList = APIRequestData.map((val, i) => {
console.log('val', val);
return {
time: times[i],
value: val
};
});
const tokenUsage = TokensData.map((val, i) => {
console.log('val', val);
return {
time: times[i],
value: val
};
});
const Usage = () => {
const handleSelectDate = (dateString: string) => {
console.log('dateString============', dateString);
};
return (
<>
<PageContainer ghost title="Usage">
<PageTools
marginBottom={10}
marginTop={0}
left={false}
right={
<DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
}
/>
</PageContainer>
<Row style={{ width: '100%' }}>
<Col span={12}>
<PageContainer title={false}>
<ColumnBar
title="API Request"
data={dataList}
xField="time"
yField="value"
height={360}
></ColumnBar>
</PageContainer>
</Col>
<Col span={12}>
<PageContainer title={false}>
<ColumnBar
title="Tokens"
data={tokenUsage}
xField="time"
yField="value"
height={360}
></ColumnBar>
</PageContainer>
</Col>
</Row>
<Row style={{ width: '100%' }}>
<Col span={12}>
<PageContainer title={false}>
<HBar
title="Top Users"
data={userDataList}
xField="time"
yField="value"
height={360}
></HBar>
</PageContainer>
</Col>
<Col span={12}>
<PageContainer title={false}>
<HBar
title="Top Projects"
data={projectDataList}
xField="time"
yField="value"
height={360}
></HBar>
</PageContainer>
</Col>
</Row>
</>
);
};
export default Usage;

@ -1,94 +1,10 @@
import BarChart from '@/components/bar-chart';
import HBar from '@/components/bar-chart/h-bar';
import ContentWrapper from '@/components/content-wrapper';
import DividerLine from '@/components/divider-line';
import PageTools from '@/components/page-tools';
import { generateRandomArray } from '@/utils';
import { PageContainer } from '@ant-design/pro-components';
import { Col, Row } from 'antd';
import GPUUtilization from './components/gpu-utilization';
import ActiveTable from './components/active-table';
import Overview from './components/over-view';
import UtilizationOvertime from './components/utilization-overtime';
import SystemLoad from './components/system-load';
import Usage from './components/usage';
const times = [
'june 1',
'june 2',
'june 3',
'june 4',
'june 5',
'june 6',
'june 7'
];
const users = ['Jim', 'Lucy', 'Lily', 'Tom', 'Jack', 'Rose', 'Jerry'];
const projects = [
'copilot-dev',
'rag-wiki',
'smart-auto-agent',
'office-auto-docs',
'smart-customer-service'
];
const APIRequestData = generateRandomArray({
length: times.length,
max: 100,
min: 0,
offset: 10
});
const TokensData = generateRandomArray({
length: times.length,
max: 2000,
min: 200,
offset: 200
});
const usersData = generateRandomArray({
length: users.length,
max: 100,
min: 0,
offset: 10
});
const projectsData = generateRandomArray({
length: projects.length,
max: 100,
min: 0,
offset: 10
});
const userDataList = usersData
.map((val, i) => {
return {
time: users[i],
value: val
};
})
.sort((a, b) => b.value - a.value);
const projectDataList = projectsData
.map((val, i) => {
return {
time: projects[i],
value: val
};
})
.sort((a, b) => b.value - a.value);
const dataList = APIRequestData.map((val, i) => {
console.log('val', val);
return {
time: times[i],
value: val
};
});
const tokenUsage = TokensData.map((val, i) => {
console.log('val', val);
return {
time: times[i],
value: val
};
});
const Dashboard: React.FC = () => {
return (
<>
@ -97,97 +13,12 @@ const Dashboard: React.FC = () => {
</PageContainer>
<DividerLine></DividerLine>
<PageContainer ghost title="System Load">
<UtilizationOvertime></UtilizationOvertime>
<SystemLoad></SystemLoad>
</PageContainer>
<DividerLine></DividerLine>
<PageContainer ghost title={false}>
<Row gutter={20} style={{ marginTop: '0px' }}>
<Col span={12}>
<PageTools
marginBottom={10}
marginTop={0}
left={
<div
style={{
height: '34px',
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center'
}}
>
VRAM
</div>
}
></PageTools>
<GPUUtilization></GPUUtilization>
</Col>
<Col span={12}>
<PageTools
marginBottom={10}
marginTop={0}
left={
<div
style={{
height: '34px',
display: 'flex',
alignItems: 'center'
}}
>
GPU Utilization
</div>
}
></PageTools>
<GPUUtilization></GPUUtilization>
</Col>
</Row>
</PageContainer>
<Usage></Usage>
<DividerLine></DividerLine>
<Row gutter={10}>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>API Request</span>}
>
<BarChart data={dataList} xField="time" yField="value"></BarChart>
</ContentWrapper>
</Col>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Tokens</span>}
>
<BarChart data={tokenUsage} xField="time" yField="value"></BarChart>
</ContentWrapper>
</Col>
</Row>
<Row gutter={10}>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Top Users</span>}
>
<HBar
data={userDataList}
xField="time"
yField="value"
height={360}
></HBar>
</ContentWrapper>
</Col>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Top Projects</span>}
>
<HBar
data={projectDataList}
xField="time"
yField="value"
height={300}
></HBar>
</ContentWrapper>
</Col>
</Row>
<ActiveTable></ActiveTable>
</>
);
};

Loading…
Cancel
Save