From ccfe0d981ac6ca5ad747befdf4455329c4259b5c Mon Sep 17 00:00:00 2001 From: cp3hnu Date: Fri, 13 Sep 2024 13:49:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=BC=94=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- react-ui/src/components/IFramePage/index.tsx | 3 +- .../src/components/ParameterSelect/config.tsx | 10 +- .../src/components/ResourceSelect/index.tsx | 5 +- .../components/ResourceInfo/index.less | 7 + .../Dataset/components/ResourceInfo/index.tsx | 44 ++++--- .../Dataset/components/ResourceList/index.tsx | 6 +- .../components/ModelEvolution/index.less | 9 +- .../Model/components/ModelEvolution/index.tsx | 13 +- .../Model/components/ModelEvolution/utils.tsx | 124 ++++++++++-------- .../Model/components/NodeTooltips/index.less | 2 + .../Model/components/NodeTooltips/index.tsx | 32 ++--- .../components/PipelineNodeDrawer/index.tsx | 5 +- .../ResourceSelectorModal/config.tsx | 115 ---------------- .../ResourceSelectorModal/index.tsx | 9 +- 14 files changed, 159 insertions(+), 225 deletions(-) diff --git a/react-ui/src/components/IFramePage/index.tsx b/react-ui/src/components/IFramePage/index.tsx index f76420a6..490c4fe8 100644 --- a/react-ui/src/components/IFramePage/index.tsx +++ b/react-ui/src/components/IFramePage/index.tsx @@ -9,6 +9,7 @@ import { } from '@/utils/sessionStorage'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; +import { createPortal } from 'react-dom'; import './index.less'; export enum IframePageType { @@ -61,7 +62,7 @@ function IframePage({ type, className, style }: IframePageProps) { return (
- {loading && } + {loading && createPortal(, document.body)}
); diff --git a/react-ui/src/components/ParameterSelect/config.tsx b/react-ui/src/components/ParameterSelect/config.tsx index 689f618d..3f9eb0fb 100644 --- a/react-ui/src/components/ParameterSelect/config.tsx +++ b/react-ui/src/components/ParameterSelect/config.tsx @@ -14,7 +14,15 @@ const filterResourceStandard: SelectProps['filterOpti }; // id 从 number 转换为 string -const convertId = (item: any) => ({ ...item, id: `${item.id}-${item.identifier}` }); +const convertId = (item: any) => ({ + ...item, + id: JSON.stringify({ + id: item.id, + name: item.name, + identifier: item.identifier, + owner: item.owner, + }), +}); export type SelectPropsConfig = { getOptions: () => Promise; // 获取下拉数据 diff --git a/react-ui/src/components/ResourceSelect/index.tsx b/react-ui/src/components/ResourceSelect/index.tsx index a7ca6514..a19ee1c2 100644 --- a/react-ui/src/components/ResourceSelect/index.tsx +++ b/react-ui/src/components/ResourceSelect/index.tsx @@ -37,7 +37,7 @@ function ResourceSelect({ type, value, onChange, ...rest }: ResourceSelectProps) onOk: (res) => { setSelectedResource(res); if (res) { - const { activeTab, id, name, version, path } = res; + const { activeTab, id, name, version, path, identifier, owner } = res; if (type === ResourceSelectorType.Mirror) { onChange?.({ value: path, @@ -50,8 +50,11 @@ function ResourceSelect({ type, value, onChange, ...rest }: ResourceSelectProps) } else { const jsonObj = { id, + name, version, path, + identifier, + owner, }; const jsonObjStr = JSON.stringify(jsonObj); const showValue = `${name}:${version}`; diff --git a/react-ui/src/pages/Dataset/components/ResourceInfo/index.less b/react-ui/src/pages/Dataset/components/ResourceInfo/index.less index 9da228b4..33ec2b6b 100644 --- a/react-ui/src/pages/Dataset/components/ResourceInfo/index.less +++ b/react-ui/src/pages/Dataset/components/ResourceInfo/index.less @@ -34,12 +34,19 @@ } &__bottom { + position: relative; height: calc(100% - 135px); padding: 8px 30px 20px; background: #ffffff; border-radius: 10px; box-shadow: 0px 2px 12px rgba(180, 182, 191, 0.09); + &__legend { + position: absolute; + top: 20px; + right: 30px; + } + :global { .ant-tabs { height: 100%; diff --git a/react-ui/src/pages/Dataset/components/ResourceInfo/index.tsx b/react-ui/src/pages/Dataset/components/ResourceInfo/index.tsx index 73aa2852..e3f31796 100644 --- a/react-ui/src/pages/Dataset/components/ResourceInfo/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceInfo/index.tsx @@ -11,14 +11,13 @@ import { ResourceVersionData, resourceConfig, } from '@/pages/Dataset/config'; +import GraphLegend from '@/pages/Model/components/GraphLegend'; import ModelEvolution from '@/pages/Model/components/ModelEvolution'; import { openAntdModal } from '@/utils/modal'; import { to } from '@/utils/promise'; -import { getSessionStorageItem, resourceItemKey } from '@/utils/sessionStorage'; import { modalConfirm } from '@/utils/ui'; import { useParams, useSearchParams } from '@umijs/max'; import { App, Button, Flex, Select, Tabs } from 'antd'; -import { pick } from 'lodash'; import { useEffect, useState } from 'react'; import AddVersionModal from '../AddVersionModal'; import ResourceIntro from '../ResourceIntro'; @@ -40,30 +39,32 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { const [info, setInfo] = useState({} as ResourceData); const locationParams = useParams(); const [searchParams] = useSearchParams(); + const resourceId = Number(locationParams.id); // 模型演化传入的 tab const defaultTab = searchParams.get('tab') || ResourceInfoTabKeys.Introduction; // 模型演化传入的版本 let versionParam = searchParams.get('version'); + const name = searchParams.get('name') || ''; + const owner = searchParams.get('owner') || ''; + const identifier = searchParams.get('identifier') || ''; const [versionList, setVersionList] = useState([]); const [version, setVersion] = useState(undefined); const [activeTab, setActiveTab] = useState(defaultTab); - const resourceId = Number(locationParams.id); const config = resourceConfig[resourceType]; const typeName = config.name; // 数据集/模型 const { message } = App.useApp(); useEffect(() => { - const info = getSessionStorageItem(resourceItemKey, true); - if (info) { - setInfo(info); - getVersionList(pick(info, ['owner', 'identifier'])); - } - }, [resourceId]); + getVersionList(); + }, [resourceId, owner, identifier]); useEffect(() => { if (version) { getResourceDetail({ - ...pick(info, ['owner', 'name', 'id', 'identifier']), + id: resourceId, + owner, + name, + identifier, version, }); } @@ -85,9 +86,14 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { }; // 获取版本列表 - const getVersionList = async (params: { owner: string; identifier: string }) => { + const getVersionList = async () => { const request = config.getVersions; - const [res] = await to(request(params)); + const [res] = await to( + request({ + owner, + identifier, + }), + ); if (res && res.data && res.data.length > 0) { setVersionList(res.data); if ( @@ -112,7 +118,7 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { resoureName: info.name, identifier: info.identifier, onOk: () => { - getVersionList(pick(info, ['owner', 'identifier'])); + getVersionList(); close(); }, }); @@ -127,13 +133,16 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { const deleteVersion = async () => { const request = config.deleteVersion; const params = { - ...pick(info, ['id', 'owner', 'identifier', 'relative_paths']), + id: resourceId, + owner, + identifier, + relative_paths: info.relative_paths, version, }; const [res] = await to(request(params)); if (res) { message.success('删除成功'); - getVersionList(pick(info, ['owner', 'identifier'])); + getVersionList(); } }; @@ -174,7 +183,7 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => { @@ -228,6 +237,9 @@ const ResourceInfo = ({ resourceType }: ResourceInfoProps) => {
setActiveTab(key)}> +
+ {activeTab === ResourceInfoTabKeys.Evolution && } +
); diff --git a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx index b5caf63c..d194540a 100644 --- a/react-ui/src/pages/Dataset/components/ResourceList/index.tsx +++ b/react-ui/src/pages/Dataset/components/ResourceList/index.tsx @@ -4,7 +4,6 @@ import { CommonTabKeys } from '@/enums'; import AddModelModal from '@/pages/Dataset/components/AddModelModal'; import { openAntdModal } from '@/utils/modal'; import { to } from '@/utils/promise'; -import { resourceItemKey, setSessionStorageItem } from '@/utils/sessionStorage'; import { modalConfirm } from '@/utils/ui'; import { useNavigate } from '@umijs/max'; import { App, Button, Input, Pagination, PaginationProps } from 'antd'; @@ -138,8 +137,9 @@ function ResourceList( activeTag: dataTag, }); const prefix = config.prefix; - setSessionStorageItem(resourceItemKey, record, true); - navigate(`/dataset/${prefix}/info/${record.id}`); + navigate( + `/dataset/${prefix}/info/${record.id}?name=${record.name}&owner=${record.owner}&identifier=${record.identifier}`, + ); }; // 分页切换 diff --git a/react-ui/src/pages/Model/components/ModelEvolution/index.less b/react-ui/src/pages/Model/components/ModelEvolution/index.less index 7459e707..b7f558f3 100644 --- a/react-ui/src/pages/Model/components/ModelEvolution/index.less +++ b/react-ui/src/pages/Model/components/ModelEvolution/index.less @@ -1,16 +1,11 @@ .model-evolution { width: 100%; height: 100%; + overflow-x: hidden; background-color: white; - &__top { - padding: 30px 0; - color: @text-color; - font-size: @font-size-content; - } - &__graph { - height: calc(100% - 92px); + height: calc(100%); background-color: @background-color; background-image: url(@/assets/img/pipeline-canvas-bg.png); background-size: 100% 100%; diff --git a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx index f6712051..63d116ad 100644 --- a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx +++ b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx @@ -9,9 +9,8 @@ import { getModelAtlasReq } from '@/services/dataset/index.js'; import themes from '@/styles/theme.less'; import { to } from '@/utils/promise'; import G6, { G6GraphEvent, Graph, INode } from '@antv/g6'; -import { Flex } from 'antd'; import { useEffect, useRef, useState } from 'react'; -import GraphLegend from '../GraphLegend'; + import NodeTooltips from '../NodeTooltips'; import styles from './index.less'; import type { ModelDepsData, ProjectDependency, TrainDataset } from './utils'; @@ -145,14 +144,15 @@ function ModelEvolution({ // 更加缩放,调整 tooltip 位置 const offsetX = (nodeWidth * zoom) / 4; const offsetY = (nodeHeight * zoom) / 4; + point.x += offsetX; const canvasWidth = graphRef.current!.clientWidth; - if (point.x + 300 > canvasWidth) { - point.x = canvasWidth - 300; + if (point.x + 300 > canvasWidth + 30) { + point.x = canvasWidth + 30 - 300; } setHoverNodeData(model); - setNodeToolTipX(point.x + offsetX); + setNodeToolTipX(point.x); setNodeToolTipY(graphRef.current!.clientHeight - point.y + offsetY); setShowNodeTooltip(true); }); @@ -248,9 +248,6 @@ function ModelEvolution({ return (
- - -
{(showNodeTooltip || enterTooltip) && ( , TreeGraphData { +export interface ModelDepsData extends Omit, TreeGraphData { children: ModelDepsData[]; expanded: boolean; // 是否展开 level: number; // 层级,从 0 开始 @@ -92,8 +93,11 @@ export function normalizeChildren(data: ModelDepsData[]) { item.model_type = NodeType.Children; item.expanded = false; item.level = 0; - item.datasetLen = item.train_dataset.length + item.test_dataset.length; - item.id = `$M_${item.current_model_id}_${item.version}`; + item.datasetLen = getDatasetLen( + item.model_meta.train_datasets, + item.model_meta.test_datasets, + ); + item.id = `$M_${item.repo_id}_${item.version}`; item.label = getLabel(item); item.style = getStyle(NodeType.Children); normalizeChildren(item.children); @@ -104,16 +108,17 @@ export function normalizeChildren(data: ModelDepsData[]) { // 获取 label export function getLabel(node: ModelDepsData | ModelDepsAPIData) { return ( - fittingString( - `${node.model_version_dependcy_vo.name ?? ''}`, - nodeWidth - labelPadding, - nodeFontSize, - ) + + fittingString(`${node.model_name ?? ''}`, nodeWidth - labelPadding, nodeFontSize) + '\n' + fittingString(`${node.version}`, nodeWidth - labelPadding, nodeFontSize) ); } +// 获取数据集数量 +export function getDatasetLen(train?: TrainDataset[], test?: TrainDataset[]) { + return (train?.length || 0) + (test?.length || 0); +} + // 获取 style export function getStyle(model_type: NodeType) { let fill = ''; @@ -148,41 +153,43 @@ export function getStyle(model_type: NodeType) { export function normalizeTreeData(apiData: ModelDepsAPIData): ModelDepsData { // 将 children_models 转换成 children let normalizedData = changePropertyName(apiData, { - children_models: 'children', + child_model_list: 'children', }) as ModelDepsData; // 设置当前模型的数据 normalizedData.model_type = NodeType.Current; - normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; + normalizedData.id = `$M_${normalizedData.repo_id}_${normalizedData.version}`; normalizedData.label = getLabel(normalizedData); normalizedData.style = getStyle(NodeType.Current); normalizedData.expanded = true; - normalizedData.datasetLen = - normalizedData.train_dataset.length + normalizedData.test_dataset.length; + normalizedData.datasetLen = getDatasetLen( + normalizedData.model_meta.train_datasets, + normalizedData.model_meta.test_datasets, + ); normalizeChildren(normalizedData.children as ModelDepsData[]); normalizedData.level = 0; // 将 parent_models 转换成树形结构 - let parent_models = normalizedData.parent_models || []; - while (parent_models.length > 0) { - const parent = parent_models[0]; + let parent_model = normalizedData.parent_model_vo; + while (parent_model) { + const parent = parent_model; normalizedData = { ...parent, expanded: false, level: 0, - datasetLen: parent.train_dataset.length + parent.test_dataset.length, + datasetLen: getDatasetLen(parent.model_meta.train_datasets, parent.model_meta.test_datasets), model_type: NodeType.Parent, - id: `$M_${parent.current_model_id}_${parent.version}`, + id: `$M_${parent.repo_id}_${parent.version}`, label: getLabel(parent), style: getStyle(NodeType.Parent), children: [ { ...normalizedData, - parent_models: [], + parent_model: null, }, ], }; - parent_models = normalizedData.parent_models || []; + parent_model = normalizedData.parent_model_vo; } return normalizedData; } @@ -195,11 +202,12 @@ export function getGraphData(data: ModelDepsData, hierarchyNodes: ModelDepsData[ getWidth: () => nodeWidth, getVGap: (node: NodeConfig) => { const model = node as ModelDepsData; - const { model_type, expanded, project_dependency } = model; + const { model_type, expanded, model_meta } = model; + const { project_depency } = model_meta; if (model_type === NodeType.Current || model_type === NodeType.Parent) { return vGap / 2; } - const selfGap = expanded && project_dependency?.url ? nodeHeight + vGap : 0; + const selfGap = expanded && project_depency?.url ? nodeHeight + vGap : 0; const nextNode = getSameHierarchyNextNode(model, hierarchyNodes); if (!nextNode) { return vGap / 2; @@ -254,28 +262,35 @@ const addDatasetDependency = ( nodes: NodeConfig[], edges: EdgeConfig[], ) => { - const { train_dataset, test_dataset, id } = data; - train_dataset.forEach((item) => { - item.id = `$DTrain_${id}_${item.dataset_id}_${item.dataset_version}`; + const { repo_id, model_meta } = data; + const { train_datasets, test_datasets } = model_meta; + train_datasets?.forEach((item) => { + if (!item.repo_id) { + item.repo_id = item.id; + } + item.id = `$DTrain_${repo_id}_${item.repo_id}_${item.version}`; item.model_type = NodeType.TrainDataset; item.style = getStyle(NodeType.TrainDataset); }); - test_dataset.forEach((item) => { - item.id = `$DTest_${id}_${item.dataset_id}_${item.dataset_version}`; + test_datasets?.forEach((item) => { + if (!item.repo_id) { + item.repo_id = item.id; + } + item.id = `$DTest_${repo_id}_${item.repo_id}_${item.version}`; item.model_type = NodeType.TestDataset; item.style = getStyle(NodeType.TestDataset); }); datasetNodes.length = 0; - const len = train_dataset.length + test_dataset.length; - [...train_dataset, ...test_dataset].forEach((item, index) => { + const len = getDatasetLen(train_datasets, test_datasets); + [...(train_datasets ?? []), ...(test_datasets ?? [])].forEach((item, index) => { const node = { ...item }; node.type = 'ellipse'; node.size = [ellipseWidth, nodeHeight]; node.label = - fittingString(node.dataset_name, ellipseWidth - labelPadding, nodeFontSize) + + fittingString(node.name, ellipseWidth - labelPadding, nodeFontSize) + '\n' + - fittingString(node.dataset_version, ellipseWidth - labelPadding, nodeFontSize); + fittingString(node.version, ellipseWidth - labelPadding, nodeFontSize); const half = len / 2 - 0.5; node.x = currentNode.x! - (half - index) * (ellipseWidth + datasetHGap); @@ -299,10 +314,11 @@ const addProjectDependency = ( nodes: NodeConfig[], edges: EdgeConfig[], ) => { - const { project_dependency, id } = data; - if (project_dependency?.url) { - const node = { ...project_dependency }; - node.id = `$P_${id}_${node.url}_${node.branch}`; + const { repo_id, model_meta } = data; + const { project_depency } = model_meta; + if (project_depency?.url) { + const node = { ...project_depency }; + node.id = `$P_${repo_id}_${node.url}_${node.branch}`; node.model_type = NodeType.Project; node.type = 'rect'; node.label = fittingString(node.name, nodeWidth - labelPadding, nodeFontSize); @@ -322,6 +338,7 @@ const addProjectDependency = ( } }; +/* // 判断两个矩形是否相交 function isRectanglesOverlap(rect1: Rect, rect2: Rect) { const a2x = rect1.x + rect1.width / 2; @@ -366,6 +383,7 @@ function adjustDatasetPosition(node: NodeConfig) { }); } } +*/ // 层级遍历树结构 export function traverseHierarchically(data: ModelDepsData | undefined): ModelDepsData[] { diff --git a/react-ui/src/pages/Model/components/NodeTooltips/index.less b/react-ui/src/pages/Model/components/NodeTooltips/index.less index 564fe812..eabb979a 100644 --- a/react-ui/src/pages/Model/components/NodeTooltips/index.less +++ b/react-ui/src/pages/Model/components/NodeTooltips/index.less @@ -2,6 +2,7 @@ position: absolute; bottom: -100px; left: -300px; + z-index: 10; width: 300px; padding: 10px; background: white; @@ -50,6 +51,7 @@ flex: 1; min-width: 0; font-weight: 500; + word-break: break-all; &:hover { text-decoration: underline @underline-color; diff --git a/react-ui/src/pages/Model/components/NodeTooltips/index.tsx b/react-ui/src/pages/Model/components/NodeTooltips/index.tsx index 4b978294..ebf2966a 100644 --- a/react-ui/src/pages/Model/components/NodeTooltips/index.tsx +++ b/react-ui/src/pages/Model/components/NodeTooltips/index.tsx @@ -14,9 +14,9 @@ function ModelInfo({ resourceId, data, onVersionChange }: ModelInfoProps) { const navigate = useNavigate(); const gotoExperimentPage = () => { - if (data.train_task?.ins_id) { + if (data.model_meta.train_task?.ins_id) { const { origin } = location; - const url = `${origin}/pipeline/experiment/instance/${data.workflow_id}/${data.train_task.ins_id}`; + const url = `${origin}/pipeline/experiment/instance/${data.model_meta.train_task.task_id}/${data.model_meta.train_task.ins_id}`; window.open(url, '_blank'); } }; @@ -25,10 +25,10 @@ function ModelInfo({ resourceId, data, onVersionChange }: ModelInfoProps) { if (data.model_type === NodeType.Current) { return; } - if (data.current_model_id === resourceId) { + if (data.repo_id === resourceId) { onVersionChange?.(data.version); } else { - const path = `/dataset/model/info/${data.current_model_id}?tab=${ResourceInfoTabKeys.Evolution}&version=${data.version}`; + const path = `/dataset/model/info/${data.repo_id}?tab=${ResourceInfoTabKeys.Evolution}&version=${data.version}&name=${data.model_name}&owner=${data.owner}&identifier=${data.identifier}`; navigate(path); } }; @@ -40,12 +40,10 @@ function ModelInfo({ resourceId, data, onVersionChange }: ModelInfoProps) {
模型名称: {data.model_type === NodeType.Current ? ( - - {data.model_version_dependcy_vo?.name || '--'} - + {data.model_name || '--'} ) : ( 模型框架: - {data.model_version_dependcy_vo?.model_type_name || '--'} + {data.model_meta.model_type || '--'}
模型大小: - {data.model_version_dependcy_vo?.file_size || '--'} + {data.model_meta.file_size || '--'}
创建时间: - {formatDate(data.model_version_dependcy_vo?.create_time)} + {formatDate(data.model_meta.create_time || '--')}
模型权限: - {data.model_version_dependcy_vo?.available_range === 1 ? '公开' : '私有'} + {data.model_meta.is_public ? '公开' : '私有'}
@@ -86,7 +84,7 @@ function ModelInfo({ resourceId, data, onVersionChange }: ModelInfoProps) {
训练任务: { const { origin } = location; - const url = `${origin}/dataset/dataset/info/${data.dataset_id}?tab=${ResourceInfoTabKeys.Version}&version=${data.dataset_version}`; + const url = `${origin}/dataset/dataset/info/${data.repo_id}?tab=${ResourceInfoTabKeys.Version}&version=${data.version}&name=${data.name}&owner=${data.owner}&identifier=${data.identifier}`; window.open(url, '_blank'); }; @@ -111,7 +109,7 @@ function DatasetInfo({ data }: { data: TrainDataset }) {
数据集名称:
数据集版本: - - {data.dataset_version || '--'} - + {data.version || '--'}
diff --git a/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx b/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx index b5e2eccd..1cea7dca 100644 --- a/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx +++ b/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx @@ -204,11 +204,14 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete }); } } else { - const { activeTab, id, name, version, path } = res; + const { activeTab, id, name, version, path, identifier, owner } = res; const value = JSON.stringify({ id, + name, version, path, + identifier, + owner, }); const showValue = `${name}:${version}`; form.setFieldValue(formItemName, { diff --git a/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx b/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx index d955d4ae..c4e8af4a 100644 --- a/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx +++ b/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx @@ -74,121 +74,6 @@ const convertMirrorVersionToTreeData = ( })); }; -// 从树形数据节点 id 中获取数据集版本列表的参数 -// const parseDatasetVersionId = (id: string) => { -// const list = id.split('-'); -// return { -// id: Number(list[0]), -// name: list[1], -// owner: list[2], -// identifier: list[3], -// version: list[4], -// }; -// }; - -// 从树形数据节点 id 中获取数据集版本列表的参数 -// const parseMirrorVersionId = (id: string) => { -// const list = id.split('-'); -// return { -// parentId: Number(list[0]), -// id: list[1], -// url: list[2], -// }; -// }; - -// export type MirrorVersion = { -// id: number; // 镜像版本 id -// status: MirrorVersionStatus; // 镜像版本状态 -// tag_name: string; // 镜像版本 name -// url: string; // 镜像版本路径 -// }; - -// export type SelectorTypeInfo = { -// getList: (params: any) => Promise; // 获取资源列表 -// getVersions: (params: any) => Promise; // 获取资源版本列表 -// getFiles: (params: any) => Promise; // 获取资源文件列表 -// handleVersionResponse: (res: any) => any[]; // 处理版本列表接口数据 -// dataToTreeData: (data: any) => TreeDataNode[]; // 数据转树形结构 -// parseTreeNodeId: (id: string) => any; // 获取版本列表请求参数 -// modalIcon: string; // modal icon -// buttonIcon: string; // button icon -// name: string; // 名称 -// litReqParamKey: 'available_range' | 'image_type'; // 表示是公开还是私有的参数名称,获取资源列表接口使用 -// tabItems: TabsProps['items']; // tab 列表 -// buttontTitle: string; // 按钮 title -// }; - -// export const selectorTypeConfig: Record = { -// [ResourceSelectorType.Model]: { -// getList: getModelList, -// getVersions: getModelVersionList, -// getFiles: getModelVersionIdList, - -// name: '模型', -// modalIcon: modelImg, -// buttonIcon: 'icon-xuanzemoxing', -// litReqParamKey: 'available_range', -// tabItems: [ -// { -// key: CommonTabKeys.Private, -// label: '我的模型', -// }, -// { -// key: CommonTabKeys.Public, -// label: '公开模型', -// }, -// ], -// buttontTitle: '选择模型', -// }, -// [ResourceSelectorType.Dataset]: { -// getList: getDatasetList, -// getVersions: getDatasetVersionList, -// getFiles: getDatasetInfo, - -// name: '数据集', -// modalIcon: datasetImg, -// buttonIcon: 'icon-xuanzeshujuji', -// litReqParamKey: 'available_range', -// tabItems: [ -// { -// key: CommonTabKeys.Private, -// label: '我的数据集', -// }, -// { -// key: CommonTabKeys.Public, -// label: '公开数据集', -// }, -// ], -// buttontTitle: '选择数据集', -// }, -// [ResourceSelectorType.Mirror]: { -// getList: getMirrorListReq, -// getVersions: (id: number) => getMirrorVersionListReq({ image_id: id, page: 0, size: 200 }), -// getFiles: getMirrorFilesReq, -// handleVersionResponse: (res) => -// res.data?.content?.filter( -// (v: MirrorVersionData) => v.status === MirrorVersionStatus.Available, -// ) || [], -// dataToTreeData: convertMirrorToTreeData, -// parseTreeNodeId: (id: string) => id, -// name: '镜像', -// modalIcon: mirrorImg, -// buttonIcon: 'icon-xuanzejingxiang', -// litReqParamKey: 'image_type', -// tabItems: [ -// { -// key: CommonTabKeys.Private, -// label: '我的镜像', -// }, -// { -// key: CommonTabKeys.Public, -// label: '公开镜像', -// }, -// ], -// buttontTitle: '选择镜像', -// }, -// }; - interface SelectorTypeInfo { getList: (isPublic: boolean) => Promise; // 获取资源列表 getVersions: (parentKey: string, parentNode: any) => Promise; // 获取资源版本列表 diff --git a/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/index.tsx b/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/index.tsx index c94db87f..ed6ed80e 100644 --- a/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/index.tsx +++ b/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/index.tsx @@ -22,6 +22,8 @@ export type ResourceSelectorResponse = { name: string; // 数据集\模型\镜像 name version: string; // 数据集\模型\镜像版本 path: string; // 数据集\模型\镜像版本路径 + identifier: string; // 数据集\模型 identifier + owner: string; // 数据集\模型 owner activeTab: CommonTabKeys; // 是我的还是公开的 }; @@ -221,12 +223,17 @@ function ResourceSelectorModal({ if (checkedKeys.length > 0) { const last = checkedKeys[0] as string; const { id, version } = getIdAndVersion(last); - const name = (treeData.find((v) => v.key === id)?.title ?? '') as string; + const treeNode = treeData.find((v) => v.key === id) as any; + const name = (treeNode?.title ?? '') as string; + const identifier = (treeNode?.identifier ?? '') as string; + const owner = (treeNode?.owner ?? '') as string; const res = { id, name, path: versionPath, version, + identifier, + owner, activeTab: activeTab as CommonTabKeys, }; onOk?.(res);