feat: can update var

This commit is contained in:
Joel 2025-08-08 16:16:52 +08:00
parent 89963ecf59
commit 81f6344aaa
11 changed files with 97 additions and 21 deletions

View File

@ -266,6 +266,7 @@ const PromptEditor: FC<PromptEditorProps> = ({
nodeTitle={hitlInputBlock.nodeTitle}
formInputs={hitlInputBlock.formInputs}
onFormInputsChange={hitlInputBlock.onFormInputsChange}
onFormInputItemRename={hitlInputBlock.onFormInputItemRename}
onFormInputItemRemove={hitlInputBlock.onFormInputItemRemove}
/>
</>

View File

@ -19,6 +19,7 @@ type Props = {
isSelected: boolean
formInput?: FormInputItem
onChange: (input: FormInputItem) => void
onRename: (payload: FormInputItem, oldName: string) => void
onRemove: (varName: string) => void
}
@ -36,6 +37,7 @@ const ComponentUI: FC<Props> = ({
},
},
onChange,
onRename,
onRemove,
}) => {
const { t } = useTranslation()
@ -70,9 +72,12 @@ const ComponentUI: FC<Props> = ({
}, [onRemove, varName])
const handleChange = useCallback((newPayload: FormInputItem) => {
onChange(newPayload)
if(varName === newPayload.output_variable_name)
onChange(newPayload)
else
onRename(newPayload, varName)
hideEditModal()
}, [onChange])
}, [onChange, varName])
return (
<div
@ -124,6 +129,7 @@ const ComponentUI: FC<Props> = ({
className='max-w-[372px] !p-0'
>
<InputField
isEdit
payload={formInput}
onChange={handleChange}
onCancel={hideEditModal}

View File

@ -11,6 +11,7 @@ type Props = {
varName: string
formInputs?: FormInputItem[]
onChange: (inputs: FormInputItem[]) => void
onRename: (payload: FormInputItem, oldName: string) => void
onRemove: (varName: string) => void
}
@ -20,6 +21,7 @@ const HITLInputComponent: FC<Props> = ({
varName,
formInputs = [],
onChange,
onRename,
onRemove,
}) => {
const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_HITL_INPUT_BLOCK_COMMAND)
@ -48,6 +50,7 @@ const HITLInputComponent: FC<Props> = ({
isSelected={isSelected}
formInput={payload}
onChange={handleChange}
onRename={onRename}
onRemove={onRemove}
/>
</div>

View File

@ -23,6 +23,7 @@ const HITLInputReplacementBlock = ({
nodeTitle,
formInputs,
onFormInputsChange,
onFormInputItemRename,
onFormInputItemRemove,
}: HITLInputBlockType) => {
const [editor] = useLexicalComposerContext()
@ -39,6 +40,7 @@ const HITLInputReplacementBlock = ({
nodeTitle,
formInputs || [],
onFormInputsChange!,
onFormInputItemRename,
onFormInputItemRemove!,
))
}, [nodeTitle, formInputs, onFormInputsChange, onFormInputItemRemove])

View File

@ -29,9 +29,6 @@ const HITLInputBlock = memo(({
throw new Error('HITLInputBlockPlugin: HITLInputBlock not registered on editor')
}, [editor, onInsert, onDelete])
// TODO
// const createHITLBlockNode = useCallback
return null
})

View File

@ -1,7 +1,7 @@
import React, { useCallback, useState } from 'react'
import Input from '@/app/components/base/input'
import PromptEditor from '@/app/components/base/prompt-editor'
import TagLabel from './tag-label'
// import PromptEditor from '@/app/components/base/prompt-editor'
// import TagLabel from './tag-label'
import Button from '../../../button'
import { useTranslation } from 'react-i18next'
import { getKeyboardKeyNameBySystem } from '@/app/components/workflow/utils'
@ -10,11 +10,13 @@ import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/
const i18nPrefix = 'workflow.nodes.humanInput.insertInputField'
type Props = {
isEdit: boolean
payload: FormInputItem
onChange: (newPayload: FormInputItem) => void
onCancel: () => void
}
const InputField: React.FC<Props> = ({
isEdit,
payload,
onChange,
onCancel,
@ -44,7 +46,7 @@ const InputField: React.FC<Props> = ({
<div className='system-xs-medium text-text-secondary'>
{t(`${i18nPrefix}.prePopulateField`)}
</div>
<PromptEditor
{/* <PromptEditor
className='mt-1.5 h-[72px] rounded-lg bg-components-input-bg-normal px-3 py-1'
placeholder={
<div className='system-sm-regular mt-1 px-3 text-text-tertiary'>
@ -63,19 +65,36 @@ const InputField: React.FC<Props> = ({
setTempPayload(prev => ({ ...prev, prePopulateField: newValue }))
}
}
/> */}
<Input
className='mt-1.5'
value={tempPayload.placeholder?.value}
onChange={(e) => {
setTempPayload(prev => ({ ...prev, placeholder: { ...(prev.placeholder || {}), value: e.target.value } } as any))
}}
/>
</div>
<div className='mt-4 flex justify-end space-x-2'>
<Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
<Button
className='flex'
variant='primary'
onClick={handleSave}
>
<span className='mr-1'>{t(`${i18nPrefix}.insert`)}</span>
<span className='system-kbd mr-0.5 flex h-4 items-center rounded-[4px] bg-components-kbd-bg-white px-1'>{getKeyboardKeyNameBySystem('ctrl')}</span>
<span className=' system-kbd flex h-4 items-center rounded-[4px] bg-components-kbd-bg-white px-1'></span>
</Button>
{isEdit ? (
<Button
variant='primary'
onClick={handleSave}
>
{t('common.operation.save')}
</Button>
) : (
<Button
className='flex'
variant='primary'
onClick={handleSave}
>
<span className='mr-1'>{t(`${i18nPrefix}.insert`)}</span>
<span className='system-kbd mr-0.5 flex h-4 items-center rounded-[4px] bg-components-kbd-bg-white px-1'>{getKeyboardKeyNameBySystem('ctrl')}</span>
<span className=' system-kbd flex h-4 items-center rounded-[4px] bg-components-kbd-bg-white px-1'></span>
</Button>
)}
</div>
</div>
)

View File

@ -8,6 +8,7 @@ export type SerializedNode = SerializedLexicalNode & {
nodeTitle: string
formInputs: FormInputItem[]
onFormInputsChange: (inputs: FormInputItem[]) => void
onFormInputItemRename: (payload: FormInputItem, oldName: string) => void
onFormInputItemRemove: (varName: string) => void
}
@ -16,6 +17,7 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
__nodeTitle: string
__formInputs?: FormInputItem[]
__onFormInputsChange: (inputs: FormInputItem[]) => void
__onFormInputItemRename: (payload: FormInputItem, oldName: string) => void
__onFormInputItemRemove: (varName: string) => void
isIsolated(): boolean {
@ -50,6 +52,11 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
return self.__onFormInputsChange
}
getOnFormInputItemRename(): (payload: FormInputItem, oldName: string) => void {
const self = this.getLatest()
return self.__onFormInputItemRename
}
getOnFormInputItemRemove(): (varName: string) => void {
const self = this.getLatest()
return self.__onFormInputItemRemove
@ -61,6 +68,7 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
node.__nodeTitle,
node.__formInputs || [],
node.__onFormInputsChange,
node.__onFormInputItemRename,
node.__onFormInputItemRemove,
node.__key,
)
@ -70,13 +78,22 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
return true
}
constructor(varName: string, nodeTitle: string, formInputs: FormInputItem[], onFormInputsChange: (inputs: FormInputItem[]) => void, onFormInputItemRemove: (varName: string) => void, key?: NodeKey) {
constructor(
varName: string,
nodeTitle: string,
formInputs: FormInputItem[],
onFormInputsChange: (inputs: FormInputItem[]) => void,
onFormInputItemRename: (payload: FormInputItem, oldName: string) => void,
onFormInputItemRemove: (varName: string) => void,
key?: NodeKey,
) {
super(key)
this.__variableName = varName
this.__nodeTitle = nodeTitle
this.__formInputs = formInputs
this.__onFormInputsChange = onFormInputsChange
this.__onFormInputItemRename = onFormInputItemRename
this.__onFormInputItemRemove = onFormInputItemRemove
}
@ -97,6 +114,7 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
nodeTitle={this.getNodeTitle()}
formInputs={this.getFormInputs()}
onChange={this.getOnFormInputsChange()}
onRename={this.getOnFormInputItemRename()}
onRemove={this.getOnFormInputItemRemove()}
/>
}
@ -107,6 +125,7 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
serializedNode.nodeTitle,
serializedNode.formInputs,
serializedNode.onFormInputsChange,
serializedNode.onFormInputItemRename,
serializedNode.onFormInputItemRemove,
)
@ -121,6 +140,7 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
nodeTitle: this.getNodeTitle(),
formInputs: this.getFormInputs(),
onFormInputsChange: this.getOnFormInputsChange(),
onFormInputItemRename: this.getOnFormInputItemRename(),
onFormInputItemRemove: this.getOnFormInputItemRemove(),
}
}
@ -130,12 +150,20 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
}
}
export function $createHITLInputNode(variableName: string, nodeTitle: string, formInputs: FormInputItem[], onFormInputsChange: (inputs: FormInputItem[]) => void, onFormInputItemRemove: (varName: string) => void): HITLInputNode {
export function $createHITLInputNode(
variableName: string,
nodeTitle: string,
formInputs: FormInputItem[],
onFormInputsChange: (inputs: FormInputItem[]) => void,
onFormInputItemRename: (payload: FormInputItem, oldName: string) => void,
onFormInputItemRemove: (varName: string) => void,
): HITLInputNode {
return new HITLInputNode(
variableName,
nodeTitle,
formInputs,
onFormInputsChange,
onFormInputItemRename,
onFormInputItemRemove,
)
}

View File

@ -84,6 +84,7 @@ export type HITLInputBlockType = {
formInputs?: FormInputItem[]
onFormInputsChange?: (inputs: FormInputItem[]) => void
onFormInputItemRemove: (varName: string) => void
onFormInputItemRename: (payload: FormInputItem, oldName: string) => void
}
export type MenuTextMatch = {

View File

@ -14,6 +14,7 @@ type Props = {
onChange: (value: string) => void
formInputs: FormInputItem[]
onFormInputsChange: (payload: FormInputItem[]) => void
onFormInputItemRename: (payload: FormInputItem, oldName: string) => void
onFormInputItemRemove: (varName: string) => void
nodeTitle: string
editorKey: number
@ -25,6 +26,7 @@ const FormContent: FC<Props> = ({
onChange,
formInputs,
onFormInputsChange,
onFormInputItemRename,
onFormInputItemRemove,
nodeTitle,
editorKey,
@ -53,6 +55,7 @@ const FormContent: FC<Props> = ({
formInputs,
nodeTitle,
onFormInputsChange,
onFormInputItemRename,
onFormInputItemRemove,
}}
workflowVariableBlock={{

View File

@ -36,6 +36,7 @@ const Panel: FC<NodePanelProps<HumanInputNodeType>> = ({
handleTimeoutChange,
handleFormContentChange,
handleFormInputsChange,
handleFormInputItemRename,
handleFormInputItemRemove,
editorKey,
} = useConfig(id, data)
@ -77,6 +78,7 @@ const Panel: FC<NodePanelProps<HumanInputNodeType>> = ({
nodeTitle={inputs.title}
formInputs={inputs.inputs}
onFormInputsChange={handleFormInputsChange}
onFormInputItemRename={handleFormInputItemRename}
onFormInputItemRemove={handleFormInputItemRemove}
/>
</div>

View File

@ -22,8 +22,21 @@ const useFormContent = (id: string, payload: HumanInputNodeType) => {
...inputs,
inputs: formInputs,
})
setEditorKey(editorKey => editorKey + 1)
}, [inputs, setInputs])
const handleFormInputItemRename = useCallback((payload: FormInputItem, oldName: string) => {
const inputs = inputsRef.current
const newInputs = produce(inputs, (draft) => {
draft.form_content = draft.form_content.replaceAll(`{{#$output.${oldName}#}}`, `{{#$output.${payload.output_variable_name}#}}`)
draft.inputs = draft.inputs.map(item => item.output_variable_name === oldName ? payload : item)
if(!draft.inputs.find(item => item.output_variable_name === payload.output_variable_name))
draft.inputs = [...draft.inputs, payload]
})
setInputs(newInputs)
setEditorKey(editorKey => editorKey + 1)
}, [setInputs])
const handleFormInputItemRemove = useCallback((varName: string) => {
const inputs = inputsRef.current
const newInputs = produce(inputs, (draft) => {
@ -31,13 +44,14 @@ const useFormContent = (id: string, payload: HumanInputNodeType) => {
draft.inputs = draft.inputs.filter(item => item.output_variable_name !== varName)
})
setInputs(newInputs)
setEditorKey(editorKey + 1)
}, [inputs, setInputs, editorKey])
setEditorKey(editorKey => editorKey + 1)
}, [setInputs, editorKey])
return {
editorKey,
handleFormContentChange,
handleFormInputsChange,
handleFormInputItemRename,
handleFormInputItemRemove,
}
}