Bookmark nodes in node library (#612)

* Basic bookmark

* Extract node leaf as component

* bigger hitbox
This commit is contained in:
Chenlei Hu
2024-08-24 10:39:18 -04:00
committed by GitHub
parent f2b02dd10b
commit a2143d9120
5 changed files with 156 additions and 28 deletions

View File

@@ -63,17 +63,11 @@
></Badge>
</template>
<template #node="{ node }">
<Tag
v-if="node.data.experimental"
:value="$t('experimental')"
severity="primary"
<NodeTreeLeaf
:node="node.data"
:isBookmarked="isBookmarked(node.data)"
@toggleBookmark="toggleBookmark(node.data.display_name)"
/>
<Tag
v-if="node.data.deprecated"
:value="$t('deprecated')"
severity="danger"
/>
<span class="node-label">{{ node.label }}</span>
</template>
</TreePlus>
<div
@@ -93,18 +87,23 @@
<script setup lang="ts">
import Badge from 'primevue/badge'
import Tag from 'primevue/tag'
import ToggleButton from 'primevue/togglebutton'
import { ComfyNodeDefImpl, useNodeDefStore } from '@/stores/nodeDefStore'
import {
buildNodeDefTree,
ComfyNodeDefImpl,
useNodeDefStore
} from '@/stores/nodeDefStore'
import { computed, ref, nextTick } from 'vue'
import type { TreeNode } from 'primevue/treenode'
import NodeTreeLeaf from './nodeLibrary/NodeTreeLeaf.vue'
import TreePlus from '@/components/primevueOverride/TreePlus.vue'
import NodePreview from '@/components/node/NodePreview.vue'
import SearchBox from '@/components/common/SearchBox.vue'
import SidebarTabTemplate from '@/components/sidebar/tabs/SidebarTabTemplate.vue'
import { useSettingStore } from '@/stores/settingStore'
import { app } from '@/scripts/app'
import { buildTree, sortedTree } from '@/utils/treeUtil'
import { sortedTree } from '@/utils/treeUtil'
import _ from 'lodash'
const nodeDefStore = useNodeDefStore()
const alphabeticalSort = ref(false)
@@ -130,13 +129,63 @@ const nodePreviewStyle = ref<Record<string, string>>({
left: '0px'
})
// Bookmarks are in format of category/display_name. e.g. "comfy/conditioning/CLIPTextEncode"
const bookmarks = computed(() =>
settingStore.get('Comfy.NodeLibrary.Bookmarks')
)
const bookmarkedNodes = computed(
() =>
new Set(
bookmarks.value.map((bookmark: string) => bookmark.split('/').pop())
)
)
const isBookmarked = (node: ComfyNodeDefImpl) =>
bookmarkedNodes.value.has(node.display_name)
const toggleBookmark = (bookmark: string) => {
if (bookmarks.value.includes(bookmark)) {
settingStore.set(
'Comfy.NodeLibrary.Bookmarks',
bookmarks.value.filter((b: string) => b !== bookmark)
)
} else {
settingStore.set('Comfy.NodeLibrary.Bookmarks', [
...bookmarks.value,
bookmark
])
}
}
const bookmarkedRoot = computed<TreeNode>(() => {
const bookmarkNodes = bookmarks.value.map((bookmark: string) => {
const parts = bookmark.split('/')
const nodeName = parts.pop()
const category = parts.join('/')
const nodeDef = _.clone(nodeDefStore.nodeDefsByDisplayName[nodeName])
nodeDef.category = category
return nodeDef
})
return buildNodeDefTree(bookmarkNodes)
})
const allNodesRoot = computed<TreeNode>(() => {
return {
key: 'all-nodes',
label: 'All Nodes',
children: [
...(bookmarkedRoot.value?.children ?? []),
...nodeDefStore.nodeTree.children
]
}
})
const root = computed(() => {
const root = filteredRoot.value || nodeDefStore.nodeTree
const root = filteredRoot.value || allNodesRoot.value
return alphabeticalSort.value ? sortedTree(root) : root
})
const renderedRoot = computed(() => {
return fillNodeInfo(root.value)
})
const fillNodeInfo = (node: TreeNode): TreeNode => {
const isExpanded = expandedKeys.value[node.key]
const icon = node.leaf
@@ -208,10 +257,7 @@ const handleSearch = (query: string) => {
limit: 64
})
filteredRoot.value = buildTree(matchedNodes, (nodeDef: ComfyNodeDefImpl) => [
...nodeDef.category.split('/'),
nodeDef.display_name
])
filteredRoot.value = buildNodeDefTree(matchedNodes)
expandNode(filteredRoot.value)
}
@@ -231,6 +277,7 @@ const expandNode = (node: TreeNode) => {
display: flex;
align-items: center;
margin-left: var(--p-tree-node-gap);
flex-grow: 1;
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<div class="node-tree-leaf">
<div class="node-content">
<Tag
v-if="node.experimental"
:value="$t('experimental')"
severity="primary"
/>
<Tag v-if="node.deprecated" :value="$t('deprecated')" severity="danger" />
<span class="node-label">{{ node.display_name }}</span>
</div>
<Button
class="bookmark-button"
size="small"
:icon="isBookmarked ? 'pi pi-bookmark-fill' : 'pi pi-bookmark'"
text
severity="secondary"
@click.stop="toggleBookmark"
/>
</div>
</template>
<script setup lang="ts">
import Button from 'primevue/button'
import Tag from 'primevue/tag'
import { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
const props = defineProps<{
node: ComfyNodeDefImpl
isBookmarked: boolean
}>()
const emit = defineEmits<{
(e: 'toggle-bookmark', value: ComfyNodeDefImpl): void
}>()
const toggleBookmark = () => {
emit('toggle-bookmark', props.node)
}
</script>
<style scoped>
.node-tree-leaf {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.node-content {
display: flex;
align-items: center;
flex-grow: 1;
}
.node-label {
margin-left: 0.5rem;
}
.bookmark-button {
width: unset;
padding: 0.25rem;
}
</style>