feat: fix import typo in node-renderer/index.ts

This commit is contained in:
谨欣
2024-08-21 21:56:16 +08:00
parent 05851586c6
commit b4d9f9030c
19 changed files with 187 additions and 496 deletions

View File

@@ -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: '向量',

View File

@@ -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>
)}

View File

@@ -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

View File

@@ -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);
}
};

View File

@@ -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}
/>
);
};

View File

@@ -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>
)
);

View File

@@ -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>
);

View File

@@ -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" />;
};

View File

@@ -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';

View File

@@ -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 />;
};

View File

@@ -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" />;
};

View File

@@ -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>
);
};

View File

@@ -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} />;
};

View File

@@ -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 }} />;
};

View File

@@ -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>
);
};

View File

@@ -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" />;
};

View File

@@ -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}
/>
);

View File

@@ -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>
)
}
);
};

View File

@@ -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 />;
};