| @@ -69,35 +69,30 @@ function ExperimentHistory({ fileUrl, isClassification }: ExperimentHistoryProps | |||
| dataIndex: 'accuracy', | |||
| key: 'accuracy', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '耗时', | |||
| dataIndex: 'duration', | |||
| key: 'duration', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '训练损失', | |||
| dataIndex: 'train_loss', | |||
| key: 'train_loss', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '特征处理', | |||
| dataIndex: 'feature', | |||
| key: 'feature', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '算法', | |||
| dataIndex: 'althorithm', | |||
| key: 'althorithm', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '状态', | |||
| @@ -261,7 +261,6 @@ function ExperimentList({ type }: ExperimentListProps) { | |||
| dataIndex: config.descProperty, | |||
| key: 'ml_description', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| @@ -269,8 +268,7 @@ function ExperimentList({ type }: ExperimentListProps) { | |||
| dataIndex: 'update_time', | |||
| key: 'update_time', | |||
| width: '20%', | |||
| render: tableCellRender(true, TableCellValueType.Date), | |||
| ellipsis: { showTitle: false }, | |||
| render: tableCellRender(false, TableCellValueType.Date), | |||
| }, | |||
| { | |||
| title: '最近五次运行状态', | |||
| @@ -154,7 +154,6 @@ function ExperimentComparison() { | |||
| fixed: 'left', | |||
| align: 'center', | |||
| render: tableCellRender(true, TableCellValueType.Array), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| ], | |||
| }, | |||
| @@ -172,7 +171,6 @@ function ExperimentComparison() { | |||
| width: 120, | |||
| align: 'center', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| sorter: (a, b) => tableSorter(a.params?.[name], b.params?.[name]), | |||
| showSorterTooltip: false, | |||
| })), | |||
| @@ -191,7 +189,6 @@ function ExperimentComparison() { | |||
| width: 120, | |||
| align: 'center', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| sorter: (a, b) => tableSorter(a.metrics?.[name], b.metrics?.[name]), | |||
| showSorterTooltip: false, | |||
| })), | |||
| @@ -383,7 +383,7 @@ function Experiment() { | |||
| title: '实验名称', | |||
| dataIndex: 'name', | |||
| key: 'name', | |||
| render: tableCellRender(), | |||
| render: tableCellRender(false), | |||
| width: '16%', | |||
| }, | |||
| { | |||
| @@ -400,7 +400,6 @@ function Experiment() { | |||
| dataIndex: 'description', | |||
| key: 'description', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '最近五次运行状态', | |||
| @@ -8,7 +8,7 @@ import { to } from '@/utils/promise'; | |||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||
| import { App, Button, Table, Tooltip, Tree, type TableProps, type TreeDataNode } from 'antd'; | |||
| import classNames from 'classnames'; | |||
| import { useState } from 'react'; | |||
| import { useEffect, useState } from 'react'; | |||
| import styles from './index.less'; | |||
| const { DirectoryTree } = Tree; | |||
| @@ -22,13 +22,16 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) { | |||
| const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]); | |||
| const { message } = App.useApp(); | |||
| const [tableData, setTableData] = useState<HyperParameterTrial[]>([]); | |||
| const [loading, setLoading] = useState(true); | |||
| const [loading, setLoading] = useState(false); | |||
| // 防止 Tabs 卡顿 | |||
| setTimeout(() => { | |||
| setTableData(trialList); | |||
| setLoading(false); | |||
| }, 100); | |||
| useEffect(() => { | |||
| setLoading(true); | |||
| setTimeout(() => { | |||
| setTableData(trialList); | |||
| setLoading(false); | |||
| }, 500); | |||
| }, []); | |||
| // 计算 column | |||
| const first: HyperParameterTrial | undefined = trialList[0]; | |||
| @@ -67,7 +70,6 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) { | |||
| render: tableCellRender(false, TableCellValueType.Custom, { | |||
| format: (value = 0) => Number(value).toFixed(2), | |||
| }), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '状态', | |||
| @@ -95,8 +97,6 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) { | |||
| width: 120, | |||
| align: 'center', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| showSorterTooltip: false, | |||
| })), | |||
| }); | |||
| } | |||
| @@ -118,8 +118,6 @@ function ExperimentHistory({ trialList = [] }: ExperimentHistoryProps) { | |||
| width: 120, | |||
| align: 'center', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| showSorterTooltip: false, | |||
| })), | |||
| }); | |||
| } | |||
| @@ -43,16 +43,14 @@ function ParameterInfo({ info }: ParameterInfoProps) { | |||
| dataIndex: 'name', | |||
| key: 'type', | |||
| width: '40%', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| render: tableCellRender('auto'), | |||
| }, | |||
| { | |||
| title: '参数类型', | |||
| dataIndex: 'type', | |||
| key: 'type', | |||
| width: '20%', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| render: tableCellRender(false), | |||
| }, | |||
| { | |||
| title: '取值范围', | |||
| @@ -64,7 +62,6 @@ function ParameterInfo({ info }: ParameterInfoProps) { | |||
| return JSON.stringify(value); | |||
| }, | |||
| }), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| ]; | |||
| @@ -81,7 +78,6 @@ function ParameterInfo({ info }: ParameterInfoProps) { | |||
| key: name, | |||
| width: 150, | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }; | |||
| }) | |||
| : []; | |||
| @@ -192,7 +192,6 @@ function MirrorList() { | |||
| key: 'description', | |||
| width: '35%', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '创建时间', | |||
| @@ -184,7 +184,6 @@ function ModelMetrics({ resourceId, identifier, owner, version }: ModelMetricsPr | |||
| width: 120, | |||
| align: 'center', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| sorter: (a, b) => tableSorter(a.params?.[name], b.params?.[name]), | |||
| showSorterTooltip: false, | |||
| })), | |||
| @@ -223,7 +222,6 @@ function ModelMetrics({ resourceId, identifier, owner, version }: ModelMetricsPr | |||
| width: 120, | |||
| align: 'center', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| sorter: (a, b) => tableSorter(a.metrics?.[name], b.metrics?.[name]), | |||
| showSorterTooltip: false, | |||
| })), | |||
| @@ -285,7 +285,6 @@ function ServiceInfo() { | |||
| key: 'model', | |||
| width: '20%', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '状态', | |||
| @@ -300,7 +299,6 @@ function ServiceInfo() { | |||
| key: 'image', | |||
| width: '20%', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '副本数量', | |||
| @@ -317,7 +315,6 @@ function ServiceInfo() { | |||
| render: tableCellRender(true, TableCellValueType.Custom, { | |||
| format: getResourceDescription, | |||
| }), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '操作', | |||
| @@ -161,7 +161,6 @@ const Pipeline = () => { | |||
| dataIndex: 'description', | |||
| key: 'description', | |||
| render: tableCellRender(true), | |||
| ellipsis: { showTitle: false }, | |||
| }, | |||
| { | |||
| title: '创建时间', | |||
| @@ -6,7 +6,7 @@ | |||
| import { isEmpty } from '@/utils'; | |||
| import { formatDate } from '@/utils/date'; | |||
| import { Typography } from 'antd'; | |||
| import { Tooltip, TooltipProps, Typography } from 'antd'; | |||
| import dayjs from 'dayjs'; | |||
| export enum TableCellValueType { | |||
| @@ -65,7 +65,7 @@ function formatArray(property?: string): TableCellFormatter { | |||
| } | |||
| function tableCellRender<T>( | |||
| ellipsis: boolean = false, | |||
| ellipsis: boolean | TooltipProps | 'auto' = false, | |||
| type: TableCellValueType = TableCellValueType.Text, | |||
| options?: TableCellValueOptions<T>, | |||
| ) { | |||
| @@ -92,14 +92,26 @@ function tableCellRender<T>( | |||
| break; | |||
| } | |||
| return renderCell(text, ellipsis, type, record, options?.onClick); | |||
| if (ellipsis === 'auto' && text) { | |||
| return renderCell(type, text, 'auto', record, options?.onClick); | |||
| } else if (ellipsis && text) { | |||
| const tooltipProps = typeof ellipsis === 'object' ? ellipsis : {}; | |||
| const { overlayStyle, ...rest } = tooltipProps; | |||
| return ( | |||
| <Tooltip {...rest} overlayStyle={{ maxWidth: 400, ...overlayStyle }} title={text}> | |||
| {renderCell(type, text, true, record, options?.onClick)} | |||
| </Tooltip> | |||
| ); | |||
| } else { | |||
| return renderCell(type, text, false, record, options?.onClick); | |||
| } | |||
| }; | |||
| } | |||
| function renderCell<T>( | |||
| type: TableCellValueType, | |||
| text: any | undefined | null, | |||
| ellipsis: boolean, | |||
| type: TableCellValueType = TableCellValueType.Text, | |||
| ellipsis: boolean | 'auto', | |||
| record: T, | |||
| onClick?: (record: T, e: React.MouseEvent) => void, | |||
| ) { | |||
| @@ -108,30 +120,9 @@ function renderCell<T>( | |||
| : renderText(text, ellipsis); | |||
| } | |||
| function renderText(text: any | undefined | null, ellipsis: boolean) { | |||
| return ( | |||
| <Typography.Paragraph | |||
| style={{ marginBottom: 0 }} | |||
| ellipsis={ | |||
| ellipsis && !isEmpty(text) | |||
| ? { | |||
| tooltip: { | |||
| title: text, | |||
| destroyTooltipOnHide: true, | |||
| overlayStyle: { maxWidth: 400 }, | |||
| }, | |||
| } | |||
| : false | |||
| } | |||
| > | |||
| {!isEmpty(text) ? text : '--'} | |||
| </Typography.Paragraph> | |||
| ); | |||
| } | |||
| function renderLink<T>( | |||
| text: any | undefined | null, | |||
| ellipsis: boolean, | |||
| ellipsis: boolean | 'auto', | |||
| record: T, | |||
| onClick?: (record: T, e: React.MouseEvent) => void, | |||
| ) { | |||
| @@ -142,4 +133,42 @@ function renderLink<T>( | |||
| ); | |||
| } | |||
| function renderText(text: any | undefined | null, ellipsis: boolean | 'auto') { | |||
| if (ellipsis === 'auto') { | |||
| return ( | |||
| <Typography.Paragraph | |||
| style={{ marginBottom: 0 }} | |||
| ellipsis={{ | |||
| tooltip: { | |||
| title: text, | |||
| destroyTooltipOnHide: true, | |||
| overlayStyle: { maxWidth: 400 }, | |||
| }, | |||
| }} | |||
| > | |||
| {!isEmpty(text) ? text : '--'} | |||
| </Typography.Paragraph> | |||
| ); | |||
| } | |||
| return ( | |||
| <span | |||
| style={ | |||
| ellipsis | |||
| ? { | |||
| whiteSpace: 'nowrap', | |||
| overflow: 'hidden', | |||
| textOverflow: 'ellipsis', | |||
| wordBreak: 'break-all', | |||
| display: 'inline-block', | |||
| maxWidth: '100%', | |||
| } | |||
| : undefined | |||
| } | |||
| > | |||
| {!isEmpty(text) ? text : '--'} | |||
| </span> | |||
| ); | |||
| } | |||
| export default tableCellRender; | |||