Compare commits

...

2 Commits

4 changed files with 80 additions and 2 deletions

View File

@@ -16,6 +16,7 @@ const {
getRoot,
resetRoot,
mockAddNodeOnGraph,
mockSelectItems,
mockSearchNode,
mockOrganizeNodes,
mockToggleNodeOnEvent
@@ -30,6 +31,7 @@ const {
capturedRoot = null
},
mockAddNodeOnGraph: vi.fn(),
mockSelectItems: vi.fn(),
mockSearchNode: vi.fn(() => []),
mockOrganizeNodes: vi.fn(
(): TreeNode => ({
@@ -46,6 +48,12 @@ vi.mock('@/services/litegraphService', () => ({
useLitegraphService: () => ({ addNodeOnGraph: mockAddNodeOnGraph })
}))
vi.mock('@/renderer/core/canvas/canvasStore', () => ({
useCanvasStore: () => ({
canvas: { selectItems: mockSelectItems }
})
}))
vi.mock('@/services/nodeOrganizationService', () => ({
DEFAULT_GROUPING_ID: 'group',
DEFAULT_SORTING_ID: 'sort',
@@ -203,6 +211,41 @@ describe('NodeLibrarySidebarTab', () => {
expect(mockAddNodeOnGraph).toHaveBeenCalledWith(mockNode)
})
it('selects the placed node so click placement matches drag (FE-564)', async () => {
const placedNode = { id: 42 }
mockAddNodeOnGraph.mockReturnValue(placedNode)
mockOrganizeNodes.mockReturnValue({
key: 'root',
label: 'Root',
children: [{ key: 'leaf', label: 'Leaf', leaf: true, data: mockNode }]
})
renderComponent()
await nextTick()
const leaf = getRoot().children?.[0]
await leaf?.handleClick?.(new MouseEvent('click'))
expect(mockSelectItems).toHaveBeenCalledWith([placedNode])
})
it('does not call selectItems when node creation fails', async () => {
mockAddNodeOnGraph.mockReturnValue(null)
mockOrganizeNodes.mockReturnValue({
key: 'root',
label: 'Root',
children: [{ key: 'leaf', label: 'Leaf', leaf: true, data: mockNode }]
})
renderComponent()
await nextTick()
const leaf = getRoot().children?.[0]
await leaf?.handleClick?.(new MouseEvent('click'))
expect(mockSelectItems).not.toHaveBeenCalled()
})
it('adds and removes filters', async () => {
const user = userEvent.setup()
renderComponent()

View File

@@ -189,6 +189,7 @@ import NodeTreeFolder from '@/components/sidebar/tabs/nodeLibrary/NodeTreeFolder
import NodeTreeLeaf from '@/components/sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue'
import Button from '@/components/ui/button/Button.vue'
import { useTreeExpansion } from '@/composables/useTreeExpansion'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useLitegraphService } from '@/services/litegraphService'
import {
DEFAULT_GROUPING_ID,
@@ -322,7 +323,8 @@ const renderedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(() => {
},
handleClick(e: MouseEvent) {
if (this.leaf && this.data) {
useLitegraphService().addNodeOnGraph(this.data)
const node = useLitegraphService().addNodeOnGraph(this.data)
if (node) useCanvasStore().canvas?.selectItems([node])
} else {
toggleNodeOnEvent(e, this)
}

View File

@@ -19,6 +19,7 @@ const {
mockIsBookmarked,
mockToggleBookmark,
mockAddNodeOnGraph,
mockSelectItems,
mockToggleNodeOnEvent,
captureRoot,
getRoot,
@@ -31,6 +32,7 @@ const {
mockIsBookmarked: vi.fn().mockReturnValue(false),
mockToggleBookmark: vi.fn(),
mockAddNodeOnGraph: vi.fn(),
mockSelectItems: vi.fn(),
mockToggleNodeOnEvent: vi.fn(),
captureRoot: (root: TreeExplorerNode<unknown>) => {
capturedRoot = root
@@ -101,6 +103,12 @@ vi.mock('@/services/litegraphService', () => ({
useLitegraphService: () => ({ addNodeOnGraph: mockAddNodeOnGraph })
}))
vi.mock('@/renderer/core/canvas/canvasStore', () => ({
useCanvasStore: () => ({
canvas: { selectItems: mockSelectItems }
})
}))
vi.mock('@/composables/useTreeExpansion', () => ({
useTreeExpansion: () => ({
expandNode: vi.fn(),
@@ -222,6 +230,29 @@ describe('NodeBookmarkTreeExplorer', () => {
expect(mockAddNodeOnGraph).toHaveBeenCalledWith(mockLeafNodeDef)
})
it('selects the placed node so click placement matches drag (FE-564)', async () => {
const placedNode = { id: 7 }
mockAddNodeOnGraph.mockReturnValue(placedNode)
const root = await renderAndGetRoot()
const leafNode = root.children?.[0].children?.[0]
await leafNode?.handleClick?.call(leafNode, new MouseEvent('click'))
expect(mockSelectItems).toHaveBeenCalledWith([placedNode])
})
it('does not call selectItems when node creation fails', async () => {
mockAddNodeOnGraph.mockReturnValue(null)
const root = await renderAndGetRoot()
const leafNode = root.children?.[0].children?.[0]
await leafNode?.handleClick?.call(leafNode, new MouseEvent('click'))
expect(mockSelectItems).not.toHaveBeenCalled()
})
it('toggles node expansion when a folder node is clicked', async () => {
const root = await renderAndGetRoot()
const folderNode = root.children?.[0]

View File

@@ -39,6 +39,7 @@ import NodePreview from '@/components/node/NodePreview.vue'
import NodeTreeFolder from '@/components/sidebar/tabs/nodeLibrary/NodeTreeFolder.vue'
import NodeTreeLeaf from '@/components/sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue'
import { useTreeExpansion } from '@/composables/useTreeExpansion'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useLitegraphService } from '@/services/litegraphService'
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
@@ -184,7 +185,8 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
},
handleClick(e: MouseEvent) {
if (this.leaf && this.data) {
useLitegraphService().addNodeOnGraph(this.data)
const placed = useLitegraphService().addNodeOnGraph(this.data)
if (placed) useCanvasStore().canvas?.selectItems([placed])
} else {
toggleNodeOnEvent(e, node)
}