mirror of https://github.com/langgenius/dify.git
layout
This commit is contained in:
parent
74d26764f8
commit
0acb2db9b6
|
|
@ -8,13 +8,13 @@ const initialNodes = [
|
|||
{
|
||||
id: '1',
|
||||
type: 'custom',
|
||||
position: { x: 130, y: 130 },
|
||||
position: { x: 0, y: 0 },
|
||||
data: { type: 'start' },
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'custom',
|
||||
position: { x: 434, y: 130 },
|
||||
position: { x: 0, y: 0 },
|
||||
data: {
|
||||
type: 'if-else',
|
||||
branches: [
|
||||
|
|
@ -32,21 +32,28 @@ const initialNodes = [
|
|||
{
|
||||
id: '3',
|
||||
type: 'custom',
|
||||
position: { x: 738, y: 130 },
|
||||
position: { x: 0, y: 0 },
|
||||
data: { type: 'question-classifier', sortIndexInBranches: 0 },
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
type: 'custom',
|
||||
position: { x: 738, y: 330 },
|
||||
data: { type: 'variable-assigner', sortIndexInBranches: 1 },
|
||||
position: { x: 0, y: 0 },
|
||||
data: {
|
||||
type: 'if-else',
|
||||
sortIndexInBranches: 1,
|
||||
branches: [
|
||||
{
|
||||
id: 'if-true',
|
||||
name: 'IS TRUE',
|
||||
},
|
||||
{
|
||||
id: 'if-false',
|
||||
name: 'IS FALSE',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// id: '5',
|
||||
// type: 'custom',
|
||||
// position: { x: 1100, y: 130 },
|
||||
// data: { type: 'llm' },
|
||||
// },
|
||||
]
|
||||
|
||||
const initialEdges = [
|
||||
|
|
@ -57,7 +64,6 @@ const initialEdges = [
|
|||
sourceHandle: 'source',
|
||||
target: '2',
|
||||
targetHandle: 'target',
|
||||
deletable: false,
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
|
|
|
|||
|
|
@ -16,10 +16,32 @@ import type {
|
|||
SelectedNode,
|
||||
} from './types'
|
||||
import { NodeInitialData } from './constants'
|
||||
import { getLayoutByDagre } from './utils'
|
||||
|
||||
export const useWorkflow = () => {
|
||||
const store = useStoreApi()
|
||||
|
||||
const handleLayout = useCallback(async () => {
|
||||
const {
|
||||
getNodes,
|
||||
edges,
|
||||
setNodes,
|
||||
} = store.getState()
|
||||
|
||||
const layout = getLayoutByDagre(getNodes(), edges)
|
||||
|
||||
const newNodes = produce(getNodes(), (draft) => {
|
||||
draft.forEach((node) => {
|
||||
const nodeWithPosition = layout.node(node.id)
|
||||
node.position = {
|
||||
x: nodeWithPosition.x,
|
||||
y: nodeWithPosition.y,
|
||||
}
|
||||
})
|
||||
})
|
||||
setNodes(newNodes)
|
||||
}, [store])
|
||||
|
||||
const handleEnterNode = useCallback<NodeMouseHandler>((_, node) => {
|
||||
const {
|
||||
getNodes,
|
||||
|
|
@ -112,7 +134,8 @@ export const useWorkflow = () => {
|
|||
return filtered
|
||||
})
|
||||
setEdges(newEdges)
|
||||
}, [store])
|
||||
handleLayout()
|
||||
}, [store, handleLayout])
|
||||
|
||||
const handleEnterEdge = useCallback<EdgeMouseHandler>((_, edge) => {
|
||||
const {
|
||||
|
|
@ -152,7 +175,8 @@ export const useWorkflow = () => {
|
|||
draft.splice(index, 1)
|
||||
})
|
||||
setEdges(newEdges)
|
||||
}, [store])
|
||||
handleLayout()
|
||||
}, [store, handleLayout])
|
||||
|
||||
const handleUpdateNodeData = useCallback(({ id, data }: SelectedNode) => {
|
||||
const {
|
||||
|
|
@ -182,7 +206,7 @@ export const useWorkflow = () => {
|
|||
data: NodeInitialData[nodeType],
|
||||
position: {
|
||||
x: currentNode.position.x + 304,
|
||||
y: currentNode.position.y,
|
||||
y: 0,
|
||||
},
|
||||
selected: true,
|
||||
}
|
||||
|
|
@ -289,5 +313,6 @@ export const useWorkflow = () => {
|
|||
handleAddNextNode,
|
||||
handleChangeCurrentNode,
|
||||
handleDeleteNode,
|
||||
handleLayout,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import ReactFlow, {
|
|||
useNodesState,
|
||||
} from 'reactflow'
|
||||
import 'reactflow/dist/style.css'
|
||||
import './style.css'
|
||||
import type {
|
||||
Edge,
|
||||
Node,
|
||||
|
|
@ -41,11 +42,6 @@ const Workflow: FC<WorkflowProps> = memo(({
|
|||
const [edges, _, onEdgesChange] = useEdgesState(initialEdges)
|
||||
const nodesInitialized = useNodesInitialized()
|
||||
|
||||
useEffect(() => {
|
||||
if (nodesInitialized)
|
||||
console.log('initialed')
|
||||
}, [nodesInitialized])
|
||||
|
||||
const {
|
||||
handleEnterNode,
|
||||
handleLeaveNode,
|
||||
|
|
@ -53,8 +49,14 @@ const Workflow: FC<WorkflowProps> = memo(({
|
|||
handleEnterEdge,
|
||||
handleLeaveEdge,
|
||||
handleDeleteEdge,
|
||||
handleLayout,
|
||||
} = useWorkflow()
|
||||
|
||||
useEffect(() => {
|
||||
if (nodesInitialized)
|
||||
handleLayout()
|
||||
}, [nodesInitialized, handleLayout])
|
||||
|
||||
useKeyPress('Backspace', handleDeleteEdge)
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
.react-flow__node {
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import {
|
|||
getConnectedEdges,
|
||||
getOutgoers,
|
||||
} from 'reactflow'
|
||||
import dagre from 'dagre'
|
||||
import type {
|
||||
Edge,
|
||||
Node,
|
||||
|
|
@ -118,3 +119,26 @@ export const getNodesPositionMap = (nodes: Node[], edges: Edge[]) => {
|
|||
|
||||
return positionMap
|
||||
}
|
||||
|
||||
export const getLayoutByDagre = (nodes: Node[], edges: Edge[]) => {
|
||||
const dagreGraph = new dagre.graphlib.Graph()
|
||||
dagreGraph.setGraph({
|
||||
rankdir: 'LR',
|
||||
align: 'UL',
|
||||
nodesep: 40,
|
||||
ranksep: 64,
|
||||
})
|
||||
nodes.forEach((node) => {
|
||||
dagreGraph.setNode(node.id, { width: node.width, height: node.height })
|
||||
})
|
||||
|
||||
edges.forEach((edge) => {
|
||||
dagreGraph.setEdge(edge.source, edge.target, {
|
||||
weight: edge?.data?.weight || 1,
|
||||
})
|
||||
})
|
||||
|
||||
dagre.layout(dagreGraph)
|
||||
|
||||
return dagreGraph
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
"classnames": "^2.3.2",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dagre": "^0.8.5",
|
||||
"dayjs": "^1.11.7",
|
||||
"echarts": "^5.4.1",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
|
|
@ -87,6 +88,7 @@
|
|||
"@faker-js/faker": "^7.6.0",
|
||||
"@rgrove/parse-xml": "^4.1.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/dagre": "^0.7.52",
|
||||
"@types/js-cookie": "^3.0.3",
|
||||
"@types/lodash-es": "^4.17.7",
|
||||
"@types/negotiator": "^0.6.1",
|
||||
|
|
|
|||
|
|
@ -919,6 +919,11 @@
|
|||
"@types/d3-transition" "*"
|
||||
"@types/d3-zoom" "*"
|
||||
|
||||
"@types/dagre@^0.7.52":
|
||||
version "0.7.52"
|
||||
resolved "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.52.tgz"
|
||||
integrity sha512-XKJdy+OClLk3hketHi9Qg6gTfe1F3y+UFnHxKA2rn9Dw+oXa4Gb378Ztz9HlMgZKSxpPmn4BNVh9wgkpvrK1uw==
|
||||
|
||||
"@types/debug@^4.0.0":
|
||||
version "4.1.8"
|
||||
resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz"
|
||||
|
|
@ -2289,6 +2294,14 @@ dagre-d3-es@7.0.10:
|
|||
d3 "^7.8.2"
|
||||
lodash-es "^4.17.21"
|
||||
|
||||
dagre@^0.8.5:
|
||||
version "0.8.5"
|
||||
resolved "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz"
|
||||
integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
|
||||
dependencies:
|
||||
graphlib "^2.1.8"
|
||||
lodash "^4.17.15"
|
||||
|
||||
damerau-levenshtein@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz"
|
||||
|
|
@ -3374,6 +3387,13 @@ graphemer@^1.4.0:
|
|||
resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz"
|
||||
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
|
||||
|
||||
graphlib@^2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz"
|
||||
integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
|
||||
dependencies:
|
||||
lodash "^4.17.15"
|
||||
|
||||
has-bigints@^1.0.1, has-bigints@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz"
|
||||
|
|
@ -4384,7 +4404,7 @@ lodash.values@^4.3.0:
|
|||
resolved "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz"
|
||||
integrity sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==
|
||||
|
||||
lodash@^4.17.21:
|
||||
lodash@^4.17.15, lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
|
|
|||
Loading…
Reference in New Issue