mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-01 03:31:58 +00:00
Typing: Slots in VueNodeData (#5759)
## Summary Replace the unknown type with the interface in Litegraph. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5759-Typing-Slots-in-VueNodeData-2786d73d36508194b286fad172b13c51) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -5,6 +5,8 @@
|
|||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
import { useChainCallback } from '@/composables/functional/useChainCallback'
|
import { useChainCallback } from '@/composables/functional/useChainCallback'
|
||||||
|
import type { INodeOutputSlot } from '@/lib/litegraph/src/interfaces'
|
||||||
|
import type { INodeInputSlot } from '@/lib/litegraph/src/interfaces'
|
||||||
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
|
import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations'
|
||||||
import { LayoutSource } from '@/renderer/core/layout/types'
|
import { LayoutSource } from '@/renderer/core/layout/types'
|
||||||
import type { WidgetValue } from '@/types/simplifiedWidget'
|
import type { WidgetValue } from '@/types/simplifiedWidget'
|
||||||
@@ -28,8 +30,8 @@ export interface VueNodeData {
|
|||||||
executing: boolean
|
executing: boolean
|
||||||
subgraphId?: string | null
|
subgraphId?: string | null
|
||||||
widgets?: SafeWidgetData[]
|
widgets?: SafeWidgetData[]
|
||||||
inputs?: unknown[]
|
inputs?: INodeInputSlot[]
|
||||||
outputs?: unknown[]
|
outputs?: INodeOutputSlot[]
|
||||||
hasErrors?: boolean
|
hasErrors?: boolean
|
||||||
flags?: {
|
flags?: {
|
||||||
collapsed?: boolean
|
collapsed?: boolean
|
||||||
|
|||||||
@@ -38,6 +38,11 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||||
|
import type {
|
||||||
|
INodeInputSlot,
|
||||||
|
INodeOutputSlot
|
||||||
|
} from '@/lib/litegraph/src/interfaces'
|
||||||
|
import { RenderShape } from '@/lib/litegraph/src/litegraph'
|
||||||
import NodeContent from '@/renderer/extensions/vueNodes/components/NodeContent.vue'
|
import NodeContent from '@/renderer/extensions/vueNodes/components/NodeContent.vue'
|
||||||
import NodeHeader from '@/renderer/extensions/vueNodes/components/NodeHeader.vue'
|
import NodeHeader from '@/renderer/extensions/vueNodes/components/NodeHeader.vue'
|
||||||
import NodeSlots from '@/renderer/extensions/vueNodes/components/NodeSlots.vue'
|
import NodeSlots from '@/renderer/extensions/vueNodes/components/NodeSlots.vue'
|
||||||
@@ -74,26 +79,29 @@ const nodeData = computed<VueNodeData>(() => {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const inputs = Object.entries(nodeDef.inputs || {})
|
const inputs: INodeInputSlot[] = Object.entries(nodeDef.inputs || {})
|
||||||
.filter(([_, input]) => !widgetStore.inputIsWidget(input))
|
.filter(([_, input]) => !widgetStore.inputIsWidget(input))
|
||||||
.map(([name, input]) => ({
|
.map(([name, input]) => ({
|
||||||
name,
|
name,
|
||||||
type: input.type,
|
type: input.type,
|
||||||
shape: input.isOptional ? 'HollowCircle' : undefined,
|
shape: input.isOptional ? RenderShape.HollowCircle : undefined,
|
||||||
boundingRect: [0, 0, 0, 0]
|
boundingRect: [0, 0, 0, 0],
|
||||||
|
link: null
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const outputs = (nodeDef.outputs || []).map((output) => {
|
const outputs: INodeOutputSlot[] = (nodeDef.outputs || []).map((output) => {
|
||||||
if (typeof output === 'string') {
|
if (typeof output === 'string') {
|
||||||
return {
|
return {
|
||||||
name: output,
|
name: output,
|
||||||
type: output,
|
type: output,
|
||||||
boundingRect: [0, 0, 0, 0]
|
boundingRect: [0, 0, 0, 0],
|
||||||
|
links: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...output,
|
...output,
|
||||||
boundingRect: [0, 0, 0, 0]
|
boundingRect: [0, 0, 0, 0],
|
||||||
|
links: []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import { type PropType, defineComponent } from 'vue'
|
|||||||
import { createI18n } from 'vue-i18n'
|
import { createI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||||
|
import type { INodeOutputSlot } from '@/lib/litegraph/src/interfaces'
|
||||||
|
import type { INodeInputSlot } from '@/lib/litegraph/src/interfaces'
|
||||||
import enMessages from '@/locales/en/main.json' with { type: 'json' }
|
import enMessages from '@/locales/en/main.json' with { type: 'json' }
|
||||||
|
|
||||||
import NodeSlots from './NodeSlots.vue'
|
import NodeSlots from './NodeSlots.vue'
|
||||||
@@ -94,15 +96,17 @@ describe('NodeSlots.vue', () => {
|
|||||||
const inputObjNoWidget = {
|
const inputObjNoWidget = {
|
||||||
name: 'objNoWidget',
|
name: 'objNoWidget',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
boundingRect: [0, 0, 0, 0]
|
boundingRect: new Float32Array([0, 0, 0, 0]),
|
||||||
|
link: null
|
||||||
}
|
}
|
||||||
const inputObjWithWidget = {
|
const inputObjWithWidget = {
|
||||||
name: 'objWithWidget',
|
name: 'objWithWidget',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
boundingRect: [0, 0, 0, 0],
|
boundingRect: new Float32Array([0, 0, 0, 0]),
|
||||||
widget: { name: 'objWithWidget' }
|
widget: { name: 'objWithWidget' },
|
||||||
|
link: null
|
||||||
}
|
}
|
||||||
const inputs = [inputObjNoWidget, inputObjWithWidget, 'stringInput']
|
const inputs: INodeInputSlot[] = [inputObjNoWidget, inputObjWithWidget]
|
||||||
|
|
||||||
const wrapper = mountSlots(makeNodeData({ inputs }))
|
const wrapper = mountSlots(makeNodeData({ inputs }))
|
||||||
|
|
||||||
@@ -143,8 +147,19 @@ describe('NodeSlots.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('maps outputs and passes correct indexes', () => {
|
it('maps outputs and passes correct indexes', () => {
|
||||||
const outputObj = { name: 'outA', type: 'any', boundingRect: [0, 0, 0, 0] }
|
const outputObj = {
|
||||||
const outputs = [outputObj, 'outB']
|
name: 'outA',
|
||||||
|
type: 'any',
|
||||||
|
boundingRect: new Float32Array([0, 0, 0, 0]),
|
||||||
|
links: []
|
||||||
|
}
|
||||||
|
const outputObjB = {
|
||||||
|
name: 'outB',
|
||||||
|
type: 'any',
|
||||||
|
boundingRect: new Float32Array([0, 0, 0, 0]),
|
||||||
|
links: []
|
||||||
|
}
|
||||||
|
const outputs: INodeOutputSlot[] = [outputObj, outputObjB]
|
||||||
|
|
||||||
const wrapper = mountSlots(makeNodeData({ outputs }))
|
const wrapper = mountSlots(makeNodeData({ outputs }))
|
||||||
const outputEls = wrapper
|
const outputEls = wrapper
|
||||||
@@ -174,7 +189,7 @@ describe('NodeSlots.vue', () => {
|
|||||||
|
|
||||||
it('passes readonly to child slots', () => {
|
it('passes readonly to child slots', () => {
|
||||||
const wrapper = mountSlots(
|
const wrapper = mountSlots(
|
||||||
makeNodeData({ inputs: ['a'], outputs: ['b'] }),
|
makeNodeData({ inputs: [], outputs: [] }),
|
||||||
/* readonly */ true
|
/* readonly */ true
|
||||||
)
|
)
|
||||||
const all = [
|
const all = [
|
||||||
|
|||||||
Reference in New Issue
Block a user