mirror of
https://github.com/langgenius/dify.git
synced 2026-05-08 11:47:35 +08:00
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: jyong <718720800@qq.com> Co-authored-by: Yansong Zhang <916125788@qq.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: hj24 <huangjian@dify.ai> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Ayush Baluni <73417844+aayushbaluni@users.noreply.github.com> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> Co-authored-by: jimcody1995 <jjimcody@gmail.com> Co-authored-by: James <63717587+jamesrayammons@users.noreply.github.com> Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai> Co-authored-by: Stephen Zhou <hi@hyoban.cc> Co-authored-by: Coding On Star <447357187@qq.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jerryzai <jerryzh8710@protonmail.com> Co-authored-by: NVIDIAN <speedy.hpc@hotmail.com> Co-authored-by: ai-hpc <ai-hpc@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Junghwan <70629228+shaun0927@users.noreply.github.com> Co-authored-by: HeYinKazune <70251095+HeYin-OS@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: yyh <yuanyouhuilyz@gmail.com> Co-authored-by: Jingyi <jingyi.qi@dify.ai> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: sxxtony <166789813+sxxtony@users.noreply.github.com>
121 lines
3.6 KiB
TypeScript
121 lines
3.6 KiB
TypeScript
import type { TFunction } from 'i18next'
|
|
import type { FC } from 'react'
|
|
import type { NodeProps } from 'reactflow'
|
|
import type { QuestionClassifierNodeType } from './types'
|
|
import * as React from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import Tooltip from '@/app/components/base/tooltip'
|
|
import {
|
|
useTextGenerationCurrentProviderAndModelAndModelList,
|
|
} from '@/app/components/header/account-setting/model-provider-page/hooks'
|
|
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
|
import { NodeSourceHandle } from '../_base/components/node-handle'
|
|
import ReadonlyInputWithSelectVar from '../_base/components/readonly-input-with-select-var'
|
|
|
|
const i18nPrefix = 'nodes.questionClassifiers'
|
|
|
|
const MAX_CLASS_TEXT_LENGTH = 50
|
|
|
|
type TruncatedClassItemProps = {
|
|
topic: { id: string, name: string }
|
|
index: number
|
|
nodeId: string
|
|
t: TFunction
|
|
}
|
|
|
|
const TruncatedClassItem: FC<TruncatedClassItemProps> = ({ topic, index, nodeId, t }) => {
|
|
const truncatedText = topic.name.length > MAX_CLASS_TEXT_LENGTH
|
|
? `${topic.name.slice(0, MAX_CLASS_TEXT_LENGTH)}...`
|
|
: topic.name
|
|
|
|
const shouldShowTooltip = topic.name.length > MAX_CLASS_TEXT_LENGTH
|
|
|
|
const content = (
|
|
<div className="truncate system-xs-regular text-text-tertiary">
|
|
<ReadonlyInputWithSelectVar
|
|
value={truncatedText}
|
|
nodeId={nodeId}
|
|
className="truncate"
|
|
/>
|
|
</div>
|
|
)
|
|
|
|
return (
|
|
<div className="flex flex-col gap-y-0.5 rounded-md bg-workflow-block-parma-bg px-[5px] py-[3px]">
|
|
<div className="system-2xs-semibold-uppercase text-text-secondary uppercase">
|
|
{`${t(`${i18nPrefix}.class`, { ns: 'workflow' })} ${index + 1}`}
|
|
</div>
|
|
{shouldShowTooltip
|
|
? (
|
|
<Tooltip
|
|
popupContent={(
|
|
<div className="max-w-[300px] wrap-break-word">
|
|
<ReadonlyInputWithSelectVar value={topic.name} nodeId={nodeId} />
|
|
</div>
|
|
)}
|
|
>
|
|
{content}
|
|
</Tooltip>
|
|
)
|
|
: content}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const Node: FC<NodeProps<QuestionClassifierNodeType>> = (props) => {
|
|
const { t } = useTranslation()
|
|
|
|
const { data, id } = props
|
|
const { provider, name: modelId } = data.model
|
|
// const tempTopics = data.topics
|
|
const topics = data.classes
|
|
const {
|
|
textGenerationModelList,
|
|
} = useTextGenerationCurrentProviderAndModelAndModelList()
|
|
const hasSetModel = provider && modelId
|
|
|
|
if (!hasSetModel && !topics.length)
|
|
return null
|
|
|
|
return (
|
|
<div className="mb-1 px-3 py-1">
|
|
{hasSetModel && (
|
|
<ModelSelector
|
|
defaultModel={{ provider, model: modelId }}
|
|
triggerClassName="h-6! rounded-md!"
|
|
modelList={textGenerationModelList}
|
|
readonly
|
|
/>
|
|
)}
|
|
{
|
|
!!topics.length && (
|
|
<div className="mt-2 space-y-0.5">
|
|
<div className="space-y-0.5">
|
|
{topics.map((topic, index) => (
|
|
<div
|
|
key={topic.id}
|
|
className="relative"
|
|
>
|
|
<TruncatedClassItem
|
|
topic={topic}
|
|
index={index}
|
|
nodeId={id}
|
|
t={t}
|
|
/>
|
|
<NodeSourceHandle
|
|
{...props}
|
|
handleId={topic.id}
|
|
handleClassName="top-1/2! -translate-y-1/2! -right-[21px]!"
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default React.memo(Node)
|