fix(editor): Fix showing and hiding canvas edge toolbar when hovering (#13009)

This commit is contained in:
Alex Grozav 2025-02-03 14:41:03 +02:00 committed by GitHub
parent 37d152c148
commit ac7bc4f191
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 67 additions and 24 deletions

View file

@ -45,8 +45,8 @@
"@typescript/vfs": "^1.6.0",
"@vue-flow/background": "^1.3.2",
"@vue-flow/controls": "^1.1.2",
"@vue-flow/core": "^1.41.6",
"@vue-flow/minimap": "^1.5.0",
"@vue-flow/core": "^1.42.1",
"@vue-flow/minimap": "^1.5.2",
"@vue-flow/node-resizer": "^1.4.0",
"@vueuse/components": "^10.11.0",
"@vueuse/core": "^10.11.0",

View file

@ -71,6 +71,30 @@ describe('CanvasEdge', () => {
expect(() => getByTestId('delete-connection-button')).toThrow();
});
it('should hide toolbar after delay', async () => {
vi.useFakeTimers();
const user = userEvent.setup({
advanceTimers: vi.advanceTimersByTime,
});
const { rerender, getByTestId, queryByTestId } = renderComponent({
props: { hovered: true },
});
await user.hover(getByTestId('edge-label'));
expect(queryByTestId('canvas-edge-toolbar')).toBeInTheDocument();
await rerender({ hovered: false });
await user.unhover(getByTestId('edge-label'));
expect(getByTestId('canvas-edge-toolbar')).toBeInTheDocument();
await vi.advanceTimersByTimeAsync(300);
expect(queryByTestId('canvas-edge-toolbar')).not.toBeInTheDocument();
});
it('should compute edgeStyle correctly', () => {
const { container } = renderComponent();

View file

@ -5,7 +5,7 @@ import { isValidNodeConnectionType } from '@/utils/typeGuards';
import type { Connection, EdgeProps } from '@vue-flow/core';
import { BaseEdge, EdgeLabelRenderer } from '@vue-flow/core';
import { NodeConnectionType } from 'n8n-workflow';
import { computed, toRef, useCssModule } from 'vue';
import { computed, ref, toRef, useCssModule, watch } from 'vue';
import CanvasEdgeToolbar from './CanvasEdgeToolbar.vue';
import { getEdgeRenderData } from './utils';
@ -33,7 +33,26 @@ const connectionType = computed(() =>
: NodeConnectionType.Main,
);
const renderToolbar = computed(() => props.hovered && !props.readOnly);
const delayedHovered = ref(props.hovered);
const delayedHoveredSetTimeoutRef = ref<NodeJS.Timeout | null>(null);
const delayedHoveredTimeout = 300;
watch(
() => props.hovered,
(isHovered) => {
if (isHovered) {
if (delayedHoveredSetTimeoutRef.value) clearTimeout(delayedHoveredSetTimeoutRef.value);
delayedHovered.value = true;
} else {
delayedHoveredSetTimeoutRef.value = setTimeout(() => {
delayedHovered.value = false;
}, delayedHoveredTimeout);
}
},
{ immediate: true },
);
const renderToolbar = computed(() => (props.selected || delayedHovered.value) && !props.readOnly);
const isMainConnection = computed(() => data.value.source.type === NodeConnectionType.Main);

View file

@ -1443,19 +1443,19 @@ importers:
version: 1.6.0(typescript@5.7.2)
'@vue-flow/background':
specifier: ^1.3.2
version: 1.3.2(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
version: 1.3.2(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
'@vue-flow/controls':
specifier: ^1.1.2
version: 1.1.2(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
version: 1.1.2(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
'@vue-flow/core':
specifier: ^1.41.6
version: 1.41.6(vue@3.5.13(typescript@5.7.2))
specifier: ^1.42.1
version: 1.42.1(vue@3.5.13(typescript@5.7.2))
'@vue-flow/minimap':
specifier: ^1.5.0
version: 1.5.0(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
specifier: ^1.5.2
version: 1.5.2(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
'@vue-flow/node-resizer':
specifier: ^1.4.0
version: 1.4.0(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
version: 1.4.0(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))
'@vueuse/components':
specifier: ^10.11.0
version: 10.11.0(vue@3.5.13(typescript@5.7.2))
@ -6288,13 +6288,13 @@ packages:
'@vue-flow/core': ^1.23.0
vue: ^3.3.0
'@vue-flow/core@1.41.6':
resolution: {integrity: sha512-8zxcGRqiudra0obDMLTg9L89WxdlV0QrDOdyPYOKWDcD/UK5aT0MIL3Br9TF9AJmHW2z8QZq4cmmgroREL0jgQ==}
'@vue-flow/core@1.42.1':
resolution: {integrity: sha512-QzzTxMAXfOeETKc+N3XMp5XpiPxKBHK5kq98avgTsE6MXyeU2E8EkANwwgSB/hvJ/k36RjU0Y7BOwCHiqiI1tw==}
peerDependencies:
vue: ^3.3.0
'@vue-flow/minimap@1.5.0':
resolution: {integrity: sha512-JhxXDF+8uTc7sgkZHDIvFpHqSl4wsK9xp8Kz5OHwNcXlgGcwqj4yad6jcc1B6bGxm+huESpNmoPotQbpMn6rVw==}
'@vue-flow/minimap@1.5.2':
resolution: {integrity: sha512-XNSpWwwXfCWqJilc2eCW+3ry3r9vhF8HmUw5wrAsUTHiss4R9k5uZLABo7c3T3VdcVRJ8pTfUJ9vjpzb8H+FKg==}
peerDependencies:
'@vue-flow/core': ^1.23.0
vue: ^3.3.0
@ -19361,17 +19361,17 @@ snapshots:
path-browserify: 1.0.1
vscode-uri: 3.0.8
'@vue-flow/background@1.3.2(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
'@vue-flow/background@1.3.2(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@vue-flow/core': 1.41.6(vue@3.5.13(typescript@5.7.2))
'@vue-flow/core': 1.42.1(vue@3.5.13(typescript@5.7.2))
vue: 3.5.13(typescript@5.7.2)
'@vue-flow/controls@1.1.2(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
'@vue-flow/controls@1.1.2(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@vue-flow/core': 1.41.6(vue@3.5.13(typescript@5.7.2))
'@vue-flow/core': 1.42.1(vue@3.5.13(typescript@5.7.2))
vue: 3.5.13(typescript@5.7.2)
'@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2))':
'@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@vueuse/core': 10.11.0(vue@3.5.13(typescript@5.7.2))
d3-drag: 3.0.0
@ -19381,16 +19381,16 @@ snapshots:
transitivePeerDependencies:
- '@vue/composition-api'
'@vue-flow/minimap@1.5.0(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
'@vue-flow/minimap@1.5.2(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@vue-flow/core': 1.41.6(vue@3.5.13(typescript@5.7.2))
'@vue-flow/core': 1.42.1(vue@3.5.13(typescript@5.7.2))
d3-selection: 3.0.0
d3-zoom: 3.0.0
vue: 3.5.13(typescript@5.7.2)
'@vue-flow/node-resizer@1.4.0(@vue-flow/core@1.41.6(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
'@vue-flow/node-resizer@1.4.0(@vue-flow/core@1.42.1(vue@3.5.13(typescript@5.7.2)))(vue@3.5.13(typescript@5.7.2))':
dependencies:
'@vue-flow/core': 1.41.6(vue@3.5.13(typescript@5.7.2))
'@vue-flow/core': 1.42.1(vue@3.5.13(typescript@5.7.2))
d3-drag: 3.0.0
d3-selection: 3.0.0
vue: 3.5.13(typescript@5.7.2)