Browse Source

feat: 流水线参数添加下拉选择数据集、模型、资源

pull/53/head
cp3hnu 1 year ago
parent
commit
0ed1d59a22
20 changed files with 254 additions and 139 deletions
  1. +0
    -2
      react-ui/src/components/ParameterInput/index.tsx
  2. +0
    -0
      react-ui/src/components/ParameterSelect/index.less
  3. +119
    -0
      react-ui/src/components/ParameterSelect/index.tsx
  4. +1
    -1
      react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx
  5. +1
    -1
      react-ui/src/pages/Dataset/components/AddModelModal/index.tsx
  6. +1
    -1
      react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx
  7. +1
    -1
      react-ui/src/pages/Dataset/components/CategoryItem/index.tsx
  8. +1
    -1
      react-ui/src/pages/Dataset/components/CategoryList/index.tsx
  9. +1
    -1
      react-ui/src/pages/Dataset/components/ResourceList/index.tsx
  10. +1
    -1
      react-ui/src/pages/Dataset/components/ResourcePage/index.tsx
  11. +1
    -1
      react-ui/src/pages/Dataset/components/Resourcetem/index.tsx
  12. +0
    -0
      react-ui/src/pages/Dataset/config.tsx
  13. +1
    -1
      react-ui/src/pages/Dataset/index.tsx
  14. +1
    -1
      react-ui/src/pages/Dataset/intro.jsx
  15. +1
    -1
      react-ui/src/pages/Model/index.tsx
  16. +1
    -1
      react-ui/src/pages/Model/intro.jsx
  17. +4
    -3
      react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx
  18. +32
    -36
      react-ui/src/pages/Pipeline/components/ResourceSelectorModal/index.tsx
  19. +80
    -82
      react-ui/src/pages/Pipeline/editPipeline/props.tsx
  20. +7
    -4
      react-ui/src/types.ts

+ 0
- 2
react-ui/src/components/ParameterInput/index.tsx View File

