Feat: sync input variable names to main() function (#21667)
This commit is contained in:
27
web/app/components/base/button/sync-button.tsx
Normal file
27
web/app/components/base/button/sync-button.tsx
Normal file
@@ -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<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)
|
@@ -65,10 +65,11 @@ const VarList: FC<Props> = ({
|
|||||||
}, [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
|
||||||
|
|
||||||
|
@@ -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 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 = [
|
||||||
@@ -40,6 +41,7 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
|
|||||||
handleVarListChange,
|
handleVarListChange,
|
||||||
handleAddVariable,
|
handleAddVariable,
|
||||||
handleRemoveVariable,
|
handleRemoveVariable,
|
||||||
|
handleSyncFunctionSignature,
|
||||||
handleCodeChange,
|
handleCodeChange,
|
||||||
handleCodeLanguageChange,
|
handleCodeLanguageChange,
|
||||||
handleVarsChange,
|
handleVarsChange,
|
||||||
@@ -68,7 +70,12 @@ const Panel: FC<NodePanelProps<CodeNodeType>> = ({
|
|||||||
<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
|
||||||
|
@@ -84,6 +84,65 @@ const useConfig = (id: string, payload: CodeNodeType) => {
|
|||||||
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,
|
||||||
@@ -119,6 +178,7 @@ const useConfig = (id: string, payload: CodeNodeType) => {
|
|||||||
handleVarListChange,
|
handleVarListChange,
|
||||||
handleAddVariable,
|
handleAddVariable,
|
||||||
handleRemoveVariable,
|
handleRemoveVariable,
|
||||||
|
handleSyncFunctionSignature,
|
||||||
handleCodeChange,
|
handleCodeChange,
|
||||||
handleCodeLanguageChange,
|
handleCodeLanguageChange,
|
||||||
handleVarsChange,
|
handleVarsChange,
|
||||||
|
@@ -136,6 +136,7 @@ export type Variable = {
|
|||||||
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[]
|
||||||
|
@@ -549,6 +549,7 @@ const translation = {
|
|||||||
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',
|
||||||
|
@@ -550,6 +550,7 @@ const translation = {
|
|||||||
advancedDependencies: '高度な依存関係',
|
advancedDependencies: '高度な依存関係',
|
||||||
advancedDependenciesTip: '消費に時間がかかる、またはデフォルトで組み込まれていない事前ロードされた依存関係を追加します',
|
advancedDependenciesTip: '消費に時間がかかる、またはデフォルトで組み込まれていない事前ロードされた依存関係を追加します',
|
||||||
searchDependencies: '依存関係を検索',
|
searchDependencies: '依存関係を検索',
|
||||||
|
syncFunctionSignature: 'コードの関数署名を同期',
|
||||||
},
|
},
|
||||||
templateTransform: {
|
templateTransform: {
|
||||||
inputVars: '入力変数',
|
inputVars: '入力変数',
|
||||||
|
@@ -550,6 +550,7 @@ const translation = {
|
|||||||
advancedDependencies: '高级依赖',
|
advancedDependencies: '高级依赖',
|
||||||
advancedDependenciesTip: '在这里添加一些预加载需要消耗较多时间或非默认内置的依赖包',
|
advancedDependenciesTip: '在这里添加一些预加载需要消耗较多时间或非默认内置的依赖包',
|
||||||
searchDependencies: '搜索依赖',
|
searchDependencies: '搜索依赖',
|
||||||
|
syncFunctionSignature: '同步函数签名至代码',
|
||||||
},
|
},
|
||||||
templateTransform: {
|
templateTransform: {
|
||||||
inputVars: '输入变量',
|
inputVars: '输入变量',
|
||||||
|
@@ -544,6 +544,7 @@ const translation = {
|
|||||||
advancedDependencies: '高級依賴',
|
advancedDependencies: '高級依賴',
|
||||||
advancedDependenciesTip: '在這裡添加一些預加載需要消耗較多時間或非默認內置的依賴包',
|
advancedDependenciesTip: '在這裡添加一些預加載需要消耗較多時間或非默認內置的依賴包',
|
||||||
searchDependencies: '搜索依賴',
|
searchDependencies: '搜索依賴',
|
||||||
|
syncFunctionSignature: '同步函數簽名至代碼',
|
||||||
},
|
},
|
||||||
templateTransform: {
|
templateTransform: {
|
||||||
inputVars: '輸入變量',
|
inputVars: '輸入變量',
|
||||||
|
Reference in New Issue
Block a user