fix: Show title, inputs, and outputs on Vue node component even when node fails to initalize (e.g., if missing) (#5540)

* add missing node error border

* update vue node data after configure

* [refactor] extract node type resolution to named const - addresses @DrJKL's readability concern

Extracted the multi-fallback type resolution logic into a clearly named
variable for improved readability and maintainability.

* [refactor] convert watch to computed pattern - addresses @DrJKL's structure comment

Replaced ref + watch pattern with computed for displayTitle, providing cleaner
reactive behavior and eliminating the need for manual sync logic.
This commit is contained in:
Christian Byrne
2025-09-13 22:17:22 -07:00
committed by GitHub
parent 8804755ffa
commit aa7a99f4e3
2 changed files with 27 additions and 18 deletions

View File

@@ -202,10 +202,17 @@ export const useGraphNodeManager = (graph: LGraph): GraphNodeManager => {
}
})
const nodeType =
node.type ||
node.constructor?.comfyClass ||
node.constructor?.title ||
node.constructor?.name ||
'Unknown'
return {
id: String(node.id),
title: node.title || 'Untitled',
type: node.type || 'Unknown',
title: typeof node.title === 'string' ? node.title : '',
type: nodeType,
mode: node.mode || 0,
selected: node.selected || false,
executing: false, // Will be updated separately based on execution state
@@ -612,7 +619,7 @@ export const useGraphNodeManager = (graph: LGraph): GraphNodeManager => {
// Set up widget callbacks BEFORE extracting data (critical order)
setupNodeWidgetCallbacks(node)
// Extract safe data for Vue
// Extract initial data for Vue (may be incomplete during graph configure)
vueNodeData.set(id, extractVueNodeData(node))
// Set up reactive tracking state
@@ -657,7 +664,11 @@ export const useGraphNodeManager = (graph: LGraph): GraphNodeManager => {
// Chain our callback with any existing onAfterGraphConfigured callback
node.onAfterGraphConfigured = useChainCallback(
node.onAfterGraphConfigured,
initializeVueNodeLayout
() => {
// Re-extract data now that configure() has populated title/slots/widgets/etc.
vueNodeData.set(id, extractVueNodeData(node))
initializeVueNodeLayout()
}
)
} else {
// Not during workflow loading - initialize layout immediately

View File

@@ -36,7 +36,7 @@
</template>
<script setup lang="ts">
import { computed, onErrorCaptured, ref, watch } from 'vue'
import { computed, onErrorCaptured, ref } from 'vue'
import EditableText from '@/components/common/EditableText.vue'
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
@@ -74,18 +74,18 @@ const isEditing = ref(false)
const nodeInfo = computed(() => props.nodeData || props.node)
// Local state for title to provide immediate feedback
const displayTitle = ref(nodeInfo.value?.title || 'Untitled')
const EMPTY_STRING = ''
const DEFAULT_TITLE = 'Untitled'
// Watch for external changes to the node title
watch(
() => nodeInfo.value?.title,
(newTitle) => {
if (newTitle && newTitle !== displayTitle.value) {
displayTitle.value = newTitle
}
}
)
const resolveTitle = (info: LGraphNode | VueNodeData | undefined) => {
const title = (info?.title ?? EMPTY_STRING).trim()
if (title.length > 0) return title
const type = (info?.type ?? EMPTY_STRING).trim()
return type.length > 0 ? type : DEFAULT_TITLE
}
// Computed title that provides reactive updates
const displayTitle = computed(() => resolveTitle(nodeInfo.value))
// Event handlers
const handleCollapse = () => {
@@ -109,7 +109,5 @@ const handleTitleEdit = (newTitle: string) => {
const handleTitleCancel = () => {
isEditing.value = false
// Reset displayTitle to the current node title
displayTitle.value = nodeInfo.value?.title || 'Untitled'
}
</script>