tweaks + tests

This commit is contained in:
pythongosssss
2026-02-25 06:42:54 -08:00
parent d36e52d36f
commit 9435c1b2c3
6 changed files with 148 additions and 37 deletions

View File

@@ -12,7 +12,7 @@
</span>
<span
v-if="rest"
class="-ml-2.5 min-w-0 max-w-max grow-1 basis-0 truncate rounded-r-full bg-component-node-widget-background"
class="-ml-2.5 min-w-0 max-w-max grow basis-0 truncate rounded-r-full bg-component-node-widget-background"
>
<span class="pr-2" v-text="rest" />
</span>

View File

@@ -1,5 +1,7 @@
<template>
<CreditBadge v-if="nodeDef.api_node && priceLabel" :text="priceLabel" />
<span v-if="nodeDef.api_node && priceLabel">
<CreditBadge :text="priceLabel" />
</span>
</template>
<script setup lang="ts">

View File

@@ -92,7 +92,7 @@ import NodeSearchListItem from '@/components/searchbox/v2/NodeSearchListItem.vue
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
import { useNodeDefStore, useNodeFrequencyStore } from '@/stores/nodeDefStore'
import { NodeSourceType } from '@/types/nodeSource'
import { isCustomNode, isEssentialNode } from '@/types/nodeSource'
import type { FuseFilter, FuseFilterWithValue } from '@/utils/fuseUtil'
import { cn } from '@/utils/tailwindUtil'
@@ -114,18 +114,6 @@ const nodeDefStore = useNodeDefStore()
const nodeFrequencyStore = useNodeFrequencyStore()
const nodeBookmarkStore = useNodeBookmarkStore()
function isEssentialNode(n: ComfyNodeDefImpl): boolean {
return n.nodeSource.type === NodeSourceType.Essentials
}
function isCustomNode(n: ComfyNodeDefImpl): boolean {
return (
n.nodeSource.type !== NodeSourceType.Core &&
!isEssentialNode(n) &&
n.python_module !== 'blueprint'
)
}
const dialogRef = ref<HTMLElement>()
const searchInputRef = ref<InstanceType<typeof NodeSearchInput>>()

View File

