mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-30 19:21:54 +00:00
Merge folder and node impl
This commit is contained in:
@@ -19,12 +19,12 @@
|
|||||||
>
|
>
|
||||||
<template #folder="{ node }">
|
<template #folder="{ node }">
|
||||||
<slot name="folder" :node="node">
|
<slot name="folder" :node="node">
|
||||||
<TreeFolder :node="node" />
|
<TreeExplorerTreeNode :node="node" />
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
<template #node="{ node }">
|
<template #node="{ node }">
|
||||||
<slot name="node" :node="node">
|
<slot name="node" :node="node">
|
||||||
<TreeNode :node="node.data" />
|
<TreeExplorerTreeNode :node="node" />
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</Tree>
|
</Tree>
|
||||||
@@ -34,8 +34,7 @@
|
|||||||
import { ref, computed, provide } from 'vue'
|
import { ref, computed, provide } from 'vue'
|
||||||
import Tree from 'primevue/tree'
|
import Tree from 'primevue/tree'
|
||||||
import ContextMenu from 'primevue/contextmenu'
|
import ContextMenu from 'primevue/contextmenu'
|
||||||
import TreeFolder from '@/components/common/treeExplorer/TreeFolder.vue'
|
import TreeExplorerTreeNode from '@/components/common/TreeExplorerTreeNode.vue'
|
||||||
import TreeNode from '@/components/common/treeExplorer/TreeNode.vue'
|
|
||||||
import type {
|
import type {
|
||||||
RenderedTreeExplorerNode,
|
RenderedTreeExplorerNode,
|
||||||
TreeExplorerNode
|
TreeExplorerNode
|
||||||
|
|||||||
@@ -1,33 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['tree-folder', { 'can-drop': canDrop }]" ref="container">
|
<div
|
||||||
<span class="folder-label">
|
:class="[
|
||||||
<slot name="folder-label" :node="props.node">
|
'tree-node',
|
||||||
{{ props.node.label }}
|
{
|
||||||
|
'can-drop': canDrop,
|
||||||
|
'tree-folder': !props.node.leaf,
|
||||||
|
'tree-leaf': props.node.leaf
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
ref="container"
|
||||||
|
>
|
||||||
|
<div class="node-content">
|
||||||
|
<span class="node-label">
|
||||||
|
<slot name="before-label" :node="props.node"></slot>
|
||||||
|
<EditableText
|
||||||
|
:modelValue="node.label"
|
||||||
|
:isEditing="isEditing"
|
||||||
|
@edit="(newName: string) => props.node.handleRename(node, newName)"
|
||||||
|
/>
|
||||||
|
<slot name="after-label" :node="props.node"></slot>
|
||||||
|
</span>
|
||||||
|
<Badge
|
||||||
|
v-if="!props.node.leaf"
|
||||||
|
:value="props.node.totalLeaves"
|
||||||
|
severity="secondary"
|
||||||
|
class="leaf-count-badge"
|
||||||
|
/>
|
||||||
|
<slot name="actions" :node="node">
|
||||||
|
<!-- Default slot content for actions -->
|
||||||
</slot>
|
</slot>
|
||||||
</span>
|
</div>
|
||||||
<Badge
|
|
||||||
v-if="props.node.totalLeaves"
|
|
||||||
:value="props.node.totalLeaves"
|
|
||||||
severity="secondary"
|
|
||||||
class="leaf-count-badge"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
import { ref, onMounted, onUnmounted, inject, Ref, computed } from 'vue'
|
||||||
import Badge from 'primevue/badge'
|
import Badge from 'primevue/badge'
|
||||||
import type {
|
|
||||||
TreeExplorerDragAndDropData,
|
|
||||||
RenderedTreeExplorerNode
|
|
||||||
} from '@/types/treeExplorerTypes'
|
|
||||||
import {
|
import {
|
||||||
dropTargetForElements,
|
dropTargetForElements,
|
||||||
draggable
|
draggable
|
||||||
} from '@atlaskit/pragmatic-drag-and-drop/element/adapter'
|
} from '@atlaskit/pragmatic-drag-and-drop/element/adapter'
|
||||||
|
import type {
|
||||||
|
TreeExplorerDragAndDropData,
|
||||||
|
RenderedTreeExplorerNode,
|
||||||
|
TreeExplorerNode
|
||||||
|
} from '@/types/treeExplorerTypes'
|
||||||
|
import EditableText from '@/components/common/EditableText.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
node: RenderedTreeExplorerNode
|
node: RenderedTreeExplorerNode
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(
|
(
|
||||||
e: 'itemDropped',
|
e: 'itemDropped',
|
||||||
@@ -37,6 +60,15 @@ const emit = defineEmits<{
|
|||||||
(e: 'dragStart', node: RenderedTreeExplorerNode): void
|
(e: 'dragStart', node: RenderedTreeExplorerNode): void
|
||||||
(e: 'dragEnd', node: RenderedTreeExplorerNode): void
|
(e: 'dragEnd', node: RenderedTreeExplorerNode): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
const labelEditable = computed<boolean>(() => !!props.node.handleRename)
|
||||||
|
const renameEditingNode = inject(
|
||||||
|
'renameEditingNode'
|
||||||
|
) as Ref<TreeExplorerNode | null>
|
||||||
|
const isEditing = computed(
|
||||||
|
() => labelEditable.value && renameEditingNode.value?.key === props.node.key
|
||||||
|
)
|
||||||
|
|
||||||
const container = ref<HTMLElement | null>(null)
|
const container = ref<HTMLElement | null>(null)
|
||||||
const canDrop = ref(false)
|
const canDrop = ref(false)
|
||||||
const treeNodeElement = ref<HTMLElement | null>(null)
|
const treeNodeElement = ref<HTMLElement | null>(null)
|
||||||
@@ -84,11 +116,21 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.tree-folder {
|
.tree-node {
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.leaf-count-badge {
|
.leaf-count-badge {
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.node-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.leaf-label {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="tree-leaf" ref="container">
|
|
||||||
<div class="leaf-content">
|
|
||||||
<span class="leaf-label">
|
|
||||||
<slot name="label" :node="node">
|
|
||||||
{{ props.node.label }}
|
|
||||||
</slot>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<slot name="actions" :node="node">
|
|
||||||
<!-- Default slot content for actions -->
|
|
||||||
</slot>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
|
||||||
import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter'
|
|
||||||
import { RenderedTreeExplorerNode } from '@/types/treeExplorerTypes'
|
|
||||||
const props = defineProps<{
|
|
||||||
node: RenderedTreeExplorerNode
|
|
||||||
}>()
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'dragStart', node: RenderedTreeExplorerNode): void
|
|
||||||
(e: 'dragEnd', node: RenderedTreeExplorerNode): void
|
|
||||||
}>()
|
|
||||||
const container = ref<HTMLElement | null>(null)
|
|
||||||
let draggableCleanup: () => void
|
|
||||||
onMounted(() => {
|
|
||||||
const treeNodeElement = container.value?.closest(
|
|
||||||
'.p-tree-node'
|
|
||||||
) as HTMLElement
|
|
||||||
draggableCleanup = draggable({
|
|
||||||
element: treeNodeElement,
|
|
||||||
getInitialData() {
|
|
||||||
return {
|
|
||||||
type: 'tree-explorer-node',
|
|
||||||
data: props.node
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDragStart: () => emit('dragStart', props.node),
|
|
||||||
onDrop: () => emit('dragEnd', props.node)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (draggableCleanup) {
|
|
||||||
draggableCleanup()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.tree-leaf {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.leaf-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.leaf-label {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Ref } from 'vue'
|
|
||||||
|
|
||||||
export interface TreeExplorerNode<T = any> {
|
export interface TreeExplorerNode<T = any> {
|
||||||
key: string
|
key: string
|
||||||
label: string
|
label: string
|
||||||
@@ -8,6 +6,8 @@ export interface TreeExplorerNode<T = any> {
|
|||||||
children?: TreeExplorerNode<T>[]
|
children?: TreeExplorerNode<T>[]
|
||||||
icon?: string
|
icon?: string
|
||||||
getIcon?: (node: TreeExplorerNode<T>) => string
|
getIcon?: (node: TreeExplorerNode<T>) => string
|
||||||
|
// Function to handle renaming the node
|
||||||
|
handleRename?: (node: TreeExplorerNode<T>, newName: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RenderedTreeExplorerNode<T = any> extends TreeExplorerNode<T> {
|
export interface RenderedTreeExplorerNode<T = any> extends TreeExplorerNode<T> {
|
||||||
@@ -22,10 +22,3 @@ export type TreeExplorerDragAndDropData<T = any> = {
|
|||||||
type: 'tree-explorer-node'
|
type: 'tree-explorer-node'
|
||||||
data: RenderedTreeExplorerNode<T>
|
data: RenderedTreeExplorerNode<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TreeExplorerNodeSlotProps {
|
|
||||||
node: RenderedTreeExplorerNode
|
|
||||||
handleItemDropped: (node: RenderedTreeExplorerNode) => void
|
|
||||||
renameEditingNode: Ref<RenderedTreeExplorerNode | null>
|
|
||||||
handleRename: (node: RenderedTreeExplorerNode, newName: string) => void
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user