mirror of https://github.com/langgenius/dify.git
feat: pass current value to form input
This commit is contained in:
parent
c28720529e
commit
a18bcf3957
|
|
@ -26,6 +26,10 @@
|
|||
@apply p-0.5 w-6 h-6 rounded-lg
|
||||
}
|
||||
|
||||
.action-btn-s {
|
||||
@apply w-5 h-5 rounded-[6px]
|
||||
}
|
||||
|
||||
.action-btn-xs {
|
||||
@apply p-0 w-4 h-4 rounded
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const actionButtonVariants = cva(
|
|||
variants: {
|
||||
size: {
|
||||
xs: 'action-btn-xs',
|
||||
s: 'action-btn-s',
|
||||
m: 'action-btn-m',
|
||||
l: 'action-btn-l',
|
||||
xl: 'action-btn-xl',
|
||||
|
|
|
|||
|
|
@ -262,7 +262,11 @@ const PromptEditor: FC<PromptEditorProps> = ({
|
|||
hitlInputBlock?.show && (
|
||||
<>
|
||||
<HITLInputBlock />
|
||||
<HITLInputBlockReplacementBlock />
|
||||
<HITLInputBlockReplacementBlock
|
||||
nodeTitle={hitlInputBlock.nodeTitle}
|
||||
formInputs={hitlInputBlock.formInputs}
|
||||
onFormInputsChange={hitlInputBlock.onFormInputsChange}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export default function DraggableBlockPlugin({
|
|||
menuRef={menuRef as any}
|
||||
targetLineRef={targetLineRef as any}
|
||||
menuComponent={
|
||||
isSupportDrag ? <div ref={menuRef} className={cn(DRAGGABLE_BLOCK_MENU_CLASSNAME, 'absolute right-[10px] top-[18px] cursor-grab opacity-0 will-change-transform active:cursor-move')}>
|
||||
isSupportDrag ? <div ref={menuRef} className={cn(DRAGGABLE_BLOCK_MENU_CLASSNAME, 'absolute right-[12px] top-[16px] cursor-grab opacity-0 will-change-transform active:cursor-move')}>
|
||||
<RiDraggable className='size-3.5 text-text-tertiary' />
|
||||
</div> : null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,63 @@
|
|||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import React, { useCallback, useEffect, useRef } from 'react'
|
||||
import { VariableX } from '../../../icons/src/vender/workflow'
|
||||
import { VarBlockIcon } from '@/app/components/workflow/block-icon'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { BlockEnum, InputVarType } from '@/app/components/workflow/types'
|
||||
import { Variable02 } from '../../../icons/src/vender/solid/development'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types'
|
||||
import ActionButton from '../../../action-button'
|
||||
import { RiDeleteBinLine, RiEditLine } from '@remixicon/react'
|
||||
import InputField from './input-field'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import Modal from '../../../modal'
|
||||
|
||||
type Props = {
|
||||
nodeName: string
|
||||
nodeTitle: string
|
||||
varName: string
|
||||
isSelected: boolean
|
||||
formInput?: FormInputItem
|
||||
onChange: (input: FormInputItem) => void
|
||||
}
|
||||
|
||||
const ComponentUI: FC<Props> = ({
|
||||
nodeName,
|
||||
nodeTitle,
|
||||
varName,
|
||||
// isSelected,
|
||||
formInput = {
|
||||
type: InputVarType.textInput,
|
||||
output_variable_name: varName,
|
||||
placeholder: {
|
||||
type: 'const',
|
||||
selector: [],
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
onChange,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [isShowEditModal, {
|
||||
setTrue: showEditModal,
|
||||
setFalse: hideEditModal,
|
||||
}] = useBoolean(false)
|
||||
|
||||
const editBtnRef = useRef<HTMLDivElement>(null)
|
||||
useEffect(() => {
|
||||
const editBtn = editBtnRef.current
|
||||
if (editBtn)
|
||||
editBtn.addEventListener('click', showEditModal)
|
||||
|
||||
return () => {
|
||||
if (editBtn)
|
||||
editBtn.removeEventListener('click', showEditModal)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleChange = useCallback((newPayload: FormInputItem) => {
|
||||
onChange(newPayload)
|
||||
hideEditModal()
|
||||
}, [onChange])
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -32,17 +71,50 @@ const ComponentUI: FC<Props> = ({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div className='flex h-[18px] items-center rounded-[5px] border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark px-1 shadow-xs'>
|
||||
<div className='flex items-center space-x-0.5 text-text-secondary'>
|
||||
<VarBlockIcon type={BlockEnum.Start} />
|
||||
<div className='system-xs-medium'>{nodeName}</div>
|
||||
<div className='flex w-full items-center justify-between'>
|
||||
{/* Node info */}
|
||||
<div className='flex h-[18px] items-center rounded-[5px] border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark px-1 shadow-xs'>
|
||||
<div className='flex items-center space-x-0.5 text-text-secondary'>
|
||||
<VarBlockIcon type={BlockEnum.HumanInput} />
|
||||
<div className='system-xs-medium'>{nodeTitle}</div>
|
||||
</div>
|
||||
<div className='system-xs-regular mx-px text-divider-deep'>/</div>
|
||||
<div className='flex items-center space-x-0.5 text-text-accent'>
|
||||
<Variable02 className='size-3.5' />
|
||||
<div className='system-xs-medium'>{varName}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='system-xs-regular mx-px text-divider-deep'>/</div>
|
||||
<div className='flex items-center space-x-0.5 text-text-accent'>
|
||||
<Variable02 className='size-3.5' />
|
||||
<div className='system-xs-medium'>{varName}</div>
|
||||
|
||||
{/* Actions */}
|
||||
<div className='flex h-full items-center space-x-1 pr-[24px]'>
|
||||
<div className='flex h-full items-center' ref={editBtnRef}>
|
||||
<ActionButton size='s'>
|
||||
<RiEditLine className='size-4 text-text-tertiary' />
|
||||
</ActionButton>
|
||||
</div>
|
||||
|
||||
<div className='flex h-full items-center' >
|
||||
<ActionButton size='s'>
|
||||
<RiDeleteBinLine className='size-4 text-text-tertiary' />
|
||||
</ActionButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isShowEditModal && (
|
||||
<Modal
|
||||
isShow
|
||||
onClose={hideEditModal}
|
||||
wrapperClassName='z-[999]'
|
||||
className='max-w-[372px] !p-0'
|
||||
>
|
||||
<InputField
|
||||
payload={formInput}
|
||||
onChange={handleChange}
|
||||
onCancel={hideEditModal}
|
||||
/>
|
||||
</Modal>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,51 @@
|
|||
import type { FC } from 'react'
|
||||
import { type FC, useCallback } from 'react'
|
||||
import { useSelectOrDelete } from '../../hooks'
|
||||
import { DELETE_HITL_INPUT_BLOCK_COMMAND } from './'
|
||||
import ComponentUi from './component-ui'
|
||||
import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types'
|
||||
import produce from 'immer'
|
||||
|
||||
type QueryBlockComponentProps = {
|
||||
nodeKey: string
|
||||
nodeName: string
|
||||
nodeTitle: string
|
||||
varName: string
|
||||
formInputs?: FormInputItem[]
|
||||
onChange: (inputs: FormInputItem[]) => void
|
||||
}
|
||||
|
||||
const HITLInputComponent: FC<QueryBlockComponentProps> = ({
|
||||
nodeKey,
|
||||
nodeName,
|
||||
nodeTitle,
|
||||
varName,
|
||||
formInputs = [],
|
||||
onChange,
|
||||
}) => {
|
||||
const [ref, isSelected] = useSelectOrDelete(nodeKey, DELETE_HITL_INPUT_BLOCK_COMMAND)
|
||||
const payload = formInputs.find(item => item.output_variable_name === varName)
|
||||
const handleChange = useCallback((newPayload: FormInputItem) => {
|
||||
if(!payload) {
|
||||
onChange([...formInputs, newPayload])
|
||||
return
|
||||
}
|
||||
if(payload?.output_variable_name !== newPayload.output_variable_name) {
|
||||
onChange(produce(formInputs, (draft) => {
|
||||
draft.splice(draft.findIndex(item => item.output_variable_name === payload?.output_variable_name), 1, newPayload)
|
||||
}))
|
||||
return
|
||||
}
|
||||
onChange(formInputs.map(item => item.output_variable_name === varName ? newPayload : item))
|
||||
}, [onChange])
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className='w-full pb-1 pt-3'
|
||||
>
|
||||
<ComponentUi
|
||||
nodeName={nodeName}
|
||||
nodeTitle={nodeTitle}
|
||||
varName={varName}
|
||||
isSelected={isSelected}
|
||||
formInput={payload}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { $applyNodeReplacement } from 'lexical'
|
|||
import { mergeRegister } from '@lexical/utils'
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||
import { decoratorTransform } from '../../utils'
|
||||
import type { QueryBlockType } from '../../types'
|
||||
import type { HITLInputBlockType } from '../../types'
|
||||
import { $createHITLInputNode } from './node'
|
||||
import {
|
||||
QueryBlockNode,
|
||||
|
|
@ -19,8 +19,11 @@ import { HITL_INPUT_REG } from '@/config'
|
|||
const REGEX = new RegExp(HITL_INPUT_REG)
|
||||
|
||||
const HITLInputReplacementBlock = ({
|
||||
onInsert,
|
||||
}: QueryBlockType) => {
|
||||
// onInsert,
|
||||
nodeTitle,
|
||||
formInputs,
|
||||
onFormInputsChange,
|
||||
}: HITLInputBlockType) => {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -29,11 +32,9 @@ const HITLInputReplacementBlock = ({
|
|||
}, [editor])
|
||||
|
||||
const createHITLInputBlockNode = useCallback((textNode: TextNode): QueryBlockNode => {
|
||||
if (onInsert)
|
||||
onInsert()
|
||||
const varName = textNode.getTextContent().split('.')[1].replace(/#}}$/, '')
|
||||
return $applyNodeReplacement($createHITLInputNode(varName))
|
||||
}, [onInsert])
|
||||
return $applyNodeReplacement($createHITLInputNode(varName, nodeTitle, formInputs || [], onFormInputsChange!))
|
||||
}, [nodeTitle, formInputs, onFormInputsChange])
|
||||
|
||||
const getMatch = useCallback((text: string) => {
|
||||
const matchArr = REGEX.exec(text)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,29 @@
|
|||
import React from 'react'
|
||||
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 Button from '../../../button'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { getKeyboardKeyNameBySystem } from '@/app/components/workflow/utils'
|
||||
import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.humanInput.insertInputField'
|
||||
const InputField: React.FC = () => {
|
||||
|
||||
type Props = {
|
||||
payload: FormInputItem
|
||||
onChange: (newPayload: FormInputItem) => void
|
||||
onCancel: () => void
|
||||
}
|
||||
const InputField: React.FC<Props> = ({
|
||||
payload,
|
||||
onChange,
|
||||
onCancel,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const [tempPayload, setTempPayload] = useState(payload)
|
||||
const handleSave = useCallback(() => {
|
||||
onChange(tempPayload)
|
||||
}, [tempPayload])
|
||||
return (
|
||||
<div className="w-[372px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-3 shadow-lg backdrop-blur-[5px]">
|
||||
<div className='system-md-semibold text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||
|
|
@ -19,6 +34,10 @@ const InputField: React.FC = () => {
|
|||
<Input
|
||||
className="mt-1.5"
|
||||
placeholder={t(`${i18nPrefix}.saveResponseAsPlaceholder`)}
|
||||
value={tempPayload.output_variable_name}
|
||||
onChange={(e) => {
|
||||
setTempPayload(prev => ({ ...prev, output_variable_name: e.target.value }))
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='mt-4'>
|
||||
|
|
@ -37,14 +56,21 @@ const InputField: React.FC = () => {
|
|||
<span>{t(`${i18nPrefix}.users`)}</span>
|
||||
</div>
|
||||
<div className="flex h-5 items-center">{t(`${i18nPrefix}.prePopulateFieldPlaceholderEnd`)}</div>
|
||||
</div>}
|
||||
</div>
|
||||
}
|
||||
onChange={
|
||||
(newValue) => {
|
||||
setTempPayload(prev => ({ ...prev, prePopulateField: newValue }))
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='mt-4 flex justify-end space-x-2'>
|
||||
<Button >{t('common.operation.cancel')}</Button>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,20 @@
|
|||
import type { LexicalNode, NodeKey, SerializedLexicalNode } from 'lexical'
|
||||
import { DecoratorNode } from 'lexical'
|
||||
import HILTInputBlockComponent from './component'
|
||||
import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types'
|
||||
|
||||
export type SerializedNode = SerializedLexicalNode & {
|
||||
variableName: string
|
||||
nodeTitle: string
|
||||
formInputs: FormInputItem[]
|
||||
onFormInputsChange: (inputs: FormInputItem[]) => void
|
||||
}
|
||||
|
||||
export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
|
||||
__variableName: string
|
||||
__nodeTitle: string
|
||||
__formInputs?: FormInputItem[]
|
||||
__onFormInputsChange: (inputs: FormInputItem[]) => void
|
||||
|
||||
isIsolated(): boolean {
|
||||
return true // This is necessary for drag-and-drop to work correctly
|
||||
|
|
@ -26,18 +33,36 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
|
|||
return self.__variableName
|
||||
}
|
||||
|
||||
getNodeTitle(): string {
|
||||
const self = this.getLatest()
|
||||
return self.__nodeTitle
|
||||
}
|
||||
|
||||
getFormInputs(): FormInputItem[] {
|
||||
const self = this.getLatest()
|
||||
return self.__formInputs || []
|
||||
}
|
||||
|
||||
getOnFormInputsChange(): (inputs: FormInputItem[]) => void {
|
||||
const self = this.getLatest()
|
||||
return self.__onFormInputsChange
|
||||
}
|
||||
|
||||
static clone(node: HITLInputNode): HITLInputNode {
|
||||
return new HITLInputNode(node.__variableName, node.__key)
|
||||
return new HITLInputNode(node.__variableName, node.__nodeTitle, node.__formInputs || [], node.__onFormInputsChange, node.__key)
|
||||
}
|
||||
|
||||
isInline(): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
constructor(varName: string, key?: NodeKey) {
|
||||
constructor(varName: string, nodeTitle: string, formInputs: FormInputItem[], onFormInputsChange: (inputs: FormInputItem[]) => void, key?: NodeKey) {
|
||||
super(key)
|
||||
|
||||
this.__variableName = varName
|
||||
this.__nodeTitle = nodeTitle
|
||||
this.__formInputs = formInputs
|
||||
this.__onFormInputsChange = onFormInputsChange
|
||||
}
|
||||
|
||||
createDOM(): HTMLElement {
|
||||
|
|
@ -51,11 +76,17 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
|
|||
}
|
||||
|
||||
decorate(): React.JSX.Element {
|
||||
return <HILTInputBlockComponent nodeKey={this.getKey()} nodeName='todo' varName={this.getVariableName()} />
|
||||
return <HILTInputBlockComponent
|
||||
nodeKey={this.getKey()}
|
||||
varName={this.getVariableName()}
|
||||
nodeTitle={this.getNodeTitle()}
|
||||
formInputs={this.getFormInputs()}
|
||||
onChange={this.getOnFormInputsChange()}
|
||||
/>
|
||||
}
|
||||
|
||||
static importJSON(serializedNode: SerializedNode): HITLInputNode {
|
||||
const node = $createHITLInputNode(serializedNode.variableName)
|
||||
const node = $createHITLInputNode(serializedNode.variableName, serializedNode.nodeTitle, serializedNode.formInputs, serializedNode.onFormInputsChange)
|
||||
|
||||
return node
|
||||
}
|
||||
|
|
@ -65,6 +96,9 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
|
|||
type: 'hitl-input-block',
|
||||
version: 1,
|
||||
variableName: this.getVariableName(),
|
||||
nodeTitle: this.getNodeTitle(),
|
||||
formInputs: this.getFormInputs(),
|
||||
onFormInputsChange: this.getOnFormInputsChange(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,8 +107,8 @@ export class HITLInputNode extends DecoratorNode<React.JSX.Element> {
|
|||
}
|
||||
}
|
||||
|
||||
export function $createHITLInputNode(variableName: string): HITLInputNode {
|
||||
return new HITLInputNode(variableName)
|
||||
export function $createHITLInputNode(variableName: string, nodeTitle: string, formInputs: FormInputItem[], onFormInputsChange: (inputs: FormInputItem[]) => void): HITLInputNode {
|
||||
return new HITLInputNode(variableName, nodeTitle, formInputs, onFormInputsChange)
|
||||
}
|
||||
|
||||
export function $isHITLInputNode(
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { FormInputItem } from '../../workflow/nodes/human-input/types'
|
||||
import type { Type } from '../../workflow/nodes/llm/types'
|
||||
import type { Dataset } from './plugins/context-block'
|
||||
import type { RoleName } from './plugins/history-block'
|
||||
|
|
@ -79,6 +80,9 @@ export type WorkflowVariableBlockType = {
|
|||
|
||||
export type HITLInputBlockType = {
|
||||
show?: boolean
|
||||
nodeTitle: string
|
||||
formInputs?: FormInputItem[]
|
||||
onFormInputsChange?: (inputs: FormInputItem[]) => void
|
||||
}
|
||||
|
||||
export type MenuTextMatch = {
|
||||
|
|
|
|||
|
|
@ -6,17 +6,24 @@ import useAvailableVarList from '../../_base/hooks/use-available-var-list'
|
|||
import { BlockEnum } from '../../../types'
|
||||
import { useWorkflowVariableType } from '../../../hooks'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import type { FormInputItem } from '../types'
|
||||
|
||||
type Props = {
|
||||
nodeId: string
|
||||
value: string
|
||||
onChange: (value: string) => void
|
||||
formInputs: FormInputItem[]
|
||||
onFormInputsChange: (payload: FormInputItem[]) => void
|
||||
nodeTitle: string
|
||||
}
|
||||
|
||||
const FormContent: FC<Props> = ({
|
||||
nodeId,
|
||||
value,
|
||||
onChange,
|
||||
formInputs,
|
||||
onFormInputsChange,
|
||||
nodeTitle,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const filterVar = () => true
|
||||
|
|
@ -38,6 +45,9 @@ const FormContent: FC<Props> = ({
|
|||
className='min-h-[80px]'
|
||||
hitlInputBlock={{
|
||||
show: true,
|
||||
formInputs,
|
||||
nodeTitle,
|
||||
onFormInputsChange,
|
||||
}}
|
||||
workflowVariableBlock={{
|
||||
show: true,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ const Panel: FC<NodePanelProps<HumanInputNodeType>> = ({
|
|||
handleUserActionDelete,
|
||||
handleTimeoutChange,
|
||||
handleFormContentChange,
|
||||
handleFormInputsChange,
|
||||
} = useConfig(id, data)
|
||||
|
||||
const { availableVars, availableNodesWithParent } = useAvailableVarList(id, {
|
||||
|
|
@ -70,6 +71,9 @@ const Panel: FC<NodePanelProps<HumanInputNodeType>> = ({
|
|||
nodeId={id}
|
||||
value={inputs.form_content}
|
||||
onChange={handleFormContentChange}
|
||||
nodeTitle={inputs.title}
|
||||
formInputs={inputs.inputs}
|
||||
onFormInputsChange={handleFormInputsChange}
|
||||
/>
|
||||
</div>
|
||||
{/* user actions */}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,7 @@ import type { CommonNodeType, InputVarType, ValueSelector, Variable } from '@/ap
|
|||
export type HumanInputNodeType = CommonNodeType & {
|
||||
delivery_methods: DeliveryMethod[]
|
||||
form_content: string
|
||||
form_input: {
|
||||
type: InputVarType
|
||||
output_variable_name: string
|
||||
placeholder?: { // only text-input and paragraph support placeholder
|
||||
type: 'variable' | 'const',
|
||||
selector: ValueSelector
|
||||
value: string
|
||||
}
|
||||
}[]
|
||||
inputs: FormInputItem[]
|
||||
user_actions: UserAction[]
|
||||
timeout: number
|
||||
timeout_unit: 'hour' | 'day'
|
||||
|
|
@ -47,6 +39,19 @@ export type DeliveryMethod = {
|
|||
config?: EmailConfig
|
||||
}
|
||||
|
||||
export type FormInputItemPlaceholder = {
|
||||
type: 'variable' | 'const',
|
||||
selector: ValueSelector
|
||||
value: string
|
||||
}
|
||||
|
||||
export type FormInputItem = {
|
||||
type: InputVarType
|
||||
output_variable_name: string
|
||||
// only text-input and paragraph support placeholder
|
||||
placeholder?: FormInputItemPlaceholder
|
||||
}
|
||||
|
||||
export enum UserActionButtonType {
|
||||
Primary = 'primary',
|
||||
Default = 'default',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import useNodeCrud from '../_base/hooks/use-node-crud'
|
||||
import type { HumanInputNodeType } from './types'
|
||||
import type { FormInputItem, HumanInputNodeType } from './types'
|
||||
|
||||
const useFormContent = (id: string, payload: HumanInputNodeType) => {
|
||||
const { inputs, setInputs } = useNodeCrud<HumanInputNodeType>(id, payload)
|
||||
|
|
@ -9,8 +9,16 @@ const useFormContent = (id: string, payload: HumanInputNodeType) => {
|
|||
form_content: value,
|
||||
})
|
||||
}
|
||||
|
||||
const handleFormInputsChange = (formInputs: FormInputItem[]) => {
|
||||
setInputs({
|
||||
...inputs,
|
||||
inputs: formInputs,
|
||||
})
|
||||
}
|
||||
return {
|
||||
handleFormContentChange,
|
||||
handleFormInputsChange,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue