| 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 | ||||
| gradientBorder = true, | gradientBorder = true, | ||||
| titleTooltip, | titleTooltip, | ||||
| inputClassName, | inputClassName, | ||||
| placeholder, | |||||
| placeholderClassName, | placeholderClassName, | ||||
| titleClassName, | titleClassName, | ||||
| editorContainerClassName, | editorContainerClassName, | ||||
| <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 |
| 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() | ||||
| 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 | |||||
| isInNode | |||||
| title={<div> | |||||
| <div className='w-[200px]'> | |||||
| <div | |||||
| className='text-xs font-semibold leading-4 text-gray-700' | |||||
| > | |||||
| {`${t(`${i18nPrefix}.class`)} ${index}`} | |||||
| </div> | |||||
| </div> | |||||
| </div>} | |||||
| <Editor | |||||
| title={`${t(`${i18nPrefix}.class`)} ${index}`} | |||||
| placeholder={t(`${i18nPrefix}.topicPlaceholder`)!} | |||||
| value={payload.name} | value={payload.name} | ||||
| onChange={handleNameChange} | onChange={handleNameChange} | ||||
| placeholder={t(`${i18nPrefix}.topicPlaceholder`)!} | |||||
| headerRight={( | |||||
| <div className='flex h-full items-center'> | |||||
| <div className='text-xs font-medium text-gray-500'>{payload.name.length}</div> | |||||
| <div className='mx-3 h-3 w-px bg-gray-200'></div> | |||||
| {!readonly && ( | |||||
| <RiDeleteBinLine | |||||
| className='mr-1 h-3.5 w-3.5 cursor-pointer text-gray-500' | |||||
| onClick={onRemove} | |||||
| /> | |||||
| )} | |||||
| </div> | |||||
| )} | |||||
| readonly={readonly} | |||||
| minHeight={64} | |||||
| showRemove | |||||
| onRemove={onRemove} | |||||
| nodesOutputVars={availableVars} | |||||
| availableNodes={availableNodesWithParent} | |||||
| readOnly={readonly} // ? | |||||
| justVar // ? | |||||
| isSupportFileVar // ? | |||||
| /> | /> | ||||
| ) | ) | ||||
| } | } |
| 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() | ||||
| 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 ( | ||||
| 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} | |||||
| /> | /> | ||||
| ) | ) | ||||
| }) | }) |
| 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 | ||||
| > | > | ||||
| <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} |
| 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 /> |