From 4e08ed64f00667ebab2f39862f2b5c99bc9cf8ab Mon Sep 17 00:00:00 2001 From: AustinMroz Date: Thu, 9 Oct 2025 13:50:15 -0700 Subject: [PATCH] Allow reordering of linked subgraph widgets (#5981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Widgets which are promoted by linking to a subgraphInput node are now also displayed in the subgraph configuration window. They can now be reordered by drag and drop along with proxyWidgets ![linked-reorder](https://github.com/user-attachments/assets/e1b8d590-211a-4d84-9f84-3a5fd5a7aa6c) Known Issues: - "Hide All" will incorrectly remove physically linked widgets ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5981-Allow-reordering-of-linked-subgraph-widgets-2866d73d365081d9b27cf4a9c3078007) by [Unito](https://www.unito.io) --- src/core/graph/subgraph/SubgraphNode.vue | 62 +++++++++---------- .../graph/subgraph/SubgraphNodeWidget.vue | 16 +++-- src/core/graph/subgraph/proxyWidget.ts | 45 +++++++++----- src/core/graph/subgraph/proxyWidgetUtils.ts | 8 ++- tests-ui/tests/widgets/proxyWidget.test.ts | 23 ++++--- 5 files changed, 89 insertions(+), 65 deletions(-) diff --git a/src/core/graph/subgraph/SubgraphNode.vue b/src/core/graph/subgraph/SubgraphNode.vue index 72e4614f5..e40bdeef2 100644 --- a/src/core/graph/subgraph/SubgraphNode.vue +++ b/src/core/graph/subgraph/SubgraphNode.vue @@ -64,15 +64,21 @@ const activeNode = computed(() => { const activeWidgets = computed({ get() { + if (!activeNode.value) return [] const node = activeNode.value - if (!node) return [] - return proxyWidgets.value.flatMap(([id, name]: [string, string]) => { + function mapWidgets([id, name]: [string, string]): WidgetItem[] { + if (id === '-1') { + const widget = node.widgets.find((w) => w.name === name) + if (!widget) return [] + return [[{ id: -1, title: '(Linked)', type: '' }, widget]] + } const wNode = node.subgraph._nodes_by_id[id] if (!wNode?.widgets) return [] - const w = wNode.widgets.find((w) => w.name === name) - if (!w) return [] - return [[wNode, w]] - }) + const widget = wNode.widgets.find((w) => w.name === name) + if (!widget) return [] + return [[wNode, widget]] + } + return proxyWidgets.value.flatMap(mapWidgets) }, set(value: WidgetItem[]) { const node = activeNode.value @@ -80,9 +86,7 @@ const activeWidgets = computed({ console.error('Attempted to toggle widgets with no node selected') return } - //map back to id/name - const widgets: ProxyWidgetsProperty = value.map(widgetItemToProperty) - proxyWidgets.value = widgets + proxyWidgets.value = value.map(widgetItemToProperty) } }) @@ -165,10 +169,10 @@ function showAll() { function hideAll() { const node = activeNode.value if (!node) return //Not reachable - //Not great from a nesting perspective, but path is cold - //and it cleans up potential error states proxyWidgets.value = proxyWidgets.value.filter( - (widgetItem) => !filteredActive.value.some(matchesWidgetItem(widgetItem)) + (propertyItem) => + !filteredActive.value.some(matchesWidgetItem(propertyItem)) || + propertyItem[0] === '-1' ) } function showRecommended() { @@ -258,20 +262,16 @@ onBeforeUnmount(() => { >
-
- -
+ :node-title="node.title" + :widget-name="widget.name" + :is-shown="true" + :is-draggable="!debouncedQuery" + :is-physical="node.id === -1" + @toggle-visibility="demote([node, widget])" + />
@@ -286,17 +286,13 @@ onBeforeUnmount(() => { {{ $t('subgraphStore.showAll') }}
-
- -
+ :node-title="node.title" + :widget-name="widget.name" + @toggle-visibility="promote([node, widget])" + />
() defineEmits<{ (e: 'toggleVisibility'): void @@ -17,11 +18,17 @@ function classes() { return cn( 'flex py-1 pr-4 pl-0 break-all rounded items-center gap-1', 'bg-node-component-surface', - props.isDraggable - ? 'drag-handle cursor-grab [.is-draggable]:cursor-grabbing' - : '' + props.isDraggable && + 'draggable-item drag-handle cursor-grab [&.is-draggable]:cursor-grabbing' ) } +function getIcon() { + return props.isPhysical + ? 'icon-[lucide--link]' + : props.isDraggable + ? 'icon-[lucide--eye]' + : 'icon-[lucide--eye-off]' +}