@@ -37,8 +37,6 @@ function ParameterInput({
disabled = false, disabled = false,
...rest ...rest
}: ParameterInputProps) { }: ParameterInputProps) {
// console.log('ParameterInput', value);

const valueObj = const valueObj =
typeof value === 'string' ? { value: value, fromSelect: false, showValue: value } : value; typeof value === 'string' ? { value: value, fromSelect: false, showValue: value } : value;
if (valueObj && !valueObj.showValue) { if (valueObj && !valueObj.showValue) {


+ 0
- 0
react-ui/src/components/ParameterSelect/index.less View File


+ 119
- 0
react-ui/src/components/ParameterSelect/index.tsx View File

@@ -0,0 +1,119 @@
import { to } from '@/utils/promise';
import { useEffect, useState } from 'react';
// import styles from './index.less';
import { getDatasetList, getModelList } from '@/services/dataset/index.js';
import { getComputingResourceReq } from '@/services/pipeline';
import { ComputingResource, PipelineNodeModelParameter } from '@/types';
import { Select, type SelectProps } from 'antd';

// 过滤资源规格
const filterResourceStandard: SelectProps<string, ComputingResource>['filterOption'] = (
input: string,
option?: ComputingResource,
) => {
return (
option?.computing_resource?.toLocaleLowerCase()?.includes(input.toLocaleLowerCase()) ?? false
);
};

type SelectPropsConfig = {
getOptions: () => Promise<any>;
fieldNames?: SelectProps['fieldNames'];
filterOption?: SelectProps['filterOption'];
};

const config: Record<string, SelectPropsConfig> = {
dataset: {
getOptions: async () => {
const res = await getDatasetList({
page: 0,
size: 1000,
available_range: 0,
});
return res?.data?.content ?? [];
},
fieldNames: {
label: 'name',
value: 'id',
},
},
model: {
getOptions: async () => {
const res = await getModelList({
page: 0,
size: 1000,
available_range: 0,
});
return res?.data?.content ?? [];
},
fieldNames: {
label: 'name',
value: 'id',
},
},
resource: {
getOptions: async () => {
const res = await getComputingResourceReq({
page: 0,
size: 1000,
resource_type: '',
});
return res?.data?.content ?? [];
},
fieldNames: {
label: 'description',
value: 'standard',
},
filterOption: filterResourceStandard as SelectProps['filterOption'],
},
};

type ParameterSelectProps = {
value?: PipelineNodeModelParameter;
onChange?: (value: PipelineNodeModelParameter) => void;
};

function ParameterSelect({ value, onChange }: ParameterSelectProps) {
const [options, setOptions] = useState([]);
const valueNonNullable = value ?? ({} as PipelineNodeModelParameter);
const { item_type } = valueNonNullable;

useEffect(() => {
getSelectOptions();
}, []);

const hangleChange = (e: string) => {
onChange?.({
...valueNonNullable,
value: e,
});
};

// 获取下拉数据
const getSelectOptions = async () => {
const propsConfig = config[item_type];
if (!propsConfig) {
return;
}
const getOptions = propsConfig.getOptions;
const [res] = await to(getOptions());
if (res) {
setOptions(res);
}
};

return (
<Select
placeholder={valueNonNullable.placeholder}
filterOption={config[item_type]?.filterOption}
options={options}
fieldNames={config[item_type]?.fieldNames}
value={valueNonNullable.value}
onChange={hangleChange}
showSearch
allowClear
/>
);
}

export default ParameterSelect;

+ 1
- 1
react-ui/src/pages/Dataset/components/AddDatasetModal/index.tsx View File

@@ -20,7 +20,7 @@ import {
} from 'antd'; } from 'antd';
import { omit } from 'lodash'; import { omit } from 'lodash';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { CategoryData } from '../../types';
import { CategoryData } from '../../config';
import styles from './index.less'; import styles from './index.less';


interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> { interface AddDatasetModalProps extends Omit<ModalProps, 'onOk'> {


+ 1
- 1
react-ui/src/pages/Dataset/components/AddModelModal/index.tsx View File

@@ -1,7 +1,7 @@
import { getAccessToken } from '@/access'; import { getAccessToken } from '@/access';
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import KFModal from '@/components/KFModal'; import KFModal from '@/components/KFModal';
import { CategoryData } from '@/pages/Dataset/types';
import { CategoryData } from '@/pages/Dataset/config';
import { addModel } from '@/services/dataset/index.js'; import { addModel } from '@/services/dataset/index.js';
import { to } from '@/utils/promise'; import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';


+ 1
- 1
react-ui/src/pages/Dataset/components/AddVersionModal/index.tsx View File

@@ -1,7 +1,7 @@
import { getAccessToken } from '@/access'; import { getAccessToken } from '@/access';
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import KFModal from '@/components/KFModal'; import KFModal from '@/components/KFModal';
import { ResourceType, resourceConfig } from '@/pages/Dataset/types';
import { ResourceType, resourceConfig } from '@/pages/Dataset/config';
import { to } from '@/utils/promise'; import { to } from '@/utils/promise';
import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui'; import { getFileListFromEvent, validateUploadFiles } from '@/utils/ui';
import { import {


+ 1
- 1
react-ui/src/pages/Dataset/components/CategoryItem/index.tsx View File

@@ -1,5 +1,5 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { CategoryData, ResourceType, resourceConfig } from '../../types';
import { CategoryData, ResourceType, resourceConfig } from '../../config';
import styles from './index.less'; import styles from './index.less';


type CategoryItemProps = { type CategoryItemProps = {


+ 1
- 1
react-ui/src/pages/Dataset/components/CategoryList/index.tsx View File

@@ -1,5 +1,5 @@
import { Flex, Input } from 'antd'; import { Flex, Input } from 'antd';
import { CategoryData, ResourceType, resourceConfig } from '../../types';
import { CategoryData, ResourceType, resourceConfig } from '../../config';
import CategoryItem from '../CategoryItem'; import CategoryItem from '../CategoryItem';
import styles from './index.less'; import styles from './index.less';




+ 1
- 1
react-ui/src/pages/Dataset/components/ResourceList/index.tsx View File

@@ -7,7 +7,7 @@ import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max'; import { useNavigate } from '@umijs/max';
import { App, Button, Input, Pagination, PaginationProps } from 'antd'; import { App, Button, Input, Pagination, PaginationProps } from 'antd';
import { Ref, forwardRef, useEffect, useImperativeHandle, useState } from 'react'; import { Ref, forwardRef, useEffect, useImperativeHandle, useState } from 'react';
import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../types';
import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../config';
import AddDatasetModal from '../AddDatasetModal'; import AddDatasetModal from '../AddDatasetModal';
import ResourceItem from '../Resourcetem'; import ResourceItem from '../Resourcetem';
import styles from './index.less'; import styles from './index.less';


+ 1
- 1
react-ui/src/pages/Dataset/components/ResourcePage/index.tsx View File

@@ -4,7 +4,7 @@ import { getAssetIcon } from '@/services/dataset/index.js';
import { to } from '@/utils/promise'; import { to } from '@/utils/promise';
import { Flex, Tabs, type TabsProps } from 'antd'; import { Flex, Tabs, type TabsProps } from 'antd';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { CategoryData, ResourceType, resourceConfig } from '../../types';
import { CategoryData, ResourceType, resourceConfig } from '../../config';
import CategoryList from '../CategoryList'; import CategoryList from '../CategoryList';
import ResourceList, { ResourceListRef } from '../ResourceList'; import ResourceList, { ResourceListRef } from '../ResourceList';
import styles from './index.less'; import styles from './index.less';


+ 1
- 1
react-ui/src/pages/Dataset/components/Resourcetem/index.tsx View File

@@ -3,7 +3,7 @@ import creatByImg from '@/assets/img/creatBy.png';
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import { formatDate } from '@/utils/date'; import { formatDate } from '@/utils/date';
import { Button, Flex, Typography } from 'antd'; import { Button, Flex, Typography } from 'antd';
import { ResourceData } from '../../types';
import { ResourceData } from '../../config';
import styles from './index.less'; import styles from './index.less';


type ResourceItemProps = { type ResourceItemProps = {


react-ui/src/pages/Dataset/types.tsx → react-ui/src/pages/Dataset/config.tsx View File


react-ui/src/pages/Dataset/index.jsx → react-ui/src/pages/Dataset/index.tsx View File

@@ -1,5 +1,5 @@
import ResourcePage from './components/ResourcePage'; import ResourcePage from './components/ResourcePage';
import { ResourceType } from './types';
import { ResourceType } from './config';


const DatasetPage = () => { const DatasetPage = () => {
return <ResourcePage resourceType={ResourceType.Dataset} />; return <ResourcePage resourceType={ResourceType.Dataset} />;

+ 1
- 1
react-ui/src/pages/Dataset/intro.jsx View File

@@ -1,5 +1,5 @@
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import { ResourceType } from '@/pages/Dataset/types';
import { ResourceType } from '@/pages/Dataset/config';
import { import {
deleteDatasetVersion, deleteDatasetVersion,
getDatasetById, getDatasetById,


react-ui/src/pages/Model/index.jsx → react-ui/src/pages/Model/index.tsx View File

@@ -1,5 +1,5 @@
import ResourcePage from '@/pages/Dataset/components/ResourcePage'; import ResourcePage from '@/pages/Dataset/components/ResourcePage';
import { ResourceType } from '@/pages/Dataset/types';
import { ResourceType } from '@/pages/Dataset/config';


const ModelPage = () => { const ModelPage = () => {
return <ResourcePage resourceType={ResourceType.Model} />; return <ResourcePage resourceType={ResourceType.Model} />;

+ 1
- 1
react-ui/src/pages/Model/intro.jsx View File

@@ -1,6 +1,6 @@
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import AddVersionModal from '@/pages/Dataset/components/AddVersionModal'; import AddVersionModal from '@/pages/Dataset/components/AddVersionModal';
import { ResourceType } from '@/pages/Dataset/types';
import { ResourceType } from '@/pages/Dataset/config';
import { import {
deleteModelVersion, deleteModelVersion,
getModelById, getModelById,


+ 4
- 3
react-ui/src/pages/Pipeline/components/ResourceSelectorModal/config.tsx View File

@@ -20,9 +20,9 @@ export enum ResourceSelectorType {
} }


export type MirrorVersion = { export type MirrorVersion = {
id: number; // 镜像版本id
id: number; // 镜像版本 id
status: MirrorVersionStatus; // 镜像版本状态 status: MirrorVersionStatus; // 镜像版本状态
tag_name: string; // 镜像版本
tag_name: string; // 镜像版本 name
url: string; // 镜像版本路径 url: string; // 镜像版本路径
}; };


@@ -39,12 +39,13 @@ export type SelectorTypeInfo = {
tabItems: TabsProps['items']; tabItems: TabsProps['items'];
}; };


// 获取镜像列表,为了兼容数据集和模型
// 获取镜像文件列表,为了兼容数据集和模型
const getMirrorFilesReq = ({ id, version }: { id: number; version: string }): Promise<any> => { const getMirrorFilesReq = ({ id, version }: { id: number; version: string }): Promise<any> => {
const index = version.indexOf('-'); const index = version.indexOf('-');
const url = version.slice(index + 1); const url = version.slice(index + 1);
return Promise.resolve({ return Promise.resolve({
data: { data: {
path: url,
content: [ content: [
{ {
id: `${id}-${version}`, id: `${id}-${version}`,


+ 32
- 36
react-ui/src/pages/Pipeline/components/ResourceSelectorModal/index.tsx View File

@@ -15,26 +15,18 @@ import { MirrorVersion, ResourceSelectorType, selectorTypeConfig } from './confi
import styles from './index.less'; import styles from './index.less';
export { ResourceSelectorType, selectorTypeConfig }; export { ResourceSelectorType, selectorTypeConfig };


// 选择数据集和模型的返回类型
// 选择数据集\模型\镜像的返回类型
export type ResourceSelectorResponse = { export type ResourceSelectorResponse = {
id: number; // 数据集或者模型 id
name: string; // 数据集或者模型 name
version: string; // 数据集或者模型版本
path: string; // 数据集或者模型版本路径
id: number; // 数据集\模型\镜像 id
name: string; // 数据集\模型\镜像 name
version: string; // 数据集\模型\镜像版本
path: string; // 数据集\模型\镜像版本路径
activeTab: CommonTabKeys; // 是我的还是公开的 activeTab: CommonTabKeys; // 是我的还是公开的
}; };


export interface ResourceSelectorModalProps extends Omit<ModalProps, 'onOk'> {
type: ResourceSelectorType; // 模型 | 数据集
defaultExpandedKeys?: React.Key[];
defaultCheckedKeys?: React.Key[];
defaultActiveTab?: CommonTabKeys;
onOk?: (params: ResourceSelectorResponse | string | null) => void;
}

type ResourceGroup = { type ResourceGroup = {
id: number; // 数据集或者模型 id
name: string; // 数据集或者模型 id
id: number; // 数据集\模型\镜像 id
name: string; // 数据集\模型\镜像 name
}; };


type ResourceFile = { type ResourceFile = {
@@ -42,9 +34,17 @@ type ResourceFile = {
file_name: string; // 文件 name file_name: string; // 文件 name
}; };


export interface ResourceSelectorModalProps extends Omit<ModalProps, 'onOk'> {
type: ResourceSelectorType; // 数据集\模型\镜像
defaultExpandedKeys?: React.Key[];
defaultCheckedKeys?: React.Key[];
defaultActiveTab?: CommonTabKeys;
onOk?: (params: ResourceSelectorResponse | null) => void;
}

type TreeRef = GetRef<typeof Tree<TreeDataNode>>; type TreeRef = GetRef<typeof Tree<TreeDataNode>>;


// list 转成 treeData
// list 数据转成 treeData
const convertToTreeData = (list: ResourceGroup[]): TreeDataNode[] => { const convertToTreeData = (list: ResourceGroup[]): TreeDataNode[] => {
return list.map((v) => ({ return list.map((v) => ({
title: v.name, title: v.name,
@@ -54,7 +54,7 @@ const convertToTreeData = (list: ResourceGroup[]): TreeDataNode[] => {
})); }));
}; };


// 版本转成 treeData
// 版本数据转成 treeData
const convertVersionToTreeData = (parentId: number) => { const convertVersionToTreeData = (parentId: number) => {
return (item: string | MirrorVersion): TreeDataNode => { return (item: string | MirrorVersion): TreeDataNode => {
if (typeof item === 'string') { if (typeof item === 'string') {
@@ -88,7 +88,7 @@ const updateChildren = (parentId: number, children: TreeDataNode[]) => {
}; };
}; };


// 得到数据集或者模型 id 和下属版本号
// 得到数据集\模型\镜像 id 和下属版本号
const getIdAndVersion = (versionKey: string) => { const getIdAndVersion = (versionKey: string) => {
const index = versionKey.indexOf('-'); const index = versionKey.indexOf('-');
const id = Number(versionKey.slice(0, index)); const id = Number(versionKey.slice(0, index));
@@ -137,12 +137,12 @@ function ResourceSelectorModal({
[originTreeData, searchText], [originTreeData, searchText],
); );


// 获取数据集或模型列表
// 获取数据集\模型\镜像列表
const getTreeData = async () => { const getTreeData = async () => {
const available_range = activeTab === CommonTabKeys.Private ? 0 : 1; const available_range = activeTab === CommonTabKeys.Private ? 0 : 1;
const params = { const params = {
page: 0, page: 0,
size: 200,
size: 1000,
[selectorTypeConfig[type].litReqParamKey]: available_range, [selectorTypeConfig[type].litReqParamKey]: available_range,
}; };
const getListReq = selectorTypeConfig[type].getList; const getListReq = selectorTypeConfig[type].getList;
@@ -159,7 +159,7 @@ function ResourceSelectorModal({
} }
}; };


// 获取数据集或模型版本列表
// 获取数据集\模型\镜像版本列表
const getVersions = async (parentId: number) => { const getVersions = async (parentId: number) => {
const getVersionsReq = selectorTypeConfig[type].getVersions; const getVersionsReq = selectorTypeConfig[type].getVersions;
const [res, error] = await to(getVersionsReq(parentId)); const [res, error] = await to(getVersionsReq(parentId));
@@ -266,21 +266,17 @@ function ResourceSelectorModal({
// 提交 // 提交
const handleOk = () => { const handleOk = () => {
if (checkedKeys.length > 0) { if (checkedKeys.length > 0) {
if (type === ResourceSelectorType.Mirror) {
onOk?.(files[0].file_name);
} else {
const last = checkedKeys[0] as string;
const { id, version } = getIdAndVersion(last);
const name = (treeData.find((v) => Number(v.key) === id)?.title ?? '') as string;
const res = {
id,
name,
path: versionPath,
version,
activeTab: activeTab as CommonTabKeys,
};
onOk?.(res);
}
const last = checkedKeys[0] as string;
const { id, version } = getIdAndVersion(last);
const name = (treeData.find((v) => Number(v.key) === id)?.title ?? '') as string;
const res = {
id,
name,
path: versionPath,
version,
activeTab: activeTab as CommonTabKeys,
};
onOk?.(res);
} else { } else {
onOk?.(null); onOk?.(null);
} }


react-ui/src/pages/Pipeline/editPipeline/props.jsx → react-ui/src/pages/Pipeline/editPipeline/props.tsx View File

@@ -1,14 +1,23 @@
import KFIcon from '@/components/KFIcon'; import KFIcon from '@/components/KFIcon';
import ParameterInput from '@/components/ParameterInput'; import ParameterInput from '@/components/ParameterInput';
import ParameterSelect from '@/components/ParameterSelect';
import SubAreaTitle from '@/components/SubAreaTitle'; import SubAreaTitle from '@/components/SubAreaTitle';
import { useComputingResource } from '@/hooks/resource'; import { useComputingResource } from '@/hooks/resource';
import {
PipelineGlobalParam,
PipelineNodeModelParameter,
PipelineNodeModelSerialize,
} from '@/types';
import { openAntdModal } from '@/utils/modal'; import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise'; import { to } from '@/utils/promise';
import { Button, Drawer, Form, Input, Select } from 'antd';
import { INode } from '@antv/g6';
import { Button, Drawer, Form, Input, MenuProps, Select } from 'antd';
import { NamePath } from 'antd/es/form/interface';
import { pick } from 'lodash'; import { pick } from 'lodash';
import { forwardRef, useImperativeHandle, useState } from 'react'; import { forwardRef, useImperativeHandle, useState } from 'react';
import PropsLabel from '../components/PropsLabel'; import PropsLabel from '../components/PropsLabel';
import ResourceSelectorModal, { import ResourceSelectorModal, {
ResourceSelectorResponse,
ResourceSelectorType, ResourceSelectorType,
selectorTypeConfig, selectorTypeConfig,
} from '../components/ResourceSelectorModal'; } from '../components/ResourceSelectorModal';
@@ -16,18 +25,28 @@ import styles from './props.less';
import { canInput, createMenuItems } from './utils'; import { canInput, createMenuItems } from './utils';
const { TextArea } = Input; const { TextArea } = Input;


const Props = forwardRef(({ onParentChange }, ref) => {
type PipelineNodeParameterProps = {
onParentChange: (data: PipelineNodeModelSerialize) => void;
};

const PipelineNodeParameter = forwardRef(({ onParentChange }: PipelineNodeParameterProps, ref) => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [stagingItem, setStagingItem] = useState({});
const [stagingItem, setStagingItem] = useState<PipelineNodeModelSerialize>(
{} as PipelineNodeModelSerialize,
);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [selectedModel, setSelectedModel] = useState(undefined); // 选择的模型,为了再次打开时恢复原来的选择
const [selectedDataset, setSelectedDataset] = useState(undefined); // 选择的数据集,为了再次打开时恢复原来的选择
const [selectedModel, setSelectedModel] = useState<ResourceSelectorResponse | undefined>(
undefined,
); // 选择的模型,为了再次打开时恢复原来的选择
const [selectedDataset, setSelectedDataset] = useState<ResourceSelectorResponse | undefined>(
undefined,
); // 选择的数据集,为了再次打开时恢复原来的选择
const [resourceStandardList, filterResourceStandard] = useComputingResource(); // 资源规模 const [resourceStandardList, filterResourceStandard] = useComputingResource(); // 资源规模
const [menuItems, setMenuItems] = useState([]);
const [menuItems, setMenuItems] = useState<MenuProps['items']>([]);


const afterOpenChange = () => { const afterOpenChange = () => {
if (!open) { if (!open) {
console.log('zzzzz', form.getFieldsValue());
console.log('getFieldsValue', form.getFieldsValue());
const control_strategy = form.getFieldValue('control_strategy'); const control_strategy = form.getFieldValue('control_strategy');
const in_parameters = form.getFieldValue('in_parameters'); const in_parameters = form.getFieldValue('in_parameters');
const out_parameters = form.getFieldValue('out_parameters'); const out_parameters = form.getFieldValue('out_parameters');
@@ -54,7 +73,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
return Promise.reject(propsError); return Promise.reject(propsError);
} }
}, },
showDrawer(e, params, parentNodes) {
showDrawer(e: any, params: PipelineGlobalParam[], parentNodes: INode[]) {
if (e.item && e.item.getModel()) { if (e.item && e.item.getModel()) {
form.resetFields(); form.resetFields();
const model = e.item.getModel(); const model = e.item.getModel();
@@ -89,9 +108,12 @@ const Props = forwardRef(({ onParentChange }, ref) => {
})); }));


// 选择数据集、模型、镜像 // 选择数据集、模型、镜像
const selectResource = (name, item) => {
let type;
let resource;
const selectResource = (
name: NamePath,
item: PipelineNodeModelParameter | { item_type: string },
) => {
let type: ResourceSelectorType;
let resource: any;
switch (item.item_type) { switch (item.item_type) {
case 'dataset': case 'dataset':
type = ResourceSelectorType.Dataset; type = ResourceSelectorType.Dataset;
@@ -113,7 +135,12 @@ const Props = forwardRef(({ onParentChange }, ref) => {
onOk: (res) => { onOk: (res) => {
if (res) { if (res) {
if (type === ResourceSelectorType.Mirror) { if (type === ResourceSelectorType.Mirror) {
form.setFieldValue(name, res);
const path = res.path;
if (name === 'image') {
form.setFieldValue(name, path);
} else {
form.setFieldValue(name, { ...item, value: path, showValue: path, fromSelect: true });
}
} else { } else {
const jsonObj = pick(res, ['id', 'version', 'path']); const jsonObj = pick(res, ['id', 'version', 'path']);
const value = JSON.stringify(jsonObj); const value = JSON.stringify(jsonObj);
@@ -140,9 +167,9 @@ const Props = forwardRef(({ onParentChange }, ref) => {
}; };


// 获取选择数据集、模型后面按钮 icon // 获取选择数据集、模型后面按钮 icon
const getSelectBtnIcon = (item) => {
const getSelectBtnIcon = (item: PipelineNodeModelParameter | { item_type: string }) => {
const type = item.item_type; const type = item.item_type;
let selectorType;
let selectorType: ResourceSelectorType;
if (type === 'dataset') { if (type === 'dataset') {
selectorType = ResourceSelectorType.Dataset; selectorType = ResourceSelectorType.Dataset;
} else if (type === 'model') { } else if (type === 'model') {
@@ -155,10 +182,33 @@ const Props = forwardRef(({ onParentChange }, ref) => {
}; };


// 参数回填 // 参数回填
const handleParameterClick = (name, value) => {
const handleParameterClick = (name: NamePath, value: any) => {
form.setFieldValue(name, value); form.setFieldValue(name, value);
}; };


// form item label
const getLabel = (
item: { key: string; value: PipelineNodeModelParameter },
namePrefix: string,
) => {
return item.value.type === 'select' ? (
item.value.label + '(' + item.key + ')'
) : (
<PropsLabel
menuItems={menuItems}
title={item.value.label + '(' + item.key + ')'}
onClick={(value) => {
handleParameterClick([namePrefix, item.key], {
...item.value,
value,
fromSelect: true,
showValue: value,
});
}}
/>
);
};

// 控制策略 // 控制策略
const controlStrategyList = Object.entries(stagingItem.control_strategy ?? {}).map( const controlStrategyList = Object.entries(stagingItem.control_strategy ?? {}).map(
([key, value]) => ({ key, value }), ([key, value]) => ({ key, value }),
@@ -290,7 +340,6 @@ const Props = forwardRef(({ onParentChange }, ref) => {
]} ]}
> >
<Select <Select
showSearch
placeholder="请选择资源规格" placeholder="请选择资源规格"
filterOption={filterResourceStandard} filterOption={filterResourceStandard}
options={resourceStandardList} options={resourceStandardList}
@@ -298,6 +347,8 @@ const Props = forwardRef(({ onParentChange }, ref) => {
label: 'description', label: 'description',
value: 'standard', value: 'standard',
}} }}
showSearch
allowClear
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@@ -332,29 +383,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
<Form.Item <Form.Item
key={item.key} key={item.key}
name={['control_strategy', item.key]} name={['control_strategy', item.key]}
label={
<PropsLabel
menuItems={menuItems}
title={item.value.label}
onClick={(value) => {
handleParameterClick(['control_strategy', item.key], {
...item.value,
value,
fromSelect: true,
showValue: value,
});
}}
/>
}
// getValueProps={(e) => {
// return { value: e.value };
// }}
// getValueFromEvent={(e) => {
// return {
// ...item.value,
// value: e.target.value,
// };
// }}
label={getLabel(item, 'control_strategy')}
> >
<ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput> <ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput>
</Form.Item> </Form.Item>
@@ -365,20 +394,7 @@ const Props = forwardRef(({ onParentChange }, ref) => {
{inParametersList.map((item) => ( {inParametersList.map((item) => (
<Form.Item <Form.Item
key={item.key} key={item.key}
label={
<PropsLabel
menuItems={menuItems}
title={item.value.label + '(' + item.key + ')'}
onClick={(value) => {
handleParameterClick(['in_parameters', item.key], {
...item.value,
value,
fromSelect: true,
showValue: value,
});
}}
/>
}
label={getLabel(item, 'in_parameters')}
required={item.value.require ? true : false} required={item.value.require ? true : false}
> >
<div className={styles['pipeline-drawer__ref-row']}> <div className={styles['pipeline-drawer__ref-row']}>
@@ -387,11 +403,15 @@ const Props = forwardRef(({ onParentChange }, ref) => {
noStyle noStyle
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
> >
<ParameterInput
placeholder={item.value.placeholder}
canInput={canInput(item.value)}
allowClear
></ParameterInput>
{item.value.type === 'select' ? (
<ParameterSelect />
) : (
<ParameterInput
placeholder={item.value.placeholder}
canInput={canInput(item.value)}
allowClear
></ParameterInput>
)}
</Form.Item> </Form.Item>
{item.value.type === 'ref' && ( {item.value.type === 'ref' && (
<Form.Item noStyle> <Form.Item noStyle>
@@ -416,30 +436,8 @@ const Props = forwardRef(({ onParentChange }, ref) => {
<Form.Item <Form.Item
key={item.key} key={item.key}
name={['out_parameters', item.key]} name={['out_parameters', item.key]}
label={
<PropsLabel
menuItems={menuItems}
title={item.value.label + '(' + item.key + ')'}
onClick={(value) => {
handleParameterClick(['out_parameters', item.key], {
...item.value,
value,
fromSelect: true,
showValue: value,
});
}}
/>
}
label={getLabel(item, 'out_parameters')}
rules={[{ required: item.value.require ? true : false }]} rules={[{ required: item.value.require ? true : false }]}
// getValueProps={(e) => {
// return { value: e.value };
// }}
// getValueFromEvent={(e) => {
// return {
// ...item.value,
// value: e.target.value,
// };
// }}
> >
<ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput> <ParameterInput placeholder={item.value.placeholder} allowClear></ParameterInput>
</Form.Item> </Form.Item>
@@ -449,4 +447,4 @@ const Props = forwardRef(({ onParentChange }, ref) => {
); );
}); });


export default Props;
export default PipelineNodeParameter;

+ 7
- 4
react-ui/src/types.ts View File

@@ -47,16 +47,19 @@ export type PipelineNodeModel = {


// 流水线节点模型数据 // 流水线节点模型数据
export type PipelineNodeModelParameter = { export type PipelineNodeModelParameter = {
label: string;
value: any;
require: number;
type: string; type: string;
item_type: string; item_type: string;
label: string;
value: any;
require?: number;
placeholder?: string; placeholder?: string;
describe?: string; describe?: string;
fromSelect?: boolean; fromSelect?: boolean;
showValue?: any; showValue?: any;
editable: number;
editable?: number;
activeTab?: string; // ResourceSelectorModal tab
expandedKeys?: string[]; // ResourceSelectorModal expandedKeys
checkedKeys?: string[]; // ResourceSelectorModal checkedKeys
}; };


// type ChangePropertyType<T, K extends keyof T, NewType> = Omit<T, K> & { [P in K]: NewType } // type ChangePropertyType<T, K extends keyof T, NewType> = Omit<T, K> & { [P in K]: NewType }


Loading…
Cancel
Save