Support variables in question classifier classes (#17227)

This commit is contained in:
Obada Khalili 2025-04-01 05:19:36 +02:00 committed by GitHub
parent 931d3390f0
commit 6372cb7b41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 46 additions and 37 deletions

View File

@ -73,6 +73,7 @@ type Props = {
titleTooltip?: ReactNode titleTooltip?: ReactNode
inputClassName?: string inputClassName?: string
editorContainerClassName?: string editorContainerClassName?: string
placeholder?: string
placeholderClassName?: string placeholderClassName?: string
titleClassName?: string titleClassName?: string
required?: boolean required?: boolean
@ -108,6 +109,7 @@ const Editor: FC<Props> = ({
gradientBorder = true, gradientBorder = true,
titleTooltip, titleTooltip,
inputClassName, inputClassName,
placeholder,
placeholderClassName, placeholderClassName,
titleClassName, titleClassName,
editorContainerClassName, editorContainerClassName,
@ -223,6 +225,7 @@ const Editor: FC<Props> = ({
<div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'relative min-h-[56px] overflow-y-auto px-3', editorContainerClassName)}> <div className={cn(isExpand ? 'grow' : 'max-h-[536px]', 'relative min-h-[56px] overflow-y-auto px-3', editorContainerClassName)}>
<PromptEditor <PromptEditor
key={controlPromptEditorRerenderKey} key={controlPromptEditorRerenderKey}
placeholder={placeholder}
placeholderClassName={placeholderClassName} placeholderClassName={placeholderClassName}
instanceId={instanceId} instanceId={instanceId}
compact compact

View File

@ -2,28 +2,31 @@
import type { FC } from 'react' import type { FC } from 'react'
import React, { useCallback } from 'react' import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import {
RiDeleteBinLine,
} from '@remixicon/react'
import type { Topic } from '../types' import type { Topic } from '../types'
import TextEditor from '../../_base/components/editor/text-editor' import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
import type { ValueSelector, Var } from '@/app/components/workflow/types'
const i18nPrefix = 'workflow.nodes.questionClassifiers' const i18nPrefix = 'workflow.nodes.questionClassifiers'
type Props = { type Props = {
nodeId: string
payload: Topic payload: Topic
onChange: (payload: Topic) => void onChange: (payload: Topic) => void
onRemove: () => void onRemove: () => void
index: number index: number
readonly?: boolean readonly?: boolean
filterVar: (payload: Var, valueSelector: ValueSelector) => boolean
} }
const ClassItem: FC<Props> = ({ const ClassItem: FC<Props> = ({
nodeId,
payload, payload,
onChange, onChange,
onRemove, onRemove,
index, index,
readonly, readonly,
filterVar,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
@ -31,35 +34,26 @@ const ClassItem: FC<Props> = ({
onChange({ ...payload, name: value }) onChange({ ...payload, name: value })
}, [onChange, payload]) }, [onChange, payload])
const { availableVars, availableNodesWithParent } = useAvailableVarList(nodeId, {
onlyLeafNodeVar: false,
hideChatVar: false,
hideEnv: false,
filterVar,
})
return ( return (
<TextEditor <Editor
isInNode title={`${t(`${i18nPrefix}.class`)} ${index}`}
title={<div> placeholder={t(`${i18nPrefix}.topicPlaceholder`)!}
<div className='w-[200px]'>
<div
className='text-xs font-semibold leading-4 text-gray-700'
>
{`${t(`${i18nPrefix}.class`)} ${index}`}
</div>
</div>
</div>}
value={payload.name} value={payload.name}
onChange={handleNameChange} onChange={handleNameChange}
placeholder={t(`${i18nPrefix}.topicPlaceholder`)!} showRemove
headerRight={( onRemove={onRemove}
<div className='flex h-full items-center'> nodesOutputVars={availableVars}
<div className='text-xs font-medium text-gray-500'>{payload.name.length}</div> availableNodes={availableNodesWithParent}
<div className='mx-3 h-3 w-px bg-gray-200'></div> readOnly={readonly} // ?
{!readonly && ( justVar // ?
<RiDeleteBinLine isSupportFileVar // ?
className='mr-1 h-3.5 w-3.5 cursor-pointer text-gray-500'
onClick={onRemove}
/>
)}
</div>
)}
readonly={readonly}
minHeight={64}
/> />
) )
} }

View File

@ -7,21 +7,24 @@ import { useEdgesInteractions } from '../../../hooks'
import AddButton from '../../_base/components/add-button' import AddButton from '../../_base/components/add-button'
import Item from './class-item' import Item from './class-item'
import type { Topic } from '@/app/components/workflow/nodes/question-classifier/types' import type { Topic } from '@/app/components/workflow/nodes/question-classifier/types'
import type { ValueSelector, Var } from '@/app/components/workflow/types'
const i18nPrefix = 'workflow.nodes.questionClassifiers' const i18nPrefix = 'workflow.nodes.questionClassifiers'
type Props = { type Props = {
id: string nodeId: string
list: Topic[] list: Topic[]
onChange: (list: Topic[]) => void onChange: (list: Topic[]) => void
readonly?: boolean readonly?: boolean
filterVar: (payload: Var, valueSelector: ValueSelector) => boolean
} }
const ClassList: FC<Props> = ({ const ClassList: FC<Props> = ({
id, nodeId,
list, list,
onChange, onChange,
readonly, readonly,
filterVar,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
const { handleEdgeDeleteByDeleteBranch } = useEdgesInteractions() const { handleEdgeDeleteByDeleteBranch } = useEdgesInteractions()
@ -44,13 +47,13 @@ const ClassList: FC<Props> = ({
const handleRemoveClass = useCallback((index: number) => { const handleRemoveClass = useCallback((index: number) => {
return () => { return () => {
handleEdgeDeleteByDeleteBranch(id, list[index].id) handleEdgeDeleteByDeleteBranch(nodeId, list[index].id)
const newList = produce(list, (draft) => { const newList = produce(list, (draft) => {
draft.splice(index, 1) draft.splice(index, 1)
}) })
onChange(newList) onChange(newList)
} }
}, [list, onChange, handleEdgeDeleteByDeleteBranch, id]) }, [list, onChange, handleEdgeDeleteByDeleteBranch, nodeId])
// Todo Remove; edit topic name // Todo Remove; edit topic name
return ( return (
@ -59,12 +62,14 @@ const ClassList: FC<Props> = ({
list.map((item, index) => { list.map((item, index) => {
return ( return (
<Item <Item
nodeId={nodeId}
key={index} key={index}
payload={item} payload={item}
onChange={handleClassChange(index)} onChange={handleClassChange(index)}
onRemove={handleRemoveClass(index)} onRemove={handleRemoveClass(index)}
index={index + 1} index={index + 1}
readonly={readonly} readonly={readonly}
filterVar={filterVar}
/> />
) )
}) })

View File

@ -9,13 +9,14 @@ import {
useTextGenerationCurrentProviderAndModelAndModelList, useTextGenerationCurrentProviderAndModelAndModelList,
} from '@/app/components/header/account-setting/model-provider-page/hooks' } from '@/app/components/header/account-setting/model-provider-page/hooks'
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
import ReadonlyInputWithSelectVar from '../_base/components/readonly-input-with-select-var'
const i18nPrefix = 'workflow.nodes.questionClassifiers' const i18nPrefix = 'workflow.nodes.questionClassifiers'
const Node: FC<NodeProps<QuestionClassifierNodeType>> = (props) => { const Node: FC<NodeProps<QuestionClassifierNodeType>> = (props) => {
const { t } = useTranslation() const { t } = useTranslation()
const { data } = props const { data, id } = props
const { provider, name: modelId } = data.model const { provider, name: modelId } = data.model
// const tempTopics = data.topics // const tempTopics = data.topics
const topics = data.classes const topics = data.classes
@ -47,7 +48,12 @@ const Node: FC<NodeProps<QuestionClassifierNodeType>> = (props) => {
> >
<InfoPanel <InfoPanel
title={`${t(`${i18nPrefix}.class`)} ${index + 1}`} title={`${t(`${i18nPrefix}.class`)} ${index + 1}`}
content={topic.name} content={
<ReadonlyInputWithSelectVar
value={topic.name}
nodeId={id}
/>
}
/> />
<NodeSourceHandle <NodeSourceHandle
{...props} {...props}

View File

@ -145,10 +145,11 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({
title={t(`${i18nPrefix}.class`)} title={t(`${i18nPrefix}.class`)}
> >
<ClassList <ClassList
id={id} nodeId={id}
list={inputs.classes} list={inputs.classes}
onChange={handleTopicsChange} onChange={handleTopicsChange}
readonly={readOnly} readonly={readOnly}
filterVar={filterVar}
/> />
</Field> </Field>
<Split /> <Split />