mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-26 19:09:52 +00:00
Fix promoted assets not being assets in vue (#7576)
- Fixes asset widgets which have been promoted failing to display as asset widgets and having red names in vue mode. - Fixes promoted subgraph widgets failing to resolve inputSpec for use in vue mode. | Before | After | | ------ | ----- | | <img width="360" alt="before" src="https://github.com/user-attachments/assets/6c2d2763-6ac3-4769-82c5-b1ab1cc5e945"/> | <img width="360" alt="after" src="https://github.com/user-attachments/assets/742e218b-ec42-411a-b5a2-021820031e2a" />| I'm not excited that this creates further bloat of SimplifiedWidget. Known issue - Similar to #7550, subgraph widgets will have an incorrect callback and will fail to update value on a fresh reload. This can be "fixed" (made worse) by entering and exiting the subgraph. Since this creates a 'leaked' widget callback which will then be called. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7576-Fix-promoted-assets-not-being-assets-in-vue-2cc6d73d3650814b8734f69b225b0228) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -6,6 +6,7 @@ import { reactiveComputed } from '@vueuse/core'
|
||||
import { reactive, shallowReactive } from 'vue'
|
||||
|
||||
import { useChainCallback } from '@/composables/functional/useChainCallback'
|
||||
import { isProxyWidget } from '@/core/graph/subgraph/proxyWidget'
|
||||
import type {
|
||||
INodeInputSlot,
|
||||
INodeOutputSlot
|
||||
@@ -42,14 +43,15 @@ export interface SafeWidgetData {
|
||||
name: string
|
||||
type: string
|
||||
value: WidgetValue
|
||||
label?: string
|
||||
options?: IWidgetOptions<unknown>
|
||||
borderStyle?: string
|
||||
callback?: ((value: unknown) => void) | undefined
|
||||
controlWidget?: SafeControlWidget
|
||||
isDOMWidget?: boolean
|
||||
label?: string
|
||||
nodeType?: string
|
||||
options?: IWidgetOptions<unknown>
|
||||
spec?: InputSpec
|
||||
slotMetadata?: WidgetSlotMetadata
|
||||
isDOMWidget?: boolean
|
||||
controlWidget?: SafeControlWidget
|
||||
borderStyle?: string
|
||||
}
|
||||
|
||||
export interface VueNodeData {
|
||||
@@ -96,6 +98,11 @@ function getControlWidget(widget: IBaseWidget): SafeControlWidget | undefined {
|
||||
update: (value) => (cagWidget.value = normalizeControlOption(value))
|
||||
}
|
||||
}
|
||||
function getNodeType(node: LGraphNode, widget: IBaseWidget) {
|
||||
if (!node.isSubgraphNode() || !isProxyWidget(widget)) return undefined
|
||||
const subNode = node.subgraph.getNodeById(widget._overlay.nodeId)
|
||||
return subNode?.type
|
||||
}
|
||||
|
||||
export function safeWidgetMapper(
|
||||
node: LGraphNode,
|
||||
@@ -131,12 +138,13 @@ export function safeWidgetMapper(
|
||||
value: value,
|
||||
borderStyle,
|
||||
callback: widget.callback,
|
||||
controlWidget: getControlWidget(widget),
|
||||
isDOMWidget: isDOMWidget(widget),
|
||||
label: widget.label,
|
||||
nodeType: getNodeType(node, widget),
|
||||
options: widget.options,
|
||||
spec,
|
||||
slotMetadata: slotInfo,
|
||||
controlWidget: getControlWidget(widget)
|
||||
slotMetadata: slotInfo
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
|
||||
@@ -168,12 +168,13 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
name: widget.name,
|
||||
type: widget.type,
|
||||
value: widget.value,
|
||||
label: widget.label,
|
||||
options: widgetOptions,
|
||||
callback: widget.callback,
|
||||
spec: widget.spec,
|
||||
borderStyle: widget.borderStyle,
|
||||
controlWidget: widget.controlWidget
|
||||
callback: widget.callback,
|
||||
controlWidget: widget.controlWidget,
|
||||
label: widget.label,
|
||||
nodeType: widget.nodeType,
|
||||
options: widgetOptions,
|
||||
spec: widget.spec
|
||||
}
|
||||
|
||||
function updateHandler(value: WidgetValue) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<WidgetSelectDropdown
|
||||
v-if="isDropdownUIWidget"
|
||||
v-bind="props"
|
||||
v-model="modelValue"
|
||||
:widget
|
||||
:node-type="widget.nodeType ?? nodeType"
|
||||
:asset-kind="assetKind"
|
||||
:allow-upload="allowUpload"
|
||||
:upload-folder="uploadFolder"
|
||||
@@ -100,10 +101,9 @@ const isAssetMode = computed(() => {
|
||||
if (isCloud) {
|
||||
const settingStore = useSettingStore()
|
||||
const isUsingAssetAPI = settingStore.get('Comfy.Assets.UseAssetAPI')
|
||||
const isEligible = assetService.isAssetBrowserEligible(
|
||||
props.nodeType,
|
||||
props.widget.name
|
||||
)
|
||||
const isEligible =
|
||||
assetService.isAssetBrowserEligible(props.nodeType, props.widget.name) ||
|
||||
props.widget.type === 'asset'
|
||||
|
||||
return isUsingAssetAPI && isEligible
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import _ from 'es-toolkit/compat'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { isProxyWidget } from '@/core/graph/subgraph/proxyWidget'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { transformNodeDefV1ToV2 } from '@/schemas/nodeDef/migration'
|
||||
import type {
|
||||
@@ -358,10 +359,21 @@ export const useNodeDefStore = defineStore('nodeDef', () => {
|
||||
node: LGraphNode,
|
||||
widgetName: string
|
||||
): InputSpecV2 | undefined {
|
||||
const nodeDef = fromLGraphNode(node)
|
||||
if (!nodeDef) return undefined
|
||||
if (!node.isSubgraphNode()) {
|
||||
const nodeDef = fromLGraphNode(node)
|
||||
if (!nodeDef) return undefined
|
||||
|
||||
return nodeDef.inputs[widgetName]
|
||||
return nodeDef.inputs[widgetName]
|
||||
}
|
||||
const widget = node.widgets?.find((w) => w.name === widgetName)
|
||||
//TODO: resolve spec for linked
|
||||
if (!widget || !isProxyWidget(widget)) return undefined
|
||||
|
||||
const { nodeId, widgetName: subWidgetName } = widget._overlay
|
||||
const subNode = node.subgraph.getNodeById(nodeId)
|
||||
if (!subNode) return undefined
|
||||
|
||||
return getInputSpecForWidget(subNode, subWidgetName)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,6 +64,9 @@ export interface SimplifiedWidget<
|
||||
/** Widget options including filtered PrimeVue props */
|
||||
options?: O
|
||||
|
||||
/** Override for use with subgraph promoted asset widgets*/
|
||||
nodeType?: string
|
||||
|
||||
/** Optional serialization method for custom value handling */
|
||||
serializeValue?: () => any
|
||||
|
||||
|
||||
Reference in New Issue
Block a user