Support selection of app inputs and outputs from vue mode (#9259)

- The input and output indicators are now plugged directly into the
`LGraphNode.vue` template. Care was taken to make implementation to have
low cost for performance and complexity when not in app mode setup.
- Context menu event handlers are added to each widget in vue mode
instead of resolving the target widget of an event
- Swap the nodeId passed by `useGraphNodeManager` to not include the
locator id. This id was never used and was incorrect since it didn't
resolve across nested subgraphs.
- Continued bug fixes for app mode as a whole.

Known issue: There is disparity of nodeId between litegraph (which
references the widget in the root graph) and vue (which promotes the
original widget). Efforts to reconcile are ongoing.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9259-Support-selection-app-inputs-and-outputs-from-vue-mode-3136d73d365081ae8e56e35bf6322409)
by [Unito](https://www.unito.io)

---------

Co-authored-by: pythongosssss <125205205+pythongosssss@users.noreply.github.com>
This commit is contained in:
AustinMroz
2026-03-02 09:49:21 -08:00
committed by GitHub
parent 84d7aa0fd9
commit 1dd789fa54
11 changed files with 237 additions and 54 deletions

View File

@@ -16,7 +16,6 @@ import { useTelemetry } from '@/platform/telemetry'
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
import DropZone from '@/renderer/extensions/linearMode/DropZone.vue'
import NodeWidgets from '@/renderer/extensions/vueNodes/components/NodeWidgets.vue'
import { applyLightThemeColor } from '@/renderer/extensions/vueNodes/utils/nodeStyleUtils'
import WidgetInputNumberInput from '@/renderer/extensions/vueNodes/widgets/components/WidgetInputNumber.vue'
import { api } from '@/scripts/api'
import { app } from '@/scripts/app'
@@ -69,7 +68,11 @@ const mappedSelections = computed(() => {
([id]) => id === nodeId
).map(([, widgetName]) => widgetName)
unprocessedInputs = unprocessedInputs.slice(inputGroup.length)
const node = app.rootGraph.getNodeById(nodeId)
const node =
app.rootGraph.getNodeById(nodeId) ??
[...app.rootGraph.subgraphs.values()]
.flatMap((sg) => sg.nodes)
.find((n) => n.id == nodeId)
if (!node) continue
const nodeData = nodeToNodeData(node)
@@ -239,7 +242,6 @@ defineExpose({ runButtonClick })
/>
<NodeWidgets
:node-data
:style="{ background: applyLightThemeColor(nodeData.bgcolor) }"
class="py-3 gap-y-3 **:[.col-span-2]:grid-cols-1 *:has-[textarea]:h-50 rounded-lg max-w-100"
/>
</template>
@@ -279,7 +281,6 @@ defineExpose({ runButtonClick })
'ring-2 ring-inset ring-node-stroke-error'
)
"
:style="{ background: applyLightThemeColor(nodeData.bgcolor) }"
/>
</DropZone>
</template>