mirror of https://github.com/langgenius/dify.git
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 EndNodeType, EndVarType } from './types'
|
||||
import { type EndNodeType } from './types'
|
||||
|
||||
const nodeDefault: NodeDefault<EndNodeType> = {
|
||||
defaultValue: {
|
||||
outputs: {
|
||||
type: EndVarType.none,
|
||||
plain_text_selector: [],
|
||||
structured_variables: [],
|
||||
},
|
||||
outputs: [],
|
||||
},
|
||||
getAvailablePrevNodes() {
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -1,26 +1,80 @@
|
|||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import type { EndNodeType } from './types'
|
||||
import type { NodeProps } from '@/app/components/workflow/types'
|
||||
|
||||
const i18nPrefix = 'workflow.nodes.end'
|
||||
import type { NodeProps, ValueSelector, Variable } from '@/app/components/workflow/types'
|
||||
import { toNodeOutputVars } from '@/app/components/workflow/nodes/_base/components/variable/utils'
|
||||
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>> = ({
|
||||
id,
|
||||
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
|
||||
return (
|
||||
<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'>
|
||||
<div className='text-xs font-medium text-gray-500 uppercase'>
|
||||
{t(`${i18nPrefix}.outputs`)}
|
||||
</div>
|
||||
<div className='text-xs font-normal text-gray-700'>
|
||||
{t(`${i18nPrefix}.type.${outputs.type}`)}
|
||||
</div>
|
||||
</div>
|
||||
{(outputs as Variable[]).map(({ value_selector }, index) => {
|
||||
const node = getNode(value_selector[0])
|
||||
const varName = value_selector[value_selector.length - 1]
|
||||
return (
|
||||
<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'>
|
||||
<div className='flex items-center text-xs font-medium text-gray-500'>
|
||||
<div className='p-[1px]'>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
import { type FC, useCallback } from 'react'
|
||||
import { type FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import cn from 'classnames'
|
||||
import VarReferencePicker from '../_base/components/variable/var-reference-picker'
|
||||
import useConfig from './use-config'
|
||||
import type { EndNodeType } from './types'
|
||||
import { EndVarType } from './types'
|
||||
import VarList from '@/app/components/workflow/nodes/_base/components/variable/var-list'
|
||||
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||
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 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>> = ({
|
||||
id,
|
||||
data,
|
||||
|
|
@ -45,9 +19,7 @@ const Panel: FC<NodePanelProps<EndNodeType>> = ({
|
|||
|
||||
const {
|
||||
inputs,
|
||||
handleOutputTypeChange,
|
||||
handleVarListChange,
|
||||
handelPlainTextSelectorChange,
|
||||
handleAddVariable,
|
||||
} = useConfig(id, data)
|
||||
|
||||
|
|
@ -55,49 +27,20 @@ const Panel: FC<NodePanelProps<EndNodeType>> = ({
|
|||
return (
|
||||
<div className='mt-2'>
|
||||
<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>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,5 @@
|
|||
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 & {
|
||||
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 type { EndNodeType, EndVarType, OutPuts } from './types'
|
||||
import type { EndNodeType } from './types'
|
||||
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
|
||||
|
||||
const useConfig = (id: string, payload: EndNodeType) => {
|
||||
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 newInputs = produce(inputs, (draft: any) => {
|
||||
draft.outputs.plain_text_selector = newList as string[]
|
||||
})
|
||||
setInputs(newInputs)
|
||||
}
|
||||
, [inputs, setInputs])
|
||||
|
||||
const { handleVarListChange, handleAddVariable } = useVarList<OutPuts>({
|
||||
inputs: inputs.outputs,
|
||||
setInputs: (newOutputs) => {
|
||||
const newInputs = produce(inputs, (draft: any) => {
|
||||
draft.outputs = newOutputs
|
||||
})
|
||||
const { handleVarListChange, handleAddVariable } = useVarList<EndNodeType>({
|
||||
inputs,
|
||||
setInputs: (newInputs) => {
|
||||
setInputs(newInputs)
|
||||
},
|
||||
varKey: 'structured_variables',
|
||||
varKey: 'outputs',
|
||||
})
|
||||
console.log(inputs)
|
||||
|
||||
return {
|
||||
inputs,
|
||||
handleOutputTypeChange,
|
||||
handelPlainTextSelectorChange,
|
||||
handleVarListChange,
|
||||
handleAddVariable,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue