feat: change to new end node

This commit is contained in:
Joel 2024-03-14 18:42:55 +08:00
parent d129d7951c
commit d9edcb2250
5 changed files with 90 additions and 127 deletions

View File

@ -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 []

View File

@ -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>
)
}

View File

@ -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>
)

View File

@ -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[]
}

View File

@ -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,
}