diff --git a/react-ui/src/components/FormInfo/index.tsx b/react-ui/src/components/FormInfo/index.tsx
index c1e23cbe..d33d615a 100644
--- a/react-ui/src/components/FormInfo/index.tsx
+++ b/react-ui/src/components/FormInfo/index.tsx
@@ -1,5 +1,5 @@
import { formatEnum } from '@/utils/format';
-import { Typography } from 'antd';
+import { Typography, type SelectProps } from 'antd';
import classNames from 'classnames';
import './index.less';
@@ -13,7 +13,9 @@ type FormInfoProps = {
/** 是否是下拉框 */
select?: boolean;
/** 下拉框数据 */
- options?: { label: string; value: any }[];
+ options?: SelectProps['options'];
+ /** 自定义节点 label、value 的字段 */
+ fieldNames?: SelectProps['fieldNames'];
/** 自定义类名 */
className?: string;
/** 自定义样式 */
@@ -26,17 +28,29 @@ type FormInfoProps = {
function FormInfo({
value,
valuePropName,
- className,
- select,
+ textArea = false,
+ select = false,
options,
+ fieldNames,
+ className,
style,
- textArea = false,
}: FormInfoProps) {
let showValue = value;
if (value && typeof value === 'object' && valuePropName) {
showValue = value[valuePropName];
} else if (select === true && options) {
- showValue = formatEnum(options)(value);
+ let _options: SelectProps['options'] = options;
+ if (fieldNames) {
+ _options = options.map((v) => {
+ return {
+ ...v,
+ label: fieldNames.label && v[fieldNames.label],
+ value: fieldNames.value && v[fieldNames.value],
+ options: fieldNames.options && v[fieldNames.options],
+ };
+ });
+ }
+ showValue = formatEnum(_options)(value);
}
return (
diff --git a/react-ui/src/components/ParameterSelect/index.tsx b/react-ui/src/components/ParameterSelect/index.tsx
index a6a911e5..9b6389d8 100644
--- a/react-ui/src/components/ParameterSelect/index.tsx
+++ b/react-ui/src/components/ParameterSelect/index.tsx
@@ -7,43 +7,50 @@
import { to } from '@/utils/promise';
import { Select, type SelectProps } from 'antd';
import { useEffect, useState } from 'react';
+import FormInfo from '../FormInfo';
import { paramSelectConfig } from './config';
-/** 值类型 */
-export type ParameterSelectValue = {
- /** 类型,参数名是和后台保持一致的 */
- item_type: 'dataset' | 'model' | 'service' | 'resource';
- /** 值 */
- value?: any;
- /** 占位符 */
- placeholder?: string;
- /** 其它属性 */
+type ParameterSelectObject = {
+ value: any;
[key: string]: any;
};
interface ParameterSelectProps extends SelectProps {
+ /** 类型 */
+ dataType: 'dataset' | 'model' | 'service' | 'resource';
+ /** 是否只是展示信息 */
+ isInfo?: boolean;
/** 值 */
- value?: ParameterSelectValue;
+ value?: string | ParameterSelectObject;
/** 修改后回调 */
- onChange?: (value: ParameterSelectValue) => void;
+ onChange?: (value: string | ParameterSelectObject) => void;
}
/** 参数选择器,支持资源规格、数据集、模型、服务 */
-function ParameterSelect({ value, onChange, ...rest }: ParameterSelectProps) {
+function ParameterSelect({
+ dataType,
+ isInfo = false,
+ value,
+ onChange,
+ ...rest
+}: ParameterSelectProps) {
const [options, setOptions] = useState([]);
- const valueNotNullable = value ?? ({} as ParameterSelectValue);
- const { item_type } = valueNotNullable;
- const propsConfig = paramSelectConfig[item_type];
+ const propsConfig = paramSelectConfig[dataType];
+ const valueText = typeof value === 'object' && value !== null ? value.value : value;
useEffect(() => {
getSelectOptions();
}, []);
- const hangleChange = (e: string) => {
- onChange?.({
- ...valueNotNullable,
- value: e,
- });
+ const handleChange = (text: string) => {
+ if (typeof value === 'object' && value !== null) {
+ onChange?.({
+ ...value,
+ value: text,
+ });
+ } else {
+ onChange?.(text);
+ }
};
// 获取下拉数据
@@ -58,16 +65,26 @@ function ParameterSelect({ value, onChange, ...rest }: ParameterSelectProps) {
}
};
+ if (isInfo) {
+ return (
+
+ );
+ }
+
return (
diff --git a/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx b/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
index 235e3087..f3b6ef42 100644
--- a/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
+++ b/react-ui/src/pages/Experiment/components/ExperimentParameter/index.tsx
@@ -3,7 +3,7 @@ import ParameterSelect from '@/components/ParameterSelect';
import SubAreaTitle from '@/components/SubAreaTitle';
import { useComputingResource } from '@/hooks/resource';
import { PipelineNodeModelSerialize } from '@/types';
-import { Form, Select } from 'antd';
+import { Form } from 'antd';
import styles from './index.less';
type ExperimentParameterProps = {
@@ -100,7 +100,7 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
-
+
-
-
+
{controlStrategyList.map((item) => (
@@ -146,7 +146,9 @@ function ExperimentParameter({ nodeData }: ExperimentParameterProps) {
rules={[{ required: item.value.require ? true : false }]}
>
{item.value.type === 'select' ? (
-
+ ['dataset', 'model', 'service', 'resource'].includes(item.value.item_type) ? (
+
+ ) : null
) : (
)}
diff --git a/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx b/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx
index de041c72..6314ea76 100644
--- a/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx
+++ b/react-ui/src/pages/Pipeline/components/PipelineNodeDrawer/index.tsx
@@ -502,7 +502,7 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
label={getLabel(item, 'control_strategy')}
rules={getFormRules(item)}
>
-
+
))}
{/* 输入参数 */}
@@ -523,9 +523,18 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
{item.value.type === 'select' ? (
-
+ ['dataset', 'model', 'service', 'resource'].includes(item.value.item_type) ? (
+
+ ) : null
) : (
-
+
)}
{item.value.type === 'ref' && (
@@ -563,7 +572,7 @@ const PipelineNodeParameter = forwardRef(({ onFormChange }: PipelineNodeParamete
label={getLabel(item, 'out_parameters')}
rules={getFormRules(item)}
>
-
+
))}
>
diff --git a/react-ui/src/stories/FormInfo.stories.tsx b/react-ui/src/stories/FormInfo.stories.tsx
index a214abae..abdf7b5e 100644
--- a/react-ui/src/stories/FormInfo.stories.tsx
+++ b/react-ui/src/stories/FormInfo.stories.tsx
@@ -38,7 +38,7 @@ export const InForm: Story = {
+
+
+
diff --git a/react-ui/src/stories/ParameterSelect.stories.tsx b/react-ui/src/stories/ParameterSelect.stories.tsx
index 6aed4e31..924ab423 100644
--- a/react-ui/src/stories/ParameterSelect.stories.tsx
+++ b/react-ui/src/stories/ParameterSelect.stories.tsx
@@ -2,7 +2,7 @@ import ParameterSelect, { ParameterSelectValue } from '@/components/ParameterSel
import { useArgs } from '@storybook/preview-api';
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
-import { Col, Form, Row } from 'antd';
+import { Button, Col, Form, Row } from 'antd';
import { http, HttpResponse } from 'msw';
import { computeResourceData, datasetListData, modelListData, serviceListData } from './mockData';
@@ -46,12 +46,32 @@ type Story = StoryObj
;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
args: {
- value: {
- item_type: 'dataset',
- placeholder: '请选择数据集',
- },
+ placeholder: '请选择',
+ dataType: 'dataset',
+ style: { width: 400 },
+ size: 'large',
+ },
+ render: function Render(args) {
+ const [{ value }, updateArgs] = useArgs();
+ function handleChange(value?: ParameterSelectValue) {
+ updateArgs({ value: value });
+ args.onChange?.(value);
+ }
+
+ return ;
+ },
+};
+
+/** 值可以是一个对象,典型的是流水线节点对象 **PipelineNodeModelParameter** */
+export const Object: Story = {
+ args: {
+ placeholder: '请选择',
+ dataType: 'dataset',
style: { width: 400 },
size: 'large',
+ value: {
+ value: undefined,
+ },
},
render: function Render(args) {
const [{ value }, updateArgs] = useArgs();
@@ -65,6 +85,9 @@ export const Primary: Story = {
};
export const InForm: Story = {
+ args: {
+ dataType: 'dataset',
+ },
render: ({ onChange }) => {
return (
);
},
diff --git a/react-ui/src/utils/format.ts b/react-ui/src/utils/format.ts
index 40d46fdc..7d37fbf5 100644
--- a/react-ui/src/utils/format.ts
+++ b/react-ui/src/utils/format.ts
@@ -122,14 +122,14 @@ export const formatBoolean = (value: boolean): string => {
return value ? '是' : '否';
};
-type FormatEnumFunc = (value: string | number) => string;
+type FormatEnumFunc = (value: string | number) => React.ReactNode;
// 格式化枚举
export const formatEnum = (
- options: { value: string | number; label: string }[],
+ options: { value?: string | number | null; label?: React.ReactNode }[],
): FormatEnumFunc => {
return (value: string | number) => {
const option = options.find((item) => item.value === value);
- return option ? option.label : '--';
+ return option && option.label ? option.label : '--';
};
};