Working drag and drop

This commit is contained in:
Austin Mroz
2025-09-10 12:32:02 -05:00
parent 2212151686
commit ec09d9b365
3 changed files with 168 additions and 90 deletions

View File

@@ -1,73 +1,100 @@
<template>
<SidebarTabTemplate
:title="'Subgraph Node'"
class="workflows-sidebar-tab bg-[var(--p-tree-background)]"
>
<template #body>
<TreeExplorer
v-model:expandedKeys="expandedKeys"
:root="renderedRoot"
>
<template #node="{ node }">
<SubgraphNodeWidget :node="node"/>
</template>
</TreeExplorer>
</template>
</SidebarTabTemplate>
</template>
<script setup lang="ts">
import { ref, watch, computed } from 'vue';
import { watchDebounced } from '@vueuse/core'
import OrderList from 'primevue/orderlist';
import { useI18n } from 'vue-i18n'
import draggable from 'vuedraggable'
import SidebarTabTemplate from '@/components/sidebar/tabs/SidebarTabTemplate.vue'
import TreeExplorer from '@/components/common/TreeExplorer.vue'
import SubgraphNodeWidget from '@/components/selectionbar/SubgraphNodeWidget.vue'
import { useCanvasStore } from '@/stores/graphStore'
import { buildTree } from '@/utils/treeUtil'
const { t } = useI18n()
const canvasStore = useCanvasStore()
const expandedKeys = ref<Record<string, boolean>>({})
const widgetTree = computed(() => {
const triggerUpdate = ref(0)
const activeNode = computed(() => {
return canvasStore.selectedItems[0]
})
function keyfn(item) {
return `${item[0].title}(${item[0].id}): ${item[1].name}`
}
const activeWidgets = computed({
get() {
triggerUpdate.value
const node = activeNode.value
const pw = node.properties.proxyWidgets ?? []
return pw.map(([id, name]) => {
const wNode = node.subgraph._nodes_by_id[id]
const w = wNode.widgets.find((w) => w.name === name)
return [wNode, w]
})
},
set(value) {
//map back to id/name
const pw = value.map(([node, widget]) => [node.id, widget.name])
activeNode.value.properties.proxyWidgets = pw
//force trigger an update
triggerUpdate.value++
canvasStore.canvas.setDirty(true)
}
})
const candidateWidgets = computed(() =>{
const node = canvasStore.selectedItems[0] ?? {}
const interiorNodes = node?.subgraph?.nodes ?? []
node.widgets ??= []
const intn = interiorNodes.map((n) =>
n.widgets?.map((w) => [n, w, node]) ?? []).flat(1)
const intn = interiorNodes.flatMap((n) =>
n.widgets?.map((w) => {
return [n,w] ?? []
}))
//widget has connected link. Should not be displayed
.filter((i) => !i[1].computedDisabled)
//TODO: filter enabled/disabled items while keeping order
return buildTree(intn, (item: [unknown, unknown]) =>
[`${item[0].title}(${item[0].id}): ${item[1].name}`]
)
return intn
})
const renderedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(() => {
const fillNodeInfo = (node: TreeNode): TreeExplorerNode<ComfyNodeDefImpl> => {
const children = node.children?.map(fillNodeInfo)
return {
key: node.key,
leaf: node.leaf,
data: node.data,
label: node.label,
getIcon() {
return 'pi pi-minus'
},
children,
onToggle: () => console.log(widgetTree,node),
draggable: true,
}
}
const ret = fillNodeInfo(widgetTree.value)
return ret
})
</script>
<template>
<SidebarTabTemplate
:title="'Subgraph Node'"
class="workflows-sidebar-tab bg-[var(--p-tree-background)]"
>
<template #body>
<div class="widgets-section">
<draggable
v-model="activeWidgets"
group="people"
:animation="100"
@start="drag=true"
@end="drag=false"
item-key="id">
<template #item="{element}">
<SubgraphNodeWidget :item="element" :node="activeNode" :draggable="true"/>
</template>
</draggable>
</div>
<div class="widgets-section">
<div v-for="element in candidateWidgets">
<SubgraphNodeWidget :item="element" :node="activeNode"/>
</div>
</div>
</template>
</SidebarTabTemplate>
</template>
<style scoped>
.widgets-section {
display: flex;
padding: 4px 0 16px 0;
flex-direction: column;
align-items: flex-start;
gap: 16px;
align-self: stretch;
border-bottom: 1px solid var(--color-node-divider, #2E3037);
}
</style>