Skip to content

Commit 5cfda91

Browse files
feat(agentflow): Node Info Icon on Toolbar Action (FLOWISE-375) (#6053)
- Reintroduced NodeInfoDialog component with improved structure and functionality. - Added new properties (badge, tags, documentation) to NodeData interface for better metadata handling. - Updated flowExport and nodeFactory utilities to preserve new metadata during data processing. - Implemented tests for NodeInfoDialog to ensure proper rendering and functionality. - Adjusted Jest configuration to include coverage for the new NodeInfoDialog component.
1 parent 6f325b0 commit 5cfda91

15 files changed

Lines changed: 744 additions & 65 deletions

File tree

packages/agentflow/jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module.exports = {
5454
'./src/features/canvas/components/ConnectionLine.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
5555
// Only getMinimumNodeHeight() is tested; the component is Tier 3 UI with no business logic
5656
'./src/features/canvas/components/NodeOutputHandles.tsx': { branches: 0, functions: 10, lines: 30, statements: 30 },
57+
'./src/features/canvas/containers/NodeInfoDialog.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
5758
'./src/features/canvas/hooks/': { branches: 80, functions: 80, lines: 80, statements: 80 },
5859
'./src/features/generator/GenerateFlowDialog.tsx': { branches: 80, functions: 80, lines: 80, statements: 80 },
5960
'./src/features/node-editor/': { branches: 80, functions: 80, lines: 80, statements: 80 },

packages/agentflow/src/core/types/node.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ export interface NodeData {
2121
icon?: string
2222
selected?: boolean
2323
hideInput?: boolean
24+
// Metadata from component definition
25+
badge?: string
26+
tags?: string[]
27+
documentation?: string
2428
// Status properties
2529
status?: 'INPROGRESS' | 'FINISHED' | 'ERROR' | 'STOPPED' | 'TERMINATED'
2630
error?: string
@@ -86,6 +90,16 @@ export interface InputParam {
8690
codeExample?: string // Example code snippet shown via an "Example" button
8791
}
8892

93+
export interface NodeConfigEntry {
94+
node: string
95+
nodeId: string
96+
label: string
97+
name: string
98+
type: string
99+
enabled?: boolean
100+
schema?: Record<string, string> | Array<{ name: string; type: string }>
101+
}
102+
89103
export interface EdgeData {
90104
sourceColor?: string
91105
targetColor?: string

packages/agentflow/src/core/utils/flowExport.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function pickExportNodeData(data: NodeData): NodeData {
2121
color: data.color,
2222
hideInput: data.hideInput,
2323
baseClasses: data.baseClasses,
24+
tags: data.tags,
2425
category: data.category,
2526
description: data.description,
2627
inputs: data.inputs,

packages/agentflow/src/core/utils/nodeFactory.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,17 @@ describe('initNode', () => {
223223
badge: 'NEW',
224224
author: 'Flowise',
225225
documentation: 'https://docs.example.com',
226+
tags: ['LLM', 'OpenAI'],
226227
loadMethods: { listModels: () => Promise.resolve([]) }
227228
} as Partial<NodeData>)
228229
const result = initNode(nodeData, 'n1')
229230
expect(result).not.toHaveProperty('filePath')
230-
expect(result).not.toHaveProperty('badge')
231231
expect(result).not.toHaveProperty('author')
232-
expect(result).not.toHaveProperty('documentation')
233232
expect(result).not.toHaveProperty('loadMethods')
233+
// badge, tags, documentation are preserved for NodeInfoDialog display
234+
expect(result.badge).toBe('NEW')
235+
expect(result.tags).toEqual(['LLM', 'OpenAI'])
236+
expect(result.documentation).toBe('https://docs.example.com')
234237
})
235238

236239
it('should strip runtime-only state from node data', () => {

packages/agentflow/src/core/utils/nodeFactory.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ function createAgentFlowOutputs(nodeData: NodeData, newNodeId: string): Array<{
9090

9191
/**
9292
* Pick only the properties that belong to NodeData from a server API response.
93-
* Strips server-only metadata (filePath, badge, author, loadMethods, etc.)
93+
* Strips server-only metadata (filePath, author, loadMethods, etc.)
9494
* and runtime-only state (status, error, warning, hint, validationErrors)
9595
* that should not be persisted in flow data.
9696
*
97-
* Mirrors the allowlist used by generateExportFlowData in agentflow v2
98-
* (packages/ui/src/utils/genericHelper.js).
97+
* Preserves component metadata needed at runtime (badge, tags, documentation)
98+
* for display in the NodeInfoDialog.
9999
*/
100100
function pickNodeData(raw: NodeData): NodeData {
101101
return {
@@ -114,7 +114,10 @@ function pickNodeData(raw: NodeData): NodeData {
114114
outputAnchors: raw.outputAnchors,
115115
color: raw.color,
116116
icon: raw.icon,
117-
hideInput: raw.hideInput
117+
hideInput: raw.hideInput,
118+
badge: raw.badge,
119+
tags: raw.tags,
120+
documentation: raw.documentation
118121
}
119122
}
120123

packages/agentflow/src/features/canvas/components/NodeInfoDialog.tsx

Lines changed: 0 additions & 38 deletions
This file was deleted.

packages/agentflow/src/features/canvas/components/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ export type { AgentflowHeaderProps } from './AgentflowHeader'
22
export { AgentflowHeader, createHeaderProps } from './AgentflowHeader'
33
export { ConnectionLine } from './ConnectionLine'
44
export { NodeIcon } from './NodeIcon'
5-
export { NodeInfoDialog } from './NodeInfoDialog'
65
export { NodeInputHandle } from './NodeInputHandle'
76
export { NodeModelConfigs } from './NodeModelConfigs'
87
export { getMinimumNodeHeight, NodeOutputHandles } from './NodeOutputHandles'

packages/agentflow/src/features/canvas/containers/AgentFlowNode.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type { NodeData } from '@/core/types'
77
import { useApiContext, useConfigContext } from '@/infrastructure/store'
88

99
import { NodeIcon } from '../components/NodeIcon'
10-
import { NodeInfoDialog } from '../components/NodeInfoDialog'
1110
import { NodeInputHandle } from '../components/NodeInputHandle'
1211
import { NodeModelConfigs } from '../components/NodeModelConfigs'
1312
import { getMinimumNodeHeight, NodeOutputHandles } from '../components/NodeOutputHandles'
@@ -17,6 +16,8 @@ import { useOpenNodeEditor } from '../hooks'
1716
import { useNodeColors } from '../hooks/useNodeColors'
1817
import { CardWrapper } from '../styled'
1918

19+
import { NodeInfoDialog } from './NodeInfoDialog'
20+
2021
/** Width of the node icon container in pixels (theme.spacing(6.25) = 50px) */
2122
const NODE_ICON_CONTAINER_WIDTH = 50
2223

@@ -118,14 +119,7 @@ function AgentFlowNodeComponent({ data }: AgentFlowNodeProps) {
118119
</Box>
119120
</CardWrapper>
120121

121-
<NodeInfoDialog
122-
open={showInfoDialog}
123-
onClose={() => setShowInfoDialog(false)}
124-
label={data.label}
125-
name={data.name}
126-
nodeId={data.id}
127-
description={data.description}
128-
/>
122+
<NodeInfoDialog open={showInfoDialog} onClose={() => setShowInfoDialog(false)} data={data} />
129123
</div>
130124
)
131125
}

packages/agentflow/src/features/canvas/containers/IterationNode.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import type { NodeData } from '@/core/types'
88
import { useAgentflowContext, useApiContext, useConfigContext } from '@/infrastructure/store'
99

1010
import { NodeIcon } from '../components/NodeIcon'
11-
import { NodeInfoDialog } from '../components/NodeInfoDialog'
1211
import { NodeInputHandle } from '../components/NodeInputHandle'
1312
import { getMinimumNodeHeight, NodeOutputHandles } from '../components/NodeOutputHandles'
1413
import { NodeStatusIndicator } from '../components/NodeStatusIndicator'
1514
import { NodeToolbarActions } from '../components/NodeToolbarActions'
1615
import { useNodeColors } from '../hooks/useNodeColors'
1716
import { CardWrapper } from '../styled'
1817

18+
import { NodeInfoDialog } from './NodeInfoDialog'
19+
1920
export interface IterationNodeProps {
2021
data: NodeData
2122
}
@@ -162,14 +163,7 @@ function IterationNodeComponent({ data }: IterationNodeProps) {
162163
</Box>
163164
</CardWrapper>
164165

165-
<NodeInfoDialog
166-
open={showInfoDialog}
167-
onClose={() => setShowInfoDialog(false)}
168-
label={data.label}
169-
name={data.name}
170-
nodeId={data.id}
171-
description={data.description}
172-
/>
166+
<NodeInfoDialog open={showInfoDialog} onClose={() => setShowInfoDialog(false)} data={data} />
173167
</div>
174168
)
175169
}

0 commit comments

Comments
 (0)