mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
fix(editor): Tweak configurable node width (#17512)
This commit is contained in:
@@ -111,8 +111,8 @@ describe('CanvasNode', () => {
|
||||
const inputHandles = getAllByTestId('canvas-node-input-handle');
|
||||
|
||||
expect(inputHandles[1]).toHaveStyle('left: 40px');
|
||||
expect(inputHandles[2]).toHaveStyle('left: 168px');
|
||||
expect(inputHandles[3]).toHaveStyle('left: 232px');
|
||||
expect(inputHandles[2]).toHaveStyle('left: 136px');
|
||||
expect(inputHandles[3]).toHaveStyle('left: 184px');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import type { EventBus } from '@n8n/utils/event-bus';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import CanvasNodeTrigger from '@/components/canvas/elements/nodes/render-types/parts/CanvasNodeTrigger.vue';
|
||||
import { CONFIGURATION_NODE_OFFSET, GRID_SIZE } from '@/utils/nodeViewUtils';
|
||||
import { CONFIGURATION_NODE_RADIUS, GRID_SIZE } from '@/utils/nodeViewUtils';
|
||||
|
||||
type Props = NodeProps<CanvasNodeData> & {
|
||||
readOnly?: boolean;
|
||||
@@ -187,7 +187,7 @@ const createEndpointMappingFn =
|
||||
connectingHandle.value?.handleId === handleId;
|
||||
const offsetValue =
|
||||
position === Position.Bottom
|
||||
? `${GRID_SIZE * 2 * (1 + index * 2) + CONFIGURATION_NODE_OFFSET}px`
|
||||
? `${CONFIGURATION_NODE_RADIUS + GRID_SIZE * (3 * index)}px`
|
||||
: isExperimentalNdvActive.value && endpoints.length === 1
|
||||
? `${(1 + index) * (GRID_SIZE * 1.5)}px`
|
||||
: `${(100 / (endpoints.length + 1)) * (index + 1)}%`;
|
||||
|
||||
@@ -209,7 +209,7 @@ describe('CanvasNodeDefault', () => {
|
||||
[
|
||||
'1 required',
|
||||
[{ type: NodeConnectionTypes.AiLanguageModel, index: 0, required: true }],
|
||||
'272px',
|
||||
'224px',
|
||||
],
|
||||
[
|
||||
'2 required, 1 optional',
|
||||
@@ -218,7 +218,7 @@ describe('CanvasNodeDefault', () => {
|
||||
{ type: NodeConnectionTypes.AiDocument, index: 0, required: true },
|
||||
{ type: NodeConnectionTypes.AiMemory, index: 0, required: true },
|
||||
],
|
||||
'272px',
|
||||
'224px',
|
||||
],
|
||||
[
|
||||
'2 required, 2 optional',
|
||||
@@ -228,7 +228,7 @@ describe('CanvasNodeDefault', () => {
|
||||
{ type: NodeConnectionTypes.AiDocument, index: 0, required: true },
|
||||
{ type: NodeConnectionTypes.AiMemory, index: 0, required: true },
|
||||
],
|
||||
'272px',
|
||||
'224px',
|
||||
],
|
||||
[
|
||||
'1 required, 4 optional',
|
||||
@@ -239,7 +239,7 @@ describe('CanvasNodeDefault', () => {
|
||||
{ type: NodeConnectionTypes.AiMemory, index: 0 },
|
||||
{ type: NodeConnectionTypes.AiMemory, index: 0 },
|
||||
],
|
||||
'336px',
|
||||
'272px',
|
||||
],
|
||||
])(
|
||||
'should adjust width css variable based on the number of non-main inputs (%s)',
|
||||
|
||||
@@ -4,7 +4,7 @@ exports[`CanvasNodeDefault > configurable > should render configurable node corr
|
||||
<div
|
||||
class="node configurable"
|
||||
data-test-id="canvas-configurable-node"
|
||||
style="--canvas-node--width: 272px; --canvas-node--height: 96px; --node-icon-size: 40px;"
|
||||
style="--canvas-node--width: 224px; --canvas-node--height: 96px; --node-icon-size: 40px;"
|
||||
>
|
||||
<!--v-if-->
|
||||
<div
|
||||
@@ -57,7 +57,7 @@ exports[`CanvasNodeDefault > configuration > should render configurable configur
|
||||
<div
|
||||
class="node configurable configuration"
|
||||
data-test-id="canvas-configurable-node"
|
||||
style="--canvas-node--width: 272px; --canvas-node--height: 80px; --node-icon-size: 30px;"
|
||||
style="--canvas-node--width: 240px; --canvas-node--height: 80px; --node-icon-size: 30px;"
|
||||
>
|
||||
<!--v-if-->
|
||||
<div
|
||||
|
||||
@@ -483,21 +483,21 @@ describe('calculateNodeSize', () => {
|
||||
const nonMainInputCount = 5;
|
||||
const mainInputCount = 3;
|
||||
const mainOutputCount = 2;
|
||||
// width = max(4, 5) * 2 * 16 * 2 = 5 * 2 * 16 * 2 + offset = 336
|
||||
// width = 80 + 0 + (max(4, 5) - 1) * 16 * 3 = 272
|
||||
// height = DEFAULT_NODE_SIZE[1] + max(0, max(3,2,1) - 2) * 16 * 2
|
||||
// maxVerticalHandles = 3
|
||||
// height = 96 + (3 - 2) * 32 = 96 + 32 = 128
|
||||
expect(
|
||||
calculateNodeSize(false, true, mainInputCount, mainOutputCount, nonMainInputCount),
|
||||
).toEqual({ width: 336, height: 128 });
|
||||
).toEqual({ width: 272, height: 128 });
|
||||
});
|
||||
|
||||
it('should return configurable configuration node size when both isConfigurable and isConfiguration are true', () => {
|
||||
const nonMainInputCount = 2;
|
||||
// width = max(4, 2) * 2 * 16 * 2 = 4 * 2 * 16 * 2 + offset = 272
|
||||
// width = 80 + 16 + (max(4, 2) - 1) * 16 * 3 = 240
|
||||
// height = CONFIGURATION_NODE_SIZE[1] = 16 * 5 = 80
|
||||
expect(calculateNodeSize(true, true, 1, 1, nonMainInputCount)).toEqual({
|
||||
width: 272,
|
||||
width: 240,
|
||||
height: 80,
|
||||
});
|
||||
});
|
||||
@@ -524,12 +524,12 @@ describe('calculateNodeSize', () => {
|
||||
|
||||
it('should respect the minimum width for configurable nodes', () => {
|
||||
const nonMainInputCount = 2; // less than NODE_MIN_INPUT_ITEMS_COUNT
|
||||
// width = 4 * 2 * 16 * 2 + offset = 272
|
||||
// width = 80 + 0 + (max(2, 4) - 1) * 16 * 3 = 224
|
||||
// height = default path, mainInputCount = 1, mainOutputCount = 1
|
||||
// maxVerticalHandles = 1
|
||||
// height = 96 + (1 - 2) * 32 = 96 + 0 = 96
|
||||
expect(calculateNodeSize(false, true, 1, 1, nonMainInputCount)).toEqual({
|
||||
width: 272,
|
||||
width: 224,
|
||||
height: 96,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,7 +35,11 @@ import {
|
||||
export const GRID_SIZE = 16;
|
||||
|
||||
export const DEFAULT_NODE_SIZE: [number, number] = [GRID_SIZE * 6, GRID_SIZE * 6];
|
||||
export const CONFIGURATION_NODE_SIZE: [number, number] = [GRID_SIZE * 5, GRID_SIZE * 5];
|
||||
export const CONFIGURATION_NODE_RADIUS = (GRID_SIZE * 5) / 2;
|
||||
export const CONFIGURATION_NODE_SIZE: [number, number] = [
|
||||
CONFIGURATION_NODE_RADIUS * 2,
|
||||
CONFIGURATION_NODE_RADIUS * 2,
|
||||
]; // the node has circle shape
|
||||
export const CONFIGURABLE_NODE_SIZE: [number, number] = [GRID_SIZE * 16, GRID_SIZE * 6];
|
||||
export const DEFAULT_START_POSITION_X = GRID_SIZE * 11;
|
||||
export const DEFAULT_START_POSITION_Y = GRID_SIZE * 15;
|
||||
@@ -48,10 +52,6 @@ export const DEFAULT_VIEWPORT_BOUNDARIES: ViewportBoundaries = {
|
||||
yMax: Infinity,
|
||||
};
|
||||
|
||||
// The top-center of the configuration node is not a multiple of GRID_SIZE,
|
||||
// therefore we need to offset non-main inputs to align with the nodes top-center
|
||||
export const CONFIGURATION_NODE_OFFSET = (CONFIGURATION_NODE_SIZE[0] / 2) % GRID_SIZE;
|
||||
|
||||
/**
|
||||
* Utility functions for returning nodes found at the edges of a group
|
||||
*/
|
||||
@@ -619,10 +619,13 @@ export function calculateNodeSize(
|
||||
const height = DEFAULT_NODE_SIZE[1] + Math.max(0, maxVerticalHandles - 2) * GRID_SIZE * 2;
|
||||
|
||||
if (isConfigurable) {
|
||||
const portCount = Math.max(NODE_MIN_INPUT_ITEMS_COUNT, nonMainInputCount);
|
||||
|
||||
return {
|
||||
// Configuration node has extra width so that its centered port aligns to the grid
|
||||
width:
|
||||
Math.max(NODE_MIN_INPUT_ITEMS_COUNT, nonMainInputCount) * GRID_SIZE * 4 +
|
||||
CONFIGURATION_NODE_OFFSET * 2,
|
||||
CONFIGURATION_NODE_RADIUS * 2 +
|
||||
GRID_SIZE * ((isConfiguration ? 1 : 0) + (portCount - 1) * 3),
|
||||
height: isConfiguration ? CONFIGURATION_NODE_SIZE[1] : height,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user