mirror of
https://github.com/langgenius/dify.git
synced 2026-04-29 20:48:01 +08:00
feat: change to new end node
This commit is contained in:
parent
d129d7951c
commit
d9edcb2250
@ -1,13 +1,9 @@
|
|||||||
import type { NodeDefault } from '../../types'
|
import type { NodeDefault } from '../../types'
|
||||||
import { type EndNodeType, EndVarType } from './types'
|
import { type EndNodeType } from './types'
|
||||||
|
|
||||||
const nodeDefault: NodeDefault<EndNodeType> = {
|
const nodeDefault: NodeDefault<EndNodeType> = {
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
outputs: {
|
outputs: [],
|
||||||
type: EndVarType.none,
|
|
||||||
plain_text_selector: [],
|
|
||||||
structured_variables: [],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
getAvailablePrevNodes() {
|
getAvailablePrevNodes() {
|
||||||
return []
|
return []
|
||||||
|
|||||||
@ -1,26 +1,80 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
|
||||||
import type { EndNodeType } from './types'
|
import type { EndNodeType } from './types'
|
||||||
import type { NodeProps } from '@/app/components/workflow/types'
|
import type { NodeProps, ValueSelector, Variable } from '@/app/components/workflow/types'
|
||||||
|
import { toNodeOutputVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||||||
const i18nPrefix = 'workflow.nodes.end'
|
import {
|
||||||
|
useIsChatMode,
|
||||||
|
useWorkflow,
|
||||||
|
} from '@/app/components/workflow/hooks'
|
||||||
|
import { VarBlockIcon } from '@/app/components/workflow/block-icon'
|
||||||
|
import { Line3 } from '@/app/components/base/icons/src/public/common'
|
||||||
|
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
||||||
|
import { BlockEnum, VarType } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
const Node: FC<NodeProps<EndNodeType>> = ({
|
const Node: FC<NodeProps<EndNodeType>> = ({
|
||||||
|
id,
|
||||||
data,
|
data,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { getBeforeNodesInSameBranch } = useWorkflow()
|
||||||
|
const availableNodes = getBeforeNodesInSameBranch(id)
|
||||||
|
const isChatMode = useIsChatMode()
|
||||||
|
const outputVars = toNodeOutputVars(availableNodes, isChatMode)
|
||||||
|
|
||||||
|
const getNode = (id: string) => {
|
||||||
|
return availableNodes.find(node => node.id === id)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getVarType = (nodeId: string, value: ValueSelector) => {
|
||||||
|
const targetVar = outputVars.find(v => v.nodeId === nodeId)
|
||||||
|
if (!targetVar)
|
||||||
|
return 'undefined'
|
||||||
|
|
||||||
|
let type: VarType = VarType.string
|
||||||
|
let curr: any = targetVar.vars;
|
||||||
|
(value).slice(1).forEach((key, i) => {
|
||||||
|
const isLast = i === value.length - 2
|
||||||
|
curr = curr.find((v: any) => v.variable === key)
|
||||||
|
if (isLast) {
|
||||||
|
type = curr.type
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (curr.type === VarType.object)
|
||||||
|
curr = curr.children
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return type
|
||||||
|
}
|
||||||
const { outputs } = data
|
const { outputs } = data
|
||||||
return (
|
return (
|
||||||
<div className='px-3'>
|
<div className='px-3'>
|
||||||
<div className='flex items-center h-6 justify-between bg-gray-100 rounded-md px-1 space-x-1 text-xs font-normal text-gray-700'>
|
{(outputs as Variable[]).map(({ value_selector }, index) => {
|
||||||
<div className='text-xs font-medium text-gray-500 uppercase'>
|
const node = getNode(value_selector[0])
|
||||||
{t(`${i18nPrefix}.outputs`)}
|
const varName = value_selector[value_selector.length - 1]
|
||||||
</div>
|
return (
|
||||||
<div className='text-xs font-normal text-gray-700'>
|
<div key={index} className='flex items-center h-6 justify-between bg-gray-100 rounded-md px-1 space-x-1 text-xs font-normal text-gray-700'>
|
||||||
{t(`${i18nPrefix}.type.${outputs.type}`)}
|
<div className='flex items-center text-xs font-medium text-gray-500'>
|
||||||
</div>
|
<div className='p-[1px]'>
|
||||||
</div>
|
<VarBlockIcon
|
||||||
|
className='!text-gray-900'
|
||||||
|
type={node?.data.type || BlockEnum.Tool}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>{node?.data.title}</div>
|
||||||
|
<Line3 className='mr-0.5'></Line3>
|
||||||
|
<div className='flex items-center text-primary-600'>
|
||||||
|
<Variable02 className='w-3.5 h-3.5' />
|
||||||
|
<div className='ml-0.5 text-xs font-medium'>{varName}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='text-xs font-normal text-gray-700'>
|
||||||
|
<div className='ml-0.5 text-xs font-normal text-gray-500 capitalize'>{getVarType(node?.id || '', value_selector)}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
import { type FC, useCallback } from 'react'
|
import { type FC } from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import cn from 'classnames'
|
|
||||||
import VarReferencePicker from '../_base/components/variable/var-reference-picker'
|
|
||||||
import useConfig from './use-config'
|
import useConfig from './use-config'
|
||||||
import type { EndNodeType } from './types'
|
import type { EndNodeType } from './types'
|
||||||
import { EndVarType } from './types'
|
|
||||||
import VarList from '@/app/components/workflow/nodes/_base/components/variable/var-list'
|
import VarList from '@/app/components/workflow/nodes/_base/components/variable/var-list'
|
||||||
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||||
import AddButton from '@/app/components/base/button/add-button'
|
import AddButton from '@/app/components/base/button/add-button'
|
||||||
@ -13,29 +10,6 @@ import { type NodePanelProps } from '@/app/components/workflow/types'
|
|||||||
|
|
||||||
const i18nPrefix = 'workflow.nodes.end'
|
const i18nPrefix = 'workflow.nodes.end'
|
||||||
|
|
||||||
const TypeItem = ({ type, current, onClick }: { type: EndVarType; current: EndVarType; onClick: (type: EndVarType) => void }) => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const handleOnClick = useCallback(() => {
|
|
||||||
if (type === current)
|
|
||||||
return
|
|
||||||
onClick(type)
|
|
||||||
}, [type, current, onClick])
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onClick={handleOnClick}
|
|
||||||
className={cn(
|
|
||||||
'grow flex items-center h-8 justify-center cursor-pointer rounded-lg bg-gray-25 text-[13px] font-normal text-gray-900',
|
|
||||||
type === current ? 'border-[1.5px] border-primary-400' : 'border border-gray-100',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{t(`${i18nPrefix}.type.${type}`)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const allTypes = [EndVarType.plainText, EndVarType.structured, EndVarType.none]
|
|
||||||
|
|
||||||
const Panel: FC<NodePanelProps<EndNodeType>> = ({
|
const Panel: FC<NodePanelProps<EndNodeType>> = ({
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
@ -45,9 +19,7 @@ const Panel: FC<NodePanelProps<EndNodeType>> = ({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
inputs,
|
inputs,
|
||||||
handleOutputTypeChange,
|
|
||||||
handleVarListChange,
|
handleVarListChange,
|
||||||
handelPlainTextSelectorChange,
|
|
||||||
handleAddVariable,
|
handleAddVariable,
|
||||||
} = useConfig(id, data)
|
} = useConfig(id, data)
|
||||||
|
|
||||||
@ -55,49 +27,20 @@ const Panel: FC<NodePanelProps<EndNodeType>> = ({
|
|||||||
return (
|
return (
|
||||||
<div className='mt-2'>
|
<div className='mt-2'>
|
||||||
<div className='px-4 pb-4 space-y-4'>
|
<div className='px-4 pb-4 space-y-4'>
|
||||||
<Field
|
|
||||||
title={t(`${i18nPrefix}.output.type`)}
|
|
||||||
>
|
|
||||||
<div className='flex space-x-2'>
|
|
||||||
{allTypes.map(type => (
|
|
||||||
<TypeItem
|
|
||||||
key={type}
|
|
||||||
type={type}
|
|
||||||
current={outputs.type}
|
|
||||||
onClick={handleOutputTypeChange}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Field>
|
|
||||||
{outputs.type !== EndVarType.none && (
|
|
||||||
<Field
|
|
||||||
title={t(`${i18nPrefix}.output.variable`)}
|
|
||||||
operations={
|
|
||||||
outputs.type === EndVarType.structured ? <AddButton onClick={handleAddVariable} /> : undefined
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{outputs.type
|
|
||||||
=== EndVarType.structured
|
|
||||||
? (
|
|
||||||
<VarList
|
|
||||||
nodeId={id}
|
|
||||||
readonly={readOnly}
|
|
||||||
list={outputs.structured_variables!}
|
|
||||||
onChange={handleVarListChange}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
: (
|
|
||||||
<VarReferencePicker
|
|
||||||
isShowNodeName
|
|
||||||
nodeId={id}
|
|
||||||
readonly={readOnly}
|
|
||||||
value={outputs.plain_text_selector!}
|
|
||||||
onChange={handelPlainTextSelectorChange}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</Field>
|
<Field
|
||||||
)}
|
title={t(`${i18nPrefix}.output.variable`)}
|
||||||
|
operations={
|
||||||
|
<AddButton onClick={handleAddVariable} />
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<VarList
|
||||||
|
nodeId={id}
|
||||||
|
readonly={readOnly}
|
||||||
|
list={outputs}
|
||||||
|
onChange={handleVarListChange}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,15 +1,5 @@
|
|||||||
import type { CommonNodeType, Variable } from '@/app/components/workflow/types'
|
import type { CommonNodeType, Variable } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
export enum EndVarType {
|
|
||||||
none = 'none',
|
|
||||||
plainText = 'plain-text',
|
|
||||||
structured = 'structured',
|
|
||||||
}
|
|
||||||
export type OutPuts = {
|
|
||||||
type: EndVarType
|
|
||||||
plain_text_selector?: string[]
|
|
||||||
structured_variables?: Variable[]
|
|
||||||
}
|
|
||||||
export type EndNodeType = CommonNodeType & {
|
export type EndNodeType = CommonNodeType & {
|
||||||
outputs: OutPuts
|
outputs: Variable[]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,21 @@
|
|||||||
import produce from 'immer'
|
|
||||||
import { useCallback } from 'react'
|
|
||||||
import useVarList from '../_base/hooks/use-var-list'
|
import useVarList from '../_base/hooks/use-var-list'
|
||||||
import type { EndNodeType, EndVarType, OutPuts } from './types'
|
import type { EndNodeType } from './types'
|
||||||
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
|
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
|
||||||
|
|
||||||
const useConfig = (id: string, payload: EndNodeType) => {
|
const useConfig = (id: string, payload: EndNodeType) => {
|
||||||
const { inputs, setInputs } = useNodeCrud<EndNodeType>(id, payload)
|
const { inputs, setInputs } = useNodeCrud<EndNodeType>(id, payload)
|
||||||
const handleOutputTypeChange = useCallback((type: EndVarType) => {
|
|
||||||
const newInputs = produce(inputs, (draft: any) => {
|
|
||||||
draft.outputs.type = type
|
|
||||||
})
|
|
||||||
setInputs(newInputs)
|
|
||||||
}, [inputs, setInputs])
|
|
||||||
|
|
||||||
const handelPlainTextSelectorChange = useCallback((newList: string[] | string) => {
|
const { handleVarListChange, handleAddVariable } = useVarList<EndNodeType>({
|
||||||
const newInputs = produce(inputs, (draft: any) => {
|
inputs,
|
||||||
draft.outputs.plain_text_selector = newList as string[]
|
setInputs: (newInputs) => {
|
||||||
})
|
|
||||||
setInputs(newInputs)
|
|
||||||
}
|
|
||||||
, [inputs, setInputs])
|
|
||||||
|
|
||||||
const { handleVarListChange, handleAddVariable } = useVarList<OutPuts>({
|
|
||||||
inputs: inputs.outputs,
|
|
||||||
setInputs: (newOutputs) => {
|
|
||||||
const newInputs = produce(inputs, (draft: any) => {
|
|
||||||
draft.outputs = newOutputs
|
|
||||||
})
|
|
||||||
setInputs(newInputs)
|
setInputs(newInputs)
|
||||||
},
|
},
|
||||||
varKey: 'structured_variables',
|
varKey: 'outputs',
|
||||||
})
|
})
|
||||||
|
console.log(inputs)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
inputs,
|
inputs,
|
||||||
handleOutputTypeChange,
|
|
||||||
handelPlainTextSelectorChange,
|
|
||||||
handleVarListChange,
|
handleVarListChange,
|
||||||
handleAddVariable,
|
handleAddVariable,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user