feat(web): 完成分支节点动态改变handle
This commit is contained in:
@@ -88,7 +88,7 @@ type AmisNodeProps = {
|
||||
nodeProps: NodeProps
|
||||
extraNodeDescription?: JSX.Element
|
||||
handler: JSX.Element
|
||||
columnSchema?: () => Schema[]
|
||||
columnSchema?: Schema[]
|
||||
resize?: { minWidth: number, minHeight: number }
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ const AmisNode: (props: AmisNodeProps) => JSX.Element = ({
|
||||
{
|
||||
type: 'divider',
|
||||
},
|
||||
...(columnSchema?.() ?? []),
|
||||
...(columnSchema ?? []),
|
||||
{
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
@@ -221,7 +221,7 @@ const AmisNode: (props: AmisNodeProps) => JSX.Element = ({
|
||||
),
|
||||
)
|
||||
setEditDrawerOpen(true)
|
||||
}, [nodeData])
|
||||
}, [id])
|
||||
const onRemoveClick = useCallback(() => {
|
||||
removeNode(id)
|
||||
removeDataById(id)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type {NodeProps} from '@xyflow/react'
|
||||
import {Tag} from 'antd'
|
||||
import React, {useCallback} from 'react'
|
||||
import React, {useMemo} from 'react'
|
||||
import {useContextStore} from '../store/ContextStore.ts'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
import {useFlowStore} from '../store/FlowStore.ts'
|
||||
@@ -19,7 +19,7 @@ const CodeNode = (props: NodeProps) => {
|
||||
|
||||
const nodeData = getDataById(props.id)
|
||||
|
||||
const columnsSchema = useCallback(() => [
|
||||
const columnsSchema = useMemo(() => [
|
||||
...inputsFormColumns(props.id, getInputSchema(), getNodes(), getEdges(), getData()),
|
||||
{
|
||||
type: 'divider',
|
||||
@@ -47,18 +47,21 @@ const CodeNode = (props: NodeProps) => {
|
||||
},
|
||||
...outputsFormColumns(true, true),
|
||||
], [props.id])
|
||||
|
||||
const extraNodeDescription = useMemo(() => {
|
||||
return nodeData?.type
|
||||
? <div className="mt-2 flex justify-between">
|
||||
<span>代码类型</span>
|
||||
<Tag className="m-0" color="blue">{languageMap[nodeData.type]}</Tag>
|
||||
</div>
|
||||
: <></>
|
||||
}, [nodeData])
|
||||
|
||||
return (
|
||||
<AmisNode
|
||||
className={nodeClassName('code')}
|
||||
nodeProps={props}
|
||||
extraNodeDescription={
|
||||
nodeData?.type
|
||||
? <div className="mt-2 flex justify-between">
|
||||
<span>代码类型</span>
|
||||
<Tag className="m-0" color="blue">{languageMap[nodeData.type]}</Tag>
|
||||
</div>
|
||||
: <></>
|
||||
}
|
||||
extraNodeDescription={extraNodeDescription}
|
||||
columnSchema={columnsSchema}
|
||||
handler={<NormalNodeHandler/>}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {NodeProps} from '@xyflow/react'
|
||||
import React, {useCallback, useEffect} from 'react'
|
||||
import React, {useEffect, useMemo} from 'react'
|
||||
import {commonInfo} from '../../../util/amis.tsx'
|
||||
import {useContextStore} from '../store/ContextStore.ts'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
@@ -24,7 +24,7 @@ const KnowledgeNode = (props: NodeProps) => {
|
||||
)
|
||||
}, [props.id])
|
||||
|
||||
const columnsSchema = useCallback(() => [
|
||||
const columnsSchema = useMemo(() => [
|
||||
...inputsFormColumns(props.id, getInputSchema(), getNodes(), getEdges(), getData()),
|
||||
{
|
||||
type: 'divider',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type {NodeProps} from '@xyflow/react'
|
||||
import {Tag} from 'antd'
|
||||
import React, {useCallback, useEffect} from 'react'
|
||||
import React, {useEffect, useMemo} from 'react'
|
||||
import {useContextStore} from '../store/ContextStore.ts'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
import {useFlowStore} from '../store/FlowStore.ts'
|
||||
@@ -31,7 +31,7 @@ const LlmNode = (props: NodeProps) => {
|
||||
)
|
||||
}, [props.id])
|
||||
|
||||
const columnsSchema = useCallback(() => [
|
||||
const columnsSchema = useMemo(() => [
|
||||
...inputsFormColumns(props.id, getInputSchema(), getNodes(), getEdges(), getData()),
|
||||
{
|
||||
type: 'divider',
|
||||
@@ -55,18 +55,21 @@ const LlmNode = (props: NodeProps) => {
|
||||
},
|
||||
...outputsFormColumns(false, true),
|
||||
], [props.id])
|
||||
|
||||
const extraNodeDescription = useMemo(() => {
|
||||
return nodeData?.model
|
||||
? <div className="mt-2 flex justify-between">
|
||||
<span>模型名称</span>
|
||||
<Tag className="m-0" color="blue">{modelMap[nodeData.model]}</Tag>
|
||||
</div>
|
||||
: <></>
|
||||
}, [nodeData])
|
||||
|
||||
return (
|
||||
<AmisNode
|
||||
className={nodeClassName('llm')}
|
||||
nodeProps={props}
|
||||
extraNodeDescription={
|
||||
nodeData?.model
|
||||
? <div className="mt-2 flex justify-between">
|
||||
<span>模型名称</span>
|
||||
<Tag className="m-0" color="blue">{modelMap[nodeData.model]}</Tag>
|
||||
</div>
|
||||
: <></>
|
||||
}
|
||||
extraNodeDescription={extraNodeDescription}
|
||||
columnSchema={columnsSchema}
|
||||
handler={<NormalNodeHandler/>}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {Background, BackgroundVariant, type NodeProps} from '@xyflow/react'
|
||||
import {classnames} from 'amis'
|
||||
import React, {useCallback, useEffect} from 'react'
|
||||
import React, {useEffect, useMemo} from 'react'
|
||||
import AddNodeButton from '../component/AddNodeButton.tsx'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
import {flowBackgroundColor, flowDotColor} from '../types.ts'
|
||||
@@ -22,7 +22,7 @@ const LoopNode = (props: NodeProps) => {
|
||||
)
|
||||
}, [props.id])
|
||||
|
||||
const columnsSchema = useCallback(() => [
|
||||
const columnsSchema = useMemo(() => [
|
||||
{
|
||||
type: 'switch',
|
||||
name: 'failFast',
|
||||
@@ -41,6 +41,26 @@ const LoopNode = (props: NodeProps) => {
|
||||
...outputsFormColumns(false, true),
|
||||
], [props.id])
|
||||
|
||||
const extraNodeDescription = useMemo(() => {
|
||||
return (
|
||||
<div className="nodrag relative w-full h-full" style={{minHeight: '211px'}}>
|
||||
<Background
|
||||
id={`loop-background-${props.id}`}
|
||||
className="rounded-xl"
|
||||
variant={BackgroundVariant.Cross}
|
||||
gap={20}
|
||||
size={3}
|
||||
style={{
|
||||
zIndex: 0,
|
||||
}}
|
||||
color={flowDotColor}
|
||||
bgColor={flowBackgroundColor}
|
||||
/>
|
||||
<AddNodeButton className="mt-2 ml-2" parent={props.id} onlyIcon/>
|
||||
</div>
|
||||
)
|
||||
}, [props.id])
|
||||
|
||||
return (
|
||||
<AmisNode
|
||||
className={classnames('w-full', 'h-full', nodeClassName('loop'))}
|
||||
@@ -49,23 +69,7 @@ const LoopNode = (props: NodeProps) => {
|
||||
minHeight: '290px',
|
||||
}}
|
||||
nodeProps={props}
|
||||
extraNodeDescription={
|
||||
<div className="nodrag relative w-full h-full" style={{minHeight: '211px'}}>
|
||||
<Background
|
||||
id={`loop-background-${props.id}`}
|
||||
className="rounded-xl"
|
||||
variant={BackgroundVariant.Cross}
|
||||
gap={20}
|
||||
size={3}
|
||||
style={{
|
||||
zIndex: 0,
|
||||
}}
|
||||
color={flowDotColor}
|
||||
bgColor={flowBackgroundColor}
|
||||
/>
|
||||
<AddNodeButton className="mt-2 ml-2" parent={props.id} onlyIcon/>
|
||||
</div>
|
||||
}
|
||||
extraNodeDescription={extraNodeDescription}
|
||||
columnSchema={columnsSchema}
|
||||
handler={<NormalNodeHandler/>}
|
||||
resize={{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {NodeProps} from '@xyflow/react'
|
||||
import React, {useCallback} from 'react'
|
||||
import React, {useMemo} from 'react'
|
||||
import {generateAllIncomerOutputVariablesFormOptions} from '../Helper.tsx'
|
||||
import {useContextStore} from '../store/ContextStore.ts'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
@@ -11,7 +11,7 @@ const OutputNode = (props: NodeProps) => {
|
||||
const {getData} = useDataStore()
|
||||
const {getInputSchema} = useContextStore()
|
||||
|
||||
const columnsSchema = useCallback(
|
||||
const columnsSchema = useMemo(
|
||||
() => [
|
||||
{
|
||||
type: 'select',
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
import {Handle, type NodeProps, Position} from '@xyflow/react'
|
||||
import type {ConditionValue} from 'amis'
|
||||
import {Tag} from 'antd'
|
||||
import React, {useCallback} from 'react'
|
||||
import {contain, isEqual} from 'licia'
|
||||
import React, {useMemo} from 'react'
|
||||
import {generateAllIncomerOutputVariablesConditions} from '../Helper.tsx'
|
||||
import {useContextStore} from '../store/ContextStore.ts'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
import {useFlowStore} from '../store/FlowStore.ts'
|
||||
import AmisNode, {nodeClassName} from './AmisNode.tsx'
|
||||
|
||||
const cases = [
|
||||
{
|
||||
index: 1,
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
},
|
||||
{
|
||||
index: 3,
|
||||
},
|
||||
]
|
||||
|
||||
const SwitchNode = (props: NodeProps) => {
|
||||
const {getNodes, getEdges} = useFlowStore()
|
||||
const {getData} = useDataStore()
|
||||
const {getNodes, getEdges, removeEdges} = useFlowStore()
|
||||
const {getData, getDataById} = useDataStore()
|
||||
const {getInputSchema} = useContextStore()
|
||||
|
||||
const columnsSchema = useCallback(() => [
|
||||
const nodeData = getDataById(props.id)
|
||||
// @ts-ignore
|
||||
const conditions: ConditionValue[] = nodeData?.conditions?.map(c => c.condition) ?? []
|
||||
|
||||
const columnsSchema = useMemo(() => [
|
||||
{
|
||||
type: 'combo',
|
||||
name: 'conditions',
|
||||
@@ -45,38 +39,55 @@ const SwitchNode = (props: NodeProps) => {
|
||||
getData(),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
], [props.id])
|
||||
|
||||
const extraNodeDescription = useMemo(() => {
|
||||
return (
|
||||
<div className="mt-2">
|
||||
{conditions.map((item, index) => (
|
||||
<div key={item.id} className="mt-1">
|
||||
<Tag className="m-0" color="blue">分支 {index + 1}</Tag>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}, [nodeData])
|
||||
|
||||
const handler = useMemo(() => {
|
||||
// @ts-ignore
|
||||
const conditions: ConditionValue[] = nodeData?.conditions?.map(c => c.condition) ?? []
|
||||
|
||||
// 移除不该存在的边
|
||||
const conditionIds = conditions.map(c => c.id)
|
||||
const removeEdgeIds = getEdges()
|
||||
.filter(edge => isEqual(edge.source, props.id) && !contain(conditionIds, edge.sourceHandle))
|
||||
.map(edge => edge.id)
|
||||
removeEdges(removeEdgeIds)
|
||||
return (
|
||||
<>
|
||||
<Handle type="target" position={Position.Left}/>
|
||||
{conditions.map((item, index) => (
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
style={{top: 91 + (26 * index)}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}, [nodeData])
|
||||
|
||||
return (
|
||||
<AmisNode
|
||||
className={nodeClassName('switch')}
|
||||
nodeProps={props}
|
||||
extraNodeDescription={
|
||||
<div className="mt-2">
|
||||
{cases.map(item => (
|
||||
<div key={item.index} className="mt-1">
|
||||
<Tag className="m-0" color="blue">分支 {item.index}</Tag>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
extraNodeDescription={extraNodeDescription}
|
||||
columnSchema={columnsSchema}
|
||||
handler={
|
||||
<>
|
||||
<Handle type="target" position={Position.Left}/>
|
||||
{cases.map((item, index) => (
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
key={item.index}
|
||||
id={`${item.index}`}
|
||||
style={{top: 85 + (25 * index)}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
handler={handler}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type {NodeProps} from '@xyflow/react'
|
||||
import {Tag} from 'antd'
|
||||
import React, {useCallback, useEffect} from 'react'
|
||||
import React, {useEffect, useMemo} from 'react'
|
||||
import {useContextStore} from '../store/ContextStore.ts'
|
||||
import {useDataStore} from '../store/DataStore.ts'
|
||||
import {useFlowStore} from '../store/FlowStore.ts'
|
||||
@@ -33,7 +33,7 @@ const TemplateNode = (props: NodeProps) => {
|
||||
)
|
||||
}, [props.id])
|
||||
|
||||
const columnsSchema = useCallback(
|
||||
const columnsSchema = useMemo(
|
||||
() => [
|
||||
...inputsFormColumns(props.id, getInputSchema(), getNodes(), getEdges(), getData()),
|
||||
{
|
||||
@@ -69,22 +69,22 @@ const TemplateNode = (props: NodeProps) => {
|
||||
},
|
||||
},
|
||||
...outputsFormColumns(false, true),
|
||||
],
|
||||
[props.id],
|
||||
)
|
||||
], [props.id])
|
||||
|
||||
const extraNodeDescription = useMemo(() => {
|
||||
return nodeData?.type
|
||||
? <div className="mt-2 flex justify-between">
|
||||
<span>模板类型</span>
|
||||
<Tag className="m-0" color="blue">{typeMap[nodeData.type]}</Tag>
|
||||
</div>
|
||||
: <></>
|
||||
}, [nodeData])
|
||||
|
||||
return (
|
||||
<AmisNode
|
||||
className={nodeClassName('template')}
|
||||
nodeProps={props}
|
||||
extraNodeDescription={
|
||||
nodeData?.type
|
||||
? <div className="mt-2 flex justify-between">
|
||||
<span>模板类型</span>
|
||||
<Tag className="m-0" color="blue">{typeMap[nodeData.type]}</Tag>
|
||||
</div>
|
||||
: <></>
|
||||
}
|
||||
extraNodeDescription={extraNodeDescription}
|
||||
columnSchema={columnsSchema}
|
||||
handler={<NormalNodeHandler/>}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user