mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
fix RightSidePanel title not updating when litegraph node title changes
- Used `useVueNodeLifecycle` to allow reactive access to the title
This commit is contained in:
95
src/components/rightSidePanel/RightSidePanel.test.ts
Normal file
95
src/components/rightSidePanel/RightSidePanel.test.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { nextTick, shallowRef } from 'vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
import { useGraphNodeManager } from '@/composables/graph/useGraphNodeManager'
|
||||
import type { GraphNodeManager } from '@/composables/graph/useGraphNodeManager'
|
||||
import enMessages from '@/locales/en/main.json'
|
||||
import { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
|
||||
import RightSidePanel from './RightSidePanel.vue'
|
||||
|
||||
const mockNodeManager = shallowRef<GraphNodeManager | null>(null)
|
||||
|
||||
vi.mock('@/composables/graph/useVueNodeLifecycle', () => ({
|
||||
useVueNodeLifecycle: () => ({
|
||||
nodeManager: mockNodeManager
|
||||
})
|
||||
}))
|
||||
|
||||
// Mock useLayoutMutations (used by useGraphNodeManager)
|
||||
vi.mock('@/renderer/core/layout/operations/layoutMutations', () => ({
|
||||
useLayoutMutations: () => ({
|
||||
createNode: vi.fn(),
|
||||
setSource: vi.fn()
|
||||
})
|
||||
}))
|
||||
|
||||
const createMountConfig = () => {
|
||||
return {
|
||||
global: {
|
||||
stubs: {
|
||||
TabParameters: true
|
||||
},
|
||||
plugins: [
|
||||
createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages: { en: enMessages }
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setupGraph = () => {
|
||||
const graph = new LGraph()
|
||||
mockNodeManager.value = useGraphNodeManager(graph)
|
||||
return { graph, canvasStore: useCanvasStore() }
|
||||
}
|
||||
|
||||
describe('RightSidePanel', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia())
|
||||
mockNodeManager.value = null
|
||||
})
|
||||
|
||||
describe('title reactivity', () => {
|
||||
it('updates panel title when node.title changes', async () => {
|
||||
const { graph, canvasStore } = setupGraph()
|
||||
|
||||
const node = new LGraphNode('Original Title', 'TestNode')
|
||||
graph.add(node)
|
||||
canvasStore.selectedItems = [node]
|
||||
|
||||
const wrapper = mount(RightSidePanel, createMountConfig())
|
||||
await nextTick()
|
||||
expect(wrapper.text()).toContain('Original Title')
|
||||
|
||||
node.title = 'Updated Title'
|
||||
|
||||
await nextTick()
|
||||
expect(wrapper.text()).toContain('Updated Title')
|
||||
})
|
||||
|
||||
it('shows selection count message when multiple nodes are selected', async () => {
|
||||
const { graph, canvasStore } = setupGraph()
|
||||
|
||||
const node1 = new LGraphNode('Node 1', 'TestNode')
|
||||
const node2 = new LGraphNode('Node 2', 'TestNode')
|
||||
graph.add(node1)
|
||||
graph.add(node2)
|
||||
canvasStore.selectedItems = [node1, node2]
|
||||
|
||||
const wrapper = mount(RightSidePanel, createMountConfig())
|
||||
await nextTick()
|
||||
|
||||
expect(wrapper.text()).toContain('2')
|
||||
expect(wrapper.text()).not.toContain('Node 1')
|
||||
expect(wrapper.text()).not.toContain('Node 2')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -7,6 +7,7 @@ import EditableText from '@/components/common/EditableText.vue'
|
||||
import Tab from '@/components/tab/Tab.vue'
|
||||
import TabList from '@/components/tab/TabList.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
|
||||
import { SubgraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
@@ -24,6 +25,7 @@ import SubgraphEditor from './subgraph/SubgraphEditor.vue'
|
||||
const canvasStore = useCanvasStore()
|
||||
const rightSidePanelStore = useRightSidePanelStore()
|
||||
const settingStore = useSettingStore()
|
||||
const { nodeManager } = useVueNodeLifecycle()
|
||||
const { t } = useI18n()
|
||||
|
||||
const { selectedItems } = storeToRefs(canvasStore)
|
||||
@@ -58,9 +60,16 @@ const selectedNode = computed(() => {
|
||||
|
||||
const selectionCount = computed(() => selectedItems.value.length)
|
||||
|
||||
const selectedNodeTitle = computed(() => {
|
||||
if (!selectedNode.value) return null
|
||||
const nodeId = String(selectedNode.value.id)
|
||||
const nodeData = nodeManager.value?.vueNodeData.get(nodeId)
|
||||
return nodeData?.title || selectedNode.value.title || selectedNode.value.type
|
||||
})
|
||||
|
||||
const panelTitle = computed(() => {
|
||||
if (isSingleNodeSelected.value && selectedNode.value) {
|
||||
return selectedNode.value.title || selectedNode.value.type || 'Node'
|
||||
return selectedNodeTitle.value || 'Node'
|
||||
}
|
||||
return t('rightSidePanel.title', { count: selectionCount.value })
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user