preview tip of human input delivery methods

This commit is contained in:
JzoNg 2025-08-25 17:13:37 +08:00
parent 305b5da764
commit 949a894f03
7 changed files with 53 additions and 3 deletions

View File

@ -1,20 +1,43 @@
import { useTranslation } from 'react-i18next'
import HumanInputForm from './human-input-form'
import type { FormData } from './human-input-form'
import { useChatContext } from '../../context'
import type { HumanInputFormData } from '@/types/workflow'
import type { DeliveryMethod } from '@/app/components/workflow/nodes/human-input/types'
import { DeliveryMethodType } from '@/app/components/workflow/nodes/human-input/types'
import Divider from '@/app/components/base/divider'
type Props = {
formData: FormData
showDebugTip?: boolean
formData: HumanInputFormData
showTimeout?: boolean
onSubmit?: (formID: string, data: any) => void
}
const HumanInputContent = ({ formData, onSubmit }: Props) => {
const { t } = useTranslation()
const {
getHumanInputNodeData,
} = useChatContext()
const deliveryMethodsConfig = getHumanInputNodeData?.(formData.node_id as any)?.data.delivery_methods || []
const isWebappEnabled = deliveryMethodsConfig.some((method: DeliveryMethod) => method.type === DeliveryMethodType.WebApp && method.enabled)
const isEmailEnabled = deliveryMethodsConfig.some((method: DeliveryMethod) => method.type === DeliveryMethodType.Email && method.enabled)
return (
<>
<HumanInputForm
formData={formData}
formData={formData as any as FormData}
onSubmit={onSubmit}
/>
{(!isWebappEnabled || isEmailEnabled) && (
<>
<Divider className='!my-2 w-[30px]' />
<div className='space-y-1 pt-1'>
{isEmailEnabled && <div className='system-xs-regular text-text-secondary'>{t('humanInputEmailTip')}</div>}
{!isWebappEnabled && <div className='system-xs-medium text-text-warning'>{t('humanInputWebappTip')}</div>}
</div>
</>
)}
</>
)
}

View File

@ -16,6 +16,7 @@ export type ChatContextValue = Pick<ChatProps, 'config'
| 'onAnnotationAdded'
| 'onAnnotationRemoved'
| 'onFeedback'
| 'getHumanInputNodeData'
>
const ChatContext = createContext<ChatContextValue>({
@ -40,6 +41,7 @@ export const ChatContextProvider = ({
onAnnotationAdded,
onAnnotationRemoved,
onFeedback,
getHumanInputNodeData,
}: ChatContextProviderProps) => {
return (
<ChatContext.Provider value={{
@ -55,6 +57,7 @@ export const ChatContextProvider = ({
onAnnotationAdded,
onAnnotationRemoved,
onFeedback,
getHumanInputNodeData,
}}>
{children}
</ChatContext.Provider>

View File

@ -75,6 +75,7 @@ export type ChatProps = {
sidebarCollapseState?: boolean
hideAvatar?: boolean
onHumanInputFormSubmit?: (formID: string, formData: any) => void
getHumanInputNodeData?: (nodeID: string) => any
}
const Chat: FC<ChatProps> = ({
@ -116,6 +117,7 @@ const Chat: FC<ChatProps> = ({
sidebarCollapseState,
hideAvatar,
onHumanInputFormSubmit,
getHumanInputNodeData,
}) => {
const { t } = useTranslation()
const { currentLogItem, setCurrentLogItem, showPromptLogModal, setShowPromptLogModal, showAgentLogModal, setShowAgentLogModal } = useAppStore(useShallow(state => ({
@ -230,6 +232,7 @@ const Chat: FC<ChatProps> = ({
onAnnotationEdited={onAnnotationEdited}
onAnnotationRemoved={onAnnotationRemoved}
onFeedback={onFeedback}
getHumanInputNodeData={getHumanInputNodeData}
>
<div className='relative h-full'>
<div

View File

@ -88,6 +88,7 @@ const ChatWrapper = (
handleRestart,
setTargetMessageId,
handleSubmitHumanInputForm,
getHumanInputNodeData,
} = useChat(
config,
{
@ -186,6 +187,7 @@ const ChatWrapper = (
onRegenerate={doRegenerate}
onStopResponding={handleStop}
onHumanInputFormSubmit={doHumanInputFormSubmit}
getHumanInputNodeData={getHumanInputNodeData}
chatNode={(
<>
{showInputsFieldsPanel && <UserInput />}

View File

@ -5,6 +5,7 @@ import {
useRef,
useState,
} from 'react'
import { useStoreApi } from 'reactflow'
import { useTranslation } from 'react-i18next'
import { produce, setAutoFreeze } from 'immer'
import { uniqBy } from 'lodash-es'
@ -36,6 +37,9 @@ import { getThreadMessages } from '@/app/components/base/chat/utils'
import { useInvalidAllLastRun } from '@/service/use-workflow'
import { useParams } from 'next/navigation'
import { submitHumanInputForm } from '@/service/workflow'
import {
CUSTOM_NODE,
} from '@/app/components/workflow/constants'
type GetAbortController = (abortController: AbortController) => void
type SendCallback = {
@ -68,6 +72,7 @@ export const useChat = (
setIterTimes,
setLoopTimes,
} = workflowStore.getState()
const store = useStoreApi()
const handleResponding = useCallback((isResponding: boolean) => {
setIsResponding(isResponding)
@ -528,6 +533,15 @@ export const useChat = (
// TODO deal with success
}
const getHumanInputNodeData = (nodeID: string) => {
const {
getNodes,
} = store.getState()
const nodes = getNodes().filter(node => node.type === CUSTOM_NODE)
const node = nodes.find(n => n.id === nodeID)
return node
}
return {
conversationId: conversationId.current,
chatList,
@ -536,6 +550,7 @@ export const useChat = (
handleStop,
handleRestart,
handleSubmitHumanInputForm,
getHumanInputNodeData,
isResponding,
suggestedQuestions,
}

View File

@ -116,6 +116,8 @@ const translation = {
loadMore: 'Load More',
noHistory: 'No History',
tagBound: 'Number of apps using this tag',
humanInputWebappTip: 'Debug preview only, user will not see this in web app.',
humanInputEmailTip: 'Email (Delivery Method) sent to your configured recipients',
},
env: {
envPanelTitle: 'Environment Variables',

View File

@ -116,6 +116,8 @@ const translation = {
loadMore: '加载更多',
noHistory: '没有历史版本',
tagBound: '使用此标签的应用数量',
humanInputWebappTip: '仅调试预览,用户在 Web 应用中看不到此内容。',
humanInputEmailTip: '电子邮件(传递方式)发送到您配置的收件人。',
},
env: {
envPanelTitle: '环境变量',