This commit is contained in:
2025-12-01 17:21:38 +08:00
parent 32fee2b8ab
commit fab8c13cb3
7511 changed files with 996300 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
import type { NodeDefault } from '../../types'
import type { AnswerNodeType } from './types'
import { genNodeMetaData } from '@/app/components/workflow/utils'
import { BlockEnum } from '@/app/components/workflow/types'
const metaData = genNodeMetaData({
sort: 2.1,
type: BlockEnum.Answer,
isRequired: true,
})
const nodeDefault: NodeDefault<AnswerNodeType> = {
metaData,
defaultValue: {
variables: [],
answer: '',
},
checkValid(payload: AnswerNodeType, t: any) {
let errorMessages = ''
const { answer } = payload
if (!answer)
errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('workflow.nodes.answer.answer') })
return {
isValid: !errorMessages,
errorMessage: errorMessages,
}
},
}
export default nodeDefault

View File

@@ -0,0 +1,26 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import InfoPanel from '../_base/components/info-panel'
import ReadonlyInputWithSelectVar from '../_base/components/readonly-input-with-select-var'
import type { AnswerNodeType } from './types'
import type { NodeProps } from '@/app/components/workflow/types'
const Node: FC<NodeProps<AnswerNodeType>> = ({
id,
data,
}) => {
const { t } = useTranslation()
return (
<div className='mb-1 px-3 py-1'>
<InfoPanel title={t('workflow.nodes.answer.answer')} content={
<ReadonlyInputWithSelectVar
value={data.answer}
nodeId={id}
/>
} />
</div>
)
}
export default React.memo(Node)

View File

@@ -0,0 +1,47 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import useConfig from './use-config'
import type { AnswerNodeType } from './types'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import type { NodePanelProps } from '@/app/components/workflow/types'
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
const i18nPrefix = 'workflow.nodes.answer'
const Panel: FC<NodePanelProps<AnswerNodeType>> = ({
id,
data,
}) => {
const { t } = useTranslation()
const {
readOnly,
inputs,
handleAnswerChange,
filterVar,
} = useConfig(id, data)
const { availableVars, availableNodesWithParent } = useAvailableVarList(id, {
onlyLeafNodeVar: false,
hideChatVar: false,
hideEnv: false,
filterVar,
})
return (
<div className='mb-2 mt-2 space-y-4 px-4'>
<Editor
readOnly={readOnly}
justVar
title={t(`${i18nPrefix}.answer`)!}
value={inputs.answer}
onChange={handleAnswerChange}
nodesOutputVars={availableVars}
availableNodes={availableNodesWithParent}
isSupportFileVar
/>
</div>
)
}
export default React.memo(Panel)

View File

@@ -0,0 +1,6 @@
import type { CommonNodeType, Variable } from '@/app/components/workflow/types'
export type AnswerNodeType = CommonNodeType & {
variables: Variable[]
answer: string
}

View File

@@ -0,0 +1,41 @@
import { useCallback } from 'react'
import { produce } from 'immer'
import useVarList from '../_base/hooks/use-var-list'
import type { Var } from '../../types'
import { VarType } from '../../types'
import type { AnswerNodeType } from './types'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import {
useNodesReadOnly,
} from '@/app/components/workflow/hooks'
const useConfig = (id: string, payload: AnswerNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const { inputs, setInputs } = useNodeCrud<AnswerNodeType>(id, payload)
// variables
const { handleVarListChange, handleAddVariable } = useVarList<AnswerNodeType>({
inputs,
setInputs,
})
const handleAnswerChange = useCallback((value: string) => {
const newInputs = produce(inputs, (draft) => {
draft.answer = value
})
setInputs(newInputs)
}, [inputs, setInputs])
const filterVar = useCallback((varPayload: Var) => {
return varPayload.type !== VarType.arrayObject
}, [])
return {
readOnly,
inputs,
handleVarListChange,
handleAddVariable,
handleAnswerChange,
filterVar,
}
}
export default useConfig

View File

@@ -0,0 +1,5 @@
import type { AnswerNodeType } from './types'
export const checkNodeValid = (_payload: AnswerNodeType) => {
return true
}