diff --git a/web/app/i18n.ts b/web/app/i18n.ts index b15332d35..f4ae1c6bd 100644 --- a/web/app/i18n.ts +++ b/web/app/i18n.ts @@ -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: '向量', diff --git a/web/components/flow/canvas-node.tsx b/web/components/flow/canvas-node.tsx index f91e0f128..461d933f7 100644 --- a/web/components/flow/canvas-node.tsx +++ b/web/components/flow/canvas-node.tsx @@ -71,26 +71,22 @@ const CanvasNode: React.FC = ({ data }) => { reactFlow.setEdges((edges) => edges.filter((edge) => edge.source !== node.id && edge.target !== node.id)); } - // function onChange(value: any) { - // data.value = value; - // } - - function onValuesChange(changedValues: any, allValues: any) { - // onChange(changedValues); - console.log('Changed xxx', changedValues); - console.log('All xxx', allValues); - console.log('xxxx', parameters); + function updateCurrentNodeValue(changedKey: string, changedVal: any) { + parameters.forEach((item) => { + if (item.name === changedKey) { + item.value = changedVal; + } + }); + } - const [changedKey, changedVal] = Object.entries(changedValues)[0]; - console.log('====', changedKey, changedVal); + async function updateDependsNodeValue(changedKey: string, changedVal: any) { + if (!changedVal) return; - // 获取以当前改变项目为 refresh_depends 的参数name - const needChangeNodes = parameters.filter(({ ui }) => ui?.refresh_depends?.includes(changedKey)); - console.log('needChangeNodes====', needChangeNodes); + const dependParamNodes = parameters.filter(({ ui }) => ui?.refresh_depends?.includes(changedKey)); - if (needChangeNodes?.length === 0) return; + if (dependParamNodes?.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 = ({ 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 = ({ 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 ( = ({ data }) => { {parameters?.length > 0 && (
- {/*
*/} - -
+ {parameters?.map((item, index) => ( - + ))} - - {/*
*/}
)} diff --git a/web/components/flow/node-handler.tsx b/web/components/flow/node-handler.tsx index e28a50261..4feed9ccd 100644 --- a/web/components/flow/node-handler.tsx +++ b/web/components/flow/node-handler.tsx @@ -101,10 +101,8 @@ const NodeHandler: React.FC = ({ node, data, type, label, inde isValidConnection={(connection) => isValidConnection(connection)} /> = ({ node, data, label, index }) => { - function onChange(value: any) { - data.value = value; - } - - function renderLabelWithTooltip(data: IFlowNodeParameter) { - return ( -
- - {data.label} - - - -
- ); - } - +const NodeParamHandler: React.FC = ({ 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 ( - //
- // {renderLabelWithTooltip(data)} - // { - // console.log('value', value); - - // onChange(value); - // }} - // /> - //
- // ); - // case 'str': - // return ( - //
- // {renderLabelWithTooltip(data)} - // {data.options?.length > 0 ? ( - // { - // onChange(e.target.value); - // }} - // /> - // )} - //
- // ); - // case 'bool': - // defaultValue = defaultValue === 'False' ? false : defaultValue; - // defaultValue = defaultValue === 'True' ? true : defaultValue; - // return ( - //
- // {renderLabelWithTooltip(data)} - // { - // onChange(e.target.checked); - // }} - // /> - //
- // ); - // } - // } function renderNodeWithoutUiParam(data: IFlowNodeParameter) { let defaultValue = data.value ?? data.default; @@ -114,139 +38,83 @@ const NodeParamHandler: React.FC = ({ node, data, label, case 'float': return ( {data.label}} tooltip={data.description ? { title: data.description, icon: } : ''} - rules={[{ required: !data.optional }]} > - + ); - { - /*
- {renderLabelWithTooltip(data)} - { - console.log('value', value); - onChange(value); - }} - /> -
*/ - } case 'str': return ( {data.label}} tooltip={data.description ? { title: data.description, icon: } : ''} - rules={[{ required: !data.optional }]} > {data.options?.length > 0 ? ( - ({ label: item.label, value: item.value }))} /> ) : ( - { - onChange(e.target.value); - }} - /> + )} - //
- // {renderLabelWithTooltip(data)} - // {data.options?.length > 0 ? ( - // { - // onChange(e.target.value); - // }} - // /> - // )} - //
); + case 'bool': defaultValue = defaultValue === 'False' ? false : defaultValue; defaultValue = defaultValue === 'True' ? true : defaultValue; return ( - //
- // {renderLabelWithTooltip(data)} - // { - // onChange(e.target.checked); - // }} - // /> - //
- {data.label}} tooltip={data.description ? { title: data.description, icon: } : ''} - rules={[{ required: !data.optional }]} > - { - onChange(e.target.checked); - }} - /> + ); } } - function renderComponentByType(type: string, props?: any) { + function renderComponentByType(type: string, data: IFlowNodeParameter) { switch (type) { case 'select': - return ; + return renderSelect(data); case 'cascader': - return ; + return renderCascader(data); case 'checkbox': - return ; + return renderCheckbox(data); case 'radio': - return ; + return renderRadio(data); case 'input': - return ; + return renderInput(data); case 'text_area': - return ; + return renderTextArea(data); case 'slider': - return ; + return renderSlider(data); case 'date_picker': - return ; + return renderDatePicker(data); case 'time_picker': - return ; + return renderTimePicker(data); case 'tree_select': - return ; + return renderTreeSelect(data); case 'password': - return ; + return renderPassword(data); case 'upload': - return ; + return renderUpload({ data }); case 'variables': - return ; + return renderVariables(data); case 'code_editor': - return ; + return renderCodeEditor(data); default: return null; } @@ -256,31 +124,26 @@ const NodeParamHandler: React.FC = ({ 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 ( - //
- // {renderLabelWithTooltip(data)} - // {renderComponentByType(data?.ui?.ui_type, props)} - //
- {data.label}} - tooltip={data.description ? { title: data.description, icon: } : ''} {...(refresh_depends && { dependencies: refresh_depends })} - rules={[{ required: !data.optional }]} + {...(data.description && { tooltip: { title: data.description, icon: } })} > - {renderComponentByType(ui_type, props)} + {renderComponentByType(ui_type, data)} ); } - if (data.category === 'resource') { - return ; - } else if (data.category === 'common') { - return data?.ui ? renderNodeWithUiParam(data) : renderNodeWithoutUiParam(data); + if (paramData.category === 'resource') { + return ; + } else if (paramData.category === 'common') { + return paramData?.ui ? renderNodeWithUiParam(paramData) : renderNodeWithoutUiParam(paramData); } }; diff --git a/web/components/flow/node-renderer/cascader.tsx b/web/components/flow/node-renderer/cascader.tsx index 118c3ac40..d16d59e58 100644 --- a/web/components/flow/node-renderer/cascader.tsx +++ b/web/components/flow/node-renderer/cascader.tsx @@ -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 ( ); }; diff --git a/web/components/flow/node-renderer/checkbox.tsx b/web/components/flow/node-renderer/checkbox.tsx index 0500d3498..973b58b2f 100644 --- a/web/components/flow/node-renderer/checkbox.tsx +++ b/web/components/flow/node-renderer/checkbox.tsx @@ -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 && (
- +
) ); diff --git a/web/components/flow/node-renderer/code-editor.tsx b/web/components/flow/node-renderer/code-editor.tsx new file mode 100644 index 000000000..15aeb92d0 --- /dev/null +++ b/web/components/flow/node-renderer/code-editor.tsx @@ -0,0 +1,63 @@ +import React, { useState, useMemo } from 'react'; +import { Button, Form, Modal } from 'antd'; +import Editor from '@monaco-editor/react'; +import { IFlowNodeParameter } from '@/types/flow'; +import { convertKeysToCamelCase } from '@/utils/flow'; +import { useTranslation } from 'react-i18next'; + +type Props = { + data: IFlowNodeParameter; + defaultValue?: any; +}; + +export const renderCodeEditor = (data: IFlowNodeParameter) => { + const { t } = useTranslation(); + // const { data, defaultValue } = params; + const attr = convertKeysToCamelCase(data.ui?.attr || {}); + + const [isModalOpen, setIsModalOpen] = useState(false); + const showModal = () => { + setIsModalOpen(true); + }; + + const onOk = () => { + setIsModalOpen(false); + }; + + const onCancel = () => { + setIsModalOpen(false); + }; + + const modalWidth = useMemo(() => { + if (data?.ui?.editor?.width) { + return data?.ui?.editor?.width + 100; + } + return '80%'; + }, [data?.ui?.editor?.width]); + + return ( +
+ + + + + + + +
+ ); +}; diff --git a/web/components/flow/node-renderer/codeEditor.tsx b/web/components/flow/node-renderer/codeEditor.tsx deleted file mode 100644 index 6be8de655..000000000 --- a/web/components/flow/node-renderer/codeEditor.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { useState, useMemo } from 'react'; -import { Button, Modal } from 'antd'; -import Editor from '@monaco-editor/react'; -import { IFlowNodeParameter } from '@/types/flow'; -import { convertKeysToCamelCase } from '@/utils/flow'; -import { useTranslation } from 'react-i18next'; - -type Props = { - data: IFlowNodeParameter; - defaultValue: any; - onChange: (value: any) => void; -}; - -export const RenderCodeEditor = (params: Props) => { - const { t } = useTranslation(); - - const { data, defaultValue, onChange } = params; - const attr = convertKeysToCamelCase(data.ui?.attr || {}); - - const [isModalOpen, setIsModalOpen] = useState(false); - const showModal = () => { - setIsModalOpen(true); - }; - - const onOk = () => { - setIsModalOpen(false); - }; - - const onCancel = () => { - setIsModalOpen(false); - }; - - const modalWidth = useMemo(() => { - if (data?.ui?.editor?.width) { - return data?.ui?.editor?.width + 100; - } - return '80%'; - }, [data?.ui?.editor?.width]); - - return ( -
- - - - - -
- ); -}; diff --git a/web/components/flow/node-renderer/date-picker.tsx b/web/components/flow/node-renderer/date-picker.tsx index b639818d9..752f5a394 100644 --- a/web/components/flow/node-renderer/date-picker.tsx +++ b/web/components/flow/node-renderer/date-picker.tsx @@ -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 ( - - ); + return ; }; diff --git a/web/components/flow/node-renderer/index.ts b/web/components/flow/node-renderer/index.ts index e5f538ec9..8339d6f9e 100644 --- a/web/components/flow/node-renderer/index.ts +++ b/web/components/flow/node-renderer/index.ts @@ -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'; diff --git a/web/components/flow/node-renderer/input.tsx b/web/components/flow/node-renderer/input.tsx index 436899fc1..d9ea79bef 100644 --- a/web/components/flow/node-renderer/input.tsx +++ b/web/components/flow/node-renderer/input.tsx @@ -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 ( - { - onChange(e.target.value); - }} - /> - ); + return ; }; diff --git a/web/components/flow/node-renderer/password.tsx b/web/components/flow/node-renderer/password.tsx index 8ab44cd90..89402ed05 100644 --- a/web/components/flow/node-renderer/password.tsx +++ b/web/components/flow/node-renderer/password.tsx @@ -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 ; + return ; }; diff --git a/web/components/flow/node-renderer/radio.tsx b/web/components/flow/node-renderer/radio.tsx index 056681ef4..f2e5062dd 100644 --- a/web/components/flow/node-renderer/radio.tsx +++ b/web/components/flow/node-renderer/radio.tsx @@ -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 (
- { - onChange(e.target.value); - }} - defaultValue={defaultValue} - /> +
); }; diff --git a/web/components/flow/node-renderer/select.tsx b/web/components/flow/node-renderer/select.tsx index cd4784596..4f8ee9cc1 100644 --- a/web/components/flow/node-renderer/select.tsx +++ b/web/components/flow/node-renderer/select.tsx @@ -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 = (params: Props) => { - const { data, defaultValue, onChange } = params; - const attr = convertKeysToCamelCase(data.ui?.attr || {}); +export const renderSelect = (data: IFlowNodeParameter) => { + const attr = convertKeysToCamelCase(data?.ui?.attr || {}); - return ( - ; }; diff --git a/web/components/flow/node-renderer/slider.tsx b/web/components/flow/node-renderer/slider.tsx index adc5c1f25..f92868a17 100644 --- a/web/components/flow/node-renderer/slider.tsx +++ b/web/components/flow/node-renderer/slider.tsx @@ -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 ? ( - - - - - - - - - ) : ( - - )} - - ); + return ; }; diff --git a/web/components/flow/node-renderer/textarea.tsx b/web/components/flow/node-renderer/textarea.tsx index e59f74ec2..01cf95da6 100644 --- a/web/components/flow/node-renderer/textarea.tsx +++ b/web/components/flow/node-renderer/textarea.tsx @@ -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 (
-