diff --git a/react-ui/src/components/ParameterSelect/config.tsx b/react-ui/src/components/ParameterSelect/config.tsx index 84c99914..eae63ec2 100644 --- a/react-ui/src/components/ParameterSelect/config.tsx +++ b/react-ui/src/components/ParameterSelect/config.tsx @@ -17,10 +17,10 @@ const filterResourceStandard: SelectProps['filterOpti const convertId = (item: any) => ({ ...item, id: String(item.id) }); export type SelectPropsConfig = { - getOptions: () => Promise; - fieldNames?: SelectProps['fieldNames']; - optionFilterProp?: SelectProps['optionFilterProp']; - filterOption?: SelectProps['filterOption']; + getOptions: () => Promise; // 获取下拉数据 + fieldNames?: SelectProps['fieldNames']; // 下拉数据字段 + optionFilterProp?: SelectProps['optionFilterProp']; // 过滤字段名 + filterOption?: SelectProps['filterOption']; // 过滤函数 }; export const paramSelectConfig: Record = { diff --git a/react-ui/src/hooks/sessionStorage.ts b/react-ui/src/hooks/sessionStorage.ts index 5c765370..e2996a5d 100644 --- a/react-ui/src/hooks/sessionStorage.ts +++ b/react-ui/src/hooks/sessionStorage.ts @@ -1,7 +1,7 @@ import { getSessionStorageItem, removeSessionStorageItem } from '@/utils/sessionStorage'; import { useEffect, useState } from 'react'; -// 获取缓存数据 +// 读取缓存数据,组件卸载时清除缓存 export function useSessionStorage(key: string, isObject: boolean, initialValue: T) { const [storage, setStorage] = useState(initialValue); diff --git a/react-ui/src/pages/Dataset/config.tsx b/react-ui/src/pages/Dataset/config.tsx index be31f697..822b7bfe 100644 --- a/react-ui/src/pages/Dataset/config.tsx +++ b/react-ui/src/pages/Dataset/config.tsx @@ -24,32 +24,32 @@ export enum ResourceType { } type ResourceTypeInfo = { - getList: (params: any) => Promise; - getVersions: (params: any) => Promise; - getFiles: (params: any) => Promise; - deleteRecord: (params: any) => Promise; - addVersion: (params: any) => Promise; - deleteVersion: (params: any) => Promise; - getInfo: (params: any) => Promise; - name: string; - typeParamKey: string; - tagParamKey: string; - fileReqParamKey: 'models_id' | 'dataset_id'; - tabItems: TabsProps['items']; - typeTitle: string; - tagTitle: string; + getList: (params: any) => Promise; // 获取资源列表 + getVersions: (params: any) => Promise; // 获取版本列表 + getFiles: (params: any) => Promise; // 获取版本下的文件列表 + deleteRecord: (params: any) => Promise; // 删除 + addVersion: (params: any) => Promise; // 新增版本 + deleteVersion: (params: any) => Promise; // 删除版本 + getInfo: (params: any) => Promise; // 获取详情 + name: string; // 名称 + typeParamKey: string; // 类型参数名称,获取资源列表接口使用 + tagParamKey: string; // 标签参数名称,获取资源列表接口使用 + fileReqParamKey: 'models_id' | 'dataset_id'; // 文件请求参数名称,获取文件列表接口使用 + tabItems: TabsProps['items']; // tab 列表 + typeTitle: string; // 类型标题 + tagTitle: string; // 标签标题 typeValue: number; // 从 getAssetIcon 接口获取特定值的数据为 type 分类 (category_id === typeValue) tagValue: number; // 从 getAssetIcon 接口获取特定值的数据为 tag 分类(category_id === tagValue) - prefix: string; // 前缀 + prefix: string; // 图片资源、详情 url 的前缀 deleteModalTitle: string; // 删除弹框的title addBtnTitle: string; // 新增按钮的title - idParamKey: 'models_id' | 'dataset_id'; - uploadAction: string; - uploadAccept?: string; - downloadAllAction: string; - downloadSingleAction: string; - infoTypePropertyName: string; - infoTagPropertyName: string; + idParamKey: 'models_id' | 'dataset_id'; // 新建版本、删除版本接口,版本 id 的参数名称 + uploadAction: string; // 上传接口 url + uploadAccept?: string; // 上传文件类型 + downloadAllAction: string; // 批量下载接口 url + downloadSingleAction: string; // 单个下载接口 url + infoTypePropertyName: string; // 详情数据中,类型属性名称 + infoTagPropertyName: string; // 详情数据中,标签属性名称 }; export const resourceConfig: Record = { diff --git a/react-ui/src/pages/Model/components/GraphLegand/index.tsx b/react-ui/src/pages/Model/components/GraphLegand/index.tsx index a70c994c..9cba12bc 100644 --- a/react-ui/src/pages/Model/components/GraphLegand/index.tsx +++ b/react-ui/src/pages/Model/components/GraphLegand/index.tsx @@ -16,19 +16,19 @@ function GraphLegand({ style }: GraphLegandProps) { const legends: GraphLegandData[] = [ { name: '父模型', - color: '#76b1ff', + color: 'linear-gradient(305deg,#43c9b1 0%,#93dfd1 100%)', radius: 2, fill: true, }, { name: '当前模型', - color: '#1664ff', + color: 'linear-gradient(139.97deg,#72a1ff 0%,#1664ff 100%)', radius: 2, fill: true, }, { name: '衍生模型', - color: '#b7cfff', + color: 'linear-gradient(139.97deg,#72b4ff 0%,#169aff 100%)', radius: 2, fill: true, }, @@ -42,7 +42,7 @@ function GraphLegand({ style }: GraphLegandProps) { width: '16px', height: '12px', borderRadius: item.radius, - backgroundColor: item.color, + background: item.color, }} >
{item.name}
diff --git a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx index 73e85be8..fbb711d4 100644 --- a/react-ui/src/pages/Model/components/ModelEvolution/index.tsx +++ b/react-ui/src/pages/Model/components/ModelEvolution/index.tsx @@ -2,264 +2,16 @@ import { useEffectWhen } from '@/hooks'; import { ResourceVersionData } from '@/pages/Dataset/config'; import { getModelAtlasReq } from '@/services/dataset/index.js'; import themes from '@/styles/theme.less'; -import { changePropertyName, fittingString } from '@/utils'; import { to } from '@/utils/promise'; -import G6, { - EdgeConfig, - G6GraphEvent, - Graph, - GraphData, - LayoutConfig, - NodeConfig, - TreeGraphData, - Util, -} from '@antv/g6'; +import G6, { G6GraphEvent, Graph, Item } from '@antv/g6'; // @ts-ignore -import Hierarchy from '@antv/hierarchy'; import { Flex, Select } from 'antd'; import { useEffect, useRef, useState } from 'react'; import GraphLegand from '../GraphLegand'; import NodeTooltips from '../NodeTooltips'; import styles from './index.less'; - -const nodeWidth = 98; -const nodeHeight = 58; -const vGap = 58; -const hGap = 58; - -enum NodeType { - current = 'current', - parent = 'parent', - children = 'children', - project = 'project', - trainDataset = 'trainDataset', - testDataset = 'testDataset', -} - -type TrainTask = { - ins_id: number; - name: string; - task_id: string; -}; - -interface TrainDataset extends NodeConfig { - dataset_id: number; - dataset_name: string; - dataset_version: string; - model_type: NodeType; -} - -interface ProjectDependency extends NodeConfig { - url: string; - name: string; - branch: string; - model_type: NodeType; -} - -type ModalDetail = { - name: string; - available_range: number; - file_name: string; - file_size: string; - description: string; - model_type_name: string; - model_tag_name: string; - create_time: string; -}; - -interface ModelDepsAPIData { - current_model_id: number; - version: string; - exp_ins_id: number; - model_type: NodeType; - current_model_name: string; - project_dependency: ProjectDependency; - test_dataset: TrainDataset[]; - train_dataset: TrainDataset[]; - train_task: TrainTask; - model_version_dependcy_vo: ModalDetail; - children_models: ModelDepsAPIData[]; - parent_models: ModelDepsAPIData[]; -} - -export interface ModelDepsData extends Omit, TreeGraphData { - children: ModelDepsData[]; -} - -// 规范化子数据 -function normalizeChildren(data: ModelDepsData[]) { - if (Array.isArray(data)) { - data.forEach((item) => { - item.model_type = NodeType.children; - item.id = `$M_${item.current_model_id}_${item.version}`; - item.label = getLabel(item); - item.style = getStyle(NodeType.children); - normalizeChildren(item.children); - }); - } -} - -// 获取 label -function getLabel(node: { current_model_name: string; version: string }) { - return ( - fittingString(`${node.current_model_name}`, 87, 8) + - '\n' + - fittingString(`${node.version}`, 87, 8) - ); -} - -// 获取 style -function getStyle(model_type: NodeType) { - let fill = ''; - switch (model_type) { - case NodeType.current: - fill = '#1664ff'; - break; - case NodeType.parent: - fill = '#76b1ff'; - break; - case NodeType.children: - fill = '#b7cfff'; - break; - case NodeType.project: - fill = '#FA8C16'; - break; - case NodeType.trainDataset: - fill = '#ff0000'; - break; - case NodeType.testDataset: - fill = '#ff00ff'; - break; - default: - break; - } - return { - fill, - }; -} - -// 将后台返回的数据转换成树形数据 -function normalizeTreeData(apiData: ModelDepsAPIData, currentNodeName: string): ModelDepsData { - // 将 children_models 转换成 children - let normalizedData = changePropertyName(apiData, { - children_models: 'children', - }) as ModelDepsData; - - // 设置当前模型的数据 - normalizedData.model_type = NodeType.current; - normalizedData.current_model_name = currentNodeName; - normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; - normalizedData.label = getLabel(normalizedData); - normalizedData.style = getStyle(NodeType.current); - - normalizeChildren(normalizedData.children as ModelDepsData[]); - - // 将 parent_models 转换成树形结构 - let parent_models = normalizedData.parent_models || []; - while (parent_models.length > 0) { - const parent = parent_models[0]; - normalizedData = { - ...parent, - model_type: NodeType.parent, - id: `$M_${parent.current_model_id}_${parent.version}`, - label: getLabel(parent), - style: getStyle(NodeType.parent), - children: [ - { - ...normalizedData, - parent_models: [], - }, - ], - }; - parent_models = normalizedData.parent_models || []; - } - return normalizedData; -} - -// 将树形数据,使用 Hierarchy 进行布局,计算出坐标,然后转换成 G6 的数据 -function getGraphData(data: ModelDepsData): GraphData { - const config = { - direction: 'LR', - getHeight: () => nodeHeight, - getWidth: () => nodeWidth, - getVGap: () => vGap / 2, - getHGap: () => hGap / 2, - }; - - // 树形布局计算出坐标 - const treeLayoutData: LayoutConfig = Hierarchy['compactBox'](data, config); - - const nodes: NodeConfig[] = []; - const edges: EdgeConfig[] = []; - Util.traverseTree(treeLayoutData, (node: NodeConfig, parent: NodeConfig) => { - const data = node.data as ModelDepsData; - nodes.push({ - ...data, - x: node.x, - y: node.y, - }); - if (parent) { - edges.push({ - source: parent.id, - target: node.id, - }); - } - - // 当前模型显示数据集和项目 - if (data.model_type === NodeType.current) { - const { project_dependency, train_dataset, test_dataset } = data; - train_dataset.forEach((item) => { - item.id = `$DTrain_${item.dataset_id}`; - item.model_type = NodeType.trainDataset; - item.type = 'ellipse'; - item.label = fittingString(`${item.dataset_name}`, 87, 8); - item.style = getStyle(NodeType.trainDataset); - }); - test_dataset.forEach((item) => { - item.id = `$DTest_${item.dataset_id}`; - item.model_type = NodeType.testDataset; - item.type = 'ellipse'; - item.label = fittingString(item.dataset_name, 87, 8); - item.style = getStyle(NodeType.testDataset); - }); - - const len = train_dataset.length + test_dataset.length; - [...train_dataset, ...test_dataset].forEach((item, index) => { - const half = len / 2 - 0.5; - item.x = node.x! - (half - index) * (nodeWidth + hGap); - item.y = node.y! - nodeHeight - vGap; - nodes.push(item); - edges.push({ - source: node.id, - target: item.id, - sourceAnchor: 2, - targetAnchor: 3, - type: 'cubic-vertical', - }); - }); - - if (project_dependency?.url) { - project_dependency.id = `$P_${project_dependency.url}`; - project_dependency.model_type = NodeType.project; - project_dependency.type = 'rect'; - project_dependency.size = [nodeHeight, nodeHeight]; - project_dependency.label = fittingString(project_dependency.name, 48, 8); - project_dependency.style = getStyle(NodeType.project); - project_dependency.x = node.x; - project_dependency.y = node.y! + nodeHeight + vGap; - nodes.push(project_dependency); - edges.push({ - source: node.id, - target: project_dependency.id, - sourceAnchor: 3, - targetAnchor: 2, - type: 'cubic-vertical', - }); - } - } - }); - return { nodes, edges }; -} +import type { ModelDepsData, ProjectDependency, TrainDataset } from './utils'; +import { NodeType, getGraphData, nodeHeight, nodeWidth, normalizeTreeData } from './utils'; type modeModelEvolutionProps = { resourceId: number; @@ -361,14 +113,15 @@ function ModelEvolution({ default: [ 'drag-canvas', 'zoom-canvas', - // { - // type: 'collapse-expand', - // onChange(item?: Item, collapsed?: boolean) { - // const data = item!.getModel(); - // data.collapsed = collapsed; - // return true; - // }, - // }, + 'drag-node', + { + type: 'collapse-expand', + onChange(item?: Item, collapsed?: boolean) { + const data = item!.getModel(); + data.collapsed = collapsed; + return true; + }, + }, ], }, }); @@ -392,16 +145,18 @@ function ModelEvolution({ return; } const point = graph.getCanvasByPoint(x!, y!); + const zoom = graph.getZoom(); + // 更加缩放,调整 tooltip 位置 + const offsetX = (nodeWidth * zoom) / 4; + const offsetY = (nodeHeight * zoom) / 4; + const canvasWidth = graphRef.current!.clientWidth; if (point.x + 300 > canvasWidth) { point.x = canvasWidth - 300; } - const zoom = graph.getZoom(); - // 更加缩放,调整 tooltip 位置 - const offsetY = (nodeHeight * zoom) / 4; setHoverNodeData(model); - setNodeToolTipX(point.x); + setNodeToolTipX(point.x + offsetX); // 92: 版本选择器的高度,296: tooltip的高度 setNodeToolTipY(point.y + 92 - 296 - offsetY); setShowNodeTooltip(true); diff --git a/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx b/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx new file mode 100644 index 00000000..bb5502e0 --- /dev/null +++ b/react-ui/src/pages/Model/components/ModelEvolution/utils.tsx @@ -0,0 +1,344 @@ +import { changePropertyName, fittingString } from '@/utils'; +import { EdgeConfig, GraphData, LayoutConfig, NodeConfig, TreeGraphData, Util } from '@antv/g6'; +// @ts-ignore +import Hierarchy from '@antv/hierarchy'; + +export const nodeWidth = 110; +export const nodeHeight = 50; +export const vGap = nodeHeight + 20; +export const hGap = nodeHeight + 20; +export const ellipseWidth = nodeWidth; + +// 数据集节点矩形数组 +const datasetRects: Rect[] = []; + +export enum NodeType { + current = 'current', + parent = 'parent', + children = 'children', + project = 'project', + trainDataset = 'trainDataset', + testDataset = 'testDataset', +} + +export type Rect = { + x: number; + y: number; + width: number; + height: number; +}; + +export type TrainTask = { + ins_id: number; + name: string; + task_id: string; +}; + +export interface TrainDataset extends NodeConfig { + dataset_id: number; + dataset_name: string; + dataset_version: string; + model_type: NodeType; +} + +export interface ProjectDependency extends NodeConfig { + url: string; + name: string; + branch: string; + model_type: NodeType; +} + +export type ModalDetail = { + name: string; + available_range: number; + file_name: string; + file_size: string; + description: string; + model_type_name: string; + model_tag_name: string; + create_time: string; +}; + +export interface ModelDepsAPIData { + current_model_id: number; + version: string; + exp_ins_id: number; + model_type: NodeType; + current_model_name: string; + project_dependency: ProjectDependency; + test_dataset: TrainDataset[]; + train_dataset: TrainDataset[]; + train_task: TrainTask; + model_version_dependcy_vo: ModalDetail; + children_models: ModelDepsAPIData[]; + parent_models: ModelDepsAPIData[]; +} + +export interface ModelDepsData extends Omit, TreeGraphData { + children: ModelDepsData[]; +} + +// 规范化子数据 +export function normalizeChildren(data: ModelDepsData[]) { + if (Array.isArray(data)) { + data.forEach((item) => { + item.model_type = NodeType.children; + item.id = `$M_${item.current_model_id}_${item.version}`; + item.label = getLabel(item); + item.style = getStyle(NodeType.children); + normalizeChildren(item.children); + }); + } +} + +// 获取 label +export function getLabel(node: { current_model_name: string; version: string }) { + return ( + fittingString(`${node.current_model_name}`, nodeWidth - 12, 8) + + '\n' + + fittingString(`${node.version}`, nodeWidth - 12, 8) + ); +} + +// 获取 style +export function getStyle(model_type: NodeType) { + let fill = ''; + switch (model_type) { + case NodeType.current: + fill = 'l(0) 0:#72a1ff 1:#1664ff'; + break; + case NodeType.parent: + fill = 'l(0) 0:#93dfd1 1:#43c9b1'; + break; + case NodeType.children: + fill = 'l(0) 0:#72b4ff 1:#169aff'; + break; + case NodeType.project: + fill = 'l(0) 0:#b3a9ff 1:#8981ff'; + break; + case NodeType.trainDataset: + fill = '#a5d878'; + break; + case NodeType.testDataset: + fill = '#d8b578'; + break; + default: + break; + } + return { + fill, + }; +} + +// 将后台返回的数据转换成树形数据 +export function normalizeTreeData( + apiData: ModelDepsAPIData, + currentNodeName: string, +): ModelDepsData { + // 将 children_models 转换成 children + let normalizedData = changePropertyName(apiData, { + children_models: 'children', + }) as ModelDepsData; + + // 设置当前模型的数据 + normalizedData.model_type = NodeType.current; + normalizedData.current_model_name = currentNodeName; + normalizedData.id = `$M_${normalizedData.current_model_id}_${normalizedData.version}`; + normalizedData.label = getLabel({ + current_model_name: currentNodeName, + version: normalizedData.version, + }); + normalizedData.style = getStyle(NodeType.current); + // let first1 = { ...normalizedData.children[0] }; + // let first2 = { ...normalizedData.children[0] }; + // let first3 = { ...normalizedData.children[0] }; + // first1.current_model_id = 202020; + // first2.current_model_id = 202021; + // first3.current_model_id = 202022; + // normalizedData.children.push(first1, first2, first3); + + normalizeChildren(normalizedData.children as ModelDepsData[]); + + // 将 parent_models 转换成树形结构 + let parent_models = normalizedData.parent_models || []; + while (parent_models.length > 0) { + const parent = parent_models[0]; + normalizedData = { + ...parent, + model_type: NodeType.parent, + id: `$M_${parent.current_model_id}_${parent.version}`, + label: getLabel(parent), + style: getStyle(NodeType.parent), + children: [ + { + ...normalizedData, + parent_models: [], + }, + ], + }; + parent_models = normalizedData.parent_models || []; + } + return normalizedData; +} + +// 将树形数据,使用 Hierarchy 进行布局,计算出坐标,然后转换成 G6 的数据 +export function getGraphData(data: ModelDepsData): GraphData { + const config = { + direction: 'LR', + getHeight: () => nodeHeight, + getWidth: () => nodeWidth, + getVGap: () => vGap / 2, + getHGap: () => hGap / 2, + }; + + // 树形布局计算出坐标 + const treeLayoutData: LayoutConfig = Hierarchy['compactBox'](data, config); + + const nodes: NodeConfig[] = []; + const edges: EdgeConfig[] = []; + Util.traverseTree(treeLayoutData, (node: NodeConfig, parent: NodeConfig) => { + const data = node.data as ModelDepsData; + console.log('data', data); + + // 当前模型显示数据集和项目 + if (data.model_type === NodeType.current) { + addDatasetDependency(data, node, nodes, edges); + addProjectDependency(data, node, nodes, edges); + } else if (data.model_type === NodeType.children) { + adjustChildrenPosition(node); + } + nodes.push({ + ...data, + x: node.x, + y: node.y, + }); + if (parent) { + edges.push({ + source: parent.id, + target: node.id, + }); + } + }); + return { nodes, edges }; +} + +// 将数据集转换成 G6 的数据 +const addDatasetDependency = ( + data: ModelDepsData, + currentNode: NodeConfig, + nodes: NodeConfig[], + edges: EdgeConfig[], +) => { + const { train_dataset, test_dataset } = data; + train_dataset.forEach((item) => { + item.id = `$DTrain_${item.dataset_id}`; + item.model_type = NodeType.trainDataset; + item.style = getStyle(NodeType.trainDataset); + }); + test_dataset.forEach((item) => { + item.id = `$DTest_${item.dataset_id}`; + item.model_type = NodeType.testDataset; + item.style = getStyle(NodeType.testDataset); + }); + + datasetRects.length = 0; + const len = train_dataset.length + test_dataset.length; + [...train_dataset, ...test_dataset].forEach((item, index) => { + const node = { ...item }; + node.type = 'ellipse'; + node.size = [ellipseWidth, nodeHeight]; + node.label = + fittingString(node.dataset_name, ellipseWidth - 12, 8) + + '\n' + + fittingString(node.dataset_version, ellipseWidth - 12, 8); + + const half = len / 2 - 0.5; + node.x = currentNode.x! - (half - index) * (ellipseWidth + hGap); + node.y = currentNode.y! - nodeHeight - vGap; + nodes.push(node); + edges.push({ + source: currentNode.id, + target: node.id, + sourceAnchor: 2, + targetAnchor: 3, + type: 'cubic-vertical', + }); + datasetRects.push({ + x: node.x - ellipseWidth / 2, + y: node.y - nodeHeight / 2, + width: ellipseWidth, + height: nodeHeight, + }); + }); +}; + +// 将模型依赖数据转换成 G6 的数据 +const addProjectDependency = ( + data: ModelDepsData, + currentNode: NodeConfig, + nodes: NodeConfig[], + edges: EdgeConfig[], +) => { + const { project_dependency } = data; + if (project_dependency?.url) { + const node = { ...project_dependency }; + node.id = `$P_${node.url}`; + node.model_type = NodeType.project; + node.type = 'rect'; + node.label = fittingString(node.name, nodeWidth - 12, 8); + node.style = getStyle(NodeType.project); + node.style.radius = nodeHeight / 2; + node.x = currentNode.x; + node.y = currentNode.y! + nodeHeight + vGap; + + nodes.push(node); + edges.push({ + source: currentNode.id, + target: node.id, + sourceAnchor: 3, + targetAnchor: 2, + type: 'cubic-vertical', + }); + } +}; + +// 判断两个矩形是否相交 +function isRectanglesIntersect(rect1: Rect, rect2: Rect) { + return !( + rect1.x + rect1.width < rect2.x || + rect1.x > rect2.x + rect2.width || + rect1.y + rect1.height < rect2.y || + rect1.y > rect2.y + rect2.height + ); +} + +// 判断子节点是否与数据集节点重叠 +function isChildrenIntersectDataset(rects: Rect[], childrenRect: Rect) { + for (const r of rects) { + if (isRectanglesIntersect(r, childrenRect)) { + return r; + } + } + + return null; +} + +// 计算子节点位置 +function adjustChildrenPosition(node: NodeConfig) { + const nodeRect = { + x: node.x! - nodeWidth / 2, + y: node.y! - nodeHeight / 2, + width: nodeWidth, + height: nodeHeight, + }; + const overlapRect = isChildrenIntersectDataset(datasetRects, nodeRect); + if (overlapRect) { + const offsetY = nodeRect.y - overlapRect.y; + const space = 10; //(vGap + Math.abs(offsetY) - nodeHeight) / 2; + if (offsetY >= 0) { + node.y = node.y! + (nodeHeight - offsetY + space); + } else { + node.y = node.y! - (nodeHeight - Math.abs(offsetY) + space); + } + } +} diff --git a/react-ui/src/pages/Model/components/NodeTooltips/index.tsx b/react-ui/src/pages/Model/components/NodeTooltips/index.tsx index 2482a3b1..5131765b 100644 --- a/react-ui/src/pages/Model/components/NodeTooltips/index.tsx +++ b/react-ui/src/pages/Model/components/NodeTooltips/index.tsx @@ -1,5 +1,5 @@ import { formatDate } from '@/utils/date'; -import { ModelDepsData } from '../ModelEvolution'; +import { ModelDepsData } from '../ModelEvolution/utils'; import styles from './index.less'; type NodeTooltipsProps = { diff --git a/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx b/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx index a798024c..66562e13 100644 --- a/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx +++ b/react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx @@ -27,16 +27,16 @@ export type MirrorVersion = { }; export type SelectorTypeInfo = { - getList: (params: any) => Promise; - getVersions: (params: any) => Promise; - getFiles: (params: any) => Promise; - handleVersionResponse: (res: any) => any[]; - modalIcon: string; - buttonIcon: string; - name: string; - litReqParamKey: 'available_range' | 'image_type'; - fileReqParamKey: 'models_id' | 'dataset_id'; - tabItems: TabsProps['items']; + getList: (params: any) => Promise; // 获取资源列表 + getVersions: (params: any) => Promise; // 获取资源版本列表 + getFiles: (params: any) => Promise; // 获取资源文件列表 + handleVersionResponse: (res: any) => any[]; // 处理版本列表接口数据 + modalIcon: string; // modal icon + buttonIcon: string; // button icon + name: string; // 名称 + litReqParamKey: 'available_range' | 'image_type'; // 表示是公开还是私有的参数名称,获取资源列表接口使用 + fileReqParamKey: 'models_id' | 'dataset_id'; // 文件请求参数名称,获取文件列表接口使用 + tabItems: TabsProps['items']; // tab 列表 }; // 获取镜像文件列表,为了兼容数据集和模型 diff --git a/react-ui/src/pages/Pipeline/editPipeline/index.jsx b/react-ui/src/pages/Pipeline/editPipeline/index.jsx index 090822f2..4a50d5a3 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/index.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/index.jsx @@ -35,13 +35,11 @@ const EditPipeline = () => { }, []); const onDragEnd = (val) => { - console.log(val); const _x = val.x; const _y = val.y; const point = graph.getPointByClient(_x, _y); - let model = {}; // 元模型 - model = { + const model = { ...val, x: point.x, y: point.y,