Skip to content

Commit 233004c

Browse files
DrJKLgithub-actions
andauthored
Feat: Add Badges for Vue Nodes (#6243)
## Summary Adds the badges to the header for Vue nodes. ## Review Focus Design, mostly. Any structures here I'm not handling but should be? ## Screenshots <img width="1514" height="642" alt="image" src="https://github.com/user-attachments/assets/387fd2f6-bb4b-4fee-b273-6166a52a3552" /> <!-- Add screenshots or video recording to help explain your changes --> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6243-Feat-Add-Badges-for-Vue-Nodes-2956d73d36508184a250d67b127ed4b1) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <[email protected]>
1 parent 7663517 commit 233004c

File tree

5 files changed

+41
-6
lines changed

5 files changed

+41
-6
lines changed
-14 Bytes
Loading

src/composables/graph/useGraphNodeManager.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type { WidgetValue } from '@/types/simplifiedWidget'
2020

2121
import type {
2222
LGraph,
23+
LGraphBadge,
2324
LGraphNode,
2425
LGraphTriggerAction,
2526
LGraphTriggerEvent,
@@ -51,6 +52,8 @@ export interface VueNodeData {
5152
mode: number
5253
selected: boolean
5354
executing: boolean
55+
apiNode?: boolean
56+
badges?: (LGraphBadge | (() => LGraphBadge))[]
5457
subgraphId?: string | null
5558
widgets?: SafeWidgetData[]
5659
inputs?: INodeInputSlot[]
@@ -117,7 +120,7 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
117120
}
118121

119122
// Extract safe data from LiteGraph node for Vue consumption
120-
const extractVueNodeData = (node: LGraphNode): VueNodeData => {
123+
function extractVueNodeData(node: LGraphNode): VueNodeData {
121124
// Determine subgraph ID - null for root graph, string for subgraphs
122125
const subgraphId =
123126
node.graph && 'id' in node.graph && node.graph !== node.graph.rootGraph
@@ -192,6 +195,9 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
192195
node.constructor?.name ||
193196
'Unknown'
194197

198+
const apiNode = node.constructor?.nodeData?.api_node ?? false
199+
const badges = node.badges
200+
195201
return {
196202
id: String(node.id),
197203
title: typeof node.title === 'string' ? node.title : '',
@@ -200,6 +206,8 @@ export function useGraphNodeManager(graph: LGraph): GraphNodeManager {
200206
selected: node.selected || false,
201207
executing: false, // Will be updated separately based on execution state
202208
subgraphId,
209+
apiNode,
210+
badges,
203211
hasErrors: !!node.has_errors,
204212
widgets: safeWidgets,
205213
inputs: node.inputs ? [...node.inputs] : undefined,

src/renderer/extensions/vueNodes/components/LGraphNode.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
{
3535
transform: `translate(${position.x ?? 0}px, ${(position.y ?? 0) - LiteGraph.NODE_TITLE_HEIGHT}px)`,
3636
zIndex: zIndex,
37-
backgroundColor: nodeBodyBackgroundColor,
38-
opacity: nodeOpacity
37+
opacity: nodeOpacity,
38+
'--node-component-surface': nodeBodyBackgroundColor
3939
},
4040
dragStyle
4141
]"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<template>
2+
<div
3+
v-if="badge.icon || badge.text"
4+
class="flex flex-auto items-center rounded-sm bg-node-component-surface px-1 py-0.5"
5+
:style="{
6+
color: badge.fgColor,
7+
backgroundColor: badge.bgColor
8+
}"
9+
>
10+
{{ badge.text }}
11+
</div>
12+
</template>
13+
<script setup lang="ts">
14+
import type { LGraphBadge } from '@/lib/litegraph/src/LGraphBadge'
15+
16+
const { badge } = defineProps<{
17+
badge: LGraphBadge
18+
}>()
19+
</script>

src/renderer/extensions/vueNodes/components/NodeHeader.vue

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
</div>
3939

4040
<div v-if="isSubgraphNode" class="icon-[comfy--workflow] size-4" />
41+
<div v-if="isApiNode" class="icon-[lucide--dollar-sign] size-4" />
42+
4143
<!-- Node Title -->
4244
<div
4345
v-tooltip.top="tooltipConfig"
@@ -60,7 +62,8 @@
6062
<LODFallback />
6163
</div>
6264

63-
<div class="lod-toggle flex shrink-0 items-center">
65+
<div class="lod-toggle flex shrink-0 items-center justify-between gap-2">
66+
<NodeBadge v-for="badge of nodeBadges" :key="badge.text" :badge />
6467
<IconButton
6568
v-if="isSubgraphNode"
6669
v-tooltip.top="enterSubgraphTooltipConfig"
@@ -80,14 +83,16 @@
8083
</template>
8184

8285
<script setup lang="ts">
83-
import { computed, onErrorCaptured, ref, watch } from 'vue'
86+
import { computed, onErrorCaptured, ref, toValue, watch } from 'vue'
8487
8588
import IconButton from '@/components/button/IconButton.vue'
8689
import EditableText from '@/components/common/EditableText.vue'
8790
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
8891
import { useErrorHandling } from '@/composables/useErrorHandling'
8992
import { st } from '@/i18n'
93+
import type { LGraphBadge } from '@/lib/litegraph/src/LGraphBadge'
9094
import { useSettingStore } from '@/platform/settings/settingStore'
95+
import NodeBadge from '@/renderer/extensions/vueNodes/components/NodeBadge.vue'
9196
import { useNodeTooltips } from '@/renderer/extensions/vueNodes/composables/useNodeTooltips'
9297
import { applyLightThemeColor } from '@/renderer/extensions/vueNodes/utils/nodeStyleUtils'
9398
import { app } from '@/scripts/app'
@@ -183,8 +188,11 @@ watch(
183188
}
184189
)
185190
191+
const nodeBadges = computed<LGraphBadge[]>(() =>
192+
(nodeData?.badges ?? []).map(toValue)
193+
)
186194
const isPinned = computed(() => Boolean(nodeData?.flags?.pinned))
187-
195+
const isApiNode = computed(() => Boolean(nodeData?.apiNode))
188196
// Subgraph detection
189197
const isSubgraphNode = computed(() => {
190198
if (!nodeData?.id) return false

0 commit comments

Comments
 (0)