balibabu
commited on
Commit
·
e3322d7
1
Parent(s):
a24094f
feat: add FlowHeader and delete edge (#959)
Browse files### What problem does this PR solve?
feat: add FlowHeader and delete edge #918
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/package-lock.json +6 -0
- web/package.json +1 -0
- web/src/locales/zh-traditional.ts +1 -1
- web/src/pages/flow/canvas/context-menu/index.tsx +0 -3
- web/src/pages/flow/canvas/index.tsx +15 -10
- web/src/pages/flow/elk-hooks.ts +35 -0
- web/src/pages/flow/elk-utils.ts +42 -0
- web/src/pages/flow/header/index.less +3 -0
- web/src/pages/flow/header/index.tsx +26 -0
- web/src/pages/flow/hooks.ts +63 -2
- web/src/pages/flow/index.tsx +2 -0
- web/src/pages/flow/mock.tsx +94 -0
- web/src/pages/flow/utils.ts +5 -2
web/package-lock.json
CHANGED
@@ -16,6 +16,7 @@
|
|
16 |
"classnames": "^2.5.1",
|
17 |
"dagre": "^0.8.5",
|
18 |
"dayjs": "^1.11.10",
|
|
|
19 |
"eventsource-parser": "^1.1.2",
|
20 |
"i18next": "^23.7.16",
|
21 |
"i18next-browser-languagedetector": "^8.0.0",
|
@@ -11110,6 +11111,11 @@
|
|
11110 |
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.767.tgz",
|
11111 |
"integrity": "sha512-nzzHfmQqBss7CE3apQHkHjXW77+8w3ubGCIoEijKCJebPufREaFETgGXWTkh32t259F3Kcq+R8MZdFdOJROgYw=="
|
11112 |
},
|
|
|
|
|
|
|
|
|
|
|
11113 |
"node_modules/elliptic": {
|
11114 |
"version": "6.5.5",
|
11115 |
"resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.5.5.tgz",
|
|
|
16 |
"classnames": "^2.5.1",
|
17 |
"dagre": "^0.8.5",
|
18 |
"dayjs": "^1.11.10",
|
19 |
+
"elkjs": "^0.9.3",
|
20 |
"eventsource-parser": "^1.1.2",
|
21 |
"i18next": "^23.7.16",
|
22 |
"i18next-browser-languagedetector": "^8.0.0",
|
|
|
11111 |
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.767.tgz",
|
11112 |
"integrity": "sha512-nzzHfmQqBss7CE3apQHkHjXW77+8w3ubGCIoEijKCJebPufREaFETgGXWTkh32t259F3Kcq+R8MZdFdOJROgYw=="
|
11113 |
},
|
11114 |
+
"node_modules/elkjs": {
|
11115 |
+
"version": "0.9.3",
|
11116 |
+
"resolved": "https://registry.npmmirror.com/elkjs/-/elkjs-0.9.3.tgz",
|
11117 |
+
"integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ=="
|
11118 |
+
},
|
11119 |
"node_modules/elliptic": {
|
11120 |
"version": "6.5.5",
|
11121 |
"resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.5.5.tgz",
|
web/package.json
CHANGED
@@ -21,6 +21,7 @@
|
|
21 |
"classnames": "^2.5.1",
|
22 |
"dagre": "^0.8.5",
|
23 |
"dayjs": "^1.11.10",
|
|
|
24 |
"eventsource-parser": "^1.1.2",
|
25 |
"i18next": "^23.7.16",
|
26 |
"i18next-browser-languagedetector": "^8.0.0",
|
|
|
21 |
"classnames": "^2.5.1",
|
22 |
"dagre": "^0.8.5",
|
23 |
"dayjs": "^1.11.10",
|
24 |
+
"elkjs": "^0.9.3",
|
25 |
"eventsource-parser": "^1.1.2",
|
26 |
"i18next": "^23.7.16",
|
27 |
"i18next-browser-languagedetector": "^8.0.0",
|
web/src/locales/zh-traditional.ts
CHANGED
@@ -24,7 +24,7 @@ export default {
|
|
24 |
copied: '複製成功',
|
25 |
comingSoon: '即將推出',
|
26 |
download: '下載',
|
27 |
-
close: '
|
28 |
preview: '預覽',
|
29 |
},
|
30 |
login: {
|
|
|
24 |
copied: '複製成功',
|
25 |
comingSoon: '即將推出',
|
26 |
download: '下載',
|
27 |
+
close: '關閉',
|
28 |
preview: '預覽',
|
29 |
},
|
30 |
login: {
|
web/src/pages/flow/canvas/context-menu/index.tsx
CHANGED
@@ -84,9 +84,6 @@ export const useHandleNodeContextMenu = (sideWidth: number) => {
|
|
84 |
// event.clientY >= pane.height - 200 ? pane.height - event.clientY : 0,
|
85 |
// });
|
86 |
|
87 |
-
console.info('clientX:', event.clientX);
|
88 |
-
console.info('clientY:', event.clientY);
|
89 |
-
|
90 |
setMenu({
|
91 |
id: node.id,
|
92 |
top: event.clientY - 72,
|
|
|
84 |
// event.clientY >= pane.height - 200 ? pane.height - event.clientY : 0,
|
85 |
// });
|
86 |
|
|
|
|
|
|
|
87 |
setMenu({
|
88 |
id: node.id,
|
89 |
top: event.clientY - 72,
|
web/src/pages/flow/canvas/index.tsx
CHANGED
@@ -17,9 +17,13 @@ import 'reactflow/dist/style.css';
|
|
17 |
import { NodeContextMenu, useHandleNodeContextMenu } from './context-menu';
|
18 |
|
19 |
import FlowDrawer from '../flow-drawer';
|
20 |
-
import {
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
23 |
import { TextUpdaterNode } from './node';
|
24 |
|
25 |
const nodeTypes = { textUpdater: TextUpdaterNode };
|
@@ -29,13 +33,11 @@ interface IProps {
|
|
29 |
}
|
30 |
|
31 |
function FlowCanvas({ sideWidth }: IProps) {
|
32 |
-
const
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
const [nodes, setNodes] = useState<Node[]>(layoutedNodes);
|
38 |
-
const [edges, setEdges] = useState<Edge[]>(layoutedEdges);
|
39 |
const { ref, menu, onNodeContextMenu, onPaneClick } =
|
40 |
useHandleNodeContextMenu(sideWidth);
|
41 |
const { drawerVisible, hideDrawer, showDrawer } = useShowDrawer();
|
@@ -60,6 +62,8 @@ function FlowCanvas({ sideWidth }: IProps) {
|
|
60 |
|
61 |
const { onDrop, onDragOver, setReactFlowInstance } = useHandleDrop(setNodes);
|
62 |
|
|
|
|
|
63 |
useEffect(() => {
|
64 |
console.info('nodes:', nodes);
|
65 |
console.info('edges:', edges);
|
@@ -82,6 +86,7 @@ function FlowCanvas({ sideWidth }: IProps) {
|
|
82 |
onDragOver={onDragOver}
|
83 |
onNodeClick={onNodeClick}
|
84 |
onInit={setReactFlowInstance}
|
|
|
85 |
>
|
86 |
<Background />
|
87 |
<Controls />
|
|
|
17 |
import { NodeContextMenu, useHandleNodeContextMenu } from './context-menu';
|
18 |
|
19 |
import FlowDrawer from '../flow-drawer';
|
20 |
+
import {
|
21 |
+
useHandleDrop,
|
22 |
+
useHandleKeyUp,
|
23 |
+
useHandleSelectionChange,
|
24 |
+
useShowDrawer,
|
25 |
+
} from '../hooks';
|
26 |
+
import { dsl } from '../mock';
|
27 |
import { TextUpdaterNode } from './node';
|
28 |
|
29 |
const nodeTypes = { textUpdater: TextUpdaterNode };
|
|
|
33 |
}
|
34 |
|
35 |
function FlowCanvas({ sideWidth }: IProps) {
|
36 |
+
const [nodes, setNodes] = useState<Node[]>(dsl.graph.nodes);
|
37 |
+
const [edges, setEdges] = useState<Edge[]>(dsl.graph.edges);
|
38 |
+
|
39 |
+
const { selectedEdges, selectedNodes } = useHandleSelectionChange();
|
40 |
+
|
|
|
|
|
41 |
const { ref, menu, onNodeContextMenu, onPaneClick } =
|
42 |
useHandleNodeContextMenu(sideWidth);
|
43 |
const { drawerVisible, hideDrawer, showDrawer } = useShowDrawer();
|
|
|
62 |
|
63 |
const { onDrop, onDragOver, setReactFlowInstance } = useHandleDrop(setNodes);
|
64 |
|
65 |
+
const { handleKeyUp } = useHandleKeyUp(selectedEdges, selectedNodes);
|
66 |
+
|
67 |
useEffect(() => {
|
68 |
console.info('nodes:', nodes);
|
69 |
console.info('edges:', edges);
|
|
|
86 |
onDragOver={onDragOver}
|
87 |
onNodeClick={onNodeClick}
|
88 |
onInit={setReactFlowInstance}
|
89 |
+
onKeyUp={handleKeyUp}
|
90 |
>
|
91 |
<Background />
|
92 |
<Controls />
|
web/src/pages/flow/elk-hooks.ts
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { useCallback, useLayoutEffect } from 'react';
|
2 |
+
import { getLayoutedElements } from './elk-utils';
|
3 |
+
|
4 |
+
export const elkOptions = {
|
5 |
+
'elk.algorithm': 'layered',
|
6 |
+
'elk.layered.spacing.nodeNodeBetweenLayers': '100',
|
7 |
+
'elk.spacing.nodeNode': '80',
|
8 |
+
};
|
9 |
+
|
10 |
+
export const useLayoutGraph = (
|
11 |
+
initialNodes,
|
12 |
+
initialEdges,
|
13 |
+
setNodes,
|
14 |
+
setEdges,
|
15 |
+
) => {
|
16 |
+
const onLayout = useCallback(({ direction, useInitialNodes = false }) => {
|
17 |
+
const opts = { 'elk.direction': direction, ...elkOptions };
|
18 |
+
const ns = initialNodes;
|
19 |
+
const es = initialEdges;
|
20 |
+
|
21 |
+
getLayoutedElements(ns, es, opts).then(
|
22 |
+
({ nodes: layoutedNodes, edges: layoutedEdges }) => {
|
23 |
+
setNodes(layoutedNodes);
|
24 |
+
setEdges(layoutedEdges);
|
25 |
+
|
26 |
+
// window.requestAnimationFrame(() => fitView());
|
27 |
+
},
|
28 |
+
);
|
29 |
+
}, []);
|
30 |
+
|
31 |
+
// Calculate the initial layout on mount.
|
32 |
+
useLayoutEffect(() => {
|
33 |
+
onLayout({ direction: 'RIGHT', useInitialNodes: true });
|
34 |
+
}, [onLayout]);
|
35 |
+
};
|
web/src/pages/flow/elk-utils.ts
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import ELK from 'elkjs/lib/elk.bundled.js';
|
2 |
+
import { Edge, Node } from 'reactflow';
|
3 |
+
|
4 |
+
const elk = new ELK();
|
5 |
+
|
6 |
+
export const getLayoutedElements = (
|
7 |
+
nodes: Node[],
|
8 |
+
edges: Edge[],
|
9 |
+
options = {},
|
10 |
+
) => {
|
11 |
+
const isHorizontal = options?.['elk.direction'] === 'RIGHT';
|
12 |
+
const graph = {
|
13 |
+
id: 'root',
|
14 |
+
layoutOptions: options,
|
15 |
+
children: nodes.map((node) => ({
|
16 |
+
...node,
|
17 |
+
// Adjust the target and source handle positions based on the layout
|
18 |
+
// direction.
|
19 |
+
targetPosition: isHorizontal ? 'left' : 'top',
|
20 |
+
sourcePosition: isHorizontal ? 'right' : 'bottom',
|
21 |
+
|
22 |
+
// Hardcode a width and height for elk to use when layouting.
|
23 |
+
width: 150,
|
24 |
+
height: 50,
|
25 |
+
})),
|
26 |
+
edges: edges,
|
27 |
+
};
|
28 |
+
|
29 |
+
return elk
|
30 |
+
.layout(graph)
|
31 |
+
.then((layoutedGraph) => ({
|
32 |
+
nodes: layoutedGraph.children.map((node) => ({
|
33 |
+
...node,
|
34 |
+
// React Flow expects a position property on the node instead of `x`
|
35 |
+
// and `y` fields.
|
36 |
+
position: { x: node.x, y: node.y },
|
37 |
+
})),
|
38 |
+
|
39 |
+
edges: layoutedGraph.edges,
|
40 |
+
}))
|
41 |
+
.catch(console.error);
|
42 |
+
};
|
web/src/pages/flow/header/index.less
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
.flowHeader {
|
2 |
+
padding: 20px;
|
3 |
+
}
|
web/src/pages/flow/header/index.tsx
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Button, Flex } from 'antd';
|
2 |
+
|
3 |
+
import { useSaveGraph } from '../hooks';
|
4 |
+
import styles from './index.less';
|
5 |
+
|
6 |
+
const FlowHeader = () => {
|
7 |
+
const { saveGraph } = useSaveGraph();
|
8 |
+
|
9 |
+
return (
|
10 |
+
<Flex
|
11 |
+
align="center"
|
12 |
+
justify="end"
|
13 |
+
gap={'large'}
|
14 |
+
className={styles.flowHeader}
|
15 |
+
>
|
16 |
+
<Button>
|
17 |
+
<b>Debug</b>
|
18 |
+
</Button>
|
19 |
+
<Button type="primary" onClick={saveGraph}>
|
20 |
+
<b>Save</b>
|
21 |
+
</Button>
|
22 |
+
</Flex>
|
23 |
+
);
|
24 |
+
};
|
25 |
+
|
26 |
+
export default FlowHeader;
|
web/src/pages/flow/hooks.ts
CHANGED
@@ -1,6 +1,18 @@
|
|
1 |
import { useSetModalState } from '@/hooks/commonHooks';
|
2 |
-
import React, {
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import { v4 as uuidv4 } from 'uuid';
|
5 |
|
6 |
export const useHandleDrag = () => {
|
@@ -75,3 +87,52 @@ export const useShowDrawer = () => {
|
|
75 |
showDrawer,
|
76 |
};
|
77 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import { useSetModalState } from '@/hooks/commonHooks';
|
2 |
+
import React, {
|
3 |
+
Dispatch,
|
4 |
+
KeyboardEventHandler,
|
5 |
+
SetStateAction,
|
6 |
+
useCallback,
|
7 |
+
useState,
|
8 |
+
} from 'react';
|
9 |
+
import {
|
10 |
+
Node,
|
11 |
+
Position,
|
12 |
+
ReactFlowInstance,
|
13 |
+
useOnSelectionChange,
|
14 |
+
useReactFlow,
|
15 |
+
} from 'reactflow';
|
16 |
import { v4 as uuidv4 } from 'uuid';
|
17 |
|
18 |
export const useHandleDrag = () => {
|
|
|
87 |
showDrawer,
|
88 |
};
|
89 |
};
|
90 |
+
|
91 |
+
export const useHandleSelectionChange = () => {
|
92 |
+
const [selectedNodes, setSelectedNodes] = useState<string[]>([]);
|
93 |
+
const [selectedEdges, setSelectedEdges] = useState<string[]>([]);
|
94 |
+
|
95 |
+
useOnSelectionChange({
|
96 |
+
onChange: ({ nodes, edges }) => {
|
97 |
+
setSelectedNodes(nodes.map((node) => node.id));
|
98 |
+
setSelectedEdges(edges.map((edge) => edge.id));
|
99 |
+
},
|
100 |
+
});
|
101 |
+
|
102 |
+
return { selectedEdges, selectedNodes };
|
103 |
+
};
|
104 |
+
|
105 |
+
export const useDeleteEdge = (selectedEdges: string[]) => {
|
106 |
+
const { setEdges } = useReactFlow();
|
107 |
+
|
108 |
+
const deleteEdge = useCallback(() => {
|
109 |
+
setEdges((edges) =>
|
110 |
+
edges.filter((edge) => selectedEdges.every((x) => x !== edge.id)),
|
111 |
+
);
|
112 |
+
}, [setEdges, selectedEdges]);
|
113 |
+
|
114 |
+
return deleteEdge;
|
115 |
+
};
|
116 |
+
|
117 |
+
export const useHandleKeyUp = (
|
118 |
+
selectedEdges: string[],
|
119 |
+
selectedNodes: string[],
|
120 |
+
) => {
|
121 |
+
const deleteEdge = useDeleteEdge(selectedEdges);
|
122 |
+
const handleKeyUp: KeyboardEventHandler = useCallback(
|
123 |
+
(e) => {
|
124 |
+
if (e.code === 'Delete') {
|
125 |
+
deleteEdge();
|
126 |
+
}
|
127 |
+
},
|
128 |
+
[deleteEdge],
|
129 |
+
);
|
130 |
+
|
131 |
+
return { handleKeyUp };
|
132 |
+
};
|
133 |
+
|
134 |
+
export const useSaveGraph = () => {
|
135 |
+
const saveGraph = useCallback(() => {}, []);
|
136 |
+
|
137 |
+
return { saveGraph };
|
138 |
+
};
|
web/src/pages/flow/index.tsx
CHANGED
@@ -3,6 +3,7 @@ import { useState } from 'react';
|
|
3 |
import { ReactFlowProvider } from 'reactflow';
|
4 |
import FlowCanvas from './canvas';
|
5 |
import Sider from './flow-sider';
|
|
|
6 |
|
7 |
const { Content } = Layout;
|
8 |
|
@@ -14,6 +15,7 @@ function RagFlow() {
|
|
14 |
<ReactFlowProvider>
|
15 |
<Sider setCollapsed={setCollapsed} collapsed={collapsed}></Sider>
|
16 |
<Layout>
|
|
|
17 |
<Content style={{ margin: '0 16px' }}>
|
18 |
<FlowCanvas sideWidth={collapsed ? 0 : 200}></FlowCanvas>
|
19 |
</Content>
|
|
|
3 |
import { ReactFlowProvider } from 'reactflow';
|
4 |
import FlowCanvas from './canvas';
|
5 |
import Sider from './flow-sider';
|
6 |
+
import FlowHeader from './header';
|
7 |
|
8 |
const { Content } = Layout;
|
9 |
|
|
|
15 |
<ReactFlowProvider>
|
16 |
<Sider setCollapsed={setCollapsed} collapsed={collapsed}></Sider>
|
17 |
<Layout>
|
18 |
+
<FlowHeader></FlowHeader>
|
19 |
<Content style={{ margin: '0 16px' }}>
|
20 |
<FlowCanvas sideWidth={collapsed ? 0 : 200}></FlowCanvas>
|
21 |
</Content>
|
web/src/pages/flow/mock.tsx
CHANGED
@@ -45,6 +45,100 @@ export const initialEdges = [
|
|
45 |
];
|
46 |
|
47 |
export const dsl = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
components: {
|
49 |
begin: {
|
50 |
obj: {
|
|
|
45 |
];
|
46 |
|
47 |
export const dsl = {
|
48 |
+
graph: {
|
49 |
+
nodes: [
|
50 |
+
{
|
51 |
+
id: 'begin',
|
52 |
+
type: 'textUpdater',
|
53 |
+
position: {
|
54 |
+
x: 50,
|
55 |
+
y: 200,
|
56 |
+
},
|
57 |
+
data: {
|
58 |
+
label: 'Begin',
|
59 |
+
},
|
60 |
+
sourcePosition: 'left',
|
61 |
+
targetPosition: 'right',
|
62 |
+
},
|
63 |
+
{
|
64 |
+
id: 'Answer:China',
|
65 |
+
type: 'textUpdater',
|
66 |
+
position: {
|
67 |
+
x: 150,
|
68 |
+
y: 200,
|
69 |
+
},
|
70 |
+
data: {
|
71 |
+
label: 'Answer',
|
72 |
+
},
|
73 |
+
sourcePosition: 'left',
|
74 |
+
targetPosition: 'right',
|
75 |
+
},
|
76 |
+
{
|
77 |
+
id: 'Retrieval:China',
|
78 |
+
type: 'textUpdater',
|
79 |
+
position: {
|
80 |
+
x: 250,
|
81 |
+
y: 200,
|
82 |
+
},
|
83 |
+
data: {
|
84 |
+
label: 'Retrieval',
|
85 |
+
},
|
86 |
+
sourcePosition: 'left',
|
87 |
+
targetPosition: 'right',
|
88 |
+
},
|
89 |
+
{
|
90 |
+
id: 'Generate:China',
|
91 |
+
type: 'textUpdater',
|
92 |
+
position: {
|
93 |
+
x: 100,
|
94 |
+
y: 100,
|
95 |
+
},
|
96 |
+
data: {
|
97 |
+
label: 'Generate',
|
98 |
+
},
|
99 |
+
sourcePosition: 'left',
|
100 |
+
targetPosition: 'right',
|
101 |
+
},
|
102 |
+
],
|
103 |
+
edges: [
|
104 |
+
{
|
105 |
+
id: '7facb53d-65c9-43b3-ac55-339c445d3891',
|
106 |
+
label: '',
|
107 |
+
source: 'begin',
|
108 |
+
target: 'Answer:China',
|
109 |
+
markerEnd: {
|
110 |
+
type: 'arrow',
|
111 |
+
},
|
112 |
+
},
|
113 |
+
{
|
114 |
+
id: '7ac83631-502d-410f-a6e7-bec6866a5e99',
|
115 |
+
label: '',
|
116 |
+
source: 'Generate:China',
|
117 |
+
target: 'Answer:China',
|
118 |
+
markerEnd: {
|
119 |
+
type: 'arrow',
|
120 |
+
},
|
121 |
+
},
|
122 |
+
{
|
123 |
+
id: '0aaab297-5779-43ed-9281-2c4d3741566f',
|
124 |
+
label: '',
|
125 |
+
source: 'Answer:China',
|
126 |
+
target: 'Retrieval:China',
|
127 |
+
markerEnd: {
|
128 |
+
type: 'arrow',
|
129 |
+
},
|
130 |
+
},
|
131 |
+
{
|
132 |
+
id: '3477f9f3-0a7d-400e-af96-a11ea7673183',
|
133 |
+
label: '',
|
134 |
+
source: 'Retrieval:China',
|
135 |
+
target: 'Generate:China',
|
136 |
+
markerEnd: {
|
137 |
+
type: 'arrow',
|
138 |
+
},
|
139 |
+
},
|
140 |
+
],
|
141 |
+
},
|
142 |
components: {
|
143 |
begin: {
|
144 |
obj: {
|
web/src/pages/flow/utils.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
import { DSLComponents } from '@/interfaces/database/flow';
|
2 |
import dagre from 'dagre';
|
3 |
-
import { Edge, Node, Position } from 'reactflow';
|
4 |
import { v4 as uuidv4 } from 'uuid';
|
5 |
|
6 |
const buildEdges = (
|
@@ -16,9 +16,12 @@ const buildEdges = (
|
|
16 |
allEdges.push({
|
17 |
id: uuidv4(),
|
18 |
label: '',
|
19 |
-
type: 'step',
|
20 |
source: source,
|
21 |
target: target,
|
|
|
|
|
|
|
22 |
});
|
23 |
}
|
24 |
});
|
|
|
1 |
import { DSLComponents } from '@/interfaces/database/flow';
|
2 |
import dagre from 'dagre';
|
3 |
+
import { Edge, MarkerType, Node, Position } from 'reactflow';
|
4 |
import { v4 as uuidv4 } from 'uuid';
|
5 |
|
6 |
const buildEdges = (
|
|
|
16 |
allEdges.push({
|
17 |
id: uuidv4(),
|
18 |
label: '',
|
19 |
+
// type: 'step',
|
20 |
source: source,
|
21 |
target: target,
|
22 |
+
markerEnd: {
|
23 |
+
type: MarkerType.Arrow,
|
24 |
+
},
|
25 |
});
|
26 |
}
|
27 |
});
|