From ab41fc3fb5f15e9c7ce7279b46cec90a511d0e0d Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Wed, 26 Feb 2025 12:42:49 +0200 Subject: [PATCH] fix(editor): Fix keyboard shortcuts no longer working after editing sticky note (#13502) --- .../src/components/canvas/Canvas.vue | 20 ++++++--- .../canvas/elements/nodes/CanvasNode.vue | 8 +++- .../render-types/CanvasNodeDefault.test.ts | 15 +++++++ .../nodes/render-types/CanvasNodeDefault.vue | 14 +++++- .../render-types/CanvasNodeStickyNote.test.ts | 44 +++++++++++++++++++ .../render-types/CanvasNodeStickyNote.vue | 27 +++++++----- .../src/composables/useCanvasOperations.ts | 5 +++ packages/editor-ui/src/types/canvas.ts | 2 +- packages/editor-ui/src/views/NodeView.vue | 10 ++++- 9 files changed, 122 insertions(+), 23 deletions(-) diff --git a/packages/editor-ui/src/components/canvas/Canvas.vue b/packages/editor-ui/src/components/canvas/Canvas.vue index bc4eab4407..a13c95e2d3 100644 --- a/packages/editor-ui/src/components/canvas/Canvas.vue +++ b/packages/editor-ui/src/components/canvas/Canvas.vue @@ -44,7 +44,8 @@ const emit = defineEmits<{ 'update:modelValue': [elements: CanvasNode[]]; 'update:node:position': [id: string, position: XYPosition]; 'update:nodes:position': [events: CanvasNodeMoveEvent[]]; - 'update:node:active': [id: string]; + 'update:node:activated': [id: string]; + 'update:node:deactivated': [id: string]; 'update:node:enabled': [id: string]; 'update:node:selected': [id?: string]; 'update:node:name': [id: string]; @@ -246,7 +247,7 @@ function selectUpstreamNodes(id: string) { const keyMap = computed(() => ({ ctrl_c: emitWithSelectedNodes((ids) => emit('copy:nodes', ids)), - enter: emitWithLastSelectedNode((id) => onSetNodeActive(id)), + enter: emitWithLastSelectedNode((id) => onSetNodeActivated(id)), ctrl_a: () => addSelectedNodes(graphNodes.value), // Support both key and code for zooming in and out 'shift_+|+|=|shift_Equal|Equal': async () => await onZoomIn(), @@ -337,9 +338,13 @@ function onSelectionDragStop(event: NodeDragEvent) { onUpdateNodesPosition(event.nodes.map(({ id, position }) => ({ id, position }))); } -function onSetNodeActive(id: string) { - props.eventBus.emit('nodes:action', { ids: [id], action: 'update:node:active' }); - emit('update:node:active', id); +function onSetNodeActivated(id: string) { + props.eventBus.emit('nodes:action', { ids: [id], action: 'update:node:activated' }); + emit('update:node:activated', id); +} + +function onSetNodeDeactivated(id: string) { + emit('update:node:deactivated', id); } function clearSelectedNodes() { @@ -607,7 +612,7 @@ function onContextMenuAction(action: ContextMenuAction, nodeIds: string[]) { case 'toggle_activation': return emit('update:nodes:enabled', nodeIds); case 'open': - return onSetNodeActive(nodeIds[0]); + return onSetNodeActivated(nodeIds[0]); case 'rename': return emit('update:node:name', nodeIds[0]); case 'change_color': @@ -772,7 +777,8 @@ provide(CanvasKey, { @run="onRunNode" @select="onSelectNode" @toggle="onToggleNodeEnabled" - @activate="onSetNodeActive" + @activate="onSetNodeActivated" + @deactivate="onSetNodeDeactivated" @open:contextmenu="onOpenNodeContextMenu" @update="onUpdateNodeParameters" @update:inputs="onUpdateNodeInputs" diff --git a/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue b/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue index feaec44b3f..3dcbdf105b 100644 --- a/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue +++ b/packages/editor-ui/src/components/canvas/elements/nodes/CanvasNode.vue @@ -59,6 +59,7 @@ const emit = defineEmits<{ select: [id: string, selected: boolean]; toggle: [id: string]; activate: [id: string]; + deactivate: [id: string]; 'open:contextmenu': [id: string, event: MouseEvent, source: 'node-button' | 'node-right-click']; update: [id: string, parameters: Record]; 'update:inputs': [id: string]; @@ -258,6 +259,10 @@ function onActivate() { emit('activate', props.id); } +function onDeactivate() { + emit('deactivate', props.id); +} + function onOpenContextMenuFromToolbar(event: MouseEvent) { emit('open:contextmenu', props.id, event, 'node-button'); } @@ -395,7 +400,8 @@ onBeforeUnmount(() => { /> { expect(getByTestId('canvas-trigger-node')).toMatchSnapshot(); }); }); + + it('should emit "activate" on double click', async () => { + const { getByText, emitted } = renderComponent({ + global: { + provide: { + ...createCanvasNodeProvide(), + }, + }, + }); + + await fireEvent.dblClick(getByText('Test Node')); + + expect(emitted()).toHaveProperty('activate'); + }); }); diff --git a/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue b/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue index 0514965008..c30786d28c 100644 --- a/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue +++ b/packages/editor-ui/src/components/canvas/elements/nodes/render-types/CanvasNodeDefault.vue @@ -12,10 +12,12 @@ const i18n = useI18n(); const emit = defineEmits<{ 'open:contextmenu': [event: MouseEvent]; + activate: [id: string]; }>(); const { initialized, viewport } = useCanvas(); const { + id, label, subtitle, inputs, @@ -122,10 +124,20 @@ watch(viewport, () => { function openContextMenu(event: MouseEvent) { emit('open:contextmenu', event); } + +function onActivate() { + emit('activate', id.value); +}