feat: benchmark detail page
This commit is contained in:
@@ -122,6 +122,7 @@ export default [
|
|||||||
icon: 'icon-speed',
|
icon: 'icon-speed',
|
||||||
selectedIcon: 'icon-speed-filled',
|
selectedIcon: 'icon-speed-filled',
|
||||||
defaultIcon: 'icon-speed',
|
defaultIcon: 'icon-speed',
|
||||||
|
access: 'canSeeAdmin',
|
||||||
component: './benchmark/index'
|
component: './benchmark/index'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -107,7 +107,47 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
} = props;
|
} = props;
|
||||||
const intl = useIntl();
|
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) {
|
if (!handleClickPrimary && !handleDeleteByBatch) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -156,56 +196,14 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
|
|||||||
)}
|
)}
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
}, [
|
};
|
||||||
actionItems,
|
|
||||||
actionType,
|
|
||||||
rowSelection?.selectedRowKeys,
|
|
||||||
handleClickPrimary,
|
|
||||||
intl
|
|
||||||
]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageTools
|
<PageTools
|
||||||
marginBottom={marginBottom}
|
marginBottom={marginBottom}
|
||||||
marginTop={0}
|
marginTop={0}
|
||||||
left={
|
left={left || renderLeft()}
|
||||||
<Space>
|
right={right || renderRight()}
|
||||||
<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}
|
|
||||||
></PageTools>
|
></PageTools>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,5 +22,9 @@ export default {
|
|||||||
'benchmark.form.profile.heavy': 'Generation Heavy',
|
'benchmark.form.profile.heavy': 'Generation Heavy',
|
||||||
'benchmark.form.profile.custom': 'Custom',
|
'benchmark.form.profile.custom': 'Custom',
|
||||||
'benchmark.table.inputTokenLength': 'Input Token Length',
|
'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'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,5 +22,9 @@ export default {
|
|||||||
'benchmark.form.profile.heavy': 'Generation Heavy',
|
'benchmark.form.profile.heavy': 'Generation Heavy',
|
||||||
'benchmark.form.profile.custom': 'Custom',
|
'benchmark.form.profile.custom': 'Custom',
|
||||||
'benchmark.table.inputTokenLength': 'Input Token Length',
|
'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'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,5 +22,9 @@ export default {
|
|||||||
'benchmark.form.profile.heavy': 'Generation Heavy',
|
'benchmark.form.profile.heavy': 'Generation Heavy',
|
||||||
'benchmark.form.profile.custom': 'Custom',
|
'benchmark.form.profile.custom': 'Custom',
|
||||||
'benchmark.table.inputTokenLength': 'Input Token Length',
|
'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'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,5 +22,9 @@ export default {
|
|||||||
'benchmark.form.profile.heavy': '高生成量',
|
'benchmark.form.profile.heavy': '高生成量',
|
||||||
'benchmark.form.profile.custom': '自定义',
|
'benchmark.form.profile.custom': '自定义',
|
||||||
'benchmark.table.inputTokenLength': '输入 Token 长度',
|
'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;
|
handleDeleteByBatch: () => void;
|
||||||
handleClickPrimary?: () => void;
|
handleClickPrimary?: () => void;
|
||||||
handleSettingFields?: () => void;
|
handleSettingFields?: () => void;
|
||||||
handleCompare?: () => void;
|
|
||||||
buttonText?: string;
|
buttonText?: string;
|
||||||
rowSelection: {
|
rowSelection: {
|
||||||
selectedRowKeys: React.Key[];
|
selectedRowKeys: React.Key[];
|
||||||
@@ -21,7 +20,6 @@ export interface RightActionsProps {
|
|||||||
const RightActions: React.FC<RightActionsProps> = ({
|
const RightActions: React.FC<RightActionsProps> = ({
|
||||||
handleDeleteByBatch,
|
handleDeleteByBatch,
|
||||||
handleClickPrimary,
|
handleClickPrimary,
|
||||||
handleCompare,
|
|
||||||
handleSettingFields,
|
handleSettingFields,
|
||||||
buttonText,
|
buttonText,
|
||||||
rowSelection
|
rowSelection
|
||||||
@@ -31,9 +29,6 @@ const RightActions: React.FC<RightActionsProps> = ({
|
|||||||
return (
|
return (
|
||||||
<Space size={16}>
|
<Space size={16}>
|
||||||
<Button onClick={handleSettingFields} icon={<SettingOutlined />}></Button>
|
<Button onClick={handleSettingFields} icon={<SettingOutlined />}></Button>
|
||||||
<Button variant="solid" color="orange" onClick={handleCompare}>
|
|
||||||
Compare
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
icon={<PlusOutlined></PlusOutlined>}
|
icon={<PlusOutlined></PlusOutlined>}
|
||||||
type="primary"
|
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;
|
||||||
@@ -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;
|
||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
updateBenchmark
|
updateBenchmark
|
||||||
} from './apis';
|
} from './apis';
|
||||||
import AddBenchmarkModal from './components/add-benchmark-modal';
|
import AddBenchmarkModal from './components/add-benchmark-modal';
|
||||||
|
import LeftActions from './components/left-actions';
|
||||||
import RightActions from './components/right-actions';
|
import RightActions from './components/right-actions';
|
||||||
import { FormData, BenchmarkListItem as ListItem } from './config/types';
|
import { FormData, BenchmarkListItem as ListItem } from './config/types';
|
||||||
import useBenchmarkColumns from './hooks/use-benchmark-columns';
|
import useBenchmarkColumns from './hooks/use-benchmark-columns';
|
||||||
@@ -123,6 +124,12 @@ const Benchmark: React.FC = () => {
|
|||||||
handleInputChange={handleNameChange}
|
handleInputChange={handleNameChange}
|
||||||
rowSelection={rowSelection}
|
rowSelection={rowSelection}
|
||||||
widths={{ input: 300 }}
|
widths={{ input: 300 }}
|
||||||
|
left={
|
||||||
|
<LeftActions
|
||||||
|
handleSearch={handleSearch}
|
||||||
|
handleInputChange={handleNameChange}
|
||||||
|
></LeftActions>
|
||||||
|
}
|
||||||
right={
|
right={
|
||||||
<RightActions
|
<RightActions
|
||||||
handleDeleteByBatch={handleDeleteBatch}
|
handleDeleteByBatch={handleDeleteBatch}
|
||||||
|
|||||||
Reference in New Issue
Block a user