mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-12 12:37:14 +00:00
feat: fix import typo in node-renderer/index.ts
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import { Domain } from '@mui/icons-material';
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
const en = {
|
||||
UploadDataSuccessfully: 'file uploaded successfully',
|
||||
UploadDataFailed: 'file upload failed',
|
||||
UploadData: 'Upload Data',
|
||||
CodeEditor: 'Code Editor:',
|
||||
openCodeEditor:'Open Code Editor',
|
||||
Upload_Data_Successfully: 'file uploaded successfully',
|
||||
Upload_Data_Failed: 'file upload failed',
|
||||
Upload_Data: 'Upload Data',
|
||||
Code_Editor: 'Code Editor',
|
||||
Open_Code_Editor: 'Open Code Editor',
|
||||
Knowledge_Space: 'Knowledge',
|
||||
space: 'space',
|
||||
Vector: 'Vector',
|
||||
@@ -23,6 +24,7 @@ const en = {
|
||||
Please_select_file: 'Please select one file',
|
||||
Description: 'Description',
|
||||
Storage: 'Storage',
|
||||
Domain: 'Domain',
|
||||
Please_input_the_description: 'Please input the description',
|
||||
Please_select_the_storage: 'Please select the storage',
|
||||
Please_select_the_domain_type: 'Please select the domain type',
|
||||
@@ -229,7 +231,7 @@ const en = {
|
||||
Chinese: 'Chinese',
|
||||
English: 'English',
|
||||
refreshSuccess: 'Refresh Success',
|
||||
Download: 'Download'
|
||||
Download: 'Download',
|
||||
} as const;
|
||||
|
||||
export type I18nKeys = keyof typeof en;
|
||||
@@ -239,11 +241,11 @@ export interface Resources {
|
||||
}
|
||||
|
||||
const zh: Resources['translation'] = {
|
||||
UploadDataSuccessfully: '文件上传成功',
|
||||
UploadDataFailed: '文件上传失败',
|
||||
UploadData: '上传数据',
|
||||
CodeEditor: '代码编辑:',
|
||||
openCodeEditor: '打开代码编辑器',
|
||||
Upload_Data_Successfully: '文件上传成功',
|
||||
Upload_Data_Failed: '文件上传失败',
|
||||
Upload_Data: '上传数据',
|
||||
Code_Editor: '代码编辑器',
|
||||
Open_Code_Editor: '打开代码编辑器',
|
||||
Knowledge_Space: '知识库',
|
||||
space: '知识库',
|
||||
Vector: '向量',
|
||||
|
@@ -71,26 +71,22 @@ const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
||||
reactFlow.setEdges((edges) => edges.filter((edge) => edge.source !== node.id && edge.target !== node.id));
|
||||
}
|
||||
|
||||
// function onChange(value: any) {
|
||||
// data.value = value;
|
||||
// }
|
||||
function updateCurrentNodeValue(changedKey: string, changedVal: any) {
|
||||
parameters.forEach((item) => {
|
||||
if (item.name === changedKey) {
|
||||
item.value = changedVal;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onValuesChange(changedValues: any, allValues: any) {
|
||||
// onChange(changedValues);
|
||||
console.log('Changed xxx', changedValues);
|
||||
console.log('All xxx', allValues);
|
||||
console.log('xxxx', parameters);
|
||||
async function updateDependsNodeValue(changedKey: string, changedVal: any) {
|
||||
if (!changedVal) return;
|
||||
|
||||
const [changedKey, changedVal] = Object.entries(changedValues)[0];
|
||||
console.log('====', changedKey, changedVal);
|
||||
const dependParamNodes = parameters.filter(({ ui }) => ui?.refresh_depends?.includes(changedKey));
|
||||
|
||||
// 获取以当前改变项目为 refresh_depends 的参数name
|
||||
const needChangeNodes = parameters.filter(({ ui }) => ui?.refresh_depends?.includes(changedKey));
|
||||
console.log('needChangeNodes====', needChangeNodes);
|
||||
if (dependParamNodes?.length === 0) return;
|
||||
|
||||
if (needChangeNodes?.length === 0) return;
|
||||
|
||||
needChangeNodes.forEach(async (item) => {
|
||||
dependParamNodes.forEach(async (item) => {
|
||||
const params = {
|
||||
id: removeIndexFromNodeId(data?.id),
|
||||
type_name: data.type_name,
|
||||
@@ -98,11 +94,11 @@ const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
||||
flow_type: 'operator' as const,
|
||||
refresh: [
|
||||
{
|
||||
name: item.name, // 要刷新的参数的name
|
||||
name: item.name,
|
||||
depends: [
|
||||
{
|
||||
name: changedKey, // 依赖的参数的name
|
||||
value: changedVal, // 依赖的参数的值
|
||||
name: changedKey,
|
||||
value: changedVal,
|
||||
has_value: true,
|
||||
},
|
||||
],
|
||||
@@ -110,29 +106,23 @@ const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
||||
],
|
||||
};
|
||||
|
||||
// const params = {
|
||||
// id: 'operator_example_refresh_operator___$$___example___$$___v1',
|
||||
// type_name: 'ExampleFlowRefreshOperator',
|
||||
// type_cls: 'unusual_prefix_90027f35e50ecfda77e3c7c7b20a0272d562480c_awel_flow_ui_components.ExampleFlowRefreshOperator',
|
||||
// flow_type: 'operator' as const,
|
||||
// refresh: [
|
||||
// {
|
||||
// name: 'recent_time', // 要刷新的参数的name
|
||||
// depends: [
|
||||
// {
|
||||
// name: 'time_interval', // 依赖的参数的name
|
||||
// value: 3, // 依赖的参数的值
|
||||
// has_value: true,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// };
|
||||
|
||||
const [_, res] = await apiInterceptors(refreshFlowNodeById(params));
|
||||
// TODO: update node value
|
||||
console.log('res', res);
|
||||
});
|
||||
}
|
||||
|
||||
function onParameterValuesChange(changedValues: any, allValues: any) {
|
||||
// TODO: update node value
|
||||
console.log('Changed xxx', changedValues);
|
||||
console.log('All xxx', allValues);
|
||||
|
||||
const [changedKey, changedVal] = Object.entries(changedValues)[0];
|
||||
|
||||
updateCurrentNodeValue(changedKey, changedVal);
|
||||
updateDependsNodeValue(changedKey, changedVal);
|
||||
}
|
||||
|
||||
return (
|
||||
<Popover
|
||||
placement="rightTop"
|
||||
@@ -194,15 +184,11 @@ const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
||||
{parameters?.length > 0 && (
|
||||
<div className="bg-zinc-100 dark:bg-zinc-700 rounded p-2">
|
||||
<TypeLabel label="Parameters" />
|
||||
{/* <div className="flex flex-col space-y-3 text-neutral-500"> */}
|
||||
|
||||
<Form form={form} layout="vertical" onValuesChange={onValuesChange} className="flex flex-col text-neutral-500">
|
||||
<Form form={form} layout="vertical" onValuesChange={onParameterValuesChange} className="flex flex-col space-y-3 text-neutral-500">
|
||||
{parameters?.map((item, index) => (
|
||||
<NodeParamHandler key={`${node.id}_param_${index}`} node={node} data={item} label="parameters" index={index} />
|
||||
<NodeParamHandler key={`${node.id}_param_${index}`} node={node} paramData={item} label="parameters" index={index} />
|
||||
))}
|
||||
</Form>
|
||||
|
||||
{/* </div> */}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
@@ -101,10 +101,8 @@ const NodeHandler: React.FC<NodeHandlerProps> = ({ node, data, type, label, inde
|
||||
isValidConnection={(connection) => isValidConnection(connection)}
|
||||
/>
|
||||
<Typography
|
||||
className={classNames('bg-white dark:bg-[#232734] w-full py-1 rounded text-neutral-500', {
|
||||
className={classNames('bg-white dark:bg-[#232734] w-full px-2 py-1 rounded text-neutral-500', {
|
||||
'text-right': label === 'outputs',
|
||||
'pl-2': label === 'inputs',
|
||||
'pr-2': label === 'outputs',
|
||||
})}
|
||||
>
|
||||
<Popconfirm
|
||||
|
@@ -1,111 +1,35 @@
|
||||
import { IFlowNode, IFlowNodeParameter } from '@/types/flow';
|
||||
import { Checkbox, Form, Input, InputNumber, Select, Tooltip } from 'antd';
|
||||
import { Checkbox, Form, Input, InputNumber, Select } from 'antd';
|
||||
import React from 'react';
|
||||
import RequiredIcon from './required-icon';
|
||||
import NodeHandler from './node-handler';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
RenderSelect,
|
||||
RenderCheckbox,
|
||||
RenderRadio,
|
||||
RenderCascader,
|
||||
RenderDatePicker,
|
||||
RenderInput,
|
||||
RenderSlider,
|
||||
RenderTreeSelect,
|
||||
RenderTimePicker,
|
||||
RenderTextArea,
|
||||
RenderUpload,
|
||||
RenderCodeEditor,
|
||||
RenderPassword,
|
||||
RenderVariables,
|
||||
renderSelect,
|
||||
renderCheckbox,
|
||||
renderRadio,
|
||||
renderCascader,
|
||||
renderDatePicker,
|
||||
renderInput,
|
||||
renderSlider,
|
||||
renderTreeSelect,
|
||||
renderTimePicker,
|
||||
renderTextArea,
|
||||
renderUpload,
|
||||
renderCodeEditor,
|
||||
renderPassword,
|
||||
renderVariables,
|
||||
} from './node-renderer';
|
||||
|
||||
interface NodeParamHandlerProps {
|
||||
node: IFlowNode;
|
||||
data: IFlowNodeParameter;
|
||||
paramData: IFlowNodeParameter;
|
||||
label: 'inputs' | 'outputs' | 'parameters';
|
||||
index: number; // index of array
|
||||
}
|
||||
|
||||
// render node parameters item
|
||||
const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label, index }) => {
|
||||
function onChange(value: any) {
|
||||
data.value = value;
|
||||
}
|
||||
|
||||
function renderLabelWithTooltip(data: IFlowNodeParameter) {
|
||||
return (
|
||||
<div>
|
||||
<RequiredIcon optional={data.optional} />
|
||||
{data.label}
|
||||
<Tooltip title={data.description || ''}>
|
||||
<InfoCircleOutlined className="ml-2 cursor-pointer" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, paramData, label, index }) => {
|
||||
// render node parameters based on AWEL1.0
|
||||
// function renderNodeWithoutUiParam(data: IFlowNodeParameter) {
|
||||
// let defaultValue = data.value ?? data.default;
|
||||
|
||||
// switch (data.type_name) {
|
||||
// case 'int':
|
||||
// case 'float':
|
||||
// return (
|
||||
// <div className="text-sm">
|
||||
// {renderLabelWithTooltip(data)}
|
||||
// <InputNumber
|
||||
// className="w-full"
|
||||
// defaultValue={defaultValue}
|
||||
// onChange={(value: number | null) => {
|
||||
// console.log('value', value);
|
||||
|
||||
// onChange(value);
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// case 'str':
|
||||
// return (
|
||||
// <div className="text-sm">
|
||||
// {renderLabelWithTooltip(data)}
|
||||
// {data.options?.length > 0 ? (
|
||||
// <Select
|
||||
// className="w-full nodrag"
|
||||
// defaultValue={defaultValue}
|
||||
// options={data.options.map((item: any) => ({ label: item.label, value: item.value }))}
|
||||
// onChange={onChange}
|
||||
// />
|
||||
// ) : (
|
||||
// <Input
|
||||
// className="w-full"
|
||||
// defaultValue={defaultValue}
|
||||
// onChange={(e) => {
|
||||
// onChange(e.target.value);
|
||||
// }}
|
||||
// />
|
||||
// )}
|
||||
// </div>
|
||||
// );
|
||||
// case 'bool':
|
||||
// defaultValue = defaultValue === 'False' ? false : defaultValue;
|
||||
// defaultValue = defaultValue === 'True' ? true : defaultValue;
|
||||
// return (
|
||||
// <div className="text-sm">
|
||||
// {renderLabelWithTooltip(data)}
|
||||
// <Checkbox
|
||||
// className="ml-2"
|
||||
// defaultChecked={defaultValue}
|
||||
// onChange={(e) => {
|
||||
// onChange(e.target.checked);
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
function renderNodeWithoutUiParam(data: IFlowNodeParameter) {
|
||||
let defaultValue = data.value ?? data.default;
|
||||
|
||||
@@ -114,139 +38,83 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
case 'float':
|
||||
return (
|
||||
<Form.Item
|
||||
className="mb-2"
|
||||
className="mb-2 text-sm"
|
||||
name={data.name}
|
||||
initialValue={defaultValue}
|
||||
rules={[{ required: !data.optional }]}
|
||||
label={<span className="text-neutral-500">{data.label}</span>}
|
||||
tooltip={data.description ? { title: data.description, icon: <InfoCircleOutlined /> } : ''}
|
||||
rules={[{ required: !data.optional }]}
|
||||
>
|
||||
<InputNumber className="w-full" defaultValue={defaultValue} onChange={onChange} />
|
||||
<InputNumber className="w-full nodrag" />
|
||||
</Form.Item>
|
||||
);
|
||||
{
|
||||
/* <div className="text-sm">
|
||||
{renderLabelWithTooltip(data)}
|
||||
<InputNumber
|
||||
className="w-full"
|
||||
defaultValue={defaultValue}
|
||||
onChange={(value: number | null) => {
|
||||
console.log('value', value);
|
||||
onChange(value);
|
||||
}}
|
||||
/>
|
||||
</div> */
|
||||
}
|
||||
|
||||
case 'str':
|
||||
return (
|
||||
<Form.Item
|
||||
className="mb-2"
|
||||
className="mb-2 text-sm"
|
||||
name={data.name}
|
||||
initialValue={defaultValue}
|
||||
rules={[{ required: !data.optional }]}
|
||||
label={<span className="text-neutral-500">{data.label}</span>}
|
||||
tooltip={data.description ? { title: data.description, icon: <InfoCircleOutlined /> } : ''}
|
||||
rules={[{ required: !data.optional }]}
|
||||
>
|
||||
{data.options?.length > 0 ? (
|
||||
<Select
|
||||
className="w-full nodrag"
|
||||
defaultValue={defaultValue}
|
||||
options={data.options.map((item: any) => ({ label: item.label, value: item.value }))}
|
||||
onChange={onChange}
|
||||
/>
|
||||
<Select className="w-full nodrag" options={data.options.map((item: any) => ({ label: item.label, value: item.value }))} />
|
||||
) : (
|
||||
<Input
|
||||
className="w-full"
|
||||
defaultValue={defaultValue}
|
||||
onChange={(e) => {
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<Input className="w-full" />
|
||||
)}
|
||||
</Form.Item>
|
||||
// <div className="text-sm">
|
||||
// {renderLabelWithTooltip(data)}
|
||||
// {data.options?.length > 0 ? (
|
||||
// <Select
|
||||
// className="w-full nodrag"
|
||||
// defaultValue={defaultValue}
|
||||
// options={data.options.map((item: any) => ({ label: item.label, value: item.value }))}
|
||||
// onChange={onChange}
|
||||
// />
|
||||
// ) : (
|
||||
// <Input
|
||||
// className="w-full"
|
||||
// defaultValue={defaultValue}
|
||||
// onChange={(e) => {
|
||||
// onChange(e.target.value);
|
||||
// }}
|
||||
// />
|
||||
// )}
|
||||
// </div>
|
||||
);
|
||||
|
||||
case 'bool':
|
||||
defaultValue = defaultValue === 'False' ? false : defaultValue;
|
||||
defaultValue = defaultValue === 'True' ? true : defaultValue;
|
||||
return (
|
||||
// <div className="text-sm">
|
||||
// {renderLabelWithTooltip(data)}
|
||||
// <Checkbox
|
||||
// className="ml-2"
|
||||
// defaultChecked={defaultValue}
|
||||
// onChange={(e) => {
|
||||
// onChange(e.target.checked);
|
||||
// }}
|
||||
// />
|
||||
// </div>
|
||||
|
||||
<Form.Item
|
||||
className="mb-2"
|
||||
className="mb-2 text-sm"
|
||||
name={data.name}
|
||||
initialValue={defaultValue}
|
||||
rules={[{ required: !data.optional }]}
|
||||
label={<span className="text-neutral-500">{data.label}</span>}
|
||||
tooltip={data.description ? { title: data.description, icon: <InfoCircleOutlined /> } : ''}
|
||||
rules={[{ required: !data.optional }]}
|
||||
>
|
||||
<Checkbox
|
||||
className="ml-2"
|
||||
defaultChecked={defaultValue}
|
||||
onChange={(e) => {
|
||||
onChange(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
<Checkbox className="ml-2" />
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderComponentByType(type: string, props?: any) {
|
||||
function renderComponentByType(type: string, data: IFlowNodeParameter) {
|
||||
switch (type) {
|
||||
case 'select':
|
||||
return <RenderSelect {...props} />;
|
||||
return renderSelect(data);
|
||||
case 'cascader':
|
||||
return <RenderCascader {...props} />;
|
||||
return renderCascader(data);
|
||||
case 'checkbox':
|
||||
return <RenderCheckbox {...props} />;
|
||||
return renderCheckbox(data);
|
||||
case 'radio':
|
||||
return <RenderRadio {...props} />;
|
||||
return renderRadio(data);
|
||||
case 'input':
|
||||
return <RenderInput {...props} />;
|
||||
return renderInput(data);
|
||||
case 'text_area':
|
||||
return <RenderTextArea {...props} />;
|
||||
return renderTextArea(data);
|
||||
case 'slider':
|
||||
return <RenderSlider {...props} />;
|
||||
return renderSlider(data);
|
||||
case 'date_picker':
|
||||
return <RenderDatePicker {...props} />;
|
||||
return renderDatePicker(data);
|
||||
case 'time_picker':
|
||||
return <RenderTimePicker {...props} />;
|
||||
return renderTimePicker(data);
|
||||
case 'tree_select':
|
||||
return <RenderTreeSelect {...props} />;
|
||||
return renderTreeSelect(data);
|
||||
case 'password':
|
||||
return <RenderPassword {...props} />;
|
||||
return renderPassword(data);
|
||||
case 'upload':
|
||||
return <RenderUpload {...props} />;
|
||||
return renderUpload({ data });
|
||||
case 'variables':
|
||||
return <RenderVariables {...props} />;
|
||||
return renderVariables(data);
|
||||
case 'code_editor':
|
||||
return <RenderCodeEditor {...props} />;
|
||||
return renderCodeEditor({ data });
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -256,31 +124,26 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
function renderNodeWithUiParam(data: IFlowNodeParameter) {
|
||||
const { refresh_depends, ui_type } = data.ui;
|
||||
let defaultValue = data.value ?? data.default;
|
||||
const props = { data, defaultValue, onChange };
|
||||
|
||||
return (
|
||||
// <div>
|
||||
// {renderLabelWithTooltip(data)}
|
||||
// {renderComponentByType(data?.ui?.ui_type, props)}
|
||||
// </div>
|
||||
|
||||
<Form.Item
|
||||
className="mb-2"
|
||||
initialValue={defaultValue}
|
||||
name={data.name}
|
||||
label={<span className="text-neutral-500">{data.label}</span>}
|
||||
tooltip={data.description ? { title: data.description, icon: <InfoCircleOutlined /> } : ''}
|
||||
{...(refresh_depends && { dependencies: refresh_depends })}
|
||||
rules={[{ required: !data.optional }]}
|
||||
label={<span className="text-neutral-500">{data.label}</span>}
|
||||
{...(refresh_depends && { dependencies: refresh_depends })}
|
||||
{...(data.description && { tooltip: { title: data.description, icon: <InfoCircleOutlined /> } })}
|
||||
>
|
||||
{renderComponentByType(ui_type, props)}
|
||||
{renderComponentByType(ui_type, data)}
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
|
||||
if (data.category === 'resource') {
|
||||
return <NodeHandler node={node} data={data} type="target" label={label} index={index} />;
|
||||
} else if (data.category === 'common') {
|
||||
return data?.ui ? renderNodeWithUiParam(data) : renderNodeWithoutUiParam(data);
|
||||
if (paramData.category === 'resource') {
|
||||
return <NodeHandler node={node} data={paramData} type="target" label={label} index={index} />;
|
||||
} else if (paramData.category === 'common') {
|
||||
return paramData?.ui ? renderNodeWithUiParam(paramData) : renderNodeWithoutUiParam(paramData);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -2,24 +2,15 @@ import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderCascader = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderCascader = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<Cascader
|
||||
{...attr}
|
||||
options={data.options}
|
||||
defaultValue={defaultValue}
|
||||
placeholder="please select"
|
||||
className="w-full nodrag"
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@@ -2,20 +2,13 @@ import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { Checkbox } from 'antd';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderCheckbox = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderCheckbox = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
data.options?.length > 0 && (
|
||||
<div className="bg-white p-2 rounded">
|
||||
<Checkbox.Group {...attr} options={data.options} defaultValue={defaultValue} onChange={onChange} />
|
||||
<Checkbox.Group {...attr} options={data.options} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { Button, Modal } from 'antd';
|
||||
import { Button, Form, Modal } from 'antd';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
@@ -7,13 +7,12 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
defaultValue?: any;
|
||||
onChange?: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderCodeEditor = (params: Props) => {
|
||||
export const renderCodeEditor = (params: Props) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
@@ -38,27 +37,29 @@ export const RenderCodeEditor = (params: Props) => {
|
||||
}, [data?.ui?.editor?.width]);
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: 'center' }} className="p-2 text-sm">
|
||||
<Button type="primary" onClick={showModal}>
|
||||
{t('openCodeEditor')}
|
||||
<div className="p-2 text-sm">
|
||||
<Button type="default" onClick={showModal}>
|
||||
{t('Open_Code_Editor')}
|
||||
</Button>
|
||||
|
||||
<Modal title={t('openCodeEditor')} width={modalWidth} open={isModalOpen} onOk={onOk} onCancel={onCancel}>
|
||||
<Editor
|
||||
{...attr}
|
||||
width={data?.ui?.editor?.width || '100%'}
|
||||
value={defaultValue}
|
||||
height={data?.ui?.editor?.height || 200}
|
||||
defaultLanguage={data?.ui?.language}
|
||||
onChange={onChange}
|
||||
theme="vs-dark"
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
wordWrap: 'on',
|
||||
}}
|
||||
/>
|
||||
<Modal title={t('Code_Editor')} width={modalWidth} open={isModalOpen} onOk={onOk} onCancel={onCancel}>
|
||||
<Form.Item name={data?.name}>
|
||||
<Editor
|
||||
{...attr}
|
||||
value={defaultValue}
|
||||
width={data?.ui?.editor?.width || '100%'}
|
||||
height={data?.ui?.editor?.height || 200}
|
||||
defaultLanguage={data?.ui?.language}
|
||||
onChange={onChange}
|
||||
theme="vs-dark"
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
wordWrap: 'on',
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
@@ -1,29 +1,9 @@
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { DatePicker, DatePickerProps } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import { DatePicker } from 'antd';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderDatePicker = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderDatePicker = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
const onChangeDate: DatePickerProps['onChange'] = (date, dateString) => {
|
||||
onChange(dateString);
|
||||
};
|
||||
|
||||
return (
|
||||
<DatePicker
|
||||
{...attr}
|
||||
className="w-full"
|
||||
placeholder="please select a date"
|
||||
defaultValue={defaultValue ? dayjs(defaultValue) : null}
|
||||
onChange={onChangeDate}
|
||||
/>
|
||||
);
|
||||
return <DatePicker {...attr} className="w-full" placeholder="please select a date" />;
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@ export * from './textarea';
|
||||
export * from './slider';
|
||||
export * from './time-picker';
|
||||
export * from './tree-select';
|
||||
export * from './codeEditor';
|
||||
export * from './code-editor';
|
||||
export * from './upload';
|
||||
export * from './password';
|
||||
export * from './variables';
|
||||
|
@@ -2,19 +2,6 @@ import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { Input } from 'antd';
|
||||
import * as Icons from '@ant-design/icons';
|
||||
import { FC } from 'react';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
const isValidIconComponent = (component: any): component is FC => {
|
||||
console.log('222', typeof component);
|
||||
|
||||
return component && typeof component === 'function';
|
||||
};
|
||||
|
||||
const getIconComponent = (iconString: string) => {
|
||||
const match = iconString.match(/^icon:(\w+)$/);
|
||||
@@ -27,21 +14,9 @@ const getIconComponent = (iconString: string) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const RenderInput = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderInput = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
attr.prefix = getIconComponent(data.ui?.attr?.prefix || '');
|
||||
|
||||
return (
|
||||
<Input
|
||||
{...attr}
|
||||
className="w-full"
|
||||
placeholder="please input"
|
||||
defaultValue={defaultValue}
|
||||
allowClear
|
||||
onChange={(e) => {
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return <Input {...attr} className="w-full" placeholder="please input" allowClear />;
|
||||
};
|
||||
|
@@ -4,15 +4,8 @@ import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
const { Password } = Input;
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderPassword = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderPassword = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return <Password {...attr} placeholder="input password" defaultValue={defaultValue} onChange={onChange} />;
|
||||
return <Password {...attr} placeholder="input password" />;
|
||||
};
|
||||
|
@@ -2,26 +2,12 @@ import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { Radio } from 'antd';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderRadio = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderRadio = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<div className="bg-white p-2 rounded">
|
||||
<Radio.Group
|
||||
{...attr}
|
||||
options={data.options}
|
||||
onChange={(e) => {
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
defaultValue={defaultValue}
|
||||
/>
|
||||
<Radio.Group {...attr} options={data.options} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -2,17 +2,8 @@ import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { Select } from 'antd';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
export const renderSelect = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data?.ui?.attr || {});
|
||||
|
||||
export const RenderSelect = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<Select {...attr} className="w-full nodrag" placeholder="please select" defaultValue={defaultValue} options={data.options} onChange={onChange} />
|
||||
);
|
||||
return <Select {...attr} className="w-full nodrag" placeholder="please select" options={data.options} />;
|
||||
};
|
||||
|
@@ -1,38 +1,10 @@
|
||||
import React from 'react';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { Col, InputNumber, Row, Slider, Space } from 'antd';
|
||||
import type { InputNumberProps } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { Slider } from 'antd';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderSlider = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderSlider = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
const [inputValue, setInputValue] = useState(defaultValue);
|
||||
const onChangeSlider: InputNumberProps['onChange'] = (newValue) => {
|
||||
setInputValue(newValue);
|
||||
onChange(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{data?.ui?.show_input ? (
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Slider className="w-full nodrag" {...attr} onChange={onChangeSlider} value={inputValue} />
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<InputNumber {...attr} style={{ margin: '0 16px' }} value={inputValue} onChange={onChangeSlider} />
|
||||
</Col>
|
||||
</Row>
|
||||
) : (
|
||||
<Slider className="w-full nodrag" {...attr} onChange={onChangeSlider} value={inputValue} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
return <Slider className="mt-8 nodrag" {...attr} tooltip={{ open: true }} />;
|
||||
};
|
||||
|
@@ -5,20 +5,12 @@ import classNames from 'classnames';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderTextArea = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
|
||||
export const renderTextArea = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<div className={classNames({ 'mb-3': attr.showCount === true })}>
|
||||
<TextArea className='nowheel' {...attr} defaultValue={defaultValue} onChange={onChange} />
|
||||
<TextArea className="nowheel" {...attr} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -1,22 +1,10 @@
|
||||
import React from 'react';
|
||||
import type { TimePickerProps } from 'antd';
|
||||
import { TimePicker } from 'antd';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderTimePicker = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderTimePicker = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
const onChangeTime: TimePickerProps['onChange'] = (time, timeString) => {
|
||||
onChange(timeString);
|
||||
};
|
||||
|
||||
return <TimePicker {...attr} className="w-full" defaultValue={defaultValue} onChange={onChangeTime} placeholder="please select a moment" />;
|
||||
return <TimePicker {...attr} className="w-full" placeholder="please select a moment" />;
|
||||
};
|
||||
|
@@ -1,25 +1,16 @@
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import { TreeSelect } from 'antd';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
export const RenderTreeSelect = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderTreeSelect = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<TreeSelect
|
||||
{...attr}
|
||||
className="w-full nodrag"
|
||||
fieldNames={{ label: 'label', value: 'value', children: 'children' }}
|
||||
value={defaultValue}
|
||||
treeDefaultExpandAll
|
||||
onChange={onChange}
|
||||
treeData={data.options}
|
||||
/>
|
||||
);
|
||||
|
@@ -8,13 +8,13 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
defaultValue?: any;
|
||||
onChange?: (value: any) => void;
|
||||
};
|
||||
export const RenderUpload = (params: Props) => {
|
||||
export const renderUpload = (params: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const urlList = useRef<string[]>([]);
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const { data, onChange } = params;
|
||||
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
const [uploading, setUploading] = useState(false);
|
||||
@@ -24,52 +24,59 @@ export const RenderUpload = (params: Props) => {
|
||||
if (urlList.current.length === data.ui.attr.max_count) {
|
||||
urlList.current.pop();
|
||||
}
|
||||
urlList.current.push(url)
|
||||
urlList.current.push(url);
|
||||
|
||||
onChange?.(urlList.current.toString());
|
||||
};
|
||||
|
||||
onChange(urlList.current.toString())
|
||||
}
|
||||
const handleFileRemove = (file: any) => {
|
||||
const index = urlList.current.indexOf(file.response.data[0].uri);
|
||||
if (index !== -1) {
|
||||
urlList.current.splice(index, 1);
|
||||
}
|
||||
onChange(urlList.current.toString())
|
||||
}
|
||||
onChange?.(urlList.current.toString());
|
||||
};
|
||||
|
||||
const props: UploadProps = {
|
||||
name: 'files',
|
||||
action: process.env.API_BASE_URL + data.ui.action,
|
||||
headers: {
|
||||
'authorization': 'authorization-text',
|
||||
authorization: 'authorization-text',
|
||||
},
|
||||
onChange(info) {
|
||||
setUploading(true)
|
||||
setUploading(true);
|
||||
if (info.file.status !== 'uploading') {
|
||||
}
|
||||
if (info.file.status === 'done') {
|
||||
setUploading(false)
|
||||
message.success(`${info.file.response.data[0].file_name} ${t('UploadDataSuccessfully')}`);
|
||||
getUploadSuccessUrl(info.file.response.data[0].uri)
|
||||
setUploading(false);
|
||||
message.success(`${info.file.response.data[0].file_name} ${t('Upload_Data_Successfully')}`);
|
||||
getUploadSuccessUrl(info.file.response.data[0].uri);
|
||||
} else if (info.file.status === 'error') {
|
||||
setUploading(false)
|
||||
message.error(`${info.file.response.data[0].file_name} ${t('UploadDataFailed')}`);
|
||||
setUploading(false);
|
||||
message.error(`${info.file.response.data[0].file_name} ${t('Upload_Data_Failed')}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (data.ui?.file_types && Array.isArray(data.ui?.file_types)) {
|
||||
setUploadType(data.ui?.file_types.toString())
|
||||
setUploadType(data.ui?.file_types.toString());
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="p-2 text-sm text-center">
|
||||
{data.is_list ? <Upload onRemove={handleFileRemove} {...props} {...attr} multiple={true} accept={uploadType}>
|
||||
<Button loading={uploading} icon={<UploadOutlined />}>{t('UploadData')}</Button>
|
||||
</Upload> : <Upload onRemove={handleFileRemove} {...props} {...attr} multiple={false} accept={uploadType}>
|
||||
<Button loading={uploading} icon={<UploadOutlined />}>{t('UploadData')}</Button>
|
||||
</Upload>}
|
||||
|
||||
{data.is_list ? (
|
||||
<Upload onRemove={handleFileRemove} {...props} {...attr} multiple={true} accept={uploadType}>
|
||||
<Button loading={uploading} icon={<UploadOutlined />}>
|
||||
{t('Upload_Data')}
|
||||
</Button>
|
||||
</Upload>
|
||||
) : (
|
||||
<Upload onRemove={handleFileRemove} {...props} {...attr} multiple={false} accept={uploadType}>
|
||||
<Button loading={uploading} icon={<UploadOutlined />}>
|
||||
{t('Upload_Data')}
|
||||
</Button>
|
||||
</Upload>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
};
|
||||
|
@@ -2,26 +2,8 @@ import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { Input } from 'antd';
|
||||
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderVariables = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
export const renderVariables = (data: IFlowNodeParameter) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<Input
|
||||
{...attr}
|
||||
className="w-full"
|
||||
placeholder="please input"
|
||||
defaultValue={defaultValue}
|
||||
allowClear
|
||||
onChange={(e) => {
|
||||
onChange(e.target.value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return <Input {...attr} className="w-full" placeholder="please input" allowClear />;
|
||||
};
|
||||
|
Reference in New Issue
Block a user