mirror of
https://github.com/enso-org/enso.git
synced 2024-11-24 00:27:16 +03:00
Fix dangling node connection (#8902)
Fixes #8871 The issue was caused by invalid port registration. Because of the existing context switch expression (which is not visible in GUI), the port incorrectly considered itself to belong to another node. This happened because the port was only aware of the visible part of the node’s AST and considered it the whole node. There are two fixes in this PR. Either of them fixes the issue, and they are both implemented for robustness: 1. We provide `nodeId` information to the widget tree, so it no longer assumes the node ID from AST. 2. The order of checks in `getPortNodeId` is swapped. Now we first search by AST, only then try to look up the port. It makes sense to me because the AST is a single root of truth, and we should only rely on registered ports if AST does not exist (which happens for unconnected ports).
This commit is contained in:
parent
2028d6b2c1
commit
801cc7b37d
@ -388,7 +388,7 @@ function portGroupStyle(port: PortData) {
|
|||||||
<div class="node" @pointerdown="handleNodeClick" v-on="dragPointer.events">
|
<div class="node" @pointerdown="handleNodeClick" v-on="dragPointer.events">
|
||||||
<SvgIcon class="icon grab-handle" :name="icon"></SvgIcon>
|
<SvgIcon class="icon grab-handle" :name="icon"></SvgIcon>
|
||||||
<div ref="contentNode" class="widget-tree">
|
<div ref="contentNode" class="widget-tree">
|
||||||
<NodeWidgetTree :ast="displayedExpression" />
|
<NodeWidgetTree :ast="displayedExpression" :nodeId="nodeId" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<GraphNodeError v-if="error" class="error" :error="error" />
|
<GraphNodeError v-if="error" class="error" :error="error" />
|
||||||
|
@ -3,11 +3,11 @@ import NodeWidget from '@/components/GraphEditor/NodeWidget.vue'
|
|||||||
import { useTransitioning } from '@/composables/animation'
|
import { useTransitioning } from '@/composables/animation'
|
||||||
import { WidgetInput, type WidgetUpdate } from '@/providers/widgetRegistry'
|
import { WidgetInput, type WidgetUpdate } from '@/providers/widgetRegistry'
|
||||||
import { provideWidgetTree } from '@/providers/widgetTree'
|
import { provideWidgetTree } from '@/providers/widgetTree'
|
||||||
import { useGraphStore } from '@/stores/graph'
|
import { useGraphStore, type NodeId } from '@/stores/graph'
|
||||||
import { Ast } from '@/util/ast'
|
import { Ast } from '@/util/ast'
|
||||||
import { computed, toRef } from 'vue'
|
import { computed, toRef } from 'vue'
|
||||||
|
|
||||||
const props = defineProps<{ ast: Ast.Ast }>()
|
const props = defineProps<{ ast: Ast.Ast; nodeId: NodeId }>()
|
||||||
const graph = useGraphStore()
|
const graph = useGraphStore()
|
||||||
const rootPort = computed(() => {
|
const rootPort = computed(() => {
|
||||||
const input = WidgetInput.FromAst(props.ast)
|
const input = WidgetInput.FromAst(props.ast)
|
||||||
@ -54,7 +54,7 @@ function handleWidgetUpdates(update: WidgetUpdate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const layoutTransitions = useTransitioning(observedLayoutTransitions)
|
const layoutTransitions = useTransitioning(observedLayoutTransitions)
|
||||||
provideWidgetTree(toRef(props, 'ast'), layoutTransitions.active)
|
provideWidgetTree(toRef(props, 'ast'), toRef(props, 'nodeId'), layoutTransitions.active)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { createContextStore } from '@/providers'
|
import { createContextStore } from '@/providers'
|
||||||
import { asNodeId } from '@/stores/graph/graphDatabase'
|
import { type NodeId } from '@/stores/graph/graphDatabase'
|
||||||
import { Ast } from '@/util/ast'
|
import { Ast } from '@/util/ast'
|
||||||
import { computed, proxyRefs, type Ref } from 'vue'
|
import { computed, proxyRefs, type Ref } from 'vue'
|
||||||
|
|
||||||
export { injectFn as injectWidgetTree, provideFn as provideWidgetTree }
|
export { injectFn as injectWidgetTree, provideFn as provideWidgetTree }
|
||||||
const { provideFn, injectFn } = createContextStore(
|
const { provideFn, injectFn } = createContextStore(
|
||||||
'Widget tree',
|
'Widget tree',
|
||||||
(astRoot: Ref<Ast.Ast>, hasActiveAnimations: Ref<boolean>) => {
|
(astRoot: Ref<Ast.Ast>, nodeId: Ref<NodeId>, hasActiveAnimations: Ref<boolean>) => {
|
||||||
const nodeId = computed(() => asNodeId(astRoot.value.id))
|
|
||||||
const nodeSpanStart = computed(() => astRoot.value.span![0])
|
const nodeSpanStart = computed(() => astRoot.value.span![0])
|
||||||
return proxyRefs({ astRoot, nodeId, nodeSpanStart, hasActiveAnimations })
|
return proxyRefs({ astRoot, nodeId, nodeSpanStart, hasActiveAnimations })
|
||||||
},
|
},
|
||||||
|
@ -388,7 +388,7 @@ export const useGraphStore = defineStore('graph', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getPortNodeId(id: PortId): NodeId | undefined {
|
function getPortNodeId(id: PortId): NodeId | undefined {
|
||||||
return getPortPrimaryInstance(id)?.nodeId ?? db.getExpressionNodeId(id as string as Ast.AstId)
|
return db.getExpressionNodeId(id as string as Ast.AstId) ?? getPortPrimaryInstance(id)?.nodeId
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user