add timeout of human input node

This commit is contained in:
JzoNg 2025-07-25 11:42:50 +08:00
parent 1ab02c6e9a
commit 95b88a0621
8 changed files with 105 additions and 19 deletions

View File

@ -0,0 +1,53 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import type { Timeout } from '../types'
import Input from '@/app/components/base/input'
import cn from '@/utils/classnames'
const i18nPrefix = 'workflow.nodes.humanInput'
type Props = {
timeout: Timeout
onChange: (state: Timeout) => void
}
const TimeoutInput: FC<Props> = ({
timeout,
onChange,
}) => {
const { t } = useTranslation()
return (
<div className='flex items-center gap-1'>
<Input
wrapperClassName='w-16'
type='number'
value={timeout.value}
min={1}
onChange={e => onChange({ ...timeout, value: Number(e.target.value) })}
/>
<div className='flex items-center gap-0.5 rounded-[10px] bg-components-segmented-control-bg-normal p-0.5'>
<div
className={cn(
'cursor-pointer rounded-lg px-2 py-1 text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
timeout.unit === 'days' && 'bg-components-segmented-control-item-active-bg text-text-accent-light-mode-only shadow-sm hover:bg-components-segmented-control-item-active-bg hover:text-text-accent-light-mode-only',
)}
onClick={() => onChange({ ...timeout, unit: 'days' })}
>
<div className='system-sm-medium p-0.5'>{t(`${i18nPrefix}.timeout.days`)}</div>
</div>
<div
className={cn(
'cursor-pointer rounded-lg px-2 py-1 text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
timeout.unit === 'hours' && 'bg-components-segmented-control-item-active-bg text-text-accent-light-mode-only shadow-sm hover:bg-components-segmented-control-item-active-bg hover:text-text-accent-light-mode-only',
)}
onClick={() => onChange({ ...timeout, unit: 'hours' })}
>
<div className='system-sm-medium p-0.5'>{t(`${i18nPrefix}.timeout.hours`)}</div>
</div>
</div>
</div>
)
}
export default TimeoutInput

View File

@ -37,6 +37,10 @@ const nodeDefault: NodeDefault<HumanInputNodeType> = {
type: UserActionButtonType.Ghost,
},
],
timeout: {
value: 3,
unit: 'days',
},
},
getAvailablePrevNodes(isChatMode: boolean) {
const nodes = isChatMode

View File

@ -1,5 +1,6 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
RiMailSendFill,
RiRobot2Fill,
@ -9,7 +10,11 @@ import type { HumanInputNodeType } from './types'
import type { NodeProps } from '@/app/components/workflow/types'
import { DeliveryMethodType } from './types'
const i18nPrefix = 'workflow.nodes.humanInput'
const Node: FC<NodeProps<HumanInputNodeType>> = (props) => {
const { t } = useTranslation()
const { data } = props
const deliveryMethods = data.deliveryMethod
const userActions = data.userActions
@ -18,7 +23,7 @@ const Node: FC<NodeProps<HumanInputNodeType>> = (props) => {
<>
{deliveryMethods.length > 0 && (
<div className='space-y-0.5 py-1'>
<div className='system-2xs-medium-uppercase px-2.5 py-0.5 text-text-tertiary'>delivery method</div>
<div className='system-2xs-medium-uppercase px-2.5 py-0.5 text-text-tertiary'>{t(`${i18nPrefix}.deliveryMethod.title`)}</div>
<div className='space-y-0.5 px-2.5'>
{deliveryMethods.map(method => (
<div key={method.type} className='flex items-center gap-1 rounded-[6px] bg-workflow-block-parma-bg p-1'>

View File

@ -1,8 +1,11 @@
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import useConfig from './use-config'
import type { HumanInputNodeType } from './types'
import type { NodePanelProps } from '@/app/components/workflow/types'
import Divider from '@/app/components/base/divider'
import TimeoutInput from './components/timeout'
const i18nPrefix = 'workflow.nodes.humanInput'
@ -11,11 +14,21 @@ const Panel: FC<NodePanelProps<HumanInputNodeType>> = ({
data,
}) => {
const { t } = useTranslation()
const {
inputs,
handleTimeoutChange,
} = useConfig(id, data)
return (
<div className='mt-2'>
<div className='space-y-4 px-4 pb-4'>
TODO
<div className='py-2'>
<div className='px-4 py-2'>
<Divider className='!my-0 !h-px !bg-divider-subtle' />
</div>
<div className='flex items-center justify-between px-4 py-2'>
<div className='system-sm-semibold-uppercase text-text-secondary'>{t(`${i18nPrefix}.timeout.title`)}</div>
<TimeoutInput
timeout={inputs.timeout}
onChange={handleTimeoutChange}
/>
</div>
</div>
)

View File

@ -4,7 +4,7 @@ export type HumanInputNodeType = CommonNodeType & {
deliveryMethod: DeliveryMethod[]
formContent: any
userActions: UserAction[]
timeout: any
timeout: Timeout
outputs: Variable[]
}

View File

@ -1,5 +1,4 @@
import useVarList from '../_base/hooks/use-var-list'
import type { HumanInputNodeType } from './types'
import type { HumanInputNodeType, Timeout } from './types'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import {
useNodesReadOnly,
@ -8,19 +7,17 @@ const useConfig = (id: string, payload: HumanInputNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const { inputs, setInputs } = useNodeCrud<HumanInputNodeType>(id, payload)
const { handleVarListChange, handleAddVariable } = useVarList<HumanInputNodeType>({
inputs,
setInputs: (newInputs) => {
setInputs(newInputs)
},
varKey: 'outputs',
})
const handleTimeoutChange = (timeout: Timeout) => {
setInputs({
...inputs,
timeout,
})
}
return {
readOnly,
inputs,
handleVarListChange,
handleAddVariable,
handleTimeoutChange,
}
}

View File

@ -905,9 +905,16 @@ const translation = {
parameterSchema: 'Parameter Schema',
},
humanInput: {
deliveryMethod: 'delivery method',
deliveryMethod: {
title: 'Delivery Method',
},
formContent: 'form content',
userActions: 'user actions',
timeout: {
title: 'Timeout',
hours: 'Hours',
days: 'Days',
},
},
},
tracing: {

View File

@ -906,9 +906,16 @@ const translation = {
parameterSchema: '参数 Schema',
},
humanInput: {
deliveryMethod: '提交方式',
deliveryMethod: {
title: '提交方式',
},
formContent: '表单内容',
userActions: '用户操作',
timeout: {
title: '超时设置',
hours: '小时',
days: '日',
},
},
},
tracing: {