Browse Source

fix: 统一tablecell render

pull/137/head
cp3hnu 1 year ago
parent
commit
a7c743e825
12 changed files with 149 additions and 160 deletions
  1. +0
    -25
      react-ui/src/components/CommonTableCell/index.tsx
  2. +0
    -20
      react-ui/src/components/DateTableCell/index.tsx
  3. +9
    -14
      react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx
  4. +5
    -6
      react-ui/src/pages/DevelopmentEnvironment/List/index.tsx
  5. +7
    -6
      react-ui/src/pages/Experiment/Comparison/index.tsx
  6. +7
    -11
      react-ui/src/pages/Experiment/index.jsx
  7. +5
    -6
      react-ui/src/pages/Mirror/Info/index.tsx
  8. +5
    -6
      react-ui/src/pages/Mirror/List/index.tsx
  9. +12
    -16
      react-ui/src/pages/ModelDeployment/List/index.tsx
  10. +10
    -17
      react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx
  11. +12
    -15
      react-ui/src/pages/Pipeline/index.jsx
  12. +77
    -18
      react-ui/src/utils/table.tsx

+ 0
- 25
react-ui/src/components/CommonTableCell/index.tsx View File

@@ -1,25 +0,0 @@
/*
* @Author: 赵伟
* @Date: 2024-04-28 14:18:11
* @Description: 自定义 Table 单元格,没有数据时展示 --
*/

import { Tooltip } from 'antd';

function renderCell(text?: any | null) {
return <span>{text ?? '--'}</span>;
}

function CommonTableCell(ellipsis: boolean = false) {
if (ellipsis) {
return (text?: any | null) => (
<Tooltip title={text} placement="topLeft" overlayStyle={{ maxWidth: '400px' }}>
{renderCell(text)}
</Tooltip>
);
} else {
return renderCell;
}
}

export default CommonTableCell;

+ 0
- 20
react-ui/src/components/DateTableCell/index.tsx View File

@@ -1,20 +0,0 @@
/*
* @Author: 赵伟
* @Date: 2024-04-28 14:18:11
* @Description: 自定义 Table 日期类单元格
*/

import { formatDate } from '@/utils/date';
import dayjs from 'dayjs';

function DateTableCell(text?: string | null) {
if (text === undefined || text === null || text === '') {
return <span>--</span>;
}
if (!dayjs(text).isValid()) {
return <span>无效的日期</span>;
}
return <span>{formatDate(text)}</span>;
}

export default DateTableCell;

+ 9
- 14
react-ui/src/pages/Dataset/components/ResourceVersion/index.tsx View File

@@ -1,5 +1,3 @@
import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import {
ResourceData,
@@ -8,7 +6,8 @@ import {
resourceConfig,
} from '@/pages/Dataset/config';
import { downLoadZip } from '@/utils/downloadfile';
import { Button, Flex, Table } from 'antd';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { Button, Flex, Table, TableProps } from 'antd';
import styles from './index.less';

type ResourceVersionProps = {
@@ -38,37 +37,33 @@ function ResourceVersion({ resourceType, info }: ResourceVersionProps) {
downLoadZip(url, { url: record.url });
};

const columns = [
const columns: TableProps<ResourceFileData>['columns'] = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
width: 80,
render(_text: string, _record: ResourceFileData, index: number) {
return <span>{index + 1}</span>;
},
render: tableCellRender(false, TableCellValueType.Index),
},
{
title: '文件名称',
dataIndex: 'file_name',
key: 'file_name',
render: (text: string, record: ResourceFileData) => (
<a className="kf-table-row-link" onClick={() => downloadAlone(record)}>
{text}
</a>
),
render: tableCellRender(false, TableCellValueType.Link, {
onClick: downloadAlone,
}),
},
{
title: '文件大小',
dataIndex: 'file_size',
key: 'file_size',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '更新时间',
dataIndex: 'update_time',
key: 'update_time',
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',


+ 5
- 6
react-ui/src/pages/DevelopmentEnvironment/List/index.tsx View File

@@ -4,8 +4,6 @@
* @Description: 开发环境列表
*/

import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import { DevEditorStatus } from '@/enums';
import { useCacheState } from '@/hooks/pageCacheState';
@@ -19,6 +17,7 @@ import themes from '@/styles/theme.less';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import {
@@ -153,7 +152,7 @@ function EditorList() {
};

// 分页切换
const handleTableChange: TableProps['onChange'] = (pagination, filters, sorter, { action }) => {
const handleTableChange: TableProps['onChange'] = (pagination, _filters, _sorter, { action }) => {
if (action === 'paginate') {
setPagination(pagination);
}
@@ -186,21 +185,21 @@ function EditorList() {
dataIndex: 'computing_resource',
key: 'computing_resource',
width: '20%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '创建者',
dataIndex: 'update_by',
key: 'update_by',
width: '20%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
width: '20%',
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',


+ 7
- 6
react-ui/src/pages/Experiment/Comparison/index.tsx View File

@@ -5,7 +5,7 @@ import {
getExpTrainInfosReq,
} from '@/services/experiment';
import { to } from '@/utils/promise';
import tableCellRender, { arrayFormatter, dateFormatter } from '@/utils/table';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { useSearchParams } from '@umijs/max';
import { App, Button, Table, /* TablePaginationConfig,*/ TableProps, Tooltip } from 'antd';
import classNames from 'classnames';
@@ -23,7 +23,7 @@ type TableData = {
metrics_names: string[];
metrics: Record<string, number>;
params_names: string[];
params: Record<string, string>;
params: Record<string, number>;
};

function ExperimentComparison() {
@@ -98,11 +98,12 @@ function ExperimentComparison() {
},
};

const columns: TableProps['columns'] = useMemo(() => {
const columns: TableProps<TableData>['columns'] = useMemo(() => {
const first: TableData | undefined = tableData[0];
return [
{
title: '基本信息',
align: 'center',
children: [
{
title: '实例 ID',
@@ -120,7 +121,7 @@ function ExperimentComparison() {
width: 180,
fixed: 'left',
align: 'center',
render: tableCellRender(false, dateFormatter),
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '运行状态',
@@ -128,7 +129,7 @@ function ExperimentComparison() {
key: 'status',
width: 100,
fixed: 'left',
align: 'center',
// align: 'center',
render: ExperimentStatusCell,
},
{
@@ -138,7 +139,7 @@ function ExperimentComparison() {
width: 180,
fixed: 'left',
align: 'center',
render: tableCellRender(true, arrayFormatter()),
render: tableCellRender(true, TableCellValueType.Array),
ellipsis: { showTitle: false },
},
],


+ 7
- 11
react-ui/src/pages/Experiment/index.jsx View File

@@ -1,4 +1,3 @@
import CommonTableCell from '@/components/CommonTableCell';
import KFIcon from '@/components/KFIcon';
import { ExperimentStatus, TensorBoardStatus } from '@/enums';
import {
@@ -15,6 +14,7 @@ import {
import { getWorkflow } from '@/services/pipeline/index.js';
import themes from '@/styles/theme.less';
import { to } from '@/utils/promise';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { App, Button, ConfigProvider, Dropdown, Space, Table } from 'antd';
import classNames from 'classnames';
@@ -273,8 +273,7 @@ function Experiment() {
};

// 跳转到流水线
const gotoPipeline = (e, record) => {
e.stopPropagation();
const gotoPipeline = (record) => {
navigate({ pathname: `/pipeline/template/info/${record.workflow_id}` });
};

@@ -348,25 +347,23 @@ function Experiment() {
title: '实验名称',
dataIndex: 'name',
key: 'name',
render: (text) => <div>{text}</div>,
render: tableCellRender(),
width: '16%',
},
{
title: '关联流水线名称',
dataIndex: 'workflow_name',
key: 'workflow_name',
render: (text, record) => (
<a className="kf-table-row-link" onClick={(e) => gotoPipeline(e, record)}>
{text}
</a>
),
render: tableCellRender(false, TableCellValueType.Link, {
onClick: gotoPipeline,
}),
width: '16%',
},
{
title: '实验描述',
dataIndex: 'description',
key: 'description',
render: CommonTableCell(true),
render: tableCellRender(true),
ellipsis: { showTitle: false },
},
{
@@ -395,7 +392,6 @@ function Experiment() {
);
},
},

{
title: '操作',
key: 'action',


+ 5
- 6
react-ui/src/pages/Mirror/Info/index.tsx View File

@@ -3,8 +3,6 @@
* @Date: 2024-04-16 13:58:08
* @Description: 镜像详情
*/
import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import PageTitle from '@/components/PageTitle';
import SubAreaTitle from '@/components/SubAreaTitle';
@@ -20,6 +18,7 @@ import themes from '@/styles/theme.less';
import { formatDate } from '@/utils/date';
import { to } from '@/utils/promise';
import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { useNavigate, useParams } from '@umijs/max';
import {
@@ -156,13 +155,13 @@ function MirrorInfo() {
dataIndex: 'tag_name',
key: 'tag_name',
width: '25%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '镜像地址',
dataIndex: 'url',
key: 'url',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '状态',
@@ -176,14 +175,14 @@ function MirrorInfo() {
dataIndex: 'file_size',
key: 'file_size',
width: 150,
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
width: 200,
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',


+ 5
- 6
react-ui/src/pages/Mirror/List/index.tsx View File

@@ -3,8 +3,6 @@
* @Date: 2024-04-16 13:58:08
* @Description: 镜像列表
*/
import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import { CommonTabKeys } from '@/enums';
import { useCacheState } from '@/hooks/pageCacheState';
@@ -12,6 +10,7 @@ import { deleteMirrorReq, getMirrorListReq } from '@/services/mirror';
import themes from '@/styles/theme.less';
import { to } from '@/utils/promise';
import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import {
@@ -169,21 +168,21 @@ function MirrorList() {
dataIndex: 'name',
key: 'name',
width: '30%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '版本数据',
dataIndex: 'version_count',
key: 'version_count',
width: '15%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '镜像描述',
dataIndex: 'description',
key: 'description',
width: '35%',
render: CommonTableCell(true),
render: tableCellRender(true),
ellipsis: { showTitle: false },
},
{
@@ -191,7 +190,7 @@ function MirrorList() {
dataIndex: 'create_time',
key: 'create_time',
width: '20%',
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',


+ 12
- 16
react-ui/src/pages/ModelDeployment/List/index.tsx View File

@@ -3,8 +3,6 @@
* @Date: 2024-04-16 13:58:08
* @Description: 模型部署服务列表
*/
import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import PageTitle from '@/components/PageTitle';
import { serviceTypeOptions } from '@/enums';
@@ -13,6 +11,7 @@ import { deleteServiceReq, getServiceListReq } from '@/services/modelDeployment'
import themes from '@/styles/theme.less';
import { to } from '@/utils/promise';
import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import {
@@ -190,42 +189,39 @@ function ModelDeployment() {
dataIndex: 'index',
key: 'index',
width: '20%',
render(_text, _record, index) {
return <span>{(pagination.current! - 1) * pagination.pageSize! + index + 1}</span>;
},
render: tableCellRender(false, TableCellValueType.PageIndex, {
page: pagination.current! - 1,
pageSize: pagination.pageSize!,
}),
},
{
title: '服务名称',
dataIndex: 'service_name',
key: 'service_name',
width: '20%',
render: (text, record) => {
return (
<a className="kf-table-row-link" onClick={() => toDetail(record)}>
{text}
</a>
);
},
render: tableCellRender(false, TableCellValueType.Link, {
onClick: toDetail,
}),
},
{
title: '服务类型',
dataIndex: 'service_type_name',
key: 'service_type_name',
width: '20%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '版本数量',
dataIndex: 'version_count',
key: 'version_count',
width: '20%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '服务描述',
dataIndex: 'description',
key: 'description',
render: CommonTableCell(),
render: tableCellRender(),
width: '20%',
},
{
@@ -233,7 +229,7 @@ function ModelDeployment() {
dataIndex: 'update_time',
key: 'update_time',
width: '20%',
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',


+ 10
- 17
react-ui/src/pages/ModelDeployment/ServiceInfo/index.tsx View File

@@ -4,7 +4,6 @@
* @Description: 模型部署列表
*/
import BasicInfo from '@/components/BasicInfo';
import CommonTableCell from '@/components/CommonTableCell';
import KFIcon from '@/components/KFIcon';
import PageTitle from '@/components/PageTitle';
import SubAreaTitle from '@/components/SubAreaTitle';
@@ -21,6 +20,7 @@ import themes from '@/styles/theme.less';
import { formatDate } from '@/utils/date';
import { to } from '@/utils/promise';
import SessionStorage from '@/utils/sessionStorage';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { useNavigate, useParams } from '@umijs/max';
import {
@@ -222,31 +222,24 @@ function ServiceInfo() {
dataIndex: 'index',
key: 'index',
width: '20%',
render(_text, _record, index) {
return <span>{(pagination.current! - 1) * pagination.pageSize! + index + 1}</span>;
},
render: tableCellRender(false, TableCellValueType.PageIndex, {
page: pagination.current! - 1,
pageSize: pagination.pageSize!,
}),
},
{
title: '服务版本',
dataIndex: 'version',
key: 'version',
width: '20%',
render: CommonTableCell(),
render: tableCellRender(),
},
{
title: '模型版本',
dataIndex: 'model',
dataIndex: ['model', 'show_value'],
key: 'model',
width: '20%',
render: (_text: string, record: ServiceVersionData) => (
<Tooltip
title={record.model.show_value}
placement="topLeft"
overlayStyle={{ maxWidth: '400px' }}
>
<span>{record.model.show_value}</span>
</Tooltip>
),
render: tableCellRender(true),
ellipsis: { showTitle: false },
},
{
@@ -261,14 +254,14 @@ function ServiceInfo() {
dataIndex: 'image',
key: 'image',
width: '20%',
render: CommonTableCell(true),
render: tableCellRender(true),
ellipsis: { showTitle: false },
},
{
title: '副本数量',
dataIndex: 'replicas',
key: 'replicas',
render: CommonTableCell(),
render: tableCellRender(),
width: '20%',
},
{


+ 12
- 15
react-ui/src/pages/Pipeline/index.jsx View File

@@ -1,5 +1,3 @@
import CommonTableCell from '@/components/CommonTableCell';
import DateTableCell from '@/components/DateTableCell';
import KFIcon from '@/components/KFIcon';
import KFModal from '@/components/KFModal';
import {
@@ -11,6 +9,7 @@ import {
removeWorkflow,
} from '@/services/pipeline/index.js';
import themes from '@/styles/theme.less';
import tableCellRender, { TableCellValueType } from '@/utils/table';
import { modalConfirm } from '@/utils/ui';
import { App, Button, ConfigProvider, Form, Input, Space, Table } from 'antd';
import classNames from 'classnames';
@@ -41,8 +40,7 @@ const Pipeline = () => {
}
});
};
const routeToEdit = (e, record) => {
e.stopPropagation();
const routeToEdit = (record) => {
navigate({ pathname: `/pipeline/template/info/${record.id}` });
};
const showModal = () => {
@@ -114,38 +112,37 @@ const Pipeline = () => {
key: 'index',
width: 120,
align: 'center',
render(text, record, index) {
return <span>{(pageOption.current.page - 1) * pageOption.current.size + index + 1}</span>;
},
render: tableCellRender(false, TableCellValueType.PageIndex, {
page: pageOption.current.page - 1,
size: pageOption.current.size,
}),
},
{
title: '流水线名称',
dataIndex: 'name',
key: 'name',
render: (text, record) => (
<a className="kf-table-row-link" onClick={(e) => routeToEdit(e, record)}>
{text}
</a>
),
render: tableCellRender(false, TableCellValueType.Link, {
onClick: routeToEdit,
}),
},
{
title: '流水线描述',
dataIndex: 'description',
key: 'description',
render: CommonTableCell(true),
render: tableCellRender(true),
ellipsis: { showTitle: false },
},
{
title: '创建时间',
dataIndex: 'create_time',
key: 'create_time',
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '修改时间',
dataIndex: 'update_time',
key: 'update_time',
render: DateTableCell,
render: tableCellRender(false, TableCellValueType.Date),
},
{
title: '操作',


+ 77
- 18
react-ui/src/utils/table.tsx View File

@@ -1,22 +1,33 @@
/*
* @Author: 赵伟
* @Date: 2024-06-26 10:05:52
* @Description: 列表自定义 render
* @Description: Table cell 自定义 render
*/

import { formatDate } from '@/utils/date';
import { Tooltip } from 'antd';
import dayjs from 'dayjs';

type TableCellFormatter = (value?: any | null) => string | undefined | null;
export enum TableCellValueType {
Index = 'Index',
PageIndex = 'PageIndex',
Text = 'Text',
Date = 'Date',
Array = 'Array',
Link = 'Link',
}

// 字符串转换函数
export const stringFormatter: TableCellFormatter = (value?: any | null) => {
return value;
export type TableCellValueOptions<T> = {
page?: number;
pageSize?: number;
property?: string;
onClick?: (record: T, e: React.MouseEvent) => void;
};

type TableCellFormatter = (value: any | undefined | null) => string | undefined | null;

// 日期转换函数
export const dateFormatter: TableCellFormatter = (value?: any | null) => {
const formatDateText: TableCellFormatter = (value?: any | null) => {
if (value === undefined || value === null || value === '') {
return null;
}
@@ -26,8 +37,12 @@ export const dateFormatter: TableCellFormatter = (value?: any | null) => {
return formatDate(value);
};

// 数组转换函数
export function arrayFormatter(property?: string) {
/**
* 数组转换函数,将数组元素转换为字符串,用逗号分隔
* @param {string} property 如果数组元素是对象,那么取数组元素的某个属性
* @returns {TableCellFormatter} Table cell 渲染函数
*/
function formatArray(property?: string): TableCellFormatter {
return (value?: any | null): ReturnType<TableCellFormatter> => {
if (
value === undefined ||
@@ -38,31 +53,75 @@ export function arrayFormatter(property?: string) {
return null;
}

let list = value;
if (property && typeof value[0] === 'object') {
list = value.map((item) => item[property]);
}
const list =
property && typeof value[0] === 'object' ? value.map((item) => item[property]) : value;
return list.join(',');
};
}

function tableCellRender(ellipsis: boolean = false, format: TableCellFormatter = stringFormatter) {
return (value?: any | null) => {
const text = format(value);
function tableCellRender<T>(
ellipsis: boolean = false,
type: TableCellValueType = TableCellValueType.Text,
options?: TableCellValueOptions<T>,
) {
return (value: any | undefined | null, record: T, index: number) => {
let text = value;
switch (type) {
case TableCellValueType.Index:
text = index + 1;
break;
case TableCellValueType.PageIndex:
text = (options?.page ?? 1) * (options?.pageSize ?? 10) + index + 1;
break;
case TableCellValueType.Text:
case TableCellValueType.Link:
text = value;
break;
case TableCellValueType.Date:
text = formatDateText(value);
break;
case TableCellValueType.Array:
text = formatArray(options?.property)(value);
break;
default:
break;
}

if (ellipsis && text) {
return (
<Tooltip title={text} placement="topLeft" overlayStyle={{ maxWidth: '400px' }}>
{renderCell(text)}
{renderCell(text, type === TableCellValueType.Link, record, options?.onClick)}
</Tooltip>
);
} else {
return renderCell(text);
return renderCell(text, type === TableCellValueType.Link, record, options?.onClick);
}
};
}

function renderCell(text?: any | null) {
function renderCell<T>(
text: any | undefined | null,
isLink: boolean,
record: T,
onClick?: (record: T, e: React.MouseEvent) => void,
) {
return isLink ? renderLink(text, record, onClick) : renderText(text);
}

function renderText(text: any | undefined | null) {
return <span>{text ?? '--'}</span>;
}

function renderLink<T>(
text: any | undefined | null,
record: T,
onClick?: (record: T, e: React.MouseEvent) => void,
) {
return (
<a className="kf-table-row-link" onClick={(e) => onClick?.(record, e)}>
{text}
</a>
);
}

export default tableCellRender;

Loading…
Cancel
Save