feat: 完成实验全局参数配置
This commit is contained in:
parent
5b98773386
commit
a00d861ab1
|
@ -48,4 +48,12 @@
|
|||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.global_param_item {
|
||||
max-height: 230px;
|
||||
padding: 20px 12px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Form, Input, Modal, Select } from 'antd';
|
||||
import { type PipelineGlobalParam } from '@/types';
|
||||
import { Form, Input, Modal, Radio, Select, type FormRule } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import styles from './addExperimentModal.less';
|
||||
|
||||
|
@ -6,6 +7,7 @@ type FormData = {
|
|||
name?: string;
|
||||
description?: string;
|
||||
workflow_id?: string | number;
|
||||
global_param?: PipelineGlobalParam[];
|
||||
};
|
||||
|
||||
type AddExperimentModalProps = {
|
||||
|
@ -17,17 +19,55 @@ type AddExperimentModalProps = {
|
|||
initialValues: FormData;
|
||||
};
|
||||
|
||||
interface GlobalParam {
|
||||
param_name: string;
|
||||
param_value: string;
|
||||
}
|
||||
|
||||
interface Workflow {
|
||||
id: string | number;
|
||||
name: string;
|
||||
global_param?: GlobalParam[] | null;
|
||||
global_param?: PipelineGlobalParam[] | null;
|
||||
}
|
||||
|
||||
// 根据参数设置输入组件
|
||||
export const getParamComponent = (paramType: number, isSensitive?: number): JSX.Element => {
|
||||
// 防止后台返回不是 number 类型
|
||||
if (Number(paramType) === 3) {
|
||||
return (
|
||||
<Radio.Group>
|
||||
<Radio value={1}>是</Radio>
|
||||
<Radio value={0}>否</Radio>
|
||||
</Radio.Group>
|
||||
);
|
||||
}
|
||||
if (isSensitive && Number(isSensitive) === 1) {
|
||||
return <Input.Password visibilityToggle={false} allowClear />;
|
||||
}
|
||||
return <Input placeholder="请输入值" allowClear />;
|
||||
};
|
||||
|
||||
// 根据参数设置校验规则
|
||||
export const getParamRules = (paramType: number, required: boolean = false): FormRule[] => {
|
||||
const rules = [];
|
||||
// 防止后台返回不是 number 类型
|
||||
if (Number(paramType) === 2) {
|
||||
rules.push({
|
||||
pattern: /^-?\d+(\.\d+)?$/,
|
||||
message: '整型必须是数字',
|
||||
});
|
||||
}
|
||||
if (required) {
|
||||
rules.push({ required: true, message: '请输入值' });
|
||||
}
|
||||
return rules;
|
||||
};
|
||||
|
||||
// 根据参数设置 label
|
||||
const getParamType = (param: PipelineGlobalParam): string => {
|
||||
const paramTypes: Readonly<Record<number, string>> = {
|
||||
1: '字符串',
|
||||
2: '整型',
|
||||
3: '布尔类型',
|
||||
};
|
||||
return param.param_name + `(${paramTypes[param.param_type]})`;
|
||||
};
|
||||
|
||||
function AddExperimentModal({
|
||||
isAdd,
|
||||
open,
|
||||
|
@ -38,20 +78,30 @@ function AddExperimentModal({
|
|||
}: AddExperimentModalProps) {
|
||||
const dialogTitle = isAdd ? '新建实验' : '编辑实验';
|
||||
const workflowDisabled = isAdd ? false : true;
|
||||
const [globalParam, setGlobalParam] = useState<GlobalParam[]>([]);
|
||||
const [globalParam, setGlobalParam] = useState<PipelineGlobalParam[]>(
|
||||
initialValues.global_param || [],
|
||||
);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const layout = {
|
||||
labelCol: { span: 24 },
|
||||
wrapperCol: { span: 24 },
|
||||
};
|
||||
|
||||
const tailLayout = {
|
||||
labelCol: { span: 8 },
|
||||
wrapperCol: { span: 16 },
|
||||
};
|
||||
|
||||
// 除了流水线选择发生变化
|
||||
const handleWorkflowChange = (id: string) => {
|
||||
const handleWorkflowChange = (id: string | number) => {
|
||||
const pipeline: Workflow | undefined = workflowList.find((v) => v.id === id);
|
||||
if (pipeline && pipeline.global_param) {
|
||||
setGlobalParam(pipeline.global_param);
|
||||
const fields = pipeline.global_param.reduce((acc, item) => {
|
||||
acc[item.param_name] = item.param_value;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
form.setFieldsValue(fields);
|
||||
form.setFieldValue('global_param', pipeline.global_param);
|
||||
} else {
|
||||
setGlobalParam([]);
|
||||
form.setFieldValue('global_param', []);
|
||||
}
|
||||
};
|
||||
return (
|
||||
|
@ -73,11 +123,12 @@ function AddExperimentModal({
|
|||
>
|
||||
<Form
|
||||
name="form"
|
||||
layout="vertical"
|
||||
layout="horizontal"
|
||||
initialValues={initialValues}
|
||||
onFinish={onFinish}
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
{...layout}
|
||||
>
|
||||
<Form.Item
|
||||
label="实验名称"
|
||||
|
@ -114,11 +165,32 @@ function AddExperimentModal({
|
|||
: null}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
{globalParam.map((item) => (
|
||||
<Form.Item label={item.param_name} name={item.param_name} key={item.param_name}>
|
||||
<Input />
|
||||
{globalParam.length > 0 && (
|
||||
<Form.Item label="运行参数" tooltip="展示关联的流水线的参数,脱敏的参数以xxxx展示">
|
||||
<div className={styles.global_param_item}>
|
||||
<Form.List name="global_param">
|
||||
{(fields) =>
|
||||
fields.map(({ key, name, ...restField }) => (
|
||||
<Form.Item
|
||||
{...tailLayout}
|
||||
{...restField}
|
||||
key={key}
|
||||
label={getParamType(globalParam[name])}
|
||||
name={[name, 'param_value']}
|
||||
labelAlign="left"
|
||||
rules={getParamRules(globalParam[name]['param_type'])}
|
||||
>
|
||||
{getParamComponent(
|
||||
globalParam[name]['param_type'],
|
||||
globalParam[name]['is_sensitive'],
|
||||
)}
|
||||
</Form.Item>
|
||||
))
|
||||
}
|
||||
</Form.List>
|
||||
</div>
|
||||
</Form.Item>
|
||||
))}
|
||||
)}
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -119,22 +119,12 @@ function Experiment() {
|
|||
};
|
||||
// 创建或者编辑实验接口请求
|
||||
const handleAddExperiment = async (values) => {
|
||||
const workflow_id = values['workflow_id'];
|
||||
let global_param = undefined;
|
||||
const pipeline = workflowList.find((v) => v.id === workflow_id);
|
||||
if (pipeline && pipeline.global_param) {
|
||||
const globalParamList = [...pipeline.global_param];
|
||||
for (const item of globalParamList) {
|
||||
item.param_value = values[item.param_name];
|
||||
values[item.param_name] = undefined;
|
||||
}
|
||||
global_param = JSON.stringify(globalParamList);
|
||||
}
|
||||
const params = {
|
||||
...values,
|
||||
global_param,
|
||||
};
|
||||
const global_param = JSON.stringify(values.global_param);
|
||||
if (!experimentId) {
|
||||
const params = {
|
||||
...values,
|
||||
global_param,
|
||||
};
|
||||
const [res, _] = await to(postExperiment(params));
|
||||
if (res) {
|
||||
message.success('新建实验成功');
|
||||
|
@ -142,7 +132,7 @@ function Experiment() {
|
|||
getList();
|
||||
}
|
||||
} else {
|
||||
const params = { ...values, id: experimentId };
|
||||
const params = { ...values, global_param, id: experimentId };
|
||||
const [res, _] = await to(putExperiment(params));
|
||||
if (res) {
|
||||
message.success('编辑实验成功');
|
||||
|
@ -431,14 +421,16 @@ function Experiment() {
|
|||
rowExpandable: (record) => true,
|
||||
}}
|
||||
/>
|
||||
<AddExperimentModal
|
||||
isAdd={isAdd}
|
||||
open={isModalOpen}
|
||||
initialValues={addFormData}
|
||||
onCancel={handleCancel}
|
||||
onFinish={handleAddExperiment}
|
||||
workflowList={workflowList}
|
||||
/>
|
||||
{isModalOpen && (
|
||||
<AddExperimentModal
|
||||
isAdd={isAdd}
|
||||
open={isModalOpen}
|
||||
initialValues={addFormData}
|
||||
onCancel={handleCancel}
|
||||
onFinish={handleAddExperiment}
|
||||
workflowList={workflowList}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,13 @@
|
|||
top: 5px;
|
||||
right: 0;
|
||||
}
|
||||
.add_button {
|
||||
.add_button_form_item {
|
||||
margin-top: 15px;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
.add_button_form_item .add_button {
|
||||
padding: 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import {
|
||||
getParamComponent,
|
||||
getParamRules,
|
||||
} from '@/pages/Experiment/experimentText/addExperimentModal';
|
||||
import { type PipelineGlobalParam } from '@/types';
|
||||
import { to } from '@/utils/promise';
|
||||
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { Button, Drawer, Form, Input, Radio } from 'antd';
|
||||
import { NamePath } from 'antd/es/form/interface';
|
||||
import { forwardRef, useImperativeHandle } from 'react';
|
||||
import styles from './globalParamsDrawer.less';
|
||||
|
||||
|
@ -26,6 +31,11 @@ const GlobalParamsDrawer = forwardRef(
|
|||
}
|
||||
},
|
||||
}));
|
||||
|
||||
const handleTypeChange = (name: NamePath) => {
|
||||
form.setFieldValue(name, null);
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
rootStyle={{ marginTop: '45px' }}
|
||||
|
@ -77,26 +87,41 @@ const GlobalParamsDrawer = forwardRef(
|
|||
label="类 型"
|
||||
rules={[{ required: true, message: '请选择类型' }]}
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio.Group
|
||||
onChange={() => handleTypeChange(['global_param', name, 'param_value'])}
|
||||
>
|
||||
<Radio value={1}>字符串</Radio>
|
||||
<Radio value={2}>整型</Radio>
|
||||
<Radio value={3}>布尔类型</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...restField}
|
||||
name={[name, 'param_value']}
|
||||
label="值"
|
||||
rules={[{ required: true, message: '请输入值' }]}
|
||||
noStyle
|
||||
shouldUpdate={(prev, cur) =>
|
||||
prev.global_param?.[name]?.param_type !==
|
||||
cur.global_param?.[name]?.param_type
|
||||
}
|
||||
>
|
||||
<Input placeholder="请输入值" allowClear />
|
||||
{({ getFieldValue }) => (
|
||||
<Form.Item
|
||||
{...restField}
|
||||
name={[name, 'param_value']}
|
||||
label="值"
|
||||
rules={getParamRules(
|
||||
getFieldValue(['global_param', name, 'param_type']),
|
||||
true,
|
||||
)}
|
||||
>
|
||||
{getParamComponent(getFieldValue(['global_param', name, 'param_type']))}
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...restField}
|
||||
name={[name, 'is_sensitive']}
|
||||
label="脱敏显示"
|
||||
rules={[{ required: true, message: '请选择' }]}
|
||||
tooltip="脱敏后的参数以*****显示"
|
||||
tooltip="展示关联的流水线的参数,脱敏的参数以xxxx展示"
|
||||
>
|
||||
<Radio.Group>
|
||||
<Radio value={1}>是</Radio>
|
||||
|
@ -111,11 +136,11 @@ const GlobalParamsDrawer = forwardRef(
|
|||
></Button>
|
||||
</div>
|
||||
))}
|
||||
<Form.Item>
|
||||
<Form.Item className={styles.add_button_form_item}>
|
||||
<Button
|
||||
className={styles.add_button}
|
||||
type="link"
|
||||
onClick={add}
|
||||
onClick={() => add()}
|
||||
icon={<PlusOutlined />}
|
||||
>
|
||||
流水线参数
|
||||
|
|
|
@ -101,13 +101,14 @@ const EditPipeline = () => {
|
|||
}
|
||||
const data = graph.save();
|
||||
console.log(data);
|
||||
let params = {
|
||||
const params = {
|
||||
...locationParams,
|
||||
dag: JSON.stringify(data),
|
||||
global_param: JSON.stringify(res.global_param),
|
||||
};
|
||||
saveWorkflow(params).then((ret) => {
|
||||
message.success('保存成功');
|
||||
closeParamsDrawer();
|
||||
setTimeout(() => {
|
||||
if (val) {
|
||||
navgite({ pathname: `/pipeline` });
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// 流水线全局参数
|
||||
export type PipelineGlobalParam = {
|
||||
workflow_id: number;
|
||||
param_name: string;
|
||||
description: string;
|
||||
param_type: number;
|
||||
|
|
|
@ -9,3 +9,4 @@ export function getNameByCode(list, code) {
|
|||
});
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue