mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat(editor): Allow jumping into sub-workflow with shortkey (#15200)
This commit is contained in:
@@ -23,7 +23,7 @@ import type {
|
||||
IParameterLabel,
|
||||
NodeParameterValueType,
|
||||
} from 'n8n-workflow';
|
||||
import { CREDENTIAL_EMPTY_VALUE, NodeHelpers } from 'n8n-workflow';
|
||||
import { CREDENTIAL_EMPTY_VALUE, isResourceLocatorValue, NodeHelpers } from 'n8n-workflow';
|
||||
|
||||
import CodeNodeEditor from '@/components/CodeNodeEditor/CodeNodeEditor.vue';
|
||||
import CredentialsSelect from '@/components/CredentialsSelect.vue';
|
||||
@@ -38,7 +38,6 @@ import SqlEditor from '@/components/SqlEditor/SqlEditor.vue';
|
||||
import TextEdit from '@/components/TextEdit.vue';
|
||||
|
||||
import { hasExpressionMapping, isValueExpression } from '@/utils/nodeTypesUtils';
|
||||
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
||||
|
||||
import {
|
||||
AI_TRANSFORM_NODE_TYPE,
|
||||
|
||||
@@ -12,9 +12,9 @@ import { useToast } from '@/composables/useToast';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { getMappedResult } from '@/utils/mappingUtils';
|
||||
import { hasExpressionMapping, hasOnlyListMode, isValueExpression } from '@/utils/nodeTypesUtils';
|
||||
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
import {
|
||||
isResourceLocatorValue,
|
||||
type INodeProperties,
|
||||
type IParameterLabel,
|
||||
type NodeParameterValueType,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import type { INodeProperties, NodeParameterValueType } from 'n8n-workflow';
|
||||
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
||||
import {
|
||||
isResourceLocatorValue,
|
||||
type INodeProperties,
|
||||
type NodeParameterValueType,
|
||||
} from 'n8n-workflow';
|
||||
import { isValueExpression } from '@/utils/nodeTypesUtils';
|
||||
import { computed } from 'vue';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
|
||||
@@ -18,19 +18,19 @@ import {
|
||||
getMainAuthField,
|
||||
hasOnlyListMode as hasOnlyListModeUtil,
|
||||
} from '@/utils/nodeTypesUtils';
|
||||
import { isResourceLocatorValue } from '@/utils/typeGuards';
|
||||
import stringify from 'fast-json-stable-stringify';
|
||||
import type { EventBus } from '@n8n/utils/event-bus';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
import type {
|
||||
INode,
|
||||
INodeListSearchItems,
|
||||
INodeParameterResourceLocator,
|
||||
INodeParameters,
|
||||
INodeProperties,
|
||||
INodePropertyMode,
|
||||
INodePropertyModeTypeOptions,
|
||||
NodeParameterValue,
|
||||
import {
|
||||
isResourceLocatorValue,
|
||||
type INode,
|
||||
type INodeListSearchItems,
|
||||
type INodeParameterResourceLocator,
|
||||
type INodeParameters,
|
||||
type INodeProperties,
|
||||
type INodePropertyMode,
|
||||
type INodePropertyModeTypeOptions,
|
||||
type NodeParameterValue,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
computed,
|
||||
|
||||
@@ -59,7 +59,7 @@ const emit = defineEmits<{
|
||||
'update:modelValue': [elements: CanvasNode[]];
|
||||
'update:node:position': [id: string, position: XYPosition];
|
||||
'update:nodes:position': [events: CanvasNodeMoveEvent[]];
|
||||
'update:node:activated': [id: string];
|
||||
'update:node:activated': [id: string, event?: MouseEvent];
|
||||
'update:node:deactivated': [id: string];
|
||||
'update:node:enabled': [id: string];
|
||||
'update:node:selected': [id?: string];
|
||||
@@ -95,6 +95,7 @@ const emit = defineEmits<{
|
||||
'create:workflow': [];
|
||||
'drag-and-drop': [position: XYPosition, event: DragEvent];
|
||||
'tidy-up': [CanvasLayoutEvent];
|
||||
'open:sub-workflow': [nodeId: string];
|
||||
}>();
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -266,6 +267,7 @@ function selectUpstreamNodes(id: string) {
|
||||
|
||||
const keyMap = computed(() => {
|
||||
const readOnlyKeymap = {
|
||||
ctrl_shift_o: emitWithLastSelectedNode((id) => emit('open:sub-workflow', id)),
|
||||
ctrl_c: emitWithSelectedNodes((ids) => emit('copy:nodes', ids)),
|
||||
enter: emitWithLastSelectedNode((id) => onSetNodeActivated(id)),
|
||||
ctrl_a: () => addSelectedNodes(graphNodes.value),
|
||||
@@ -368,9 +370,9 @@ function onSelectionEnd() {
|
||||
}
|
||||
}
|
||||
|
||||
function onSetNodeActivated(id: string) {
|
||||
function onSetNodeActivated(id: string, event?: MouseEvent) {
|
||||
props.eventBus.emit('nodes:action', { ids: [id], action: 'update:node:activated' });
|
||||
emit('update:node:activated', id);
|
||||
emit('update:node:activated', id, event);
|
||||
}
|
||||
|
||||
function onSetNodeDeactivated(id: string) {
|
||||
@@ -661,6 +663,9 @@ async function onContextMenuAction(action: ContextMenuAction, nodeIds: string[])
|
||||
return props.eventBus.emit('nodes:action', { ids: nodeIds, action: 'update:sticky:color' });
|
||||
case 'tidy_up':
|
||||
return await onTidyUp({ source: 'context-menu' });
|
||||
case 'open_sub_workflow': {
|
||||
return emit('open:sub-workflow', nodeIds[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ const emit = defineEmits<{
|
||||
run: [id: string];
|
||||
select: [id: string, selected: boolean];
|
||||
toggle: [id: string];
|
||||
activate: [id: string];
|
||||
activate: [id: string, event: MouseEvent];
|
||||
deactivate: [id: string];
|
||||
'open:contextmenu': [id: string, event: MouseEvent, source: 'node-button' | 'node-right-click'];
|
||||
update: [id: string, parameters: Record<string, unknown>];
|
||||
@@ -240,8 +240,8 @@ function onDisabledToggle() {
|
||||
emit('toggle', props.id);
|
||||
}
|
||||
|
||||
function onActivate() {
|
||||
emit('activate', props.id);
|
||||
function onActivate(id: string, event: MouseEvent) {
|
||||
emit('activate', id, event);
|
||||
}
|
||||
|
||||
function onDeactivate() {
|
||||
|
||||
@@ -12,7 +12,7 @@ const i18n = useI18n();
|
||||
|
||||
const emit = defineEmits<{
|
||||
'open:contextmenu': [event: MouseEvent];
|
||||
activate: [id: string];
|
||||
activate: [id: string, event: MouseEvent];
|
||||
}>();
|
||||
|
||||
const { initialized, viewport } = useCanvas();
|
||||
@@ -130,8 +130,8 @@ function openContextMenu(event: MouseEvent) {
|
||||
emit('open:contextmenu', event);
|
||||
}
|
||||
|
||||
function onActivate() {
|
||||
emit('activate', id.value);
|
||||
function onActivate(event: MouseEvent) {
|
||||
emit('activate', id.value, event);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user