mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-11 13:58:58 +00:00
feat: add slider textarea treeSelect(80%) timePicker
This commit is contained in:
@@ -4,8 +4,8 @@ import React from 'react';
|
||||
import RequiredIcon from './required-icon';
|
||||
import NodeHandler from './node-handler';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { RenderSelect, RenderCascader } from './node-renderer';
|
||||
|
||||
import { RenderSelect, RenderSlider, RenderTreeSelect, RenderTimePicker, RenderTextArea, RenderCascader } from './node-renderer';
|
||||
import { uiAtrrtUnderlineToHump } from '@/utils/flow'
|
||||
interface NodeParamHandlerProps {
|
||||
node: IFlowNode;
|
||||
data: IFlowNodeParameter;
|
||||
@@ -16,6 +16,7 @@ interface NodeParamHandlerProps {
|
||||
// render node parameters item
|
||||
const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label, index }) => {
|
||||
function onChange(value: any) {
|
||||
console.log(value);
|
||||
data.value = value;
|
||||
}
|
||||
|
||||
@@ -102,11 +103,26 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
// render node parameters based on AWEL2.0
|
||||
function renderNodeWithUiParam(data: IFlowNodeParameter) {
|
||||
let defaultValue = data.value !== null && data.value !== undefined ? data.value : data.default;
|
||||
|
||||
if (data?.ui?.attr) {
|
||||
uiAtrrtUnderlineToHump(data.ui.attr)
|
||||
}
|
||||
// TODO: 根据ui_type渲染不同的组件
|
||||
switch (data?.ui?.ui_type) {
|
||||
case 'select':
|
||||
return <RenderSelect data={data} defaultValue={defaultValue} onChange={onChange} />;
|
||||
break
|
||||
case 'text_area':
|
||||
return <RenderTextArea data={data} defaultValue={defaultValue} onChange={onChange} />;
|
||||
break
|
||||
case 'slider':
|
||||
return <RenderSlider data={data} defaultValue={defaultValue} onChange={onChange} />;
|
||||
break
|
||||
case 'time_picker':
|
||||
return <RenderTimePicker data={data} defaultValue={defaultValue} onChange={onChange} />;
|
||||
break
|
||||
case 'tree_select':
|
||||
return <RenderTreeSelect data={data} defaultValue={defaultValue} onChange={onChange} />;
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,3 +134,4 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
};
|
||||
|
||||
export default NodeParamHandler;
|
||||
|
||||
|
@@ -1,2 +1,6 @@
|
||||
export * from "./select";
|
||||
export * from "./cascader";
|
||||
export * from "./textarea";
|
||||
export * from "./slider";
|
||||
export * from "./timePicker";
|
||||
export * from "./treeSelect";
|
53
web/components/flow/node-renderer/slider.tsx
Normal file
53
web/components/flow/node-renderer/slider.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { IFlowNodeParameter } from "@/types/flow";
|
||||
import { Col, InputNumber, Row, Slider, Space } from 'antd';
|
||||
import { uiAtrrtUnderlineToHump } from '@/utils/flow'
|
||||
import type { InputNumberProps } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
|
||||
type TextAreaProps = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const RenderSlider = (params: TextAreaProps) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
|
||||
const [inputValue, setInputValue] = useState(defaultValue);
|
||||
|
||||
const onChangeSlider: InputNumberProps['onChange'] = (newValue) => {
|
||||
setInputValue(newValue as number);
|
||||
onChange(newValue as number)
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{data?.ui?.show_input ? <Row>
|
||||
<Col span={12}>
|
||||
<Slider
|
||||
{...data.ui.attr}
|
||||
onChange={onChangeSlider}
|
||||
value={typeof inputValue === 'number' ? inputValue : 0}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<InputNumber
|
||||
{...data.ui.attr}
|
||||
style={{ margin: '0 16px' }}
|
||||
value={inputValue}
|
||||
onChange={onChangeSlider}
|
||||
/>
|
||||
</Col>
|
||||
</Row>:
|
||||
<Slider
|
||||
{...data.ui.attr}
|
||||
onChange={onChangeSlider}
|
||||
value={typeof inputValue === 'number' ? inputValue : 0}
|
||||
/>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
53
web/components/flow/node-renderer/sliderList.tsx
Normal file
53
web/components/flow/node-renderer/sliderList.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { IFlowNodeParameter } from "@/types/flow";
|
||||
import { Col, InputNumber, Row, Slider, Space } from 'antd';
|
||||
import { uiAtrrtUnderlineToHump } from '@/utils/flow'
|
||||
import type { InputNumberProps } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
|
||||
type TextAreaProps = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const RenderSlider = (params: TextAreaProps) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
|
||||
const [inputValue, setInputValue] = useState(defaultValue);
|
||||
|
||||
const onChangeSlider: InputNumberProps['onChange'] = (newValue) => {
|
||||
setInputValue(newValue as number);
|
||||
onChange(newValue as number)
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{data?.ui?.show_input ? <Row>
|
||||
<Col span={12}>
|
||||
<Slider
|
||||
{...data.ui.attr}
|
||||
onChange={onChangeSlider}
|
||||
value={typeof inputValue === 'number' ? inputValue : 0}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<InputNumber
|
||||
{...data.ui.attr}
|
||||
style={{ margin: '0 16px' }}
|
||||
value={inputValue}
|
||||
onChange={onChangeSlider}
|
||||
/>
|
||||
</Col>
|
||||
</Row>:
|
||||
<Slider
|
||||
{...data.ui.attr}
|
||||
onChange={onChangeSlider}
|
||||
value={typeof inputValue === 'number' ? inputValue : 0}
|
||||
/>
|
||||
}
|
||||
</>
|
||||
)
|
||||
}
|
22
web/components/flow/node-renderer/textarea.tsx
Normal file
22
web/components/flow/node-renderer/textarea.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { IFlowNodeParameter } from "@/types/flow";
|
||||
import { Input } from 'antd';
|
||||
import { uiAtrrtUnderlineToHump } from '@/utils/flow'
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
type TextAreaProps = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
|
||||
|
||||
export const RenderTextArea = (params: TextAreaProps) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
if(data?.ui?.autosize){
|
||||
uiAtrrtUnderlineToHump(data.ui.autosize)
|
||||
}
|
||||
return (
|
||||
<TextArea {...data.ui.attr} defaultValue={defaultValue} onChange={(e) => onChange(e.target.value)} {...data.ui.autosize} rows={4} />
|
||||
)
|
||||
}
|
34
web/components/flow/node-renderer/timePicker.tsx
Normal file
34
web/components/flow/node-renderer/timePicker.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React, { useState } from 'react';
|
||||
import type { TimePickerProps } from 'antd';
|
||||
import { TimePicker } from 'antd';
|
||||
|
||||
|
||||
import { IFlowNodeParameter } from "@/types/flow";
|
||||
|
||||
type TextAreaProps = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
export const RenderTimePicker = (params: TextAreaProps) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const [value, setValue] = useState(defaultValue);
|
||||
|
||||
// dayjs.extend(customParseFormat);
|
||||
|
||||
const onChangeTime: TimePickerProps['onChange'] = (time, timeString) => {
|
||||
// console.log(timeString);
|
||||
onChange(timeString)
|
||||
setValue(time)
|
||||
};
|
||||
|
||||
return (
|
||||
<TimePicker
|
||||
style={{ width: '100%' }}
|
||||
{...data.ui.attr} value={value}
|
||||
onChange={onChangeTime} />
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
|
95
web/components/flow/node-renderer/treeSelect.tsx
Normal file
95
web/components/flow/node-renderer/treeSelect.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import React, { useState } from 'react';
|
||||
import { TreeSelect } from 'antd';
|
||||
import type { TreeSelectProps } from 'antd';
|
||||
import { IFlowNodeParameter } from "@/types/flow";
|
||||
import { Label } from '@mui/icons-material';
|
||||
|
||||
type TextAreaProps = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
}
|
||||
const treeData = [
|
||||
{
|
||||
value: 'parent 1',
|
||||
title: 'parent 1',
|
||||
children: [
|
||||
{
|
||||
value: 'parent 1-0',
|
||||
title: 'parent 1-0',
|
||||
children: [
|
||||
{
|
||||
value: 'leaf1',
|
||||
title: 'leaf1',
|
||||
},
|
||||
{
|
||||
value: 'leaf2',
|
||||
title: 'leaf2',
|
||||
},
|
||||
{
|
||||
value: 'leaf3',
|
||||
title: 'leaf3',
|
||||
}, {
|
||||
value: 'leaf4',
|
||||
title: 'leaf4',
|
||||
},
|
||||
{
|
||||
value: 'leaf5',
|
||||
title: 'leaf5',
|
||||
},
|
||||
{
|
||||
value: 'leaf6',
|
||||
title: 'leaf6',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
value: 'parent 1-1',
|
||||
title: 'parent 1-1',
|
||||
children: [
|
||||
{
|
||||
value: 'leaf11',
|
||||
title: <b style={{ color: '#08c' }}>leaf11</b>,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
export const RenderTreeSelect = (params: TextAreaProps) => {
|
||||
// const { data, defaultValue, onChange } = params;
|
||||
// console.log(data.options);
|
||||
const [value, setValue] = useState<string>();
|
||||
|
||||
const onChange = (newValue: string) => {
|
||||
setValue(newValue);
|
||||
};
|
||||
const focuss = ()=>{
|
||||
console.log('focus==========');
|
||||
|
||||
}
|
||||
return (
|
||||
<TreeSelect
|
||||
fieldNames={{ label: 'label', value: 'value', children: 'children' }}
|
||||
{...data.ui.attr}
|
||||
style={{ width: '100%' }}
|
||||
value={defaultValue}
|
||||
treeDefaultExpandAll
|
||||
onChange={onChange}
|
||||
treeData={data.options}
|
||||
/>
|
||||
|
||||
// <TreeSelect
|
||||
// showSearch
|
||||
// style={{ width: '100%' }}
|
||||
// value={value}
|
||||
// dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
// placeholder="Please select"
|
||||
// allowClear
|
||||
// treeDefaultExpandAll
|
||||
// onChange={onChange}
|
||||
// treeData={treeData}
|
||||
// getPopupContainer={() => document.body}
|
||||
// />
|
||||
);
|
||||
}
|
@@ -58,6 +58,13 @@ export type IFlowNodeParameterUI = {
|
||||
disabled: boolean;
|
||||
[key: string]: any;
|
||||
};
|
||||
autosize: {
|
||||
minRows: number;
|
||||
maxRows: number;
|
||||
min_rows: number;
|
||||
max_rows: number;
|
||||
};
|
||||
show_input: boolean;
|
||||
};
|
||||
|
||||
export type IFlowNodeInput = {
|
||||
|
@@ -10,6 +10,26 @@ export const getUniqueNodeId = (nodeData: IFlowNode, nodes: Node[]) => {
|
||||
});
|
||||
return `${nodeData.id}_${count}`;
|
||||
};
|
||||
/**
|
||||
*
|
||||
* 下划线转驼峰
|
||||
*/
|
||||
export const uiAtrrtUnderlineToHump = (obj: any) => {
|
||||
for(let key in obj){
|
||||
if(key.indexOf('_') !== -1){
|
||||
let newKey = key.replace(/_(\w)/g, (all, letter) => {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
|
||||
obj[newKey] = obj[key];
|
||||
delete obj[key];
|
||||
// 判断是否为对象
|
||||
if(typeof obj[newKey] === 'object'){
|
||||
uiAtrrtUnderlineToHump(obj[newKey]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 驼峰转下划线,接口协议字段命名规范
|
||||
export const mapHumpToUnderline = (flowData: IFlowData) => {
|
||||
|
Reference in New Issue
Block a user