mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Merge e5fa17e111
into d2dd1796a8
This commit is contained in:
commit
1753af5ad1
|
@ -55,7 +55,7 @@ export function createCanvasNodeData({
|
||||||
|
|
||||||
export function createCanvasNodeElement({
|
export function createCanvasNodeElement({
|
||||||
id = '1',
|
id = '1',
|
||||||
type = 'default',
|
type = 'canvas-node',
|
||||||
label = 'Node',
|
label = 'Node',
|
||||||
position = { x: 100, y: 100 },
|
position = { x: 100, y: 100 },
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
MANUAL_TRIGGER_NODE_TYPE,
|
MANUAL_TRIGGER_NODE_TYPE,
|
||||||
NO_OP_NODE_TYPE,
|
NO_OP_NODE_TYPE,
|
||||||
SET_NODE_TYPE,
|
SET_NODE_TYPE,
|
||||||
|
SIMULATE_NODE_TYPE,
|
||||||
STICKY_NODE_TYPE,
|
STICKY_NODE_TYPE,
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
import type { INodeUi, IWorkflowDb } from '@/Interface';
|
import type { INodeUi, IWorkflowDb } from '@/Interface';
|
||||||
|
@ -50,6 +51,7 @@ export const mockNode = ({
|
||||||
|
|
||||||
export const mockNodeTypeDescription = ({
|
export const mockNodeTypeDescription = ({
|
||||||
name = SET_NODE_TYPE,
|
name = SET_NODE_TYPE,
|
||||||
|
icon = 'fa:pen',
|
||||||
version = 1,
|
version = 1,
|
||||||
credentials = [],
|
credentials = [],
|
||||||
inputs = [NodeConnectionType.Main],
|
inputs = [NodeConnectionType.Main],
|
||||||
|
@ -58,6 +60,7 @@ export const mockNodeTypeDescription = ({
|
||||||
properties = [],
|
properties = [],
|
||||||
}: {
|
}: {
|
||||||
name?: INodeTypeDescription['name'];
|
name?: INodeTypeDescription['name'];
|
||||||
|
icon?: INodeTypeDescription['icon'];
|
||||||
version?: INodeTypeDescription['version'];
|
version?: INodeTypeDescription['version'];
|
||||||
credentials?: INodeTypeDescription['credentials'];
|
credentials?: INodeTypeDescription['credentials'];
|
||||||
inputs?: INodeTypeDescription['inputs'];
|
inputs?: INodeTypeDescription['inputs'];
|
||||||
|
@ -67,6 +70,7 @@ export const mockNodeTypeDescription = ({
|
||||||
} = {}) =>
|
} = {}) =>
|
||||||
mock<INodeTypeDescription>({
|
mock<INodeTypeDescription>({
|
||||||
name,
|
name,
|
||||||
|
icon,
|
||||||
displayName: name,
|
displayName: name,
|
||||||
description: '',
|
description: '',
|
||||||
version,
|
version,
|
||||||
|
@ -101,6 +105,7 @@ export const mockNodes = [
|
||||||
mockNode({ name: 'Chat Trigger', type: CHAT_TRIGGER_NODE_TYPE }),
|
mockNode({ name: 'Chat Trigger', type: CHAT_TRIGGER_NODE_TYPE }),
|
||||||
mockNode({ name: 'Agent', type: AGENT_NODE_TYPE }),
|
mockNode({ name: 'Agent', type: AGENT_NODE_TYPE }),
|
||||||
mockNode({ name: 'Sticky', type: STICKY_NODE_TYPE }),
|
mockNode({ name: 'Sticky', type: STICKY_NODE_TYPE }),
|
||||||
|
mockNode({ name: 'Simulate', type: SIMULATE_NODE_TYPE }),
|
||||||
mockNode({ name: CanvasNodeRenderType.AddNodes, type: CanvasNodeRenderType.AddNodes }),
|
mockNode({ name: CanvasNodeRenderType.AddNodes, type: CanvasNodeRenderType.AddNodes }),
|
||||||
mockNode({ name: 'End', type: NO_OP_NODE_TYPE }),
|
mockNode({ name: 'End', type: NO_OP_NODE_TYPE }),
|
||||||
];
|
];
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { N8nTooltip } from '@n8n/design-system';
|
||||||
import { createEventBus } from '@n8n/utils/event-bus';
|
import { createEventBus } from '@n8n/utils/event-bus';
|
||||||
import { computed, onMounted, ref, useCssModule } from 'vue';
|
import { computed, onMounted, ref, useCssModule } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||||
|
|
||||||
const workflowsStore = useWorkflowsStore();
|
const workflowsStore = useWorkflowsStore();
|
||||||
const nodeTypesStore = useNodeTypesStore();
|
const nodeTypesStore = useNodeTypesStore();
|
||||||
|
@ -51,6 +52,23 @@ const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping(
|
||||||
connections,
|
connections,
|
||||||
workflowObject,
|
workflowObject,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const nodeTypeDescriptions = computed(() => {
|
||||||
|
return nodes.value.reduce<Record<string, INodeTypeDescription>>((acc, node) => {
|
||||||
|
const key = `${node.type}@${node.typeVersion}`;
|
||||||
|
if (acc[key]) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeTypeDescription = nodeTypesStore.getNodeType(node.type, node.typeVersion);
|
||||||
|
if (nodeTypeDescription) {
|
||||||
|
acc[key] = nodeTypeDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
});
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
workflowsStore.resetState();
|
workflowsStore.resetState();
|
||||||
resetWorkspace();
|
resetWorkspace();
|
||||||
|
@ -141,6 +159,7 @@ onMounted(loadData);
|
||||||
:class="{ [$style.canvas]: true }"
|
:class="{ [$style.canvas]: true }"
|
||||||
:nodes="mappedNodes"
|
:nodes="mappedNodes"
|
||||||
:connections="mappedConnections"
|
:connections="mappedConnections"
|
||||||
|
:node-type-descriptions="nodeTypeDescriptions"
|
||||||
:show-bug-reporting-button="false"
|
:show-bug-reporting-button="false"
|
||||||
:read-only="true"
|
:read-only="true"
|
||||||
:event-bus="eventBus"
|
:event-bus="eventBus"
|
||||||
|
|
|
@ -8,6 +8,8 @@ import { createCanvasConnection, createCanvasNodeElement } from '@/__tests__/dat
|
||||||
import { NodeConnectionType } from 'n8n-workflow';
|
import { NodeConnectionType } from 'n8n-workflow';
|
||||||
import type { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
|
import type { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
|
||||||
import { useVueFlow } from '@vue-flow/core';
|
import { useVueFlow } from '@vue-flow/core';
|
||||||
|
import { defaultNodeTypes, mockNodeTypeDescription } from '@/__tests__/mocks';
|
||||||
|
import { SET_NODE_TYPE, SIMULATE_NODE_TYPE } from '@/constants';
|
||||||
|
|
||||||
const matchMedia = global.window.matchMedia;
|
const matchMedia = global.window.matchMedia;
|
||||||
// @ts-expect-error Initialize window object
|
// @ts-expect-error Initialize window object
|
||||||
|
@ -273,4 +275,37 @@ describe('Canvas', () => {
|
||||||
expect(patternCanvas?.innerHTML).not.toContain('<circle');
|
expect(patternCanvas?.innerHTML).not.toContain('<circle');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('simulate', () => {
|
||||||
|
it('should render simulate node', async () => {
|
||||||
|
const nodes = [
|
||||||
|
createCanvasNodeElement({
|
||||||
|
id: '1',
|
||||||
|
label: 'Node',
|
||||||
|
position: { x: 200, y: 200 },
|
||||||
|
data: {
|
||||||
|
type: SIMULATE_NODE_TYPE,
|
||||||
|
typeVersion: 1,
|
||||||
|
simulatedType: SET_NODE_TYPE,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const nodeTypeDescriptions = {
|
||||||
|
[SET_NODE_TYPE]: mockNodeTypeDescription({ name: SET_NODE_TYPE, icon: 'fa:pen' }),
|
||||||
|
[`${SIMULATE_NODE_TYPE}@1`]: defaultNodeTypes[SIMULATE_NODE_TYPE].type.description,
|
||||||
|
};
|
||||||
|
|
||||||
|
const { container } = renderComponent({
|
||||||
|
props: {
|
||||||
|
nodes,
|
||||||
|
nodeTypeDescriptions,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => expect(container.querySelectorAll('.vue-flow__node')).toHaveLength(1));
|
||||||
|
|
||||||
|
expect(container.querySelector('.icon')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,6 +45,7 @@ import { onKeyDown, onKeyUp, useThrottleFn } from '@vueuse/core';
|
||||||
import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
|
import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
|
||||||
import CanvasBackground from './elements/background/CanvasBackground.vue';
|
import CanvasBackground from './elements/background/CanvasBackground.vue';
|
||||||
import { useCanvasTraversal } from '@/composables/useCanvasTraversal';
|
import { useCanvasTraversal } from '@/composables/useCanvasTraversal';
|
||||||
|
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||||
import { NodeConnectionType } from 'n8n-workflow';
|
import { NodeConnectionType } from 'n8n-workflow';
|
||||||
import { useCanvasNodeHover } from '@/composables/useCanvasNodeHover';
|
import { useCanvasNodeHover } from '@/composables/useCanvasNodeHover';
|
||||||
import { useCanvasLayout } from '@/composables/useCanvasLayout';
|
import { useCanvasLayout } from '@/composables/useCanvasLayout';
|
||||||
|
@ -97,6 +98,7 @@ const props = withDefaults(
|
||||||
id?: string;
|
id?: string;
|
||||||
nodes: CanvasNode[];
|
nodes: CanvasNode[];
|
||||||
connections: CanvasConnection[];
|
connections: CanvasConnection[];
|
||||||
|
nodeTypeDescriptions?: Record<string, INodeTypeDescription>;
|
||||||
controlsPosition?: PanelPosition;
|
controlsPosition?: PanelPosition;
|
||||||
eventBus?: EventBus<CanvasEventBusEvents>;
|
eventBus?: EventBus<CanvasEventBusEvents>;
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
|
@ -108,6 +110,7 @@ const props = withDefaults(
|
||||||
id: 'canvas',
|
id: 'canvas',
|
||||||
nodes: () => [],
|
nodes: () => [],
|
||||||
connections: () => [],
|
connections: () => [],
|
||||||
|
nodeTypeDescriptions: () => ({}),
|
||||||
controlsPosition: PanelPosition.BottomLeft,
|
controlsPosition: PanelPosition.BottomLeft,
|
||||||
eventBus: () => createEventBus(),
|
eventBus: () => createEventBus(),
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
|
@ -804,6 +807,10 @@ provide(CanvasKey, {
|
||||||
:event-bus="eventBus"
|
:event-bus="eventBus"
|
||||||
:hovered="nodesHoveredById[nodeProps.id]"
|
:hovered="nodesHoveredById[nodeProps.id]"
|
||||||
:nearby-hovered="nodeProps.id === hoveredTriggerNode.id.value"
|
:nearby-hovered="nodeProps.id === hoveredTriggerNode.id.value"
|
||||||
|
:node-type-description="
|
||||||
|
nodeTypeDescriptions[`${nodeProps.data.type}@${nodeProps.data.typeVersion}`]
|
||||||
|
"
|
||||||
|
:simulated-node-type-description="nodeTypeDescriptions[nodeProps.data.simulatedType]"
|
||||||
@delete="onDeleteNode"
|
@delete="onDeleteNode"
|
||||||
@run="onRunNode"
|
@run="onRunNode"
|
||||||
@select="onSelectNode"
|
@select="onSelectNode"
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Canvas from '@/components/canvas/Canvas.vue';
|
import Canvas from '@/components/canvas/Canvas.vue';
|
||||||
import { computed, ref, toRef, useCssModule } from 'vue';
|
import { computed, ref, toRef, useCssModule } from 'vue';
|
||||||
import type { Workflow } from 'n8n-workflow';
|
import type { INodeTypeDescription, Workflow } from 'n8n-workflow';
|
||||||
import type { IWorkflowDb } from '@/Interface';
|
import type { IWorkflowDb } from '@/Interface';
|
||||||
import { useCanvasMapping } from '@/composables/useCanvasMapping';
|
import { useCanvasMapping } from '@/composables/useCanvasMapping';
|
||||||
import type { EventBus } from '@n8n/utils/event-bus';
|
import type { EventBus } from '@n8n/utils/event-bus';
|
||||||
import { createEventBus } from '@n8n/utils/event-bus';
|
import { createEventBus } from '@n8n/utils/event-bus';
|
||||||
import type { CanvasEventBusEvents } from '@/types';
|
import type { CanvasEventBusEvents } from '@/types';
|
||||||
import { useVueFlow } from '@vue-flow/core';
|
import { useVueFlow } from '@vue-flow/core';
|
||||||
|
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
@ -34,6 +35,8 @@ const props = withDefaults(
|
||||||
|
|
||||||
const $style = useCssModule();
|
const $style = useCssModule();
|
||||||
|
|
||||||
|
const nodeTypesStore = useNodeTypesStore();
|
||||||
|
|
||||||
const { onNodesInitialized } = useVueFlow({ id: props.id });
|
const { onNodesInitialized } = useVueFlow({ id: props.id });
|
||||||
|
|
||||||
const workflow = toRef(props, 'workflow');
|
const workflow = toRef(props, 'workflow');
|
||||||
|
@ -52,6 +55,33 @@ const { nodes: mappedNodes, connections: mappedConnections } = useCanvasMapping(
|
||||||
workflowObject,
|
workflowObject,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const nodeTypeDescriptions = computed(() => {
|
||||||
|
return mappedNodes.value.reduce<Record<string, INodeTypeDescription>>((acc, node) => {
|
||||||
|
if (!node.data) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.data.simulatedType) {
|
||||||
|
const simulatedNodeType = nodeTypesStore.getNodeType(node.data.simulatedType);
|
||||||
|
if (simulatedNodeType) {
|
||||||
|
acc[simulatedNodeType.name] = simulatedNodeType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = `${node.data.type}@${node.data.typeVersion}`;
|
||||||
|
if (acc[key]) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeTypeDescription = nodeTypesStore.getNodeType(node.data.type, node.data.typeVersion);
|
||||||
|
if (nodeTypeDescription) {
|
||||||
|
acc[key] = nodeTypeDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
});
|
||||||
|
|
||||||
const initialFitViewDone = ref(false); // Workaround for https://github.com/bcakmakoglu/vue-flow/issues/1636
|
const initialFitViewDone = ref(false); // Workaround for https://github.com/bcakmakoglu/vue-flow/issues/1636
|
||||||
onNodesInitialized(() => {
|
onNodesInitialized(() => {
|
||||||
if (!initialFitViewDone.value || props.showFallbackNodes) {
|
if (!initialFitViewDone.value || props.showFallbackNodes) {
|
||||||
|
@ -69,6 +99,7 @@ onNodesInitialized(() => {
|
||||||
:id="id"
|
:id="id"
|
||||||
:nodes="mappedNodes"
|
:nodes="mappedNodes"
|
||||||
:connections="mappedConnections"
|
:connections="mappedConnections"
|
||||||
|
:node-type-descriptions="nodeTypeDescriptions"
|
||||||
:event-bus="eventBus"
|
:event-bus="eventBus"
|
||||||
:read-only="readOnly"
|
:read-only="readOnly"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
|
|
@ -18,7 +18,6 @@ import type {
|
||||||
} from '@/types';
|
} from '@/types';
|
||||||
import { CanvasConnectionMode, CanvasNodeRenderType } from '@/types';
|
import { CanvasConnectionMode, CanvasNodeRenderType } from '@/types';
|
||||||
import NodeIcon from '@/components/NodeIcon.vue';
|
import NodeIcon from '@/components/NodeIcon.vue';
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
|
||||||
import CanvasNodeToolbar from '@/components/canvas/elements/nodes/CanvasNodeToolbar.vue';
|
import CanvasNodeToolbar from '@/components/canvas/elements/nodes/CanvasNodeToolbar.vue';
|
||||||
import CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRenderer.vue';
|
import CanvasNodeRenderer from '@/components/canvas/elements/nodes/CanvasNodeRenderer.vue';
|
||||||
import CanvasHandleRenderer from '@/components/canvas/elements/handles/CanvasHandleRenderer.vue';
|
import CanvasHandleRenderer from '@/components/canvas/elements/handles/CanvasHandleRenderer.vue';
|
||||||
|
@ -36,12 +35,15 @@ import type { EventBus } from '@n8n/utils/event-bus';
|
||||||
import { createEventBus } from '@n8n/utils/event-bus';
|
import { createEventBus } from '@n8n/utils/event-bus';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import CanvasNodeTrigger from '@/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue';
|
import CanvasNodeTrigger from '@/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue';
|
||||||
|
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||||
|
|
||||||
type Props = NodeProps<CanvasNodeData> & {
|
type Props = NodeProps<CanvasNodeData> & {
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
eventBus?: EventBus<CanvasEventBusEvents>;
|
eventBus?: EventBus<CanvasEventBusEvents>;
|
||||||
hovered?: boolean;
|
hovered?: boolean;
|
||||||
nearbyHovered?: boolean;
|
nearbyHovered?: boolean;
|
||||||
|
nodeTypeDescription: INodeTypeDescription;
|
||||||
|
simulatedNodeTypeDescription?: INodeTypeDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
const slots = defineSlots<{
|
const slots = defineSlots<{
|
||||||
|
@ -71,7 +73,6 @@ const style = useCssModule();
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
const nodeTypesStore = useNodeTypesStore();
|
|
||||||
const contextMenu = useContextMenu();
|
const contextMenu = useContextMenu();
|
||||||
|
|
||||||
const { connectingHandle } = useCanvas();
|
const { connectingHandle } = useCanvas();
|
||||||
|
@ -98,10 +99,6 @@ const {
|
||||||
|
|
||||||
const isDisabled = computed(() => props.data.disabled);
|
const isDisabled = computed(() => props.data.disabled);
|
||||||
|
|
||||||
const nodeTypeDescription = computed(() => {
|
|
||||||
return nodeTypesStore.getNodeType(props.data.type, props.data.typeVersion);
|
|
||||||
});
|
|
||||||
|
|
||||||
const classes = computed(() => ({
|
const classes = computed(() => ({
|
||||||
[style.canvasNode]: true,
|
[style.canvasNode]: true,
|
||||||
[style.showToolbar]: showToolbar.value,
|
[style.showToolbar]: showToolbar.value,
|
||||||
|
@ -407,7 +404,7 @@ onBeforeUnmount(() => {
|
||||||
@open:contextmenu="onOpenContextMenuFromNode"
|
@open:contextmenu="onOpenContextMenuFromNode"
|
||||||
>
|
>
|
||||||
<NodeIcon
|
<NodeIcon
|
||||||
:node-type="nodeTypeDescription"
|
:node-type="simulatedNodeTypeDescription ?? nodeTypeDescription"
|
||||||
:size="nodeIconSize"
|
:size="nodeIconSize"
|
||||||
:shrink="false"
|
:shrink="false"
|
||||||
:disabled="isDisabled"
|
:disabled="isDisabled"
|
||||||
|
|
|
@ -44,7 +44,14 @@ import {
|
||||||
WAIT_INDEFINITELY,
|
WAIT_INDEFINITELY,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import type { INodeUi } from '@/Interface';
|
import type { INodeUi } from '@/Interface';
|
||||||
import { CUSTOM_API_CALL_KEY, FORM_NODE_TYPE, STICKY_NODE_TYPE, WAIT_NODE_TYPE } from '@/constants';
|
import {
|
||||||
|
CUSTOM_API_CALL_KEY,
|
||||||
|
FORM_NODE_TYPE,
|
||||||
|
SIMULATE_NODE_TYPE,
|
||||||
|
SIMULATE_TRIGGER_NODE_TYPE,
|
||||||
|
STICKY_NODE_TYPE,
|
||||||
|
WAIT_NODE_TYPE,
|
||||||
|
} from '@/constants';
|
||||||
import { sanitizeHtml } from '@/utils/htmlUtils';
|
import { sanitizeHtml } from '@/utils/htmlUtils';
|
||||||
import { MarkerType } from '@vue-flow/core';
|
import { MarkerType } from '@vue-flow/core';
|
||||||
import { useNodeHelpers } from './useNodeHelpers';
|
import { useNodeHelpers } from './useNodeHelpers';
|
||||||
|
@ -510,6 +517,26 @@ export function useCanvasMapping({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const simulatedNodeTypesById = computed(() => {
|
||||||
|
return nodes.value.reduce<Record<string, string | undefined>>((acc, node) => {
|
||||||
|
if ([SIMULATE_NODE_TYPE, SIMULATE_TRIGGER_NODE_TYPE].includes(node.type)) {
|
||||||
|
const icon = node.parameters?.icon as string;
|
||||||
|
const iconValue = workflowObject.value.expression.getSimpleParameterValue(
|
||||||
|
node,
|
||||||
|
icon,
|
||||||
|
'internal',
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (iconValue && typeof iconValue === 'string') {
|
||||||
|
acc[node.id] = iconValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
});
|
||||||
|
|
||||||
const mappedNodes = computed<CanvasNode[]>(() => [
|
const mappedNodes = computed<CanvasNode[]>(() => [
|
||||||
...nodes.value.map<CanvasNode>((node) => {
|
...nodes.value.map<CanvasNode>((node) => {
|
||||||
const inputConnections = workflowObject.value.connectionsByDestinationNode[node.name] ?? {};
|
const inputConnections = workflowObject.value.connectionsByDestinationNode[node.name] ?? {};
|
||||||
|
@ -521,6 +548,7 @@ export function useCanvasMapping({
|
||||||
subtitle: nodeSubtitleById.value[node.id] ?? '',
|
subtitle: nodeSubtitleById.value[node.id] ?? '',
|
||||||
type: node.type,
|
type: node.type,
|
||||||
typeVersion: node.typeVersion,
|
typeVersion: node.typeVersion,
|
||||||
|
simulatedType: simulatedNodeTypesById.value[node.id],
|
||||||
disabled: node.disabled,
|
disabled: node.disabled,
|
||||||
inputs: nodeInputsById.value[node.id] ?? [],
|
inputs: nodeInputsById.value[node.id] ?? [],
|
||||||
outputs: nodeOutputsById.value[node.id] ?? [],
|
outputs: nodeOutputsById.value[node.id] ?? [],
|
||||||
|
|
|
@ -95,6 +95,7 @@ export interface CanvasNodeData {
|
||||||
subtitle: string;
|
subtitle: string;
|
||||||
type: INodeUi['type'];
|
type: INodeUi['type'];
|
||||||
typeVersion: INodeUi['typeVersion'];
|
typeVersion: INodeUi['typeVersion'];
|
||||||
|
simulatedType?: INodeUi['type'];
|
||||||
disabled: INodeUi['disabled'];
|
disabled: INodeUi['disabled'];
|
||||||
inputs: CanvasConnectionPort[];
|
inputs: CanvasConnectionPort[];
|
||||||
outputs: CanvasConnectionPort[];
|
outputs: CanvasConnectionPort[];
|
||||||
|
|
Loading…
Reference in a new issue