feat(web): 增加节点分组
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import {type Connection, type Edge, getOutgoers, type Node} from '@xyflow/react'
|
||||
import {find, has, isEmpty, isEqual, lpad, toStr} from 'licia'
|
||||
import NodeRegistry from './NodeRegistry.tsx'
|
||||
import {NodeRegistryMap} from './NodeRegistry.tsx'
|
||||
|
||||
export class CheckError extends Error {
|
||||
readonly id: string
|
||||
@@ -83,7 +83,7 @@ export const checkSave: (inputSchema: Record<string, Record<string, any>>, nodes
|
||||
throw nodeTypeNotFound()
|
||||
}
|
||||
let nodeType = node.type!
|
||||
let nodeDefine = NodeRegistry[nodeType]
|
||||
let nodeDefine = NodeRegistryMap[nodeType]
|
||||
for (let checker of nodeDefine.checkers) {
|
||||
let checkResult = checker(nodeId, inputSchema, nodes, edges, data)
|
||||
if (checkResult.error) {
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import {PlusCircleFilled, RollbackOutlined, SaveFilled} from '@ant-design/icons'
|
||||
import {Background, BackgroundVariant, Controls, MiniMap, ReactFlow} from '@xyflow/react'
|
||||
import {Button, Dropdown, message, Popconfirm, Space} from 'antd'
|
||||
import {arrToMap, randomId} from 'licia'
|
||||
import {arrToMap, isEqual, randomId, unique} from 'licia'
|
||||
import {useEffect} from 'react'
|
||||
import {useNavigate} from 'react-router'
|
||||
import styled from 'styled-components'
|
||||
import '@xyflow/react/dist/style.css'
|
||||
import {commonInfo} from '../../util/amis.tsx'
|
||||
import {checkAddConnection, checkAddNode, checkSave} from './FlowChecker.tsx'
|
||||
import NodeRegistry from './NodeRegistry.tsx'
|
||||
import {NodeRegistry, NodeRegistryMap} from './NodeRegistry.tsx'
|
||||
import {useContextStore} from './store/ContextStore.ts'
|
||||
import {useDataStore} from './store/DataStore.ts'
|
||||
import {useFlowStore} from './store/FlowStore.ts'
|
||||
@@ -88,7 +88,13 @@ function FlowEditor(props: FlowEditorProps) {
|
||||
<Space className="toolbar">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: Object.keys(NodeRegistry).map(key => ({key: key, label: NodeRegistry[key]!.name})),
|
||||
items: unique(NodeRegistry.map(i => i.group))
|
||||
.map(group => ({
|
||||
type: 'group',
|
||||
label: group,
|
||||
children: NodeRegistry.filter(i => isEqual(group, i.group))
|
||||
.map(i => ({key: i.key, label: i.name}))
|
||||
})),
|
||||
onClick: ({key}) => {
|
||||
try {
|
||||
if (commonInfo.debug) {
|
||||
@@ -97,7 +103,7 @@ function FlowEditor(props: FlowEditorProps) {
|
||||
checkAddNode(key, nodes, edges)
|
||||
|
||||
let nodeId = randomId(10, 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM')
|
||||
let define = NodeRegistry[key]
|
||||
let define = NodeRegistryMap[key]
|
||||
|
||||
setDataById(
|
||||
nodeId,
|
||||
@@ -171,7 +177,7 @@ function FlowEditor(props: FlowEditorProps) {
|
||||
}
|
||||
}}
|
||||
// @ts-ignore
|
||||
nodeTypes={arrToMap(Object.keys(NodeRegistry), key => NodeRegistry[key]!.component)}
|
||||
nodeTypes={arrToMap(Object.keys(NodeRegistryMap), key => NodeRegistryMap[key]!.component)}
|
||||
>
|
||||
<Controls/>
|
||||
<MiniMap/>
|
||||
|
||||
@@ -14,7 +14,7 @@ const inputVariableChecker: NodeChecker = (id, inputSchema, nodes, edges, data)
|
||||
if (!isEmpty(inputs)) {
|
||||
let outputVariables = new Set([
|
||||
...getAllIncomerNodeOutputVariables(id, nodes, edges, data).map(i => `${i.id}.${i.variable}`),
|
||||
...Object.keys(inputSchema)
|
||||
...Object.keys(inputSchema),
|
||||
])
|
||||
for (const key of Object.keys(inputs)) {
|
||||
let variable = inputs[key]?.variable ?? ''
|
||||
@@ -31,43 +31,55 @@ const inputVariableChecker: NodeChecker = (id, inputSchema, nodes, edges, data)
|
||||
}
|
||||
|
||||
type NodeDefine = {
|
||||
key: string,
|
||||
group: string,
|
||||
name: string,
|
||||
description: string,
|
||||
component: any,
|
||||
checkers: NodeChecker[],
|
||||
}
|
||||
|
||||
const NodeRegistry: Record<string, NodeDefine> = {
|
||||
'output-node': {
|
||||
name: '输出',
|
||||
description: '定义输出变量',
|
||||
component: OutputNode,
|
||||
checkers: [inputVariableChecker],
|
||||
},
|
||||
'llm-node': {
|
||||
export const NodeRegistry: NodeDefine[] = [
|
||||
{
|
||||
key: 'llm-node',
|
||||
group: '普通节点',
|
||||
name: '大模型',
|
||||
description: '使用大模型对话',
|
||||
component: LlmNode,
|
||||
checkers: [inputVariableChecker],
|
||||
},
|
||||
'knowledge-node': {
|
||||
{
|
||||
key: 'knowledge-node',
|
||||
group: '普通节点',
|
||||
name: '知识库',
|
||||
description: '',
|
||||
component: KnowledgeNode,
|
||||
checkers: [inputVariableChecker],
|
||||
},
|
||||
'code-node': {
|
||||
{
|
||||
key: 'code-node',
|
||||
group: '普通节点',
|
||||
name: '代码执行',
|
||||
description: '执行自定义的处理代码',
|
||||
component: CodeNode,
|
||||
checkers: [inputVariableChecker],
|
||||
},
|
||||
'switch-node': {
|
||||
name: '分支节点',
|
||||
{
|
||||
key: 'switch-node',
|
||||
group: '逻辑节点',
|
||||
name: '分支',
|
||||
description: '根据不同的情况前往不同的分支',
|
||||
component: SwitchNode,
|
||||
checkers: [],
|
||||
},
|
||||
}
|
||||
{
|
||||
key: 'output-node',
|
||||
group: '输出节点',
|
||||
name: '输出',
|
||||
description: '定义输出变量',
|
||||
component: OutputNode,
|
||||
checkers: [inputVariableChecker],
|
||||
},
|
||||
]
|
||||
|
||||
export default NodeRegistry
|
||||
export const NodeRegistryMap: Record<string, NodeDefine> = NodeRegistry.reduce((a, v) => ({...a, [v.key]: v}), {})
|
||||
|
||||
Reference in New Issue
Block a user