| @@ -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 +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; | |||||
| @@ -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,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,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,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,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'; | ||||
| @@ -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'; | ||||
| @@ -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'; | ||||
| @@ -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 = { | ||||
| @@ -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,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, | ||||
| @@ -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,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, | ||||
| @@ -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}`, | ||||
| @@ -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); | ||||
| } | } | ||||
| @@ -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; | |||||
| @@ -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 } | ||||