diff --git a/web/app/components/base/button/sync-button.tsx b/web/app/components/base/button/sync-button.tsx new file mode 100644 index 000000000..013c86889 --- /dev/null +++ b/web/app/components/base/button/sync-button.tsx @@ -0,0 +1,27 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { RiRefreshLine } from '@remixicon/react' +import cn from '@/utils/classnames' +import TooltipPlus from '@/app/components/base/tooltip' + +type Props = { + className?: string, + popupContent?: string, + onClick: () => void +} + +const SyncButton: FC = ({ + className, + popupContent = '', + onClick, +}) => { + return ( + +
+ +
+
+ ) +} +export default React.memo(SyncButton) diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx index 181b27805..fe489a5b8 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx @@ -65,10 +65,11 @@ const VarList: FC = ({ }, [list, onVarNameChange, onChange]) const handleVarReferenceChange = useCallback((index: number) => { - return (value: ValueSelector | string, varKindType: VarKindType) => { + return (value: ValueSelector | string, varKindType: VarKindType, varInfo?: Var) => { const newList = produce(list, (draft) => { if (!isSupportConstantValue || varKindType === VarKindType.variable) { draft[index].value_selector = value as ValueSelector + draft[index].value_type = varInfo?.type if (isSupportConstantValue) draft[index].variable_type = VarKindType.variable diff --git a/web/app/components/workflow/nodes/code/panel.tsx b/web/app/components/workflow/nodes/code/panel.tsx index 05d6cd795..f928c13bd 100644 --- a/web/app/components/workflow/nodes/code/panel.tsx +++ b/web/app/components/workflow/nodes/code/panel.tsx @@ -14,6 +14,7 @@ import Split from '@/app/components/workflow/nodes/_base/components/split' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector' import type { NodePanelProps } from '@/app/components/workflow/types' +import SyncButton from '@/app/components/base/button/sync-button' const i18nPrefix = 'workflow.nodes.code' const codeLanguages = [ @@ -40,6 +41,7 @@ const Panel: FC> = ({ handleVarListChange, handleAddVariable, handleRemoveVariable, + handleSyncFunctionSignature, handleCodeChange, handleCodeLanguageChange, handleVarsChange, @@ -68,7 +70,12 @@ const Panel: FC> = ({ : undefined + !readOnly ? ( +
+ + +
+ ) : undefined } > { setInputs(newInputs) }, [allLanguageDefault, inputs, setInputs]) + const handleSyncFunctionSignature = useCallback(() => { + const generateSyncSignatureCode = (code: string) => { + let mainDefRe + let newMainDef + if (inputs.code_language === CodeLanguage.javascript) { + mainDefRe = /function\s+main\b\s*\([\s\S]*?\)/g + newMainDef = 'function main({{var_list}})' + let param_list = inputs.variables?.map(item => item.variable).join(', ') || '' + param_list = param_list ? `{${param_list}}` : '' + newMainDef = newMainDef.replace('{{var_list}}', param_list) + } + + else if (inputs.code_language === CodeLanguage.python3) { + mainDefRe = /def\s+main\b\s*\([\s\S]*?\)/g + const param_list = [] + for (const item of inputs.variables) { + let param = item.variable + let param_type = '' + switch (item.value_type) { + case VarType.string: + param_type = ': str' + break + case VarType.number: + param_type = ': float' + break + case VarType.object: + param_type = ': dict' + break + case VarType.array: + param_type = ': list' + break + case VarType.arrayNumber: + param_type = ': list[float]' + break + case VarType.arrayString: + param_type = ': list[str]' + break + case VarType.arrayObject: + param_type = ': list[dict]' + break + } + param += param_type + param_list.push(`${param}`) + } + + newMainDef = `def main(${param_list.join(', ')})` + } + else { return code } + + const newCode = code.replace(mainDefRe, newMainDef) + return newCode + } + + const newInputs = produce(inputs, (draft) => { + draft.code = generateSyncSignatureCode(draft.code) + }) + setInputs(newInputs) + }, [inputs, setInputs]) + const { handleVarsChange, handleAddVariable: handleAddOutputVariable, @@ -119,6 +178,7 @@ const useConfig = (id: string, payload: CodeNodeType) => { handleVarListChange, handleAddVariable, handleRemoveVariable, + handleSyncFunctionSignature, handleCodeChange, handleCodeLanguageChange, handleVarsChange, diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index f80ade86c..c9e5aa31b 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -136,6 +136,7 @@ export type Variable = { variable: string } value_selector: ValueSelector + value_type?: VarType variable_type?: VarKindType value?: string options?: string[] diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index 0285333e3..df0bb904f 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -549,6 +549,7 @@ const translation = { advancedDependencies: 'Advanced Dependencies', advancedDependenciesTip: 'Add some preloaded dependencies that take more time to consume or are not default built-in here', searchDependencies: 'Search Dependencies', + syncFunctionSignature: 'Sync function signature to code', }, templateTransform: { inputVars: 'Input Variables', diff --git a/web/i18n/ja-JP/workflow.ts b/web/i18n/ja-JP/workflow.ts index 5700d9c9b..3c959669b 100644 --- a/web/i18n/ja-JP/workflow.ts +++ b/web/i18n/ja-JP/workflow.ts @@ -550,6 +550,7 @@ const translation = { advancedDependencies: '高度な依存関係', advancedDependenciesTip: '消費に時間がかかる、またはデフォルトで組み込まれていない事前ロードされた依存関係を追加します', searchDependencies: '依存関係を検索', + syncFunctionSignature: 'コードの関数署名を同期', }, templateTransform: { inputVars: '入力変数', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 26ba7f382..aa9dcae26 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -550,6 +550,7 @@ const translation = { advancedDependencies: '高级依赖', advancedDependenciesTip: '在这里添加一些预加载需要消耗较多时间或非默认内置的依赖包', searchDependencies: '搜索依赖', + syncFunctionSignature: '同步函数签名至代码', }, templateTransform: { inputVars: '输入变量', diff --git a/web/i18n/zh-Hant/workflow.ts b/web/i18n/zh-Hant/workflow.ts index 2ee345ecc..8262e6035 100644 --- a/web/i18n/zh-Hant/workflow.ts +++ b/web/i18n/zh-Hant/workflow.ts @@ -544,6 +544,7 @@ const translation = { advancedDependencies: '高級依賴', advancedDependenciesTip: '在這裡添加一些預加載需要消耗較多時間或非默認內置的依賴包', searchDependencies: '搜索依賴', + syncFunctionSignature: '同步函數簽名至代碼', }, templateTransform: { inputVars: '輸入變量',