From 8bb774f7ca2c33ea98e152dd69e91dfbebc00e8d Mon Sep 17 00:00:00 2001 From: DrJKL Date: Fri, 3 Jul 2026 16:46:31 -0700 Subject: [PATCH] refactor: pass single host instead of parents array to widget rows The promoted-widget side panel only ever has one host SubgraphNode, so collapse the parents: SubgraphNode[] prop to host?: SubgraphNode across SectionWidgets/WidgetItem/WidgetActions and drop the [node] wrapper in TabSubgraphInputs. Amp-Thread-ID: https://ampcode.com/threads/T-019f2964-7a96-7579-8883-caeb3b2b07da Co-authored-by: Amp --- .../rightSidePanel/parameters/SectionWidgets.vue | 6 +++--- .../parameters/TabSubgraphInputs.test.ts | 2 +- .../parameters/TabSubgraphInputs.vue | 6 ++---- .../parameters/WidgetActions.test.ts | 14 +++++++------- .../rightSidePanel/parameters/WidgetActions.vue | 15 +++++---------- .../rightSidePanel/parameters/WidgetItem.vue | 10 +++++----- 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/components/rightSidePanel/parameters/SectionWidgets.vue b/src/components/rightSidePanel/parameters/SectionWidgets.vue index 045ecad3ba..394aab7b58 100644 --- a/src/components/rightSidePanel/parameters/SectionWidgets.vue +++ b/src/components/rightSidePanel/parameters/SectionWidgets.vue @@ -43,12 +43,12 @@ const { isDraggable = false, hiddenFavoriteIndicator = false, showNodeName = false, - parents = [], + host, enableEmptyState = false, tooltip } = defineProps<{ label?: string - parents?: SubgraphNode[] + host?: SubgraphNode node?: LGraphNode widgets: { widget: IBaseWidget; node: LGraphNode }[] showLocateButton?: boolean @@ -377,7 +377,7 @@ defineExpose({ :is-draggable="isDraggable" :hidden-favorite-indicator="hiddenFavoriteIndicator" :show-node-name="showNodeName" - :parents="parents" + :host="host" @update:widget-value="handleWidgetValueUpdate(node, widget, $event)" @reset-to-default="handleWidgetReset(node, widget, $event)" /> diff --git a/src/components/rightSidePanel/parameters/TabSubgraphInputs.test.ts b/src/components/rightSidePanel/parameters/TabSubgraphInputs.test.ts index f4b7077096..3fb7498cb3 100644 --- a/src/components/rightSidePanel/parameters/TabSubgraphInputs.test.ts +++ b/src/components/rightSidePanel/parameters/TabSubgraphInputs.test.ts @@ -33,7 +33,7 @@ const captured: { rows: { node: LGraphNode; widget: IBaseWidget }[] } = { } const SectionWidgetsStub = { - props: ['widgets', 'node', 'parents'], + props: ['widgets', 'node', 'host'], setup(props: Record) { captured.rows = props.widgets as { node: LGraphNode diff --git a/src/components/rightSidePanel/parameters/TabSubgraphInputs.vue b/src/components/rightSidePanel/parameters/TabSubgraphInputs.vue index 83e83b2dd6..6e6fc4e1f6 100644 --- a/src/components/rightSidePanel/parameters/TabSubgraphInputs.vue +++ b/src/components/rightSidePanel/parameters/TabSubgraphInputs.vue @@ -88,8 +88,6 @@ const advancedInputsWidgets = computed((): NodeWidgetsList => { ) }) -const parents = computed(() => [node]) - const searchedWidgetsList = shallowRef(widgetsList.value) const isSearching = ref(false) @@ -140,7 +138,7 @@ const label = computed(() => { :collapse="firstSectionCollapsed && !isSearching" :node :label - :parents + :host="node" :widgets="searchedWidgetsList" :is-draggable="!isSearching" :enable-empty-state="isSearching" @@ -164,7 +162,7 @@ const label = computed(() => { ref="advancedInputsSectionRef" v-model:collapse="advancedInputsCollapsed" :label="t('rightSidePanel.advancedInputs')" - :parents="parents" + :host="node" :widgets="advancedInputsWidgets" show-node-name class="border-b border-interface-stroke" diff --git a/src/components/rightSidePanel/parameters/WidgetActions.test.ts b/src/components/rightSidePanel/parameters/WidgetActions.test.ts index 96a1d6c4ed..0f72bb6998 100644 --- a/src/components/rightSidePanel/parameters/WidgetActions.test.ts +++ b/src/components/rightSidePanel/parameters/WidgetActions.test.ts @@ -209,19 +209,19 @@ describe('WidgetActions', () => { expect(onResetToDefault).toHaveBeenCalledWith('option1') }) - it('promotes the widget when "Show input" is clicked on a node with parents', async () => { + it('promotes the widget into the host when "Show input" is clicked', async () => { const widget = createMockWidget() const node = createMockNode() - const parents = [fromAny({ id: 2 })] + const host = fromAny({ id: 2 }) - const { user } = renderWidgetActions(widget, node, { parents }) + const { user } = renderWidgetActions(widget, node, { host }) await user.click(screen.getByRole('button', { name: /Show input/ })) - expect(promoteWidget).toHaveBeenCalledWith(node, widget, parents) + expect(promoteWidget).toHaveBeenCalledWith(node, widget, [host]) }) - it('does not offer "Show input" without parents', () => { + it('does not offer "Show input" without a host', () => { renderWidgetActions(createMockWidget(), createMockNode()) expect( @@ -238,9 +238,9 @@ describe('WidgetActions', () => { isSubgraphNode: () => true, getSlotFromWidget: () => ({ widgetId: 'graph-test:1:test_widget' }) }) - const parents = [fromAny({ id: 2 })] + const host = fromAny({ id: 2 }) - renderWidgetActions(widget, node, { parents }) + renderWidgetActions(widget, node, { host }) expect( screen.queryByRole('button', { name: /Show input/ }) diff --git a/src/components/rightSidePanel/parameters/WidgetActions.vue b/src/components/rightSidePanel/parameters/WidgetActions.vue index 86603cc79f..a1fcbc87f6 100644 --- a/src/components/rightSidePanel/parameters/WidgetActions.vue +++ b/src/components/rightSidePanel/parameters/WidgetActions.vue @@ -16,14 +16,10 @@ import { useFavoritedWidgetsStore } from '@/stores/workspace/favoritedWidgetsSto import { getWidgetDefaultValue, promptWidgetLabel } from '@/utils/widgetUtil' import type { WidgetValue } from '@/utils/widgetUtil' -const { - widget, - node, - parents = [] -} = defineProps<{ +const { widget, node, host } = defineProps<{ widget: IBaseWidget node: LGraphNode - parents?: SubgraphNode[] + host?: SubgraphNode }>() const emit = defineEmits<{ @@ -36,12 +32,11 @@ const favoritedWidgetsStore = useFavoritedWidgetsStore() const nodeDefStore = useNodeDefStore() const { t } = useI18n() -const hasParents = computed(() => parents?.length > 0) const isLinked = computed(() => { if (!node.isSubgraphNode()) return false return inputForWidget(node, widget)?.widgetId != null }) -const canShowInput = computed(() => hasParents.value && !isLinked.value) +const canShowInput = computed(() => host != null && !isLinked.value) const isFavorited = computed(() => favoritedWidgetsStore.isFavorited(node, widget.name) ) @@ -72,8 +67,8 @@ async function handleRename() { } function handleShowInput() { - if (!parents?.length) return - promoteWidget(node, widget, parents) + if (!host) return + promoteWidget(node, widget, [host]) } function handleToggleFavorite() { diff --git a/src/components/rightSidePanel/parameters/WidgetItem.vue b/src/components/rightSidePanel/parameters/WidgetItem.vue index f8ce7dac7f..9981780343 100644 --- a/src/components/rightSidePanel/parameters/WidgetItem.vue +++ b/src/components/rightSidePanel/parameters/WidgetItem.vue @@ -40,7 +40,7 @@ const { hiddenFavoriteIndicator = false, hiddenWidgetActions = false, showNodeName = false, - parents = [] + host } = defineProps<{ widget: IBaseWidget node: LGraphNode @@ -48,7 +48,7 @@ const { hiddenFavoriteIndicator?: boolean hiddenWidgetActions?: boolean showNodeName?: boolean - parents?: SubgraphNode[] + host?: SubgraphNode }>() const emit = defineEmits<{ @@ -113,7 +113,7 @@ const displayNodeName = computed((): string | null => { }) }) -const hasParents = computed(() => parents?.length > 0) +const hasHost = computed(() => host != null) const widgetValue = computed({ get: () => widget.value, @@ -175,7 +175,7 @@ const displayLabel = customRef((track, trigger) => { /> {{ displayNodeName }} @@ -188,7 +188,7 @@ const displayLabel = customRef((track, trigger) => { v-model:label="displayLabel" :widget="widget" :node="node" - :parents="parents" + :host="host" @reset-to-default="emit('resetToDefault', $event)" />