mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-10 07:30:08 +00:00
Node library custom bookmark folder (#631)
* Add new folder button * Add tree util test * nit * Support empty folder in node library * Drag to bookmark folder * Use bookmark icon for bookmark folder * Highlight on dragover * nit * Auto-expand on item added * Extract bookmark system as store * Add context menu on bookmark folder * Add editable text * Fix reactivity * Plumb editable text * refactor * Rename node * Fix focus * Prevent name collision * nit * Add new folder * nested folder support * Change drag behavior * Add basic playwright tests * nit * Target tree-node-content instead of tree-node
This commit is contained in:
90
src/components/sidebar/tabs/nodeLibrary/NodeTreeFolder.vue
Normal file
90
src/components/sidebar/tabs/nodeLibrary/NodeTreeFolder.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div
|
||||
:class="[
|
||||
'node-tree-folder',
|
||||
{ bookmark: props.isBookmarkFolder, 'can-drop': canDrop }
|
||||
]"
|
||||
ref="container"
|
||||
>
|
||||
<span class="folder-label">
|
||||
<slot name="folder-label" :node="props.node">
|
||||
{{ props.node.label }}
|
||||
</slot>
|
||||
</span>
|
||||
<Badge
|
||||
:value="props.node.totalNodes"
|
||||
severity="secondary"
|
||||
:style="{ marginLeft: '0.5rem' }"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
||||
import { useNodeBookmarkStore } from '@/stores/nodeBookmarkStore'
|
||||
import type { CanvasDragAndDropData } from '@/types/litegraphTypes'
|
||||
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter'
|
||||
import Badge from 'primevue/badge'
|
||||
import type { TreeNode } from 'primevue/treenode'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
node: TreeNode
|
||||
isBookmarkFolder: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'itemDropped', node: TreeNode): void
|
||||
}>()
|
||||
|
||||
const nodeBookmarkStore = useNodeBookmarkStore()
|
||||
|
||||
const addNodeToBookmarkFolder = (node: ComfyNodeDefImpl) => {
|
||||
if (!props.node.data) {
|
||||
console.error('Bookmark folder does not have data!')
|
||||
return
|
||||
}
|
||||
if (nodeBookmarkStore.isBookmarked(node)) {
|
||||
nodeBookmarkStore.toggleBookmark(node)
|
||||
}
|
||||
|
||||
const folderNodeDef = props.node.data as ComfyNodeDefImpl
|
||||
const nodePath = folderNodeDef.category + '/' + node.display_name
|
||||
nodeBookmarkStore.addBookmark(nodePath)
|
||||
}
|
||||
|
||||
const container = ref<HTMLElement | null>(null)
|
||||
const canDrop = ref(false)
|
||||
|
||||
let dropTargetCleanup = () => {}
|
||||
onMounted(() => {
|
||||
if (!props.isBookmarkFolder) return
|
||||
|
||||
const treeNodeElement = container.value?.closest(
|
||||
'.p-tree-node-content'
|
||||
) as HTMLElement
|
||||
dropTargetCleanup = dropTargetForElements({
|
||||
element: treeNodeElement,
|
||||
onDrop: (event) => {
|
||||
const dndData = event.source.data as CanvasDragAndDropData
|
||||
if (dndData.type === 'add-node') {
|
||||
addNodeToBookmarkFolder(dndData.data)
|
||||
canDrop.value = false
|
||||
emit('itemDropped', props.node)
|
||||
}
|
||||
},
|
||||
onDragEnter: (event) => {
|
||||
const dndData = event.source.data as CanvasDragAndDropData
|
||||
if (dndData.type === 'add-node') {
|
||||
canDrop.value = true
|
||||
}
|
||||
},
|
||||
onDragLeave: (event) => {
|
||||
canDrop.value = false
|
||||
}
|
||||
})
|
||||
})
|
||||
onUnmounted(() => {
|
||||
dropTargetCleanup()
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user