diff --git a/app/gui2/e2e/widgets.spec.ts b/app/gui2/e2e/widgets.spec.ts index 17b29579d267..80beea7aa617 100644 --- a/app/gui2/e2e/widgets.spec.ts +++ b/app/gui2/e2e/widgets.spec.ts @@ -60,6 +60,10 @@ test('Selection widgets in Data.read node', async ({ page }) => { // Check initially visible arguments const node = locate.graphNodeByBinding(page, 'data') const argumentNames = node.locator('.WidgetArgumentName') + await expect(argumentNames).toHaveCount(1) + + // Check arguments after selecting node + await node.click() await expect(argumentNames).toHaveCount(3) // Set value on `on_problems` (static drop-down) @@ -129,6 +133,10 @@ test('Managing aggregates in `aggregate` node', async ({ page }) => { // Check initially visible arguments const node = locate.graphNodeByBinding(page, 'aggregated') const argumentNames = node.locator('.WidgetArgumentName') + await expect(argumentNames).toHaveCount(1) + + // Check arguments after selecting node + await node.click() await expect(argumentNames).toHaveCount(3) // Add first aggregate diff --git a/app/gui2/mock/providers.ts b/app/gui2/mock/providers.ts index 5100853d8bca..9845731a5550 100644 --- a/app/gui2/mock/providers.ts +++ b/app/gui2/mock/providers.ts @@ -30,6 +30,7 @@ export const graphSelection: GraphSelection = { hoveredNode: undefined, hoveredPort: undefined, isSelected: () => false, + isChanging: false, mouseHandler: () => false, selectAll: () => {}, selected: new Set(), diff --git a/app/gui2/src/components/GraphEditor/GraphNode.vue b/app/gui2/src/components/GraphEditor/GraphNode.vue index 5b2ea3584b5b..3dbdeff2d2ea 100644 --- a/app/gui2/src/components/GraphEditor/GraphNode.vue +++ b/app/gui2/src/components/GraphEditor/GraphNode.vue @@ -88,14 +88,6 @@ const contentNode = ref() const nodeSize = useResizeObserver(rootNode) const baseNodeSize = computed(() => new Vec2(contentNode.value?.scrollWidth ?? 0, nodeSize.value.y)) -/// Menu can be full, partial or off -enum MenuState { - Full, - Partial, - Off, -} -const menuVisible = ref(MenuState.Off) - const error = computed(() => { const externalId = graph.db.idToExternal(nodeId.value) if (!externalId) return @@ -122,12 +114,19 @@ const warning = computed(() => { }) const isSelected = computed(() => nodeSelection?.isSelected(nodeId.value) ?? false) -const isOnlyOneSelected = computed(() => isSelected.value && nodeSelection?.selected.size === 1) -watch(isSelected, (selected) => { - if (!selected) { - menuVisible.value = MenuState.Off - } +const isOnlyOneSelected = computed( + () => isSelected.value && nodeSelection?.selected.size === 1 && !nodeSelection.isChanging, +) + +const menuVisible = isOnlyOneSelected +const menuFull = ref(false) +watch(menuVisible, (visible) => { + if (!visible) menuFull.value = false }) +function openFullMenu() { + menuFull.value = true + nodeSelection?.setSelection(new Set([nodeId.value])) +} const isDocsVisible = ref(false) const visualizationWidth = computed(() => props.node.vis?.width ?? null) @@ -181,7 +180,6 @@ const dragPointer = usePointer((pos, event, type) => { ) { nodeSelection?.handleSelectionOf(event, new Set([nodeId.value])) handleNodeClick(event) - menuVisible.value = MenuState.Partial } startEvent = null startEpochMs.value = 0 @@ -363,13 +361,6 @@ function portGroupStyle(port: PortData) { } } -function openFullMenu() { - if (!nodeSelection?.isSelected(nodeId.value)) { - nodeSelection?.setSelection(new Set([nodeId.value])) - } - menuVisible.value = MenuState.Full -} - const editingComment = ref(false) const documentation = computed({ @@ -419,12 +410,12 @@ const documentation = computed({ {{ node.pattern?.code() ?? '' }} ({ :nodeSize="baseNodeSize" :scale="navigator?.scale ?? 1" :nodePosition="props.node.position" - :isCircularMenuVisible="menuVisible === MenuState.Full || menuVisible === MenuState.Partial" + :isCircularMenuVisible="menuVisible" :currentType="node.vis?.identifier" :isFullscreen="isVisualizationFullscreen" :dataSource="{ type: 'node', nodeId: externalId }" @@ -474,6 +465,7 @@ const documentation = computed({ :icon="icon" :connectedSelfArgumentId="connectedSelfArgumentId" :potentialSelfArgumentId="potentialSelfArgumentId" + :extended="isOnlyOneSelected" @openFullMenu="openFullMenu" /> @@ -484,7 +476,7 @@ const documentation = computed({ () const emit = defineEmits<{ openFullMenu: [] @@ -69,6 +70,7 @@ provideWidgetTree( toRef(props, 'icon'), toRef(props, 'connectedSelfArgumentId'), toRef(props, 'potentialSelfArgumentId'), + toRef(props, 'extended'), layoutTransitions.active, () => { emit('openFullMenu') diff --git a/app/gui2/src/components/GraphEditor/widgets/WidgetApplication.vue b/app/gui2/src/components/GraphEditor/widgets/WidgetApplication.vue index 8da01424979b..1f7935aa934e 100644 --- a/app/gui2/src/components/GraphEditor/widgets/WidgetApplication.vue +++ b/app/gui2/src/components/GraphEditor/widgets/WidgetApplication.vue @@ -1,11 +1,13 @@