mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-19 11:01:15 +00:00
feat(editor): Add context menu to canvas v2 (no-changelog) (#10088)
This commit is contained in:
@@ -8,6 +8,7 @@ import CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRen
|
||||
import HandleRenderer from '@/components/canvas/elements/handles/HandleRenderer.vue';
|
||||
import { useNodeConnections } from '@/composables/useNodeConnections';
|
||||
import { CanvasNodeKey } from '@/constants';
|
||||
import { useContextMenu } from '@/composables/useContextMenu';
|
||||
import { Position } from '@vue-flow/core';
|
||||
import type { XYPosition, NodeProps } from '@vue-flow/core';
|
||||
|
||||
@@ -17,12 +18,14 @@ const emit = defineEmits<{
|
||||
select: [id: string, selected: boolean];
|
||||
toggle: [id: string];
|
||||
activate: [id: string];
|
||||
'open:contextmenu': [id: string, event: MouseEvent, source: 'node-button' | 'node-right-click'];
|
||||
update: [id: string, parameters: Record<string, unknown>];
|
||||
move: [id: string, position: XYPosition];
|
||||
}>();
|
||||
const props = defineProps<NodeProps<CanvasNodeData>>();
|
||||
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const contextMenu = useContextMenu();
|
||||
|
||||
const inputs = computed(() => props.data.inputs);
|
||||
const outputs = computed(() => props.data.outputs);
|
||||
@@ -110,6 +113,13 @@ function onActivate() {
|
||||
emit('activate', props.id);
|
||||
}
|
||||
|
||||
function onOpenContextMenuFromToolbar(event: MouseEvent) {
|
||||
emit('open:contextmenu', props.id, event, 'node-button');
|
||||
}
|
||||
|
||||
function onOpenContextMenuFromNode(event: MouseEvent) {
|
||||
emit('open:contextmenu', props.id, event, 'node-right-click');
|
||||
}
|
||||
function onUpdate(parameters: Record<string, unknown>) {
|
||||
emit('update', props.id, parameters);
|
||||
}
|
||||
@@ -135,6 +145,11 @@ provide(CanvasNodeKey, {
|
||||
nodeType,
|
||||
});
|
||||
|
||||
const showToolbar = computed(() => {
|
||||
const target = contextMenu.target.value;
|
||||
return contextMenu.isOpen && target?.source === 'node-button' && target.nodeId === id.value;
|
||||
});
|
||||
|
||||
/**
|
||||
* Lifecycle
|
||||
*/
|
||||
@@ -148,7 +163,10 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="$style.canvasNode" data-test-id="canvas-node">
|
||||
<div
|
||||
:class="[$style.canvasNode, { [$style.showToolbar]: showToolbar }]"
|
||||
data-test-id="canvas-node"
|
||||
>
|
||||
<template v-for="source in outputsWithPosition" :key="`${source.type}/${source.index}`">
|
||||
<HandleRenderer
|
||||
mode="output"
|
||||
@@ -182,9 +200,15 @@ watch(
|
||||
@delete="onDelete"
|
||||
@toggle="onDisabledToggle"
|
||||
@run="onRun"
|
||||
@open:contextmenu="onOpenContextMenuFromToolbar"
|
||||
/>
|
||||
|
||||
<CanvasNodeRenderer @dblclick="onActivate" @move="onMove" @update="onUpdate">
|
||||
<CanvasNodeRenderer
|
||||
@dblclick="onActivate"
|
||||
@move="onMove"
|
||||
@update="onUpdate"
|
||||
@open:contextmenu="onOpenContextMenuFromNode"
|
||||
>
|
||||
<NodeIcon
|
||||
v-if="nodeType"
|
||||
:node-type="nodeType"
|
||||
@@ -199,7 +223,8 @@ watch(
|
||||
|
||||
<style lang="scss" module>
|
||||
.canvasNode {
|
||||
&:hover {
|
||||
&:hover,
|
||||
&.showToolbar {
|
||||
.canvasNodeToolbar {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -214,8 +239,4 @@ watch(
|
||||
transform: translate(-50%, -100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.canvasNodeToolbar:focus-within {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user