Skip to content

Commit cb3fc87

Browse files
committed
feat(flow): add shared useEditFlow hook
1 parent 8279143 commit cb3fc87

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { NodeType } from '@emqx/shared-ui-constants'
2+
import { unionBy } from 'lodash'
3+
import { Ref, ref } from 'vue'
4+
import useFlowNode from './useFlowNode'
5+
import useGenerateFlowDataUtils from './useGenerateFlowDataUtils'
6+
import type { Edge, Node } from '@vue-flow/core'
7+
import type { AICompletionProfile, AIProviderForm, GroupedNode } from '../types'
8+
9+
export default (): {
10+
initialAIData: Ref<{
11+
provider: Array<string>
12+
completion: Array<string>
13+
}>
14+
addAIRecordDataToNodes: (
15+
nodes: Node[],
16+
getAICompletionProfileDetail: (name: string) => Promise<AICompletionProfile>,
17+
getAIProviderDetail: (name: string) => Promise<AIProviderForm>,
18+
) => Promise<Node[]>
19+
updateInitialAIDataAfterRemoveAINode: (
20+
uselessProvider: Array<string>,
21+
uselessCompletion: Array<string>,
22+
) => void
23+
addFallbackDataToFlow: (
24+
nodes: GroupedNode,
25+
edges: Array<Edge>,
26+
generateFlowDataFromActionItem: (action: any) => {
27+
nodes: GroupedNode
28+
edges: Array<Edge>
29+
},
30+
) => { nodes: GroupedNode; edges: Edge[] }
31+
} => {
32+
const { isBridgerNode, isAIType } = useFlowNode()
33+
const { addAIRecordToAINode } = useGenerateFlowDataUtils()
34+
35+
/**
36+
* for remove useless AI data when submit
37+
*/
38+
const initialAIData = ref<{
39+
provider: Array<string>
40+
completion: Array<string>
41+
}>({ provider: [], completion: [] })
42+
43+
const assignInitialAIData = (name: string, type: 'provider' | 'completion') => {
44+
if (!initialAIData.value[type].includes(name)) {
45+
initialAIData.value[type].push(name)
46+
}
47+
}
48+
49+
const addAIRecordDataToNodes = async (
50+
nodes: Array<Node>,
51+
getAICompletionProfileDetail: (name: string) => Promise<AICompletionProfile>,
52+
getAIProviderDetail: (name: string) => Promise<AIProviderForm>,
53+
) => {
54+
await Promise.allSettled(
55+
nodes.map(async (item) => {
56+
try {
57+
if (isAIType(item.data.specificType)) {
58+
const completion = await getAICompletionProfileDetail(item.data.formData?.name)
59+
assignInitialAIData(completion.name, 'completion')
60+
const provider = await getAIProviderDetail(completion.provider_name)
61+
assignInitialAIData(provider.name, 'provider')
62+
addAIRecordToAINode(item, provider, completion)
63+
}
64+
return Promise.resolve()
65+
} catch (error) {
66+
return Promise.reject()
67+
}
68+
}),
69+
)
70+
71+
return nodes
72+
}
73+
const updateInitialAIDataAfterRemoveAINode = (
74+
uselessProvider: Array<string>,
75+
uselessCompletion: Array<string>,
76+
) => {
77+
// Update initAIData to reflect current state after cleanup
78+
initialAIData.value.provider = initialAIData.value.provider.filter(
79+
(provider) => !uselessProvider.includes(provider),
80+
)
81+
initialAIData.value.completion = initialAIData.value.completion.filter(
82+
(completion) => !uselessCompletion.includes(completion),
83+
)
84+
}
85+
const addFallbackNodeToNodes = (fallbackNode: Node, nodes: GroupedNode) => {
86+
const sinkNodeIndex = nodes[NodeType.Sink].findIndex((item) => item.id === fallbackNode.id)
87+
if (sinkNodeIndex > -1) {
88+
nodes[NodeType.Sink].splice(sinkNodeIndex, 1)
89+
}
90+
if (!nodes[NodeType.Fallback]) {
91+
nodes[NodeType.Fallback] = []
92+
}
93+
nodes[NodeType.Fallback].push(fallbackNode)
94+
}
95+
const addFallbackDataToFlow = (
96+
nodes: GroupedNode,
97+
edges: Array<Edge>,
98+
generateFlowDataFromActionItem: (action: any) => {
99+
nodes: GroupedNode
100+
edges: Array<Edge>
101+
},
102+
) => {
103+
const retEdges = [...edges]
104+
const outputNodes = nodes[NodeType.Sink]
105+
for (let index = 0; index < outputNodes.length; index++) {
106+
const node = outputNodes[index]
107+
if (isBridgerNode(node) && node.data.isCreated) {
108+
const { nodes: fallbackNodes, edges: fallbackEdges } = generateFlowDataFromActionItem(
109+
node.data.formData,
110+
)
111+
if (fallbackEdges.length) {
112+
;(fallbackNodes[NodeType.Fallback] ?? []).forEach((item) => {
113+
addFallbackNodeToNodes(item, nodes)
114+
})
115+
retEdges.push(...fallbackEdges)
116+
}
117+
}
118+
}
119+
nodes[NodeType.Fallback] = unionBy(nodes[NodeType.Fallback], 'id')
120+
return { nodes, edges: retEdges }
121+
}
122+
123+
return {
124+
initialAIData,
125+
addAIRecordDataToNodes,
126+
updateInitialAIDataAfterRemoveAINode,
127+
addFallbackDataToFlow,
128+
}
129+
}

packages/components/flow/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import useActionAndSourceStatus from './composables/useActionAndSourceStatus'
1111
import FlowNode from './form/FlowNode.vue'
1212
import useFlowEdge from './composables/useFlowEdge'
1313
import useFlowEditorDataHandler from './composables/useFlowEditorDataHandler'
14+
import useEditFlow from './composables/useEditFlow'
1415

1516
interface FlowComponentOptions {
1617
componentPrefix?: string
@@ -44,6 +45,7 @@ export {
4445
useNodeForm,
4546
useFlowEdge,
4647
useFlowEditorDataHandler,
48+
useEditFlow,
4749
}
4850

4951
export * from './types'

packages/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ export {
3434
useNodeForm,
3535
useFlowEdge,
3636
useFlowEditorDataHandler,
37+
useEditFlow,
3738
} from './flow/index'
3839
export * from './flow/types'

0 commit comments

Comments
 (0)