[Major Refactor] Use TreeExplorer on nodeLibrarySidebarTab (#699)

* Basic move

* Add back node bookmark

* Move node preview

* Fix drag node to canvas

* Restore click node to add to canvas

* Split bookmark tree and library tree

* Migrate rename and delete context menu

* Fix expanded keys

* Split components

* Support extra menu items

* Context menu only for folder

* Migrate add folder

* Handle drop

* Store color customization

* remove extra padding

* Do not show context menu if no item

* Hide divider if no bookmark

* Sort bookmarks alphabetically default

* nit

* proper edit

* Update test selectors

* Auto expand on item drop

* nit

* Fix tests

* Search also searches bookmarks tree

* Add serach playwright test
This commit is contained in:
Chenlei Hu
2024-09-01 14:03:15 -04:00
committed by GitHub
parent 5383f97eba
commit d04dbcd2c1
9 changed files with 516 additions and 477 deletions

View File

@@ -1,103 +1,42 @@
<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 ref="container" class="node-lib-node-container">
<TreeExplorerTreeNode
:node="node"
@item-dropped="handleItemDrop"
></TreeExplorerTreeNode>
</div>
</template>
<script setup lang="ts">
import TreeExplorerTreeNode from '@/components/common/TreeExplorerTreeNode.vue'
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 { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { computed, inject, onMounted, onUnmounted, Ref, ref, watch } from 'vue'
import type { BookmarkCustomization } from '@/types/apiTypes'
import { RenderedTreeExplorerNode } from '@/types/treeExplorerTypes'
const props = defineProps<{
node: TreeNode
isBookmarkFolder: boolean
}>()
const emit = defineEmits<{
(e: 'itemDropped', node: TreeNode): void
node: RenderedTreeExplorerNode<ComfyNodeDefImpl>
}>()
const nodeBookmarkStore = useNodeBookmarkStore()
const customization = computed<BookmarkCustomization | undefined>(() => {
return nodeBookmarkStore.bookmarksCustomization[props.node.data.nodePath]
})
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)
const treeNodeElement = ref<HTMLElement | null>(null)
const iconElement = ref<HTMLElement | null>(null)
let dropTargetCleanup = () => {}
let stopWatchCustomization: (() => void) | null = null
const container = ref<HTMLElement | null>(null)
onMounted(() => {
if (!props.isBookmarkFolder) return
treeNodeElement.value = container.value?.closest(
'.p-tree-node-content'
) as HTMLElement
dropTargetCleanup = dropTargetForElements({
element: treeNodeElement.value,
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
}
})
iconElement.value = treeNodeElement.value.querySelector(
':scope > .p-tree-node-icon'
) as HTMLElement
updateIconColor()
// Start watching after the component is mounted
@@ -111,16 +50,13 @@ const updateIconColor = () => {
}
onUnmounted(() => {
dropTargetCleanup()
if (stopWatchCustomization) {
stopWatchCustomization()
}
})
</script>
<style scoped>
.node-tree-folder {
display: flex;
align-items: center;
const expandedKeys = inject<Ref<Record<string, boolean>>>('expandedKeys')
const handleItemDrop = (node: RenderedTreeExplorerNode) => {
expandedKeys.value[node.key] = true
}
</style>
</script>