feat: replace timeout handling with expiration time in HumanInput form and add ExpirationTime component

This commit is contained in:
twwu
2025-12-25 18:16:32 +08:00
parent be0f493e61
commit e744d4de80
9 changed files with 74 additions and 26 deletions

View File

@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import ContentItem from '@/app/components/base/chat/chat/answer/human-input-content/content-item'
import ExpirationTime from '@/app/components/base/chat/chat/answer/human-input-content/expiration-time'
import Loading from '@/app/components/base/loading'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import { UserActionButtonType } from '@/app/components/workflow/nodes/human-input/types'
@ -24,8 +25,7 @@ export type FormData = {
form_content: string
inputs: FormInputItem[]
user_actions: UserAction[]
timeout: number
timeout_unit: 'hour' | 'day'
expiration_time: number
}
const FormContent = () => {
@ -249,9 +249,7 @@ const FormContent = () => {
</Button>
))}
</div>
<div className="system-xs-regular mt-1 text-text-tertiary">
{formData.timeout_unit === 'day' ? t('share.humanInput.timeoutDay', { count: formData.timeout }) : t('share.humanInput.timeoutHour', { count: formData.timeout })}
</div>
<ExpirationTime expirationTime={formData.expiration_time} />
</div>
<div className="flex flex-row-reverse px-2 py-3">
<div className={cn(

View File

@ -0,0 +1,24 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useI18N } from '@/context/i18n'
import { formatRelativeTimeInZone } from './utils'
type ExpirationTimeProps = {
expirationTime: number
}
const ExpirationTime = ({
expirationTime,
}: ExpirationTimeProps) => {
const { t } = useTranslation()
const { locale } = useI18N()
const relativeTime = formatRelativeTimeInZone(expirationTime, locale)
return (
<div className="system-xs-regular mt-1 text-text-tertiary">
{t('share.humanInput.expirationTime', { relativeTime })}
</div>
)
}
export default ExpirationTime

View File

@ -2,20 +2,17 @@
import type { HumanInputFormProps } from './type'
import * as React from 'react'
import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import ContentItem from './content-item'
import ExpirationTime from './expiration-time'
import { getButtonStyle, initializeInputs, splitByOutputVar } from './utils'
const HumanInputForm = ({
formData,
showTimeout,
timeout,
timeoutUnit,
onSubmit,
expirationTime,
}: HumanInputFormProps) => {
const { t } = useTranslation()
const formID = formData.form_id
const defaultInputs = initializeInputs(formData.inputs)
const contentList = splitByOutputVar(formData.form_content)
@ -59,10 +56,8 @@ const HumanInputForm = ({
</Button>
))}
</div>
{showTimeout && (
<div className="system-xs-regular mt-1 text-text-tertiary">
{timeoutUnit === 'day' ? t('share.humanInput.timeoutDay', { count: timeout }) : t('share.humanInput.timeoutHour', { count: timeout })}
</div>
{showTimeout && typeof expirationTime === 'number' && (
<ExpirationTime expirationTime={expirationTime} />
)}
</>
)

View File

@ -12,16 +12,14 @@ export type HumanInputContentProps = {
showEmailTip?: boolean
showDebugModeTip?: boolean
showTimeout?: boolean
timeout?: number
timeoutUnit?: 'hour' | 'day'
expirationTime?: number
onSubmit?: (formID: string, data: any) => Promise<void>
}
export type HumanInputFormProps = {
formData: HumanInputFormData
showTimeout?: boolean
timeout?: number
timeoutUnit?: 'hour' | 'day'
expirationTime?: number
onSubmit?: (formID: string, data: any) => Promise<void>
}

View File

@ -1,5 +1,15 @@
import type { FormInputItem } from '@/app/components/workflow/nodes/human-input/types'
import type { Locale } from '@/i18n-config'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import utc from 'dayjs/plugin/utc'
import { UserActionButtonType } from '@/app/components/workflow/nodes/human-input/types'
import 'dayjs/locale/en'
import 'dayjs/locale/zh-cn'
import 'dayjs/locale/ja'
dayjs.extend(utc)
dayjs.extend(relativeTime)
export const getButtonStyle = (style: UserActionButtonType) => {
if (style === UserActionButtonType.Primary)
@ -28,3 +38,21 @@ export const initializeInputs = (formInputs: FormInputItem[]) => {
})
return initialInputs
}
const localeMap: Record<string, string> = {
'en-US': 'en',
'zh-Hans': 'zh-cn',
'ja-JP': 'ja',
}
export const formatRelativeTimeInZone = (
utcTimestamp: string | number,
locale: Locale = 'en-US',
) => {
const dayjsLocale = localeMap[locale] ?? 'en'
return dayjs
.utc(utcTimestamp)
.locale(dayjsLocale)
.fromNow()
}