Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { uniqueId } from 'lodash-es'
const i18nPrefix = 'workflow.nodes.questionClassifiers'

type Props = {
className?: string
headerClassName?: string
nodeId: string
payload: Topic
onChange: (payload: Topic) => void
Expand All @@ -21,6 +23,8 @@ type Props = {
}

const ClassItem: FC<Props> = ({
className,
headerClassName,
nodeId,
payload,
onChange,
Expand Down Expand Up @@ -49,6 +53,8 @@ const ClassItem: FC<Props> = ({

return (
<Editor
className={className}
headerClassName={headerClassName}
title={`${t(`${i18nPrefix}.class`)} ${index}`}
placeholder={t(`${i18nPrefix}.topicPlaceholder`)!}
value={payload.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import AddButton from '../../_base/components/add-button'
import Item from './class-item'
import type { Topic } from '@/app/components/workflow/nodes/question-classifier/types'
import type { ValueSelector, Var } from '@/app/components/workflow/types'
import { ReactSortable } from 'react-sortablejs'
import { noop } from 'lodash-es'
import cn from '@/utils/classnames'

const i18nPrefix = 'workflow.nodes.questionClassifiers'

Expand All @@ -17,6 +20,7 @@ type Props = {
onChange: (list: Topic[]) => void
readonly?: boolean
filterVar: (payload: Var, valueSelector: ValueSelector) => boolean
handleSortTopic?: (newTopics: (Topic & { id: string })[]) => void
}

const ClassList: FC<Props> = ({
Expand All @@ -25,6 +29,7 @@ const ClassList: FC<Props> = ({
onChange,
readonly,
filterVar,
handleSortTopic = noop,
}) => {
const { t } = useTranslation()
const { handleEdgeDeleteByDeleteBranch } = useEdgesInteractions()
Expand Down Expand Up @@ -55,22 +60,48 @@ const ClassList: FC<Props> = ({
}
}, [list, onChange, handleEdgeDeleteByDeleteBranch, nodeId])

const topicCount = list.length
const handleSideWidth = 3
// Todo Remove; edit topic name
return (
<div className='space-y-2'>
<ReactSortable
list={list.map(item => ({ ...item }))}
setList={handleSortTopic}
handle='.handle'
ghostClass='bg-components-panel-bg'
animation={150}
disabled={readonly}
className='space-y-2'
>
{
list.map((item, index) => {
const canDrag = (() => {
if (readonly)
return false

return topicCount >= 2
})()
return (
<Item
nodeId={nodeId}
key={list[index].id}
payload={item}
onChange={handleClassChange(index)}
onRemove={handleRemoveClass(index)}
index={index + 1}
readonly={readonly}
filterVar={filterVar}
/>
<div key={item.id}
className={cn(
'group relative rounded-[10px] bg-components-panel-bg',
`-ml-${handleSideWidth} min-h-[40px] px-0 py-0`,
)}>
<div >
<Item
className={cn(canDrag && 'handle')}
headerClassName={cn(canDrag && 'cursor-grab')}
nodeId={nodeId}
key={list[index].id}
payload={item}
onChange={handleClassChange(index)}
onRemove={handleRemoveClass(index)}
index={index + 1}
readonly={readonly}
filterVar={filterVar}
/>
</div>
</div>
)
})
}
Expand All @@ -81,7 +112,7 @@ const ClassList: FC<Props> = ({
/>
)}

</div>
</ReactSortable>
)
}
export default React.memo(ClassList)
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({
handleVisionResolutionChange,
handleVisionResolutionEnabledChange,
filterVar,
handleSortTopic,
} = useConfig(id, data)

const model = inputs.model
Expand Down Expand Up @@ -99,6 +100,7 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({
onChange={handleTopicsChange}
readonly={readOnly}
filterVar={filterVar}
handleSortTopic={handleSortTopic}
/>
</Field>
<Split />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import {
import { useStore } from '../../store'
import useAvailableVarList from '../_base/hooks/use-available-var-list'
import useConfigVision from '../../hooks/use-config-vision'
import type { QuestionClassifierNodeType } from './types'
import type { QuestionClassifierNodeType, Topic } from './types'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
import { useUpdateNodeInternals } from 'reactflow'

const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
const updateNodeInternals = useUpdateNodeInternals()
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const isChatMode = useIsChatMode()
const defaultConfig = useStore(s => s.nodesDefaultConfigs)[payload.type]
Expand Down Expand Up @@ -166,6 +168,17 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
return varPayload.type === VarType.string
}, [])

const handleSortTopic = useCallback((newTopics: (Topic & { id: string })[]) => {
const newInputs = produce(inputs, (draft) => {
draft.classes = newTopics.filter(Boolean).map(item => ({
id: item.id,
name: item.name,
}))
})
setInputs(newInputs)
updateNodeInternals(id)
}, [id, inputs, setInputs, updateNodeInternals])

return {
readOnly,
inputs,
Expand All @@ -185,6 +198,7 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
isVisionModel,
handleVisionResolutionEnabledChange,
handleVisionResolutionChange,
handleSortTopic,
}
}

Expand Down
Loading