| '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<Props> = ({ | |||||
| className, | |||||
| popupContent = '', | |||||
| onClick, | |||||
| }) => { | |||||
| return ( | |||||
| <TooltipPlus popupContent={popupContent}> | |||||
| <div className={cn(className, 'cursor-pointer select-none rounded-md p-1 hover:bg-state-base-hover')} onClick={onClick}> | |||||
| <RiRefreshLine className='h-4 w-4 text-text-tertiary' /> | |||||
| </div> | |||||
| </TooltipPlus> | |||||
| ) | |||||
| } | |||||
| export default React.memo(SyncButton) |
| }, [list, onVarNameChange, onChange]) | }, [list, onVarNameChange, onChange]) | ||||
| const handleVarReferenceChange = useCallback((index: number) => { | const handleVarReferenceChange = useCallback((index: number) => { | ||||
| return (value: ValueSelector | string, varKindType: VarKindType) => { | |||||
| return (value: ValueSelector | string, varKindType: VarKindType, varInfo?: Var) => { | |||||
| const newList = produce(list, (draft) => { | const newList = produce(list, (draft) => { | ||||
| if (!isSupportConstantValue || varKindType === VarKindType.variable) { | if (!isSupportConstantValue || varKindType === VarKindType.variable) { | ||||
| draft[index].value_selector = value as ValueSelector | draft[index].value_selector = value as ValueSelector | ||||
| draft[index].value_type = varInfo?.type | |||||
| if (isSupportConstantValue) | if (isSupportConstantValue) | ||||
| draft[index].variable_type = VarKindType.variable | draft[index].variable_type = VarKindType.variable | ||||
| import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' | import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' | ||||
| import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector' | import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector' | ||||
| import type { NodePanelProps } from '@/app/components/workflow/types' | import type { NodePanelProps } from '@/app/components/workflow/types' | ||||
| import SyncButton from '@/app/components/base/button/sync-button' | |||||
| const i18nPrefix = 'workflow.nodes.code' | const i18nPrefix = 'workflow.nodes.code' | ||||
| const codeLanguages = [ | const codeLanguages = [ | ||||
| handleVarListChange, | handleVarListChange, | ||||
| handleAddVariable, | handleAddVariable, | ||||
| handleRemoveVariable, | handleRemoveVariable, | ||||
| handleSyncFunctionSignature, | |||||
| handleCodeChange, | handleCodeChange, | ||||
| handleCodeLanguageChange, | handleCodeLanguageChange, | ||||
| handleVarsChange, | handleVarsChange, | ||||
| <Field | <Field | ||||
| title={t(`${i18nPrefix}.inputVars`)} | title={t(`${i18nPrefix}.inputVars`)} | ||||
| operations={ | operations={ | ||||
| !readOnly ? <AddButton onClick={handleAddVariable} /> : undefined | |||||
| !readOnly ? ( | |||||
| <div className="flex gap-2"> | |||||
| <SyncButton popupContent={t(`${i18nPrefix}.syncFunctionSignature`)} onClick={handleSyncFunctionSignature} /> | |||||
| <AddButton onClick={handleAddVariable} /> | |||||
| </div> | |||||
| ) : undefined | |||||
| } | } | ||||
| > | > | ||||
| <VarList | <VarList |
| setInputs(newInputs) | setInputs(newInputs) | ||||
| }, [allLanguageDefault, inputs, setInputs]) | }, [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 { | const { | ||||
| handleVarsChange, | handleVarsChange, | ||||
| handleAddVariable: handleAddOutputVariable, | handleAddVariable: handleAddOutputVariable, | ||||
| handleVarListChange, | handleVarListChange, | ||||
| handleAddVariable, | handleAddVariable, | ||||
| handleRemoveVariable, | handleRemoveVariable, | ||||
| handleSyncFunctionSignature, | |||||
| handleCodeChange, | handleCodeChange, | ||||
| handleCodeLanguageChange, | handleCodeLanguageChange, | ||||
| handleVarsChange, | handleVarsChange, |
| variable: string | variable: string | ||||
| } | } | ||||
| value_selector: ValueSelector | value_selector: ValueSelector | ||||
| value_type?: VarType | |||||
| variable_type?: VarKindType | variable_type?: VarKindType | ||||
| value?: string | value?: string | ||||
| options?: string[] | options?: string[] |
| advancedDependencies: 'Advanced Dependencies', | advancedDependencies: 'Advanced Dependencies', | ||||
| advancedDependenciesTip: 'Add some preloaded dependencies that take more time to consume or are not default built-in here', | advancedDependenciesTip: 'Add some preloaded dependencies that take more time to consume or are not default built-in here', | ||||
| searchDependencies: 'Search Dependencies', | searchDependencies: 'Search Dependencies', | ||||
| syncFunctionSignature: 'Sync function signature to code', | |||||
| }, | }, | ||||
| templateTransform: { | templateTransform: { | ||||
| inputVars: 'Input Variables', | inputVars: 'Input Variables', |
| advancedDependencies: '高度な依存関係', | advancedDependencies: '高度な依存関係', | ||||
| advancedDependenciesTip: '消費に時間がかかる、またはデフォルトで組み込まれていない事前ロードされた依存関係を追加します', | advancedDependenciesTip: '消費に時間がかかる、またはデフォルトで組み込まれていない事前ロードされた依存関係を追加します', | ||||
| searchDependencies: '依存関係を検索', | searchDependencies: '依存関係を検索', | ||||
| syncFunctionSignature: 'コードの関数署名を同期', | |||||
| }, | }, | ||||
| templateTransform: { | templateTransform: { | ||||
| inputVars: '入力変数', | inputVars: '入力変数', |
| advancedDependencies: '高级依赖', | advancedDependencies: '高级依赖', | ||||
| advancedDependenciesTip: '在这里添加一些预加载需要消耗较多时间或非默认内置的依赖包', | advancedDependenciesTip: '在这里添加一些预加载需要消耗较多时间或非默认内置的依赖包', | ||||
| searchDependencies: '搜索依赖', | searchDependencies: '搜索依赖', | ||||
| syncFunctionSignature: '同步函数签名至代码', | |||||
| }, | }, | ||||
| templateTransform: { | templateTransform: { | ||||
| inputVars: '输入变量', | inputVars: '输入变量', |
| advancedDependencies: '高級依賴', | advancedDependencies: '高級依賴', | ||||
| advancedDependenciesTip: '在這裡添加一些預加載需要消耗較多時間或非默認內置的依賴包', | advancedDependenciesTip: '在這裡添加一些預加載需要消耗較多時間或非默認內置的依賴包', | ||||
| searchDependencies: '搜索依賴', | searchDependencies: '搜索依賴', | ||||
| syncFunctionSignature: '同步函數簽名至代碼', | |||||
| }, | }, | ||||
| templateTransform: { | templateTransform: { | ||||
| inputVars: '輸入變量', | inputVars: '輸入變量', |