diff --git a/src/components/seal-form/simple-select.tsx b/src/components/seal-form/simple-select.tsx index 5c9e73f4..76b8ab6a 100644 --- a/src/components/seal-form/simple-select.tsx +++ b/src/components/seal-form/simple-select.tsx @@ -113,7 +113,7 @@ const SimpleSelect: React.FC = indeterminate={allSelection.indeterminate} onChange={handleOnCheckboxChange} > - {intl.formatMessage({ id: 'common.checbox.all' })} + {intl.formatMessage({ id: 'common.checkbox.all' })} )} diff --git a/src/locales/en-US/benchmark.ts b/src/locales/en-US/benchmark.ts index 73732095..007300fd 100644 --- a/src/locales/en-US/benchmark.ts +++ b/src/locales/en-US/benchmark.ts @@ -40,20 +40,21 @@ export default { 'benchmark.table.filter.bygpu': 'Filter by GPU', 'benchmark.table.filter.bymodel': 'Filter by Model', 'benchmark.table.filter.bydataset': 'Filter by Dataset', - 'benchmark.table.avg': 'Average', + 'benchmark.table.avg': 'Avg', 'benchmark.table.columnSettings': 'Column Settings', 'benchmark.detail.summary.results': 'Test Results', + 'benchmark.detail.summary.metadata': 'Metadata', 'benchmark.detail.summary.metrics': 'Test Metrics', 'benchmark.detail.summary.latency': 'Latency', 'benchmark.detail.summary.throughput': 'Throughput', 'benchmark.detail.summary.request': 'Requests', - 'benchmark.detail.avg.reqLatency': 'Average Request Latency', - 'benchmark.detail.avg.ttft': 'Average TTFT', - 'benchmark.detail.avg.tpot': 'Average TPOT', - 'benchmark.detail.avg.itl': 'Average ITL', - 'benchmark.detail.throughput.totalToken': 'Total Token Throughput', - 'benchmark.detail.throughput.inputToken': 'Input Token Throughput', - 'benchmark.detail.throughput.outputToken': 'Output Token Throughput', + 'benchmark.detail.avg.reqLatency': 'Request Latency Avg', + 'benchmark.detail.avg.ttft': 'TTFT Avg', + 'benchmark.detail.avg.tpot': 'TPOT Avg', + 'benchmark.detail.avg.itl': 'ITL Avg', + 'benchmark.detail.throughput.totalToken': 'Total Throughput', + 'benchmark.detail.throughput.inputToken': 'Input Throughput', + 'benchmark.detail.throughput.outputToken': 'Output Throughput', 'benchmark.detail.requests.total': 'Total Requests', 'benchmark.detail.requests.success': 'Successful Requests', 'benchmark.detail.requests.failed': 'Failed Requests', diff --git a/src/locales/en-US/common.ts b/src/locales/en-US/common.ts index d9889738..721321fc 100644 --- a/src/locales/en-US/common.ts +++ b/src/locales/en-US/common.ts @@ -97,7 +97,7 @@ export default { 'common.form.field.input.required': 'required', 'common.form.field.select.required': 'required', 'common.select.option': 'All', - 'common.checbox.all': 'Select all', + 'common.checkbox.all': 'Select all', 'common.select.all': 'All {type}', 'common.data.unkonwn': 'Unknown', 'common.data.none': 'No Data', diff --git a/src/locales/ja-JP/benchmark.ts b/src/locales/ja-JP/benchmark.ts index 73732095..007300fd 100644 --- a/src/locales/ja-JP/benchmark.ts +++ b/src/locales/ja-JP/benchmark.ts @@ -40,20 +40,21 @@ export default { 'benchmark.table.filter.bygpu': 'Filter by GPU', 'benchmark.table.filter.bymodel': 'Filter by Model', 'benchmark.table.filter.bydataset': 'Filter by Dataset', - 'benchmark.table.avg': 'Average', + 'benchmark.table.avg': 'Avg', 'benchmark.table.columnSettings': 'Column Settings', 'benchmark.detail.summary.results': 'Test Results', + 'benchmark.detail.summary.metadata': 'Metadata', 'benchmark.detail.summary.metrics': 'Test Metrics', 'benchmark.detail.summary.latency': 'Latency', 'benchmark.detail.summary.throughput': 'Throughput', 'benchmark.detail.summary.request': 'Requests', - 'benchmark.detail.avg.reqLatency': 'Average Request Latency', - 'benchmark.detail.avg.ttft': 'Average TTFT', - 'benchmark.detail.avg.tpot': 'Average TPOT', - 'benchmark.detail.avg.itl': 'Average ITL', - 'benchmark.detail.throughput.totalToken': 'Total Token Throughput', - 'benchmark.detail.throughput.inputToken': 'Input Token Throughput', - 'benchmark.detail.throughput.outputToken': 'Output Token Throughput', + 'benchmark.detail.avg.reqLatency': 'Request Latency Avg', + 'benchmark.detail.avg.ttft': 'TTFT Avg', + 'benchmark.detail.avg.tpot': 'TPOT Avg', + 'benchmark.detail.avg.itl': 'ITL Avg', + 'benchmark.detail.throughput.totalToken': 'Total Throughput', + 'benchmark.detail.throughput.inputToken': 'Input Throughput', + 'benchmark.detail.throughput.outputToken': 'Output Throughput', 'benchmark.detail.requests.total': 'Total Requests', 'benchmark.detail.requests.success': 'Successful Requests', 'benchmark.detail.requests.failed': 'Failed Requests', diff --git a/src/locales/ja-JP/common.ts b/src/locales/ja-JP/common.ts index 2dc37c39..bedef316 100644 --- a/src/locales/ja-JP/common.ts +++ b/src/locales/ja-JP/common.ts @@ -97,7 +97,7 @@ export default { 'common.form.field.input.required': '必須', 'common.form.field.select.required': '必須', 'common.select.option': 'すべて', - 'common.checbox.all': 'すべて', + 'common.checkbox.all': 'すべて', 'common.select.all': 'すべての {type}', 'common.data.unkonwn': '不明', 'common.data.none': 'データなし', diff --git a/src/locales/ru-RU/benchmark.ts b/src/locales/ru-RU/benchmark.ts index 73732095..007300fd 100644 --- a/src/locales/ru-RU/benchmark.ts +++ b/src/locales/ru-RU/benchmark.ts @@ -40,20 +40,21 @@ export default { 'benchmark.table.filter.bygpu': 'Filter by GPU', 'benchmark.table.filter.bymodel': 'Filter by Model', 'benchmark.table.filter.bydataset': 'Filter by Dataset', - 'benchmark.table.avg': 'Average', + 'benchmark.table.avg': 'Avg', 'benchmark.table.columnSettings': 'Column Settings', 'benchmark.detail.summary.results': 'Test Results', + 'benchmark.detail.summary.metadata': 'Metadata', 'benchmark.detail.summary.metrics': 'Test Metrics', 'benchmark.detail.summary.latency': 'Latency', 'benchmark.detail.summary.throughput': 'Throughput', 'benchmark.detail.summary.request': 'Requests', - 'benchmark.detail.avg.reqLatency': 'Average Request Latency', - 'benchmark.detail.avg.ttft': 'Average TTFT', - 'benchmark.detail.avg.tpot': 'Average TPOT', - 'benchmark.detail.avg.itl': 'Average ITL', - 'benchmark.detail.throughput.totalToken': 'Total Token Throughput', - 'benchmark.detail.throughput.inputToken': 'Input Token Throughput', - 'benchmark.detail.throughput.outputToken': 'Output Token Throughput', + 'benchmark.detail.avg.reqLatency': 'Request Latency Avg', + 'benchmark.detail.avg.ttft': 'TTFT Avg', + 'benchmark.detail.avg.tpot': 'TPOT Avg', + 'benchmark.detail.avg.itl': 'ITL Avg', + 'benchmark.detail.throughput.totalToken': 'Total Throughput', + 'benchmark.detail.throughput.inputToken': 'Input Throughput', + 'benchmark.detail.throughput.outputToken': 'Output Throughput', 'benchmark.detail.requests.total': 'Total Requests', 'benchmark.detail.requests.success': 'Successful Requests', 'benchmark.detail.requests.failed': 'Failed Requests', diff --git a/src/locales/ru-RU/common.ts b/src/locales/ru-RU/common.ts index 9a7153a6..08c81c0c 100644 --- a/src/locales/ru-RU/common.ts +++ b/src/locales/ru-RU/common.ts @@ -97,7 +97,7 @@ export default { 'common.form.field.input.required': 'обязательно', 'common.form.field.select.required': 'обязательно', 'common.select.option': 'Все', - 'common.checbox.all': 'Все', + 'common.checkbox.all': 'Все', 'common.select.all': 'Все {type}', 'common.data.unkonwn': 'Неизвестно', 'common.data.none': 'Нет данных', diff --git a/src/locales/zh-CN/benchmark.ts b/src/locales/zh-CN/benchmark.ts index 77c149fa..376777b0 100644 --- a/src/locales/zh-CN/benchmark.ts +++ b/src/locales/zh-CN/benchmark.ts @@ -43,17 +43,18 @@ export default { 'benchmark.table.avg': '均值', 'benchmark.table.columnSettings': '列设置', 'benchmark.detail.summary.results': '测试结果', + 'benchmark.detail.summary.metadata': '元数据', 'benchmark.detail.summary.metrics': '测试指标', 'benchmark.detail.summary.latency': '延迟', 'benchmark.detail.summary.throughput': '吞吐', 'benchmark.detail.summary.request': '请求数', - 'benchmark.detail.avg.reqLatency': '平均请求延迟', - 'benchmark.detail.avg.ttft': '平均 TTFT', - 'benchmark.detail.avg.tpot': '平均 TPOT', - 'benchmark.detail.avg.itl': '平均 ITL', - 'benchmark.detail.throughput.totalToken': '总 Token 吞吐量', - 'benchmark.detail.throughput.inputToken': '输入 Token 吞吐量', - 'benchmark.detail.throughput.outputToken': '输出 Token 吞吐量', + 'benchmark.detail.avg.reqLatency': '请求延迟 均值', + 'benchmark.detail.avg.ttft': 'TTFT 均值', + 'benchmark.detail.avg.tpot': 'TPOT 均值', + 'benchmark.detail.avg.itl': 'ITL 均值', + 'benchmark.detail.throughput.totalToken': '总吞吐量', + 'benchmark.detail.throughput.inputToken': '输入吞吐量', + 'benchmark.detail.throughput.outputToken': '输出吞吐量', 'benchmark.detail.requests.total': '请求总数', 'benchmark.detail.requests.success': '请求成功数', 'benchmark.detail.requests.failed': '请求失败数', diff --git a/src/locales/zh-CN/common.ts b/src/locales/zh-CN/common.ts index 7e27b9ba..bea519a7 100644 --- a/src/locales/zh-CN/common.ts +++ b/src/locales/zh-CN/common.ts @@ -94,7 +94,7 @@ export default { 'common.data.unkonwn': '未知', 'common.data.none': '暂无', 'common.action.none': '无', - 'common.checbox.all': '全选', + 'common.checkbox.all': '全选', 'common.select.all': '全部{type}', 'common.button.addfile': '添加文件', 'common.logout.msg': '登出成功', diff --git a/src/pages/_components/column-settings.tsx b/src/pages/_components/column-settings.tsx index ea84a478..e8f11df2 100644 --- a/src/pages/_components/column-settings.tsx +++ b/src/pages/_components/column-settings.tsx @@ -1,8 +1,12 @@ import OverlayScroller from '@/components/overlay-scroller'; +import { + readColumnSettings, + writeColumnSettings +} from '@/utils/localstore/index'; import { SettingOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button, Checkbox, Col, Popover, Row, Tooltip } from 'antd'; -import React from 'react'; +import React, { useEffect } from 'react'; import styled from 'styled-components'; const Container = styled.div` @@ -32,24 +36,53 @@ const Title = styled.div` `; const ColumnSettings: React.FC<{ + width?: number; + fixedColumns?: string[]; + tableName: string; contentHeight: number; columns: { - title: string; + title: React.ReactNode; dataIndex?: string; - children?: { title: string; dataIndex?: string }[]; + children?: { title: React.ReactNode; dataIndex?: string }[]; }[]; selectedColumns?: string[]; + defaultSelectedColumns?: string[]; grouped?: boolean; + onReset?: () => void; onChange?: (selectedColumns: string[]) => void; }> = (props) => { const intl = useIntl(); - const { contentHeight, columns, selectedColumns, grouped, onChange } = props; + const { + tableName, + contentHeight, + width = 420, + columns, + selectedColumns, + defaultSelectedColumns, + grouped, + onReset, + onChange, + fixedColumns + } = props; const [open, setOpen] = React.useState(false); + const [innerSelectedColumns, setInnerSelectedColumns] = React.useState< + string[] + >(defaultSelectedColumns || []); + + React.useEffect(() => { + if (open) { + setInnerSelectedColumns(selectedColumns ?? defaultSelectedColumns ?? []); + } + }, [open, selectedColumns, defaultSelectedColumns]); const handleToggle = () => { setOpen(!open); }; + const handleDraftChange = (columns: string[]) => { + setInnerSelectedColumns(columns); + }; + const handleSelectAll = () => { if (grouped) { const allCols: string[] = []; @@ -60,23 +93,55 @@ const ColumnSettings: React.FC<{ } }); }); - onChange?.(allCols); + handleDraftChange(allCols); } else { const allCols = columns .map((col) => col.dataIndex) .filter((dataIndex): dataIndex is string => Boolean(dataIndex)); - onChange?.(allCols); + handleDraftChange(allCols); } }; const handleConfirm = () => { setOpen(false); + writeColumnSettings(tableName, innerSelectedColumns); + onChange?.(innerSelectedColumns); }; + const handleReset = () => { + const resetCols = defaultSelectedColumns ?? []; + writeColumnSettings(tableName, resetCols); + onChange?.(resetCols); + setInnerSelectedColumns(resetCols); + onReset?.(); + }; + + const handleOpenChange = (isOpen: boolean) => { + setOpen(isOpen); + }; + + useEffect(() => { + const initColumns = async () => { + const stored = await readColumnSettings(tableName); + console.log('stored columns:', stored); + if (stored && stored.length > 0) { + setInnerSelectedColumns(stored); + onChange?.(stored); + } else { + setInnerSelectedColumns(defaultSelectedColumns || []); + } + }; + initColumns(); + }, []); + const contentRender = () => { return ( - {!grouped &&
Column Settings
} + {!grouped && ( +
+ {intl.formatMessage({ id: 'benchmark.table.columnSettings' })} +
+ )} { - onChange?.(checkedValues as string[]); - }} + value={innerSelectedColumns} + onChange={handleDraftChange} > <> {grouped ? ( @@ -100,6 +163,9 @@ const ColumnSettings: React.FC<{ {row.children?.map((col) => ( @@ -115,6 +181,7 @@ const ColumnSettings: React.FC<{ {columns.map((col) => ( @@ -129,20 +196,15 @@ const ColumnSettings: React.FC<{
-
@@ -152,17 +214,21 @@ const ColumnSettings: React.FC<{ return ( - + diff --git a/src/pages/benchmark/components/summary/metrics-result.tsx b/src/pages/benchmark/components/summary/metrics-result.tsx index 459598d1..ef281d96 100644 --- a/src/pages/benchmark/components/summary/metrics-result.tsx +++ b/src/pages/benchmark/components/summary/metrics-result.tsx @@ -68,7 +68,7 @@ const latencyColumns = [ const requestColumns = [ { - label: 'benchmark.detail.requests.total', + title: 'benchmark.detail.requests.total', key: 'total_requests', dataIndex: 'total_requests', path: 'total_requests', @@ -77,7 +77,7 @@ const requestColumns = [ unit: '' }, { - label: 'benchmark.detail.requests.success', + title: 'benchmark.detail.requests.success', key: 'total_requests', dataIndex: 'successful_requests', path: ['raw_metrics', 'benchmarks', '0'], @@ -88,7 +88,7 @@ const requestColumns = [ unit: '' }, { - label: 'benchmark.detail.requests.failed', + title: 'benchmark.detail.requests.failed', key: 'total_requests', dataIndex: 'failed_requests', path: ['raw_metrics', 'benchmarks', '0'], @@ -99,7 +99,7 @@ const requestColumns = [ unit: '' }, { - label: 'benchmark.detail.requests.concurrency', + title: 'benchmark.detail.requests.concurrency', key: 'request_concurrency', dataIndex: 'request_concurrency', path: ['raw_metrics', 'benchmarks', '0'], @@ -180,9 +180,9 @@ const PercentileResult: React.FC = () => { ); const requestItems = requestColumns.map( - ({ label, dataIndex, path, render, unit, color }) => ({ + ({ title, dataIndex, path, render, unit, color }) => ({ key: dataIndex, - label: intl.formatMessage({ id: label }), + label: intl.formatMessage({ id: title }), children: unit ? ( {render(_.get(detailData, path) ?? 0)}{' '} diff --git a/src/pages/benchmark/hooks/use-benchmark-columns.tsx b/src/pages/benchmark/hooks/use-benchmark-columns.tsx index ca63075e..2ea1ab32 100644 --- a/src/pages/benchmark/hooks/use-benchmark-columns.tsx +++ b/src/pages/benchmark/hooks/use-benchmark-columns.tsx @@ -1,22 +1,21 @@ // columns.ts import AutoTooltip from '@/components/auto-tooltip'; -import StatusTag from '@/components/status-tag'; import { tableSorter } from '@/config/settings'; import { useIntl } from '@umijs/max'; -import { Progress, Typography } from 'antd'; +import { Typography } from 'antd'; import { ColumnsType } from 'antd/es/table'; -import _ from 'lodash'; import { useMemo } from 'react'; import RowActions from '../components/row-actions'; -import { BenchmarkStatus, BenchmarkStatusLabelMap } from '../config'; import { BenchmarkListItem as ListItem } from '../config/types'; -const useBenchmarkColumns = ( - sortOrder: string[], - handleSelect: (val: string, record: ListItem) => void, - onCellClick?: (record: ListItem, dataIndex: string) => void -): ColumnsType => { +const useBenchmarkColumns = (params: { + sortOrder: string[]; + columns: ColumnsType; + handleSelect: (val: string, record: ListItem) => void; + onCellClick?: (record: ListItem, dataIndex: string) => void; +}): ColumnsType => { const intl = useIntl(); + const { onCellClick, handleSelect, columns } = params; return useMemo(() => { return [ @@ -32,55 +31,10 @@ const useBenchmarkColumns = ( ) }, - { - title: intl.formatMessage({ id: 'benchmark.table.model' }), - dataIndex: 'model_name', - sorter: tableSorter(1), - render: (text: string) => ( - - {text} - - ) - }, - { - title: intl.formatMessage({ id: 'benchmark.table.dataset' }), - dataIndex: 'dataset_name', - sorter: tableSorter(1), - render: (text: string) => ( - - {text} - - ) - }, - { - title: intl.formatMessage({ id: 'common.table.status' }), - dataIndex: 'state', - ellipsis: { - showTitle: false - }, - width: 120, - render: (value: number, record: ListItem) => ( - - - {record.progress !== undefined && record.progress < 100 && ( - - )} - - ) - }, + ...columns, // { - // title: intl.formatMessage({ id: 'benchmark.table.requestRate' }), - // dataIndex: 'request_rate', + // title: intl.formatMessage({ id: 'benchmark.table.model' }), + // dataIndex: 'model_name', // sorter: tableSorter(1), // render: (text: string) => ( // @@ -88,88 +42,93 @@ const useBenchmarkColumns = ( // // ) // }, - { - title: intl.formatMessage({ id: 'benchmark.table.gpu' }), - dataIndex: 'gpu_summary', - sorter: tableSorter(1), - render: (text: string) => ( - - {text} - - ) - }, - { - title: ( - - {intl.formatMessage({ id: 'benchmark.table.itl' })} - Avg (ms) - - ), - dataIndex: 'inter_token_latency_mean', - sorter: tableSorter(1), - render: (text: string) => ( - - {_.round(text, 1)} - - ) - }, - { - title: ( - - {intl.formatMessage({ id: 'benchmark.table.tpot' })} - Avg (ms) - - ), - dataIndex: 'time_per_output_token_mean', - sorter: tableSorter(1), - render: (text: string) => ( - - {_.round(text, 2)} - - ) - }, - { - title: ( - - {intl.formatMessage({ id: 'benchmark.table.ttft' })} - Avg (ms) - - ), - dataIndex: 'time_to_first_token_mean', - sorter: tableSorter(1), - render: (text: string) => ( - - {_.round(text, 2)} - - ) - }, - { - title: intl.formatMessage({ id: 'benchmark.table.rps' }), - dataIndex: 'requests_per_second_mean', - sorter: tableSorter(1), - render: (text: string) => ( - - {_.round(text, 0)} - - ) - }, - { - title: intl.formatMessage({ id: 'benchmark.table.tps' }), - dataIndex: 'tokens_per_second_mean', - sorter: tableSorter(1), - render: (text: string) => ( - - {_.round(text, 2)} - - ) - }, // { - // title: intl.formatMessage({ id: 'common.table.createTime' }), - // dataIndex: 'created_at', - // sorter: tableSorter(3), - // render: (value: string) => ( - // - // {dayjs(value).format('YYYY-MM-DD HH:mm:ss')} + // title: intl.formatMessage({ id: 'benchmark.table.dataset' }), + // dataIndex: 'dataset_name', + // sorter: tableSorter(1), + // render: (text: string) => ( + // + // {text} + // + // ) + // }, + // { + // title: intl.formatMessage({ id: 'common.table.status' }), + // dataIndex: 'state', + // ellipsis: { + // showTitle: false + // }, + // width: 120, + // render: (value: number, record: ListItem) => ( + // + // + // {record.progress !== undefined && record.progress < 100 && ( + // + // )} + // + // ) + // }, + // { + // title: intl.formatMessage({ id: 'benchmark.table.gpu' }), + // dataIndex: 'gpu_summary', + // sorter: tableSorter(1), + // render: (text: string) => ( + // + // {text} + // + // ) + // }, + // { + // title: 'TPS', + // dataIndex: 'tokens_per_second_mean', + // sorter: tableSorter(1), + // render: (text: string) => ( + // + // {_.round(text, 2)} + // + // ) + // }, + // { + // title: ( + // + // {intl.formatMessage({ id: 'benchmark.table.ttft' })} + // + // {intl.formatMessage({ id: 'benchmark.table.avg' })} (ms) + // + // + // ), + // dataIndex: 'time_to_first_token_mean', + // sorter: tableSorter(1), + // render: (text: string) => ( + // + // {_.round(text, 2)} + // + // ) + // }, + // { + // title: ( + // + // {intl.formatMessage({ id: 'benchmark.table.tpot' })} + // + // {intl.formatMessage({ id: 'benchmark.table.avg' })} (ms) + // + // + // ), + // dataIndex: 'time_per_output_token_mean', + // sorter: tableSorter(1), + // render: (text: string) => ( + // + // {_.round(text, 2)} // // ) // }, @@ -184,7 +143,7 @@ const useBenchmarkColumns = ( ) } ]; - }, [intl, onCellClick, handleSelect]); + }, [intl, onCellClick, handleSelect, columns]); }; export default useBenchmarkColumns; diff --git a/src/pages/benchmark/hooks/use-column-settings.tsx b/src/pages/benchmark/hooks/use-column-settings.tsx index f87019d4..cee29d7e 100644 --- a/src/pages/benchmark/hooks/use-column-settings.tsx +++ b/src/pages/benchmark/hooks/use-column-settings.tsx @@ -1,112 +1,392 @@ +import AutoTooltip from '@/components/auto-tooltip'; +import StatusTag from '@/components/status-tag'; +import { tableSorter } from '@/config/settings'; import ColumnSettings from '@/pages/_components/column-settings'; import { useIntl } from '@umijs/max'; +import { Progress } from 'antd'; +import dayjs from 'dayjs'; +import _, { round } from 'lodash'; import React from 'react'; +import styled from 'styled-components'; +import { BenchmarkStatus, BenchmarkStatusLabelMap } from '../config'; +import { BenchmarkListItem as ListItem } from '../config/types'; + +const SubTitleWrapper = styled.span` + display: list-item; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +`; + +const defaultColumns: string[] = [ + 'model_name', + 'dataset_name', + 'state', + 'gpu_summary', + 'tokens_per_second_mean', + 'time_to_first_token_mean', + 'time_per_output_token_mean' +]; +const fixedColumns: string[] = []; const useColumnSettings = (options: { contentHeight: number }) => { const intl = useIntl(); const { contentHeight } = options; - const [selectedColumns, setSelectedColumns] = React.useState([]); + const [selectedColumns, setSelectedColumns] = + React.useState(defaultColumns); + + const renderTitle = ( + title: React.ReactNode, + options?: { subTitle?: React.ReactNode } + ): React.ReactNode => { + return ( + + + {title} + + {options?.subTitle && ( + {options.subTitle} + )} + + ); + }; + + const resultColumns = [ + { + title: renderTitle( + `${intl.formatMessage({ id: 'benchmark.detail.summary.latency' })}`, + { + subTitle: `${intl.formatMessage({ id: 'benchmark.table.avg' })} (ms)` + } + ), + pos: 11, + dataIndex: 'request_latency_mean', + path: 'request_latency_mean', + unit: 'ms', + sorter: tableSorter(1), + render: (value: number) => round(value, 2) + }, + { + title: 'TPS', + pos: 12, + dataIndex: 'tokens_per_second_mean', + path: 'tokens_per_second_mean', + unit: 'Tokens/s', + sorter: tableSorter(1), + render: (text: number) => ( + + {_.round(text, 2)} + + ) + }, + { + title: renderTitle('TTFT', { + subTitle: `${intl.formatMessage({ id: 'benchmark.table.avg' })} (ms)` + }), + pos: 13, + sorter: tableSorter(1), + dataIndex: 'time_to_first_token_mean', + path: 'time_to_first_token_mean', + unit: 'ms', + render: (text: number) => ( + + {_.round(text, 2)} + + ) + }, + { + title: renderTitle('TPOT', { + subTitle: `${intl.formatMessage({ id: 'benchmark.table.avg' })} (ms)` + }), + pos: 14, + sorter: tableSorter(1), + dataIndex: 'time_per_output_token_mean', + path: 'time_per_output_token_mean', + unit: 'ms', + render: (text: number) => ( + + {_.round(text, 2)} + + ) + }, + { + title: renderTitle('ITL', { + subTitle: `${intl.formatMessage({ id: 'benchmark.table.avg' })} (ms)` + }), + pos: 15, + sorter: tableSorter(1), + dataIndex: 'inter_token_latency_mean', + path: 'inter_token_latency_mean', + unit: 'ms', + render: (value: number) => round(value, 2) + }, + { + title: 'RPS', + pos: 16, + dataIndex: 'requests_per_second_mean', + sorter: tableSorter(1), + render: (text: string) => ( + + {_.round(text, 0)} + + ) + }, + { + title: renderTitle( + `${intl.formatMessage({ + id: 'benchmark.detail.throughput.inputToken' + })}`, + { + subTitle: '(Tokens/s)' + } + ), + pos: 17, + dataIndex: 'input_tokens_per_second_mean', + path: 'input_tokens_per_second_mean', + unit: 'Tokens/s', + render: (value: number) => ( + + {round(value, 2)} + + ) + }, + { + title: renderTitle( + `${intl.formatMessage({ + id: 'benchmark.detail.throughput.outputToken' + })}`, + { + subTitle: '(Tokens/s)' + } + ), + pos: 18, + dataIndex: 'output_tokens_per_second_mean', + path: 'output_tokens_per_second_mean', + unit: 'Tokens/s', + render: (value: number) => ( + + {round(value, 2)} + + ) + }, + { + title: renderTitle( + intl.formatMessage({ id: 'benchmark.detail.requests.total' }) + ), + pos: 19, + key: 'total_requests', + dataIndex: 'total_requests', + path: 'total_requests', + precision: 0, + render: (value: number) => ( + + {round(value, 0) || 0} + + ), + unit: '' + }, + { + title: renderTitle( + intl.formatMessage({ id: 'benchmark.detail.requests.success' }) + ), + pos: 20, + key: 'total_requests', + dataIndex: 'successful_requests', + path: ['raw_metrics', 'benchmarks', '0'], + render: (value: number) => + round(_.get(value, ['metrics', 'request_totals', 'successful']), 0) || + 0, + precision: 0, + color: 'var(--ant-color-success)', + unit: '' + }, + { + title: renderTitle( + intl.formatMessage({ id: 'benchmark.detail.requests.failed' }) + ), + pos: 21, + key: 'total_requests', + dataIndex: 'failed_requests', + path: ['raw_metrics', 'benchmarks', '0'], + render: (value: number) => + round(_.get(value, ['metrics', 'request_totals', 'errored']), 0) || 0, + precision: 0, + color: 'var(--ant-color-error)', + unit: '' + }, + { + title: renderTitle( + intl.formatMessage({ + id: 'benchmark.detail.requests.concurrency' + }) + ), + pos: 22, + key: 'request_concurrency', + dataIndex: 'request_concurrency', + path: ['raw_metrics', 'benchmarks', '0'], + render: (value: number) => + round(_.get(value, 'metrics.request_concurrency.successful.mean'), 0) || + 0, + precision: 0, + unit: '' + } + ]; + + const metadataColumns = [ + { + title: renderTitle(intl.formatMessage({ id: 'clusters.title' })), + pos: 1, + dataIndex: 'cluster_id', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle(intl.formatMessage({ id: 'resources.worker' })), + pos: 2, + dataIndex: 'worker_id', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle( + intl.formatMessage({ id: 'benchmark.detail.modelName' }) + ), + pos: 3, + dataIndex: 'model_name', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle(intl.formatMessage({ id: 'benchmark.table.dataset' })), + pos: 4, + dataIndex: 'dataset_name', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle(intl.formatMessage({ id: 'benchmark.form.profile' })), + pos: 5, + dataIndex: 'profile', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle(intl.formatMessage({ id: 'benchmark.table.gpu' })), + pos: 6, + dataIndex: 'gpu_summary', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle(intl.formatMessage({ id: 'common.table.status' })), + pos: 7, + width: 120, + dataIndex: 'state', + render: (value: number, record: ListItem) => ( + + + {record.progress !== undefined && record.progress < 100 && ( + + )} + + ) + }, + { + title: renderTitle( + intl.formatMessage({ id: 'benchmark.table.requestRate' }) + ), + pos: 8, + dataIndex: 'request_rate', + render: (text: string) => ( + + {text} + + ) + }, + { + title: renderTitle(intl.formatMessage({ id: 'common.table.createTime' })), + pos: 23, + dataIndex: 'created_at', + sorter: tableSorter(6), + render: (value: string) => ( + + {dayjs(value).format('YYYY-MM-DD HH:mm:ss')} + + ) + } + ]; const handleOnChange = (columns: string[]) => { setSelectedColumns(columns); console.log('selected columns:', columns); }; - const resultColumns = [ - { - title: intl.formatMessage({ id: 'benchmark.table.rps' }), - dataIndex: 'requests_per_second_mean' - }, - { - title: 'Throughput', - dataIndex: 'throughput_mean' - }, - { - title: 'Throughput request', - dataIndex: 'throughput_request_mean' - }, - { - title: 'Generated Tokens', - dataIndex: 'generated_tokens_mean' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.tps' }), - dataIndex: 'tokens_per_second_mean' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.itl' }), - dataIndex: 'inter_token_latency_mean' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.tpot' }), - dataIndex: 'time_per_output_token_mean' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.ttft' }), - dataIndex: 'time_to_first_token_mean' - }, - { - title: 'Latency Avg', - dataIndex: 'latency_mean' - } - ]; + const handleOnReset = () => { + setSelectedColumns(defaultColumns); + }; - const metadataColumns = [ - { - title: intl.formatMessage({ id: 'clusters.title' }), - dataIndex: 'cluster_id' - }, - { - title: intl.formatMessage({ id: 'resources.worker' }), - dataIndex: 'worker_id' - }, - { - title: intl.formatMessage({ id: 'common.table.name' }), - dataIndex: 'name' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.model' }), - dataIndex: 'model_name' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.dataset' }), - dataIndex: 'dataset_name' - }, - { - title: intl.formatMessage({ id: 'common.table.status' }), - dataIndex: 'state' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.requestRate' }), - dataIndex: 'request_rate' - }, - { - title: intl.formatMessage({ id: 'benchmark.table.gpu' }), - dataIndex: 'gpu_summary' - }, - { - title: intl.formatMessage({ id: 'common.table.createTime' }), - dataIndex: 'created_at' - }, - { - title: intl.formatMessage({ id: 'common.table.operation' }), - dataIndex: 'operations' - } - ]; + const columns = React.useMemo(() => { + const allColumns = [...metadataColumns, ...resultColumns]; + const selected = allColumns.filter((col) => + selectedColumns.includes(col.dataIndex as string) + ); + // Sort by pos + selected.sort((a, b) => (a.pos || 0) - (b.pos || 0)); + console.log('columns===', selected); + return selected; + }, [selectedColumns]); const SettingsButton = ( { return { SettingsButton, - selectedColumns + columns }; }; diff --git a/src/pages/benchmark/index.tsx b/src/pages/benchmark/index.tsx index a289c0b5..55442e92 100644 --- a/src/pages/benchmark/index.tsx +++ b/src/pages/benchmark/index.tsx @@ -63,7 +63,7 @@ const Benchmark: React.FC = () => { }); const { openViewLogsModal, closeViewLogsModal, openViewLogsModalStatus } = useViewLogs(); - const { SettingsButton, selectedColumns } = useColumnSettings({ + const { SettingsButton, columns: selectedColumns } = useColumnSettings({ contentHeight: 320 }); const { handleStopBenchmark } = useStopBenchmark(); @@ -162,11 +162,12 @@ const Benchmark: React.FC = () => { ); }; - const columns = useBenchmarkColumns( + const columns = useBenchmarkColumns({ sortOrder, + columns: selectedColumns, handleSelect, - handleOnCellClick - ); + onCellClick: handleOnCellClick + }); const handleExportData = () => { exportData(rowSelection.selectedRowKeys); diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index ec4aaf56..21521197 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -91,8 +91,6 @@ const Login = () => { const [userInfo, setUserInfo] = useAtom(userAtom); const { initialState, setInitialState } = useModel('@@initialState') || {}; - console.log('useSettings==========', userSettings); - const gotoDefaultPage = async (userInfo: any) => { if (!userInfo || userInfo?.require_password_change) { return; diff --git a/src/utils/localstore/index.ts b/src/utils/localstore/index.ts index 360e92eb..c82a0d43 100644 --- a/src/utils/localstore/index.ts +++ b/src/utils/localstore/index.ts @@ -37,14 +37,24 @@ const writeState = (key: string, data: any) => { } }; +const readColumnSettings = (key: string) => { + return readState(key); +}; + +const writeColumnSettings = (key: string, data: any) => { + writeState(key, data); +}; + export { CRYPT_TEXT, IS_FIRST_LOGIN, REMEMBER_ME_KEY, getRememberMe, + readColumnSettings, readState, rememberMe, removeRememberMe, + writeColumnSettings, writeState };