feat: benchmark detail page

This commit is contained in:
jialin
2026-01-30 18:48:55 +08:00
parent fb0e45ebed
commit 9ab8f233a2
17 changed files with 281 additions and 55 deletions
+1
View File
@@ -122,6 +122,7 @@ export default [
icon: 'icon-speed',
selectedIcon: 'icon-speed-filled',
defaultIcon: 'icon-speed',
access: 'canSeeAdmin',
component: './benchmark/index'
}
]
+44 -46
View File
@@ -107,7 +107,47 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
} = props;
const intl = useIntl();
const renderRight = useMemo(() => {
const renderLeft = () => {
return (
<Space>
<Input
prefix={
<SearchOutlined
style={{ color: 'var(--ant-color-text-placeholder)' }}
></SearchOutlined>
}
placeholder={
inputHolder ||
intl.formatMessage({
id: 'common.filter.name'
})
}
style={{ width: widths?.input || 230 }}
allowClear
onChange={handleInputChange}
></Input>
{showSelect && (
<BaseSelect
allowClear
showSearch={false}
placeholder={selectHolder}
style={{ width: widths?.select || 230 }}
size="large"
onChange={handleSelectChange}
options={selectOptions}
></BaseSelect>
)}
<Button
type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }}
onClick={handleSearch}
icon={<SyncOutlined></SyncOutlined>}
></Button>
</Space>
);
};
const renderRight = () => {
if (!handleClickPrimary && !handleDeleteByBatch) {
return null;
}
@@ -156,56 +196,14 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
)}
</Space>
);
}, [
actionItems,
actionType,
rowSelection?.selectedRowKeys,
handleClickPrimary,
intl
]);
};
return (
<PageTools
marginBottom={marginBottom}
marginTop={0}
left={
<Space>
<Input
prefix={
<SearchOutlined
style={{ color: 'var(--ant-color-text-placeholder)' }}
></SearchOutlined>
}
placeholder={
inputHolder ||
intl.formatMessage({
id: 'common.filter.name'
})
}
style={{ width: widths?.input || 230 }}
allowClear
onChange={handleInputChange}
></Input>
{showSelect && (
<BaseSelect
allowClear
showSearch={false}
placeholder={selectHolder}
style={{ width: widths?.select || 230 }}
size="large"
onChange={handleSelectChange}
options={selectOptions}
></BaseSelect>
)}
<Button
type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }}
onClick={handleSearch}
icon={<SyncOutlined></SyncOutlined>}
></Button>
</Space>
}
right={right || renderRight}
left={left || renderLeft()}
right={right || renderRight()}
></PageTools>
);
};
+5 -1
View File
@@ -22,5 +22,9 @@ export default {
'benchmark.form.profile.heavy': 'Generation Heavy',
'benchmark.form.profile.custom': 'Custom',
'benchmark.table.inputTokenLength': 'Input Token Length',
'benchmark.table.outputTokenLength': 'Output Token Length'
'benchmark.table.outputTokenLength': 'Output Token Length',
'benchmark.detail.summary.title': 'Summary',
'benchmark.detail.configure.title': 'Configure',
'benchmark.detail.environment.title': 'Environment',
'benchmark.detail.logs.title': 'Logs'
};
+5 -1
View File
@@ -22,5 +22,9 @@ export default {
'benchmark.form.profile.heavy': 'Generation Heavy',
'benchmark.form.profile.custom': 'Custom',
'benchmark.table.inputTokenLength': 'Input Token Length',
'benchmark.table.outputTokenLength': 'Output Token Length'
'benchmark.table.outputTokenLength': 'Output Token Length',
'benchmark.detail.summary.title': 'Summary',
'benchmark.detail.configure.title': 'Configure',
'benchmark.detail.environment.title': 'Environment',
'benchmark.detail.logs.title': 'Logs'
};
+5 -1
View File
@@ -22,5 +22,9 @@ export default {
'benchmark.form.profile.heavy': 'Generation Heavy',
'benchmark.form.profile.custom': 'Custom',
'benchmark.table.inputTokenLength': 'Input Token Length',
'benchmark.table.outputTokenLength': 'Output Token Length'
'benchmark.table.outputTokenLength': 'Output Token Length',
'benchmark.detail.summary.title': 'Summary',
'benchmark.detail.configure.title': 'Configure',
'benchmark.detail.environment.title': 'Environment',
'benchmark.detail.logs.title': 'Logs'
};
+5 -1
View File
@@ -22,5 +22,9 @@ export default {
'benchmark.form.profile.heavy': '高生成量',
'benchmark.form.profile.custom': '自定义',
'benchmark.table.inputTokenLength': '输入 Token 长度',
'benchmark.table.outputTokenLength': '输出 Token 长度'
'benchmark.table.outputTokenLength': '输出 Token 长度',
'benchmark.detail.summary.title': '摘要',
'benchmark.detail.configure.title': '配置',
'benchmark.detail.environment.title': '环境',
'benchmark.detail.logs.title': '日志'
};
@@ -0,0 +1,49 @@
import { useHover } from 'ahooks';
import { Popover } from 'antd';
import { useRef, useState } from 'react';
import styled from 'styled-components';
const Container = styled.div`
display: flex;
align-items: center;
border: 1px solid var(--ant-color-border);
border-radius: 4px;
padding: 8.5px 11px;
height: 40px;
width: 240px;
cursor: pointer;
&:hover {
border-color: var(--ant-color-primary-hover);
}
&:active {
box-shadow: var(--ant-input-active-shadow);
}
.holder {
color: var(--ant-color-text-placeholder);
}
`;
const CompareConditions: React.FC = () => {
const [open, setOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const isHovering = useHover(containerRef);
return (
<Popover
trigger={'click'}
content="Compare Conditions Content"
arrow={false}
placement="bottom"
styles={{
root: {
width: '240px'
}
}}
>
<Container>
<span className="holder">Compare Filter</span>
</Container>
</Popover>
);
};
export default CompareConditions;
@@ -0,0 +1,9 @@
import React from 'react';
import { useDetailContext } from '../../config/detail-context';
const Configure: React.FC = () => {
const { detailData } = useDetailContext();
return <div>Configure Content</div>;
};
export default Configure;
@@ -0,0 +1,9 @@
import React from 'react';
import { useDetailContext } from '../../config/detail-context';
const Environment: React.FC = () => {
const { detailData } = useDetailContext();
return <div>Environment Content</div>;
};
export default Environment;
@@ -0,0 +1,44 @@
import { SearchOutlined, SyncOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Input, Space } from 'antd';
import React from 'react';
import CompareConditions from './compare-conditions';
export interface RightActionsProps {
handleInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
handleSearch: () => void;
}
const RightActions: React.FC<RightActionsProps> = ({
handleInputChange,
handleSearch
}) => {
const intl = useIntl();
return (
<Space>
<Input
prefix={
<SearchOutlined
style={{ color: 'var(--ant-color-text-placeholder)' }}
></SearchOutlined>
}
placeholder={intl.formatMessage({
id: 'common.filter.name'
})}
style={{ width: 230 }}
allowClear
onChange={handleInputChange}
></Input>
<CompareConditions></CompareConditions>
<Button
type="text"
style={{ color: 'var(--ant-color-text-tertiary)' }}
onClick={handleSearch}
icon={<SyncOutlined></SyncOutlined>}
></Button>
</Space>
);
};
export default RightActions;
@@ -0,0 +1,9 @@
import React from 'react';
import { useDetailContext } from '../../config/detail-context';
const Logs: React.FC = () => {
const { id } = useDetailContext();
return <div>Logs Content</div>;
};
export default Logs;
@@ -11,7 +11,6 @@ export interface RightActionsProps {
handleDeleteByBatch: () => void;
handleClickPrimary?: () => void;
handleSettingFields?: () => void;
handleCompare?: () => void;
buttonText?: string;
rowSelection: {
selectedRowKeys: React.Key[];
@@ -21,7 +20,6 @@ export interface RightActionsProps {
const RightActions: React.FC<RightActionsProps> = ({
handleDeleteByBatch,
handleClickPrimary,
handleCompare,
handleSettingFields,
buttonText,
rowSelection
@@ -31,9 +29,6 @@ const RightActions: React.FC<RightActionsProps> = ({
return (
<Space size={16}>
<Button onClick={handleSettingFields} icon={<SettingOutlined />}></Button>
<Button variant="solid" color="orange" onClick={handleCompare}>
Compare
</Button>
<Button
icon={<PlusOutlined></PlusOutlined>}
type="primary"
@@ -0,0 +1,9 @@
import React from 'react';
import { useDetailContext } from '../../config/detail-context';
const Summary: React.FC = () => {
const { detailData } = useDetailContext();
return <div>Summary Content</div>;
};
export default Summary;
@@ -0,0 +1,21 @@
import { createContext, useContext } from 'react';
interface DetailContextProps {
detailData: any;
id: number;
loading?: boolean;
}
const DetailContext = createContext<DetailContextProps>(
{} as DetailContextProps
);
export const useDetailContext = () => {
const context = useContext(DetailContext);
if (!context) {
throw new Error('useDetailContext must be used within a DetailProvider');
}
return context;
};
export default DetailContext;
+56
View File
@@ -0,0 +1,56 @@
import { useIntl } from '@umijs/max';
import { Tabs, TabsProps } from 'antd';
import React, { useState } from 'react';
import PageBox from '../_components/page-box';
import Configure from './components/configure';
import Environment from './components/environment';
import Logs from './components/logs';
import Summary from './components/summary';
import DetailContext from './config/detail-context';
const Details: React.FC = () => {
const intl = useIntl();
const [activeKey, setActiveKey] = useState('summary');
const items: TabsProps['items'] = [
{
key: 'summary',
label: intl.formatMessage({ id: 'benchmark.detail.summary.title' }),
children: <Summary />
},
{
key: 'configure',
label: intl.formatMessage({ id: 'benchmark.detail.configure.title' }),
children: <Configure />
},
{
key: 'environment',
label: intl.formatMessage({ id: 'benchmark.detail.environment.title' }),
children: <Environment />
},
{
key: 'logs',
label: intl.formatMessage({ id: 'benchmark.detail.logs.title' }),
children: <Logs />
}
];
const handleChangeTab = (key: string) => {
setActiveKey(key);
};
return (
<PageBox>
<DetailContext.Provider value={{}}>
<Tabs
activeKey={activeKey}
onChange={handleChangeTab}
items={items}
type="card"
/>
</DetailContext.Provider>
</PageBox>
);
};
export default Details;
@@ -0,0 +1,3 @@
const useCompareConditions = () => {};
export default useCompareConditions;
+7
View File
@@ -17,6 +17,7 @@ import {
updateBenchmark
} from './apis';
import AddBenchmarkModal from './components/add-benchmark-modal';
import LeftActions from './components/left-actions';
import RightActions from './components/right-actions';
import { FormData, BenchmarkListItem as ListItem } from './config/types';
import useBenchmarkColumns from './hooks/use-benchmark-columns';
@@ -123,6 +124,12 @@ const Benchmark: React.FC = () => {
handleInputChange={handleNameChange}
rowSelection={rowSelection}
widths={{ input: 300 }}
left={
<LeftActions
handleSearch={handleSearch}
handleInputChange={handleNameChange}
></LeftActions>
}
right={
<RightActions
handleDeleteByBatch={handleDeleteBatch}