mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-08-05 10:29:36 +00:00
chore: Update AddFlowVariable component to remove unnecessary code in parameter management (#1948)
This commit is contained in:
commit
7661de8602
@ -1,78 +1,115 @@
|
|||||||
import { apiInterceptors, getFlowNodes } from '@/client/api';
|
// import { IFlowNode } from '@/types/flow';
|
||||||
import { IFlowNode } from '@/types/flow';
|
|
||||||
import { FLOW_NODES_KEY } from '@/utils';
|
|
||||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
import { Button, Form, Input, Modal } from 'antd';
|
import { Button, Form, Input, Modal, Select, Space } from 'antd';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
type GroupType = { category: string; categoryLabel: string; nodes: IFlowNode[] };
|
// ype GroupType = { category: string; categoryLabel: string; nodes: IFlowNode[] };
|
||||||
|
type ValueType = 'str' | 'int' | 'float' | 'bool' | 'ref';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
const DAG_PARAM_KEY = 'dbgpt.core.flow.params';
|
||||||
|
const DAG_PARAM_SCOPE = 'flow_priv';
|
||||||
|
|
||||||
const AddFlowVariable: React.FC = () => {
|
const AddFlowVariable: React.FC = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [operators, setOperators] = useState<Array<IFlowNode>>([]);
|
// const [operators, setOperators] = useState<Array<IFlowNode>>([]);
|
||||||
const [resources, setResources] = useState<Array<IFlowNode>>([]);
|
// const [resources, setResources] = useState<Array<IFlowNode>>([]);
|
||||||
const [operatorsGroup, setOperatorsGroup] = useState<GroupType[]>([]);
|
// const [operatorsGroup, setOperatorsGroup] = useState<GroupType[]>([]);
|
||||||
const [resourcesGroup, setResourcesGroup] = useState<GroupType[]>([]);
|
// const [resourcesGroup, setResourcesGroup] = useState<GroupType[]>([]);
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
const [form] = Form.useForm(); // const [form] = Form.useForm<IFlowUpdateParam>();
|
||||||
|
|
||||||
const showModal = () => {
|
const showModal = () => {
|
||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
// TODO: get keys
|
||||||
getNodes();
|
// useEffect(() => {
|
||||||
}, []);
|
// getNodes();
|
||||||
|
// }, []);
|
||||||
|
|
||||||
async function getNodes() {
|
// async function getNodes() {
|
||||||
const [_, data] = await apiInterceptors(getFlowNodes());
|
// const [_, data] = await apiInterceptors(getFlowNodes());
|
||||||
if (data && data.length > 0) {
|
// if (data && data.length > 0) {
|
||||||
localStorage.setItem(FLOW_NODES_KEY, JSON.stringify(data));
|
// localStorage.setItem(FLOW_NODES_KEY, JSON.stringify(data));
|
||||||
const operatorNodes = data.filter(node => node.flow_type === 'operator');
|
// const operatorNodes = data.filter(node => node.flow_type === 'operator');
|
||||||
const resourceNodes = data.filter(node => node.flow_type === 'resource');
|
// const resourceNodes = data.filter(node => node.flow_type === 'resource');
|
||||||
setOperators(operatorNodes);
|
// setOperators(operatorNodes);
|
||||||
setResources(resourceNodes);
|
// setResources(resourceNodes);
|
||||||
setOperatorsGroup(groupNodes(operatorNodes));
|
// setOperatorsGroup(groupNodes(operatorNodes));
|
||||||
setResourcesGroup(groupNodes(resourceNodes));
|
// setResourcesGroup(groupNodes(resourceNodes));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
function groupNodes(data: IFlowNode[]) {
|
// function groupNodes(data: IFlowNode[]) {
|
||||||
const groups: GroupType[] = [];
|
// const groups: GroupType[] = [];
|
||||||
const categoryMap: Record<string, { category: string; categoryLabel: string; nodes: IFlowNode[] }> = {};
|
// const categoryMap: Record<string, { category: string; categoryLabel: string; nodes: IFlowNode[] }> = {};
|
||||||
data.forEach(item => {
|
// data.forEach(item => {
|
||||||
const { category, category_label } = item;
|
// const { category, category_label } = item;
|
||||||
if (!categoryMap[category]) {
|
// if (!categoryMap[category]) {
|
||||||
categoryMap[category] = { category, categoryLabel: category_label, nodes: [] };
|
// categoryMap[category] = { category, categoryLabel: category_label, nodes: [] };
|
||||||
groups.push(categoryMap[category]);
|
// groups.push(categoryMap[category]);
|
||||||
}
|
// }
|
||||||
categoryMap[category].nodes.push(item);
|
// categoryMap[category].nodes.push(item);
|
||||||
});
|
// });
|
||||||
return groups;
|
// return groups;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const formItemLayout = {
|
|
||||||
labelCol: {
|
|
||||||
xs: { span: 24 },
|
|
||||||
sm: { span: 4 },
|
|
||||||
},
|
|
||||||
wrapperCol: {
|
|
||||||
xs: { span: 24 },
|
|
||||||
sm: { span: 20 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const formItemLayoutWithOutLabel = {
|
|
||||||
wrapperCol: {
|
|
||||||
xs: { span: 24, offset: 0 },
|
|
||||||
sm: { span: 20, offset: 2 },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const onFinish = (values: any) => {
|
const onFinish = (values: any) => {
|
||||||
console.log('Received values of form:', values);
|
console.log('Received values of form:', values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onNameChange(e: React.ChangeEvent<HTMLInputElement>, index: number) {
|
||||||
|
const name = e.target.value;
|
||||||
|
|
||||||
|
const result = name
|
||||||
|
?.split('_')
|
||||||
|
?.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||||
|
?.join(' ');
|
||||||
|
|
||||||
|
form.setFields([
|
||||||
|
{
|
||||||
|
name: ['parameters', index, 'label'],
|
||||||
|
value: result,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// change value to ref
|
||||||
|
const type = form.getFieldValue(['parameters', index, 'value_type']);
|
||||||
|
|
||||||
|
if (type === 'ref') {
|
||||||
|
const parameters = form.getFieldValue('parameters');
|
||||||
|
const param = parameters?.[index];
|
||||||
|
|
||||||
|
if (param) {
|
||||||
|
const { name = '' } = param;
|
||||||
|
param.value = `${DAG_PARAM_KEY}:${name}@scope:${DAG_PARAM_SCOPE}`;
|
||||||
|
|
||||||
|
form.setFieldsValue({
|
||||||
|
parameters: [...parameters],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onValueTypeChange(type: ValueType, index: number) {
|
||||||
|
if (type === 'ref') {
|
||||||
|
const parameters = form.getFieldValue('parameters');
|
||||||
|
const param = parameters?.[index];
|
||||||
|
|
||||||
|
if (param) {
|
||||||
|
const { name = '' } = param;
|
||||||
|
param.value = `${DAG_PARAM_KEY}:${name}@scope:${DAG_PARAM_SCOPE}`;
|
||||||
|
|
||||||
|
form.setFieldsValue({
|
||||||
|
parameters: [...parameters],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
@ -83,64 +120,111 @@ const AddFlowVariable: React.FC = () => {
|
|||||||
onClick={showModal}
|
onClick={showModal}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Modal title={t('Add_Global_Variable_of_Flow')} open={isModalOpen} footer={null}>
|
<Modal
|
||||||
<Form name='dynamic_form_item' {...formItemLayoutWithOutLabel} onFinish={onFinish} className='mt-8'>
|
title={t('Add_Global_Variable_of_Flow')}
|
||||||
<Form.List
|
open={isModalOpen}
|
||||||
name='names'
|
footer={null}
|
||||||
rules={[
|
width={1000}
|
||||||
{
|
styles={{
|
||||||
validator: async (_, names) => {
|
body: {
|
||||||
if (!names || names.length < 2) {
|
maxHeight: '70vh',
|
||||||
return Promise.reject(new Error('At least 2 passengers'));
|
overflow: 'scroll',
|
||||||
}
|
backgroundColor: 'rgba(0,0,0,0.02)',
|
||||||
|
padding: '0 8px',
|
||||||
|
borderRadius: 4,
|
||||||
},
|
},
|
||||||
},
|
}}
|
||||||
]}
|
onClose={() => setIsModalOpen(false)}
|
||||||
>
|
>
|
||||||
{(fields, { add, remove }, { errors }) => (
|
<Form
|
||||||
|
name='dynamic_form_nest_item'
|
||||||
|
onFinish={onFinish}
|
||||||
|
form={form}
|
||||||
|
autoComplete='off'
|
||||||
|
layout='vertical'
|
||||||
|
className='mt-8'
|
||||||
|
initialValues={{ parameters: [{}] }}
|
||||||
|
>
|
||||||
|
<Form.List name='parameters'>
|
||||||
|
{(fields, { add, remove }) => (
|
||||||
<>
|
<>
|
||||||
{fields.map((field, index) => (
|
{fields.map(({ key, name, ...restField }, index) => (
|
||||||
|
<Space key={key} style={{ display: 'flex', marginBottom: 8 }} align='baseline'>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
{...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
|
{...restField}
|
||||||
label={index === 0 ? 'Passengers' : ''}
|
name={[name, 'name']}
|
||||||
required={false}
|
label={`参数 ${index + 1} 名称`}
|
||||||
key={field.key}
|
style={{ width: 140 }}
|
||||||
>
|
|
||||||
<Form.Item
|
|
||||||
{...field}
|
|
||||||
validateTrigger={['onChange', 'onBlur']}
|
|
||||||
rules={[
|
rules={[
|
||||||
|
{ required: true, message: 'Missing parameter name' },
|
||||||
{
|
{
|
||||||
required: true,
|
pattern: /^[a-zA-Z0-9]+(_[a-zA-Z0-9]+)*$/,
|
||||||
whitespace: true,
|
message: '名称必须是字母、数字或下划线,并使用下划线分隔多个单词',
|
||||||
message: "Please input passenger's name or delete this field.",
|
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
noStyle
|
|
||||||
>
|
>
|
||||||
<Input placeholder='passenger name' style={{ width: '60%' }} />
|
<Input placeholder='Parameter Name' onChange={e => onNameChange(e, index)} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{fields.length > 1 ? (
|
|
||||||
<MinusCircleOutlined className='dynamic-delete-button' onClick={() => remove(field.name)} />
|
<Form.Item
|
||||||
) : null}
|
{...restField}
|
||||||
|
name={[name, 'label']}
|
||||||
|
label='标题'
|
||||||
|
style={{ width: 130 }}
|
||||||
|
rules={[{ required: true, message: 'Missing parameter label' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder='Parameter Label' />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'value_type']}
|
||||||
|
label='类型'
|
||||||
|
style={{ width: 100 }}
|
||||||
|
rules={[{ required: true, message: 'Missing parameter type' }]}
|
||||||
|
>
|
||||||
|
<Select placeholder='Select' onChange={value => onValueTypeChange(value, index)}>
|
||||||
|
{['str', 'int', 'float', 'bool', 'ref'].map(type => (
|
||||||
|
<Option key={type} value={type}>
|
||||||
|
{type}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
{...restField}
|
||||||
|
name={[name, 'value']}
|
||||||
|
label='值'
|
||||||
|
style={{ width: 320 }}
|
||||||
|
rules={[{ required: true, message: 'Missing parameter value' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder='Parameter Value' />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item {...restField} name={[name, 'description']} label='描述' style={{ width: 170 }}>
|
||||||
|
<Input placeholder='Parameter Description' />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<MinusCircleOutlined onClick={() => remove(name)} />
|
||||||
|
</Space>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button type='dashed' onClick={() => add()} className='w-full' icon={<PlusOutlined />}>
|
<Button type='dashed' onClick={() => add()} block icon={<PlusOutlined />}>
|
||||||
Add field
|
{t('Add_Parameter')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Form.ErrorList errors={errors} />
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Form.List>
|
</Form.List>
|
||||||
|
<Form.Item wrapperCol={{ offset: 20, span: 4 }}>
|
||||||
<Form.Item wrapperCol={{ offset: 18, span: 8 }}>
|
<Space>
|
||||||
|
<Button onClick={() => setIsModalOpen(false)}>{t('cancel')}</Button>
|
||||||
<Button type='primary' htmlType='submit'>
|
<Button type='primary' htmlType='submit'>
|
||||||
Submit
|
{t('verify')}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Space>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -43,7 +43,6 @@ export const ExportFlowModal: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
centered
|
|
||||||
title={t('Export_Flow')}
|
title={t('Export_Flow')}
|
||||||
open={isExportFlowModalOpen}
|
open={isExportFlowModalOpen}
|
||||||
onCancel={() => setIsExportFlowModalOpen(false)}
|
onCancel={() => setIsExportFlowModalOpen(false)}
|
||||||
|
@ -61,7 +61,6 @@ export const ImportFlowModal: React.FC<Props> = ({ isImportModalOpen, setIsImpor
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
centered
|
|
||||||
title={t('Import_Flow')}
|
title={t('Import_Flow')}
|
||||||
open={isImportModalOpen}
|
open={isImportModalOpen}
|
||||||
onCancel={() => setIsImportFlowModalOpen(false)}
|
onCancel={() => setIsImportFlowModalOpen(false)}
|
||||||
|
@ -89,7 +89,6 @@ export const SaveFlowModal: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
centered
|
|
||||||
title={t('flow_modal_title')}
|
title={t('flow_modal_title')}
|
||||||
open={isSaveFlowModalOpen}
|
open={isSaveFlowModalOpen}
|
||||||
onCancel={() => {
|
onCancel={() => {
|
||||||
@ -142,7 +141,7 @@ export const SaveFlowModal: React.FC<Props> = ({
|
|||||||
<TextArea rows={3} />
|
<TextArea rows={3} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item label='Editable' name='editable' initialValue={flowInfo?.editable} valuePropName='checked'>
|
<Form.Item label='Editable' name='editable' initialValue={flowInfo?.editable || true} valuePropName='checked'>
|
||||||
<Checkbox />
|
<Checkbox />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
@ -18,4 +18,5 @@ export const FlowEn = {
|
|||||||
No: 'No',
|
No: 'No',
|
||||||
Please_Add_Nodes_First: 'Please add nodes first',
|
Please_Add_Nodes_First: 'Please add nodes first',
|
||||||
Add_Global_Variable_of_Flow: 'Add global variable of flow',
|
Add_Global_Variable_of_Flow: 'Add global variable of flow',
|
||||||
|
Add_Parameter: 'Add Parameter',
|
||||||
};
|
};
|
||||||
|
@ -18,4 +18,5 @@ export const FlowZn = {
|
|||||||
No: '否',
|
No: '否',
|
||||||
Please_Add_Nodes_First: '请先添加节点',
|
Please_Add_Nodes_First: '请先添加节点',
|
||||||
Add_Global_Variable_of_Flow: '添加 Flow 全局变量',
|
Add_Global_Variable_of_Flow: '添加 Flow 全局变量',
|
||||||
|
Add_Parameter: '添加参数',
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user