@@ -2,36 +2,64 @@
<div
class="option-container flex w-full cursor-pointer items-center justify-between overflow-hidden"
>
<div class="flex flex-col gap-0.5 overflow-hidden">
<div class="font-semibold text-foreground flex items-center gap-2">
<div class="flex min-w-0 flex-1 flex-col gap-0.5 overflow-hidden">
<!-- Row 1: Name (left) + badges (right) -->
<div class="flex items-center gap-2 font-semibold text-foreground">
<span v-if="isBookmarked && !hideBookmarkIcon">
<i class="pi pi-bookmark-fill mr-1 text-sm" />
</span>
<span v-html="highlightQuery(nodeDef.display_name, currentQuery)" />
<span
class="truncate"
v-html="highlightQuery(nodeDef.display_name, currentQuery)"
/>
<span v-if="showIdName">&nbsp;</span>
<span
v-if="showIdName"
class="rounded bg-secondary-background px-1.5 py-0.5 text-xs text-muted-foreground"
class="shrink-0 rounded bg-secondary-background px-1.5 py-0.5 text-xs text-muted-foreground"
v-html="highlightQuery(nodeDef.name, currentQuery)"
/>
<NodePricingBadge :node-def="nodeDef" />
<NodeProviderBadge v-if="nodeDef.api_node" :node-def="nodeDef" />
<template v-if="showDescription">
<div class="flex-1" />
<div class="flex shrink-0 items-center gap-1">
<span
v-if="showSourceBadge && !isCustomNode"
aria-hidden="true"
class="flex size-[18px] shrink-0 items-center justify-center rounded-full bg-secondary-background-selected"
>
<ComfyLogo :size="10" mode="fill" color="currentColor" />
</span>
<span
v-else-if="showSourceBadge && isCustomNode"
:class="badgePillClass"
>
<span class="truncate text-[10px]">
{{ nodeDef.nodeSource.displayText }}
</span>
</span>
<span
v-if="nodeDef.api_node && providerName"
:class="badgePillClass"
>
<i
aria-hidden="true"
class="icon-[lucide--component] size-3 text-amber-400"
/>
<i
aria-hidden="true"
:class="cn(getProviderIcon(providerName), 'size-3')"
/>
</span>
</div>
</template>
<template v-else>
<NodePricingBadge :node-def="nodeDef" />
<NodeProviderBadge v-if="nodeDef.api_node" :node-def="nodeDef" />
</template>
</div>
<div
v-if="showDescription"
class="flex items-center gap-1 text-[11px] text-muted-foreground"
>
<span
v-if="
showSourceBadge &&
nodeDef.nodeSource.type !== NodeSourceType.Core &&
nodeDef.nodeSource.type !== NodeSourceType.Unknown
"
class="inline-flex shrink-0 rounded border border-border px-1.5 py-0.5 text-xs bg-base-foreground/5 text-base-foreground/70 mr-0.5"
>
{{ nodeDef.nodeSource.displayText }}
</span>
<div v-if="showDescription" class="text-[11px] text-muted-foreground">
<TextTicker v-if="nodeDef.description">
{{ nodeDef.description }}
</TextTicker>
@@ -82,14 +110,20 @@
import { computed } from 'vue'
import TextTicker from '@/components/common/TextTicker.vue'
import ComfyLogo from '@/components/icons/ComfyLogo.vue'
import NodePricingBadge from '@/components/node/NodePricingBadge.vue'
import NodeProviderBadge from '@/components/node/NodeProviderBadge.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
import { useNodeFrequencyStore } from '@/stores/nodeDefStore'
import { NodeSourceType } from '@/types/nodeSource'
import {
isCustomNode as isCustomNodeDef,
NodeSourceType
} from '@/types/nodeSource'
import { getProviderIcon, getProviderName } from '@/utils/categoryUtil'
import { formatNumberWithSuffix, highlightQuery } from '@/utils/formatUtil'
import { cn } from '@/utils/tailwindUtil'
const {
nodeDef,
@@ -105,6 +139,9 @@ const {
hideBookmarkIcon?: boolean
}>()
const badgePillClass =
'flex h-[18px] max-w-28 shrink-0 items-center justify-center gap-1 rounded-full bg-secondary-background-selected px-2'
const settingStore = useSettingStore()
const showCategory = computed(() =>
settingStore.get('Comfy.NodeSearchBoxImpl.ShowCategory')
@@ -122,6 +159,8 @@ const nodeFrequency = computed(() =>
const nodeBookmarkStore = useNodeBookmarkStore()
const isBookmarked = computed(() => nodeBookmarkStore.isBookmarked(nodeDef))
const providerName = computed(() => getProviderName(nodeDef.category))
const isCustomNode = computed(() => isCustomNodeDef(nodeDef))
</script>
<style scoped>

View File

@@ -1,6 +1,12 @@
import { describe, expect, it } from 'vitest'
import { NodeSourceType, getNodeSource } from '@/types/nodeSource'
import {
NodeSourceType,
getNodeSource,
isCustomNode,
isEssentialNode
} from '@/types/nodeSource'
import type { NodeSource } from '@/types/nodeSource'
describe('getNodeSource', () => {
it('should return UNKNOWN_NODE_SOURCE when python_module is undefined', () => {
@@ -119,3 +125,61 @@ describe('getNodeSource', () => {
})
})
})
function makeNode(
type: NodeSourceType,
python_module?: string
): { nodeSource: NodeSource; python_module?: string } {
return {
nodeSource: {
type,
className: '',
displayText: '',
badgeText: ''
},
python_module
}
}
describe('isEssentialNode', () => {
it('returns true for Essentials nodes', () => {
expect(isEssentialNode(makeNode(NodeSourceType.Essentials))).toBe(true)
})
it.for([
NodeSourceType.Core,
NodeSourceType.CustomNodes,
NodeSourceType.Blueprint,
NodeSourceType.Unknown
])('returns false for %s nodes', (type) => {
expect(isEssentialNode(makeNode(type))).toBe(false)
})
})
describe('isCustomNode', () => {
it('returns true for CustomNodes', () => {
expect(
isCustomNode(makeNode(NodeSourceType.CustomNodes, 'custom_nodes.foo'))
).toBe(true)
})
it('returns false for Core nodes', () => {
expect(isCustomNode(makeNode(NodeSourceType.Core, 'nodes.foo'))).toBe(false)
})
it('returns false for Essentials nodes', () => {
expect(
isCustomNode(makeNode(NodeSourceType.Essentials, 'custom_nodes.foo'))
).toBe(false)
})
it('returns false for Unknown nodes', () => {
expect(isCustomNode(makeNode(NodeSourceType.Unknown))).toBe(false)
})
it('returns false for Blueprint nodes', () => {
expect(isCustomNode(makeNode(NodeSourceType.Blueprint, 'blueprint'))).toBe(
false
)
})
})

View File

@@ -129,6 +129,24 @@ export const getNodeSource = (
}
}
interface NodeDefLike {
nodeSource: NodeSource
python_module?: string
}
export function isEssentialNode(node: NodeDefLike): boolean {
return node.nodeSource.type === NodeSourceType.Essentials
}
export function isCustomNode(node: NodeDefLike): boolean {
return (
node.nodeSource.type !== NodeSourceType.Core &&
node.nodeSource.type !== NodeSourceType.Unknown &&
!isEssentialNode(node) &&
node.python_module !== 'blueprint'
)
}
export enum NodeBadgeMode {
None = 'None',
ShowAll = 'Show all',