Add workflow info popover

This commit is contained in:
Austin Mroz
2026-01-05 21:52:53 -08:00
parent 5c693c5d23
commit f01bb4d8d2
2 changed files with 55 additions and 30 deletions

View File

@@ -11,7 +11,7 @@ import Button from '@/components/ui/button/Button.vue'
import { cn } from '@/utils/tailwindUtil' import { cn } from '@/utils/tailwindUtil'
defineProps<{ defineProps<{
entries: { label: string; action?: () => void; icon?: string }[][] entries?: { label: string; action?: () => void; icon?: string }[][]
icon?: string icon?: string
}>() }>()
</script> </script>
@@ -29,12 +29,13 @@ defineProps<{
<PopoverContent <PopoverContent
side="bottom" side="bottom"
:side-offset="5" :side-offset="5"
:collision-padding="10"
class="rounded-lg p-2 bg-base-background shadow-sm border border-border-subtle will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-slideDownAndFade data-[state=open]:data-[side=right]:animate-slideLeftAndFade data-[state=open]:data-[side=bottom]:animate-slideUpAndFade data-[state=open]:data-[side=left]:animate-slideRightAndFade" class="rounded-lg p-2 bg-base-background shadow-sm border border-border-subtle will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-slideDownAndFade data-[state=open]:data-[side=right]:animate-slideLeftAndFade data-[state=open]:data-[side=bottom]:animate-slideUpAndFade data-[state=open]:data-[side=left]:animate-slideRightAndFade"
> >
<slot> <slot>
<div class="flex flex-col p-1"> <div class="flex flex-col p-1">
<popover-group <popover-group
v-for="(entryGroup, index) in entries" v-for="(entryGroup, index) in entries ?? []"
:key="index" :key="index"
class="flex flex-col border-b-2 last:border-none border-border-subtle" class="flex flex-col border-b-2 last:border-none border-border-subtle"
> >

View File

@@ -73,36 +73,37 @@ const graphNodes = shallowRef<LGraphNode[]>(app.rootGraph.nodes)
useEventListener( useEventListener(
app.rootGraph.events, app.rootGraph.events,
'configured', 'configured',
() => (graphNodes.value = app.rootGraph.nodes) () => (graphNodes.value = app.rootGraph.nodes.reverse())
) )
const nodeDatas = computed(() => { function nodeToNodeData(node: LGraphNode) {
function nodeToNodeData(node: LGraphNode) { const mapper = safeWidgetMapper(node, new Map())
const mapper = safeWidgetMapper(node, new Map()) const widgets = node.widgets?.map(mapper) ?? []
const widgets = node.widgets?.map(mapper) ?? [] const dropIndicator =
const dropIndicator = node.type !== 'LoadImage'
node.type !== 'LoadImage' ? undefined
? undefined : {
: { iconClass: 'icon-[lucide--image]',
iconClass: 'icon-[lucide--image]', label: t('Click to browse or drag an image'),
label: t('Click to browse or drag an image'), onClick: node.widgets?.[1]?.callback
onClick: node.widgets?.[1]?.callback }
} //of VueNodeData, only widgets is actually used
//of VueNodeData, only widgets is actually used return {
return { executing: false,
executing: false, id: `${node.id}`,
id: `${node.id}`, mode: 0,
mode: 0, selected: false,
selected: false, title: node.title,
title: node.title, type: node.type,
type: node.type, widgets,
widgets,
dropIndicator, dropIndicator,
onDragDrop: node.onDragDrop, onDragDrop: node.onDragDrop,
onDragOver: node.onDragOver onDragOver: node.onDragOver
}
} }
}
const nodeDatas = computed(() => {
return graphNodes.value return graphNodes.value
.filter( .filter(
(node) => (node) =>
@@ -111,7 +112,16 @@ const nodeDatas = computed(() => {
!['MarkdownNote', 'Note'].includes(node.type) !['MarkdownNote', 'Note'].includes(node.type)
) )
.map(nodeToNodeData) .map(nodeToNodeData)
.reverse() })
const noteDatas = computed(() => {
return graphNodes.value
.filter(
(node) =>
node.mode === 0 &&
node.widgets?.length &&
['MarkdownNote', 'Note'].includes(node.type)
)
.map(nodeToNodeData)
}) })
const batchCountWidget = { const batchCountWidget = {
@@ -602,7 +612,21 @@ useEventListener(document.body, 'keydown', (e: KeyboardEvent) => {
v-text="workflowStore.activeWorkflow?.filename" v-text="workflowStore.activeWorkflow?.filename"
/> />
<div class="flex-1" /> <div class="flex-1" />
<i class="icon-[lucide--info]" /> <Popover v-if="noteDatas.length">
<template #button>
<Button variant="muted-textonly">
<i class="icon-[lucide--info]" />
</Button>
</template>
<div>
<NodeWidgets
v-for="nodeData in noteDatas"
:key="nodeData.id"
:node-data
class="border-b-1 border-node-component-border py-3 last:border-none"
/>
</div>
</Popover>
<Button> {{ t('publish') }} </Button> <Button> {{ t('publish') }} </Button>
</linear-workflow-info> </linear-workflow-info>
<div <div