[backport core/1.41] feat: improve essentials tab blueprint support and display names (#10162)

Backport of #10113 to core/1.41.

Cherry-picked merge commit d6c1dd2e59.

Conflict resolved in
`src/components/sidebar/tabs/NodeLibrarySidebarTabV2.vue`: kept
core/1.41's `SearchBox` import (the PR's new component imports like
`Tab`, `TabList`, `TabPanel`, `SearchInput`, `Button`, `SidebarTopArea`
don't exist on core/1.41), while adding the PR's new
`resolveBlueprintSuffix` import.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10162-backport-core-1-41-feat-improve-essentials-tab-blueprint-support-and-display-names-3266d73d365081deb9b5cb459d3e2812)
by [Unito](https://www.unito.io)

Co-authored-by: Yourz <crazilou@vip.qq.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Christian Byrne
2026-03-17 01:49:32 -07:00
committed by GitHub
parent 06797faaed
commit 752290223b
24 changed files with 181 additions and 36 deletions

View File

@@ -179,7 +179,10 @@ import {
import { computed, nextTick, onMounted, ref, watchEffect } from 'vue'
import { useI18n } from 'vue-i18n'
import { resolveEssentialsDisplayName } from '@/constants/essentialsDisplayNames'
import {
resolveBlueprintSuffix,
resolveEssentialsDisplayName
} from '@/constants/essentialsDisplayNames'
import SearchBox from '@/components/common/SearchBoxV2.vue'
import { useFeatureFlags } from '@/composables/useFeatureFlags'
import { useNodeDragToCanvas } from '@/composables/node/useNodeDragToCanvas'
@@ -378,11 +381,38 @@ const essentialSections = computed(() => {
)
})
function disambiguateBlueprintLabels(
root: RenderedTreeExplorerNode<ComfyNodeDefImpl>
): RenderedTreeExplorerNode<ComfyNodeDefImpl> {
if (!root.children) return root
return {
...root,
children: root.children.map((folder) => {
if (folder.type !== 'folder' || !folder.children) return folder
const labelCounts = new Map<string, number>()
for (const node of folder.children) {
if (node.label)
labelCounts.set(node.label, (labelCounts.get(node.label) ?? 0) + 1)
}
return {
...folder,
children: folder.children.map((node) => {
if ((labelCounts.get(node.label ?? '') ?? 0) <= 1) return node
const suffix = resolveBlueprintSuffix(node.data?.name ?? '')
if (!suffix) return node
return { ...node, label: `${node.label} (${suffix})` }
})
}
})
}
}
const renderedEssentialRoot = computed(() => {
const section = essentialSections.value[0]
return section
const root = section
? fillNodeInfo(applySorting(section.tree), { useEssentialsLabels: true })
: fillNodeInfo({ key: 'root', label: '', children: [] })
return disambiguateBlueprintLabels(root)
})
function flattenRenderedLeaves(