| @@ -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; | |||||
| @@ -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; | |||||
| @@ -1,5 +1,3 @@ | |||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import DateTableCell from '@/components/DateTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { | import { | ||||
| ResourceData, | ResourceData, | ||||
| @@ -8,7 +6,8 @@ import { | |||||
| resourceConfig, | resourceConfig, | ||||
| } from '@/pages/Dataset/config'; | } from '@/pages/Dataset/config'; | ||||
| import { downLoadZip } from '@/utils/downloadfile'; | 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'; | import styles from './index.less'; | ||||
| type ResourceVersionProps = { | type ResourceVersionProps = { | ||||
| @@ -38,37 +37,33 @@ function ResourceVersion({ resourceType, info }: ResourceVersionProps) { | |||||
| downLoadZip(url, { url: record.url }); | downLoadZip(url, { url: record.url }); | ||||
| }; | }; | ||||
| const columns = [ | |||||
| const columns: TableProps<ResourceFileData>['columns'] = [ | |||||
| { | { | ||||
| title: '序号', | title: '序号', | ||||
| dataIndex: 'index', | dataIndex: 'index', | ||||
| key: 'index', | key: 'index', | ||||
| width: 80, | width: 80, | ||||
| render(_text: string, _record: ResourceFileData, index: number) { | |||||
| return <span>{index + 1}</span>; | |||||
| }, | |||||
| render: tableCellRender(false, TableCellValueType.Index), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '文件名称', | title: '文件名称', | ||||
| dataIndex: 'file_name', | dataIndex: 'file_name', | ||||
| key: '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: '文件大小', | title: '文件大小', | ||||
| dataIndex: 'file_size', | dataIndex: 'file_size', | ||||
| key: 'file_size', | key: 'file_size', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '更新时间', | title: '更新时间', | ||||
| dataIndex: 'update_time', | dataIndex: 'update_time', | ||||
| key: 'update_time', | key: 'update_time', | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| @@ -4,8 +4,6 @@ | |||||
| * @Description: 开发环境列表 | * @Description: 开发环境列表 | ||||
| */ | */ | ||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import DateTableCell from '@/components/DateTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { DevEditorStatus } from '@/enums'; | import { DevEditorStatus } from '@/enums'; | ||||
| import { useCacheState } from '@/hooks/pageCacheState'; | import { useCacheState } from '@/hooks/pageCacheState'; | ||||
| @@ -19,6 +17,7 @@ import themes from '@/styles/theme.less'; | |||||
| import { openAntdModal } from '@/utils/modal'; | import { openAntdModal } from '@/utils/modal'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | import SessionStorage from '@/utils/sessionStorage'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import { | 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') { | if (action === 'paginate') { | ||||
| setPagination(pagination); | setPagination(pagination); | ||||
| } | } | ||||
| @@ -186,21 +185,21 @@ function EditorList() { | |||||
| dataIndex: 'computing_resource', | dataIndex: 'computing_resource', | ||||
| key: 'computing_resource', | key: 'computing_resource', | ||||
| width: '20%', | width: '20%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '创建者', | title: '创建者', | ||||
| dataIndex: 'update_by', | dataIndex: 'update_by', | ||||
| key: 'update_by', | key: 'update_by', | ||||
| width: '20%', | width: '20%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '创建时间', | title: '创建时间', | ||||
| dataIndex: 'create_time', | dataIndex: 'create_time', | ||||
| key: 'create_time', | key: 'create_time', | ||||
| width: '20%', | width: '20%', | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| @@ -5,7 +5,7 @@ import { | |||||
| getExpTrainInfosReq, | getExpTrainInfosReq, | ||||
| } from '@/services/experiment'; | } from '@/services/experiment'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import tableCellRender, { arrayFormatter, dateFormatter } from '@/utils/table'; | |||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { useSearchParams } from '@umijs/max'; | import { useSearchParams } from '@umijs/max'; | ||||
| import { App, Button, Table, /* TablePaginationConfig,*/ TableProps, Tooltip } from 'antd'; | import { App, Button, Table, /* TablePaginationConfig,*/ TableProps, Tooltip } from 'antd'; | ||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
| @@ -23,7 +23,7 @@ type TableData = { | |||||
| metrics_names: string[]; | metrics_names: string[]; | ||||
| metrics: Record<string, number>; | metrics: Record<string, number>; | ||||
| params_names: string[]; | params_names: string[]; | ||||
| params: Record<string, string>; | |||||
| params: Record<string, number>; | |||||
| }; | }; | ||||
| function ExperimentComparison() { | 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]; | const first: TableData | undefined = tableData[0]; | ||||
| return [ | return [ | ||||
| { | { | ||||
| title: '基本信息', | title: '基本信息', | ||||
| align: 'center', | |||||
| children: [ | children: [ | ||||
| { | { | ||||
| title: '实例 ID', | title: '实例 ID', | ||||
| @@ -120,7 +121,7 @@ function ExperimentComparison() { | |||||
| width: 180, | width: 180, | ||||
| fixed: 'left', | fixed: 'left', | ||||
| align: 'center', | align: 'center', | ||||
| render: tableCellRender(false, dateFormatter), | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '运行状态', | title: '运行状态', | ||||
| @@ -128,7 +129,7 @@ function ExperimentComparison() { | |||||
| key: 'status', | key: 'status', | ||||
| width: 100, | width: 100, | ||||
| fixed: 'left', | fixed: 'left', | ||||
| align: 'center', | |||||
| // align: 'center', | |||||
| render: ExperimentStatusCell, | render: ExperimentStatusCell, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -138,7 +139,7 @@ function ExperimentComparison() { | |||||
| width: 180, | width: 180, | ||||
| fixed: 'left', | fixed: 'left', | ||||
| align: 'center', | align: 'center', | ||||
| render: tableCellRender(true, arrayFormatter()), | |||||
| render: tableCellRender(true, TableCellValueType.Array), | |||||
| ellipsis: { showTitle: false }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| ], | ], | ||||
| @@ -1,4 +1,3 @@ | |||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { ExperimentStatus, TensorBoardStatus } from '@/enums'; | import { ExperimentStatus, TensorBoardStatus } from '@/enums'; | ||||
| import { | import { | ||||
| @@ -15,6 +14,7 @@ import { | |||||
| import { getWorkflow } from '@/services/pipeline/index.js'; | import { getWorkflow } from '@/services/pipeline/index.js'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { App, Button, ConfigProvider, Dropdown, Space, Table } from 'antd'; | import { App, Button, ConfigProvider, Dropdown, Space, Table } from 'antd'; | ||||
| import classNames from 'classnames'; | 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}` }); | navigate({ pathname: `/pipeline/template/info/${record.workflow_id}` }); | ||||
| }; | }; | ||||
| @@ -348,25 +347,23 @@ function Experiment() { | |||||
| title: '实验名称', | title: '实验名称', | ||||
| dataIndex: 'name', | dataIndex: 'name', | ||||
| key: 'name', | key: 'name', | ||||
| render: (text) => <div>{text}</div>, | |||||
| render: tableCellRender(), | |||||
| width: '16%', | width: '16%', | ||||
| }, | }, | ||||
| { | { | ||||
| title: '关联流水线名称', | title: '关联流水线名称', | ||||
| dataIndex: 'workflow_name', | dataIndex: 'workflow_name', | ||||
| key: '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%', | width: '16%', | ||||
| }, | }, | ||||
| { | { | ||||
| title: '实验描述', | title: '实验描述', | ||||
| dataIndex: 'description', | dataIndex: 'description', | ||||
| key: 'description', | key: 'description', | ||||
| render: CommonTableCell(true), | |||||
| render: tableCellRender(true), | |||||
| ellipsis: { showTitle: false }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -395,7 +392,6 @@ function Experiment() { | |||||
| ); | ); | ||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| key: 'action', | key: 'action', | ||||
| @@ -3,8 +3,6 @@ | |||||
| * @Date: 2024-04-16 13:58:08 | * @Date: 2024-04-16 13:58:08 | ||||
| * @Description: 镜像详情 | * @Description: 镜像详情 | ||||
| */ | */ | ||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import DateTableCell from '@/components/DateTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import PageTitle from '@/components/PageTitle'; | import PageTitle from '@/components/PageTitle'; | ||||
| import SubAreaTitle from '@/components/SubAreaTitle'; | import SubAreaTitle from '@/components/SubAreaTitle'; | ||||
| @@ -20,6 +18,7 @@ import themes from '@/styles/theme.less'; | |||||
| import { formatDate } from '@/utils/date'; | import { formatDate } from '@/utils/date'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | import SessionStorage from '@/utils/sessionStorage'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate, useParams } from '@umijs/max'; | import { useNavigate, useParams } from '@umijs/max'; | ||||
| import { | import { | ||||
| @@ -156,13 +155,13 @@ function MirrorInfo() { | |||||
| dataIndex: 'tag_name', | dataIndex: 'tag_name', | ||||
| key: 'tag_name', | key: 'tag_name', | ||||
| width: '25%', | width: '25%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '镜像地址', | title: '镜像地址', | ||||
| dataIndex: 'url', | dataIndex: 'url', | ||||
| key: 'url', | key: 'url', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '状态', | title: '状态', | ||||
| @@ -176,14 +175,14 @@ function MirrorInfo() { | |||||
| dataIndex: 'file_size', | dataIndex: 'file_size', | ||||
| key: 'file_size', | key: 'file_size', | ||||
| width: 150, | width: 150, | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '创建时间', | title: '创建时间', | ||||
| dataIndex: 'create_time', | dataIndex: 'create_time', | ||||
| key: 'create_time', | key: 'create_time', | ||||
| width: 200, | width: 200, | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| @@ -3,8 +3,6 @@ | |||||
| * @Date: 2024-04-16 13:58:08 | * @Date: 2024-04-16 13:58:08 | ||||
| * @Description: 镜像列表 | * @Description: 镜像列表 | ||||
| */ | */ | ||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import DateTableCell from '@/components/DateTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import { CommonTabKeys } from '@/enums'; | import { CommonTabKeys } from '@/enums'; | ||||
| import { useCacheState } from '@/hooks/pageCacheState'; | import { useCacheState } from '@/hooks/pageCacheState'; | ||||
| @@ -12,6 +10,7 @@ import { deleteMirrorReq, getMirrorListReq } from '@/services/mirror'; | |||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | import SessionStorage from '@/utils/sessionStorage'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import { | import { | ||||
| @@ -169,21 +168,21 @@ function MirrorList() { | |||||
| dataIndex: 'name', | dataIndex: 'name', | ||||
| key: 'name', | key: 'name', | ||||
| width: '30%', | width: '30%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '版本数据', | title: '版本数据', | ||||
| dataIndex: 'version_count', | dataIndex: 'version_count', | ||||
| key: 'version_count', | key: 'version_count', | ||||
| width: '15%', | width: '15%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '镜像描述', | title: '镜像描述', | ||||
| dataIndex: 'description', | dataIndex: 'description', | ||||
| key: 'description', | key: 'description', | ||||
| width: '35%', | width: '35%', | ||||
| render: CommonTableCell(true), | |||||
| render: tableCellRender(true), | |||||
| ellipsis: { showTitle: false }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -191,7 +190,7 @@ function MirrorList() { | |||||
| dataIndex: 'create_time', | dataIndex: 'create_time', | ||||
| key: 'create_time', | key: 'create_time', | ||||
| width: '20%', | width: '20%', | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| @@ -3,8 +3,6 @@ | |||||
| * @Date: 2024-04-16 13:58:08 | * @Date: 2024-04-16 13:58:08 | ||||
| * @Description: 模型部署服务列表 | * @Description: 模型部署服务列表 | ||||
| */ | */ | ||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import DateTableCell from '@/components/DateTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import PageTitle from '@/components/PageTitle'; | import PageTitle from '@/components/PageTitle'; | ||||
| import { serviceTypeOptions } from '@/enums'; | import { serviceTypeOptions } from '@/enums'; | ||||
| @@ -13,6 +11,7 @@ import { deleteServiceReq, getServiceListReq } from '@/services/modelDeployment' | |||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | import SessionStorage from '@/utils/sessionStorage'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import { | import { | ||||
| @@ -190,42 +189,39 @@ function ModelDeployment() { | |||||
| dataIndex: 'index', | dataIndex: 'index', | ||||
| key: 'index', | key: 'index', | ||||
| width: '20%', | 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: '服务名称', | title: '服务名称', | ||||
| dataIndex: 'service_name', | dataIndex: 'service_name', | ||||
| key: 'service_name', | key: 'service_name', | ||||
| width: '20%', | 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: '服务类型', | title: '服务类型', | ||||
| dataIndex: 'service_type_name', | dataIndex: 'service_type_name', | ||||
| key: 'service_type_name', | key: 'service_type_name', | ||||
| width: '20%', | width: '20%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '版本数量', | title: '版本数量', | ||||
| dataIndex: 'version_count', | dataIndex: 'version_count', | ||||
| key: 'version_count', | key: 'version_count', | ||||
| width: '20%', | width: '20%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '服务描述', | title: '服务描述', | ||||
| dataIndex: 'description', | dataIndex: 'description', | ||||
| key: 'description', | key: 'description', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| width: '20%', | width: '20%', | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -233,7 +229,7 @@ function ModelDeployment() { | |||||
| dataIndex: 'update_time', | dataIndex: 'update_time', | ||||
| key: 'update_time', | key: 'update_time', | ||||
| width: '20%', | width: '20%', | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| @@ -4,7 +4,6 @@ | |||||
| * @Description: 模型部署列表 | * @Description: 模型部署列表 | ||||
| */ | */ | ||||
| import BasicInfo from '@/components/BasicInfo'; | import BasicInfo from '@/components/BasicInfo'; | ||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import PageTitle from '@/components/PageTitle'; | import PageTitle from '@/components/PageTitle'; | ||||
| import SubAreaTitle from '@/components/SubAreaTitle'; | import SubAreaTitle from '@/components/SubAreaTitle'; | ||||
| @@ -21,6 +20,7 @@ import themes from '@/styles/theme.less'; | |||||
| import { formatDate } from '@/utils/date'; | import { formatDate } from '@/utils/date'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | import SessionStorage from '@/utils/sessionStorage'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { useNavigate, useParams } from '@umijs/max'; | import { useNavigate, useParams } from '@umijs/max'; | ||||
| import { | import { | ||||
| @@ -222,31 +222,24 @@ function ServiceInfo() { | |||||
| dataIndex: 'index', | dataIndex: 'index', | ||||
| key: 'index', | key: 'index', | ||||
| width: '20%', | 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: '服务版本', | title: '服务版本', | ||||
| dataIndex: 'version', | dataIndex: 'version', | ||||
| key: 'version', | key: 'version', | ||||
| width: '20%', | width: '20%', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '模型版本', | title: '模型版本', | ||||
| dataIndex: 'model', | |||||
| dataIndex: ['model', 'show_value'], | |||||
| key: 'model', | key: 'model', | ||||
| width: '20%', | 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 }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -261,14 +254,14 @@ function ServiceInfo() { | |||||
| dataIndex: 'image', | dataIndex: 'image', | ||||
| key: 'image', | key: 'image', | ||||
| width: '20%', | width: '20%', | ||||
| render: CommonTableCell(true), | |||||
| render: tableCellRender(true), | |||||
| ellipsis: { showTitle: false }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| { | { | ||||
| title: '副本数量', | title: '副本数量', | ||||
| dataIndex: 'replicas', | dataIndex: 'replicas', | ||||
| key: 'replicas', | key: 'replicas', | ||||
| render: CommonTableCell(), | |||||
| render: tableCellRender(), | |||||
| width: '20%', | width: '20%', | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -1,5 +1,3 @@ | |||||
| import CommonTableCell from '@/components/CommonTableCell'; | |||||
| import DateTableCell from '@/components/DateTableCell'; | |||||
| import KFIcon from '@/components/KFIcon'; | import KFIcon from '@/components/KFIcon'; | ||||
| import KFModal from '@/components/KFModal'; | import KFModal from '@/components/KFModal'; | ||||
| import { | import { | ||||
| @@ -11,6 +9,7 @@ import { | |||||
| removeWorkflow, | removeWorkflow, | ||||
| } from '@/services/pipeline/index.js'; | } from '@/services/pipeline/index.js'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import tableCellRender, { TableCellValueType } from '@/utils/table'; | |||||
| import { modalConfirm } from '@/utils/ui'; | import { modalConfirm } from '@/utils/ui'; | ||||
| import { App, Button, ConfigProvider, Form, Input, Space, Table } from 'antd'; | import { App, Button, ConfigProvider, Form, Input, Space, Table } from 'antd'; | ||||
| import classNames from 'classnames'; | 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}` }); | navigate({ pathname: `/pipeline/template/info/${record.id}` }); | ||||
| }; | }; | ||||
| const showModal = () => { | const showModal = () => { | ||||
| @@ -114,38 +112,37 @@ const Pipeline = () => { | |||||
| key: 'index', | key: 'index', | ||||
| width: 120, | width: 120, | ||||
| align: 'center', | 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: '流水线名称', | title: '流水线名称', | ||||
| dataIndex: 'name', | dataIndex: 'name', | ||||
| key: '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: '流水线描述', | title: '流水线描述', | ||||
| dataIndex: 'description', | dataIndex: 'description', | ||||
| key: 'description', | key: 'description', | ||||
| render: CommonTableCell(true), | |||||
| render: tableCellRender(true), | |||||
| ellipsis: { showTitle: false }, | ellipsis: { showTitle: false }, | ||||
| }, | }, | ||||
| { | { | ||||
| title: '创建时间', | title: '创建时间', | ||||
| dataIndex: 'create_time', | dataIndex: 'create_time', | ||||
| key: 'create_time', | key: 'create_time', | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '修改时间', | title: '修改时间', | ||||
| dataIndex: 'update_time', | dataIndex: 'update_time', | ||||
| key: 'update_time', | key: 'update_time', | ||||
| render: DateTableCell, | |||||
| render: tableCellRender(false, TableCellValueType.Date), | |||||
| }, | }, | ||||
| { | { | ||||
| title: '操作', | title: '操作', | ||||
| @@ -1,22 +1,33 @@ | |||||
| /* | /* | ||||
| * @Author: 赵伟 | * @Author: 赵伟 | ||||
| * @Date: 2024-06-26 10:05:52 | * @Date: 2024-06-26 10:05:52 | ||||
| * @Description: 列表自定义 render | |||||
| * @Description: Table cell 自定义 render | |||||
| */ | */ | ||||
| import { formatDate } from '@/utils/date'; | import { formatDate } from '@/utils/date'; | ||||
| import { Tooltip } from 'antd'; | import { Tooltip } from 'antd'; | ||||
| import dayjs from 'dayjs'; | 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 === '') { | if (value === undefined || value === null || value === '') { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -26,8 +37,12 @@ export const dateFormatter: TableCellFormatter = (value?: any | null) => { | |||||
| return formatDate(value); | 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> => { | return (value?: any | null): ReturnType<TableCellFormatter> => { | ||||
| if ( | if ( | ||||
| value === undefined || | value === undefined || | ||||
| @@ -38,31 +53,75 @@ export function arrayFormatter(property?: string) { | |||||
| return null; | 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(','); | 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) { | if (ellipsis && text) { | ||||
| return ( | return ( | ||||
| <Tooltip title={text} placement="topLeft" overlayStyle={{ maxWidth: '400px' }}> | <Tooltip title={text} placement="topLeft" overlayStyle={{ maxWidth: '400px' }}> | ||||
| {renderCell(text)} | |||||
| {renderCell(text, type === TableCellValueType.Link, record, options?.onClick)} | |||||
| </Tooltip> | </Tooltip> | ||||
| ); | ); | ||||
| } else { | } 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>; | 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; | export default tableCellRender; | ||||