mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-12 15:44:06 -08:00
feat(editor): Update connection line to reuse getCustomPath
in new canvas (no-changelog) (#10175)
This commit is contained in:
parent
79bccf0305
commit
b781095be1
|
@ -401,6 +401,10 @@ watch(() => props.readOnly, setReadonly, {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #connection-line="connectionLineProps">
|
||||||
|
<CanvasConnectionLine v-bind="connectionLineProps" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<Background data-test-id="canvas-background" pattern-color="#aaa" :gap="GRID_SIZE" />
|
<Background data-test-id="canvas-background" pattern-color="#aaa" :gap="GRID_SIZE" />
|
||||||
|
|
||||||
<MiniMap data-test-id="canvas-minimap" pannable />
|
<MiniMap data-test-id="canvas-minimap" pannable />
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import CanvasConnectionLine from './CanvasConnectionLine.vue';
|
||||||
|
import { createComponentRenderer } from '@/__tests__/render';
|
||||||
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
|
import { setActivePinia } from 'pinia';
|
||||||
|
import type { ConnectionLineProps } from '@vue-flow/core';
|
||||||
|
import { Position } from '@vue-flow/core';
|
||||||
|
|
||||||
|
const DEFAULT_PROPS = {
|
||||||
|
sourceX: 0,
|
||||||
|
sourceY: 0,
|
||||||
|
sourcePosition: Position.Top,
|
||||||
|
targetX: 100,
|
||||||
|
targetY: 100,
|
||||||
|
targetPosition: Position.Bottom,
|
||||||
|
} satisfies Partial<ConnectionLineProps>;
|
||||||
|
const renderComponent = createComponentRenderer(CanvasConnectionLine, {
|
||||||
|
props: DEFAULT_PROPS,
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const pinia = createTestingPinia();
|
||||||
|
setActivePinia(pinia);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('CanvasConnectionLine', () => {
|
||||||
|
it('should render a correct bezier path', () => {
|
||||||
|
const { container } = renderComponent({
|
||||||
|
props: DEFAULT_PROPS,
|
||||||
|
});
|
||||||
|
|
||||||
|
const edge = container.querySelector('.vue-flow__edge-path');
|
||||||
|
|
||||||
|
expect(edge).toHaveAttribute('d', 'M0,0 C0,-62.5 100,162.5 100,100');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a correct smooth step path when the connection is backwards', () => {
|
||||||
|
const { container } = renderComponent({
|
||||||
|
props: {
|
||||||
|
...DEFAULT_PROPS,
|
||||||
|
sourceX: 0,
|
||||||
|
sourceY: 0,
|
||||||
|
sourcePosition: Position.Right,
|
||||||
|
targetX: -100,
|
||||||
|
targetY: -100,
|
||||||
|
targetPosition: Position.Left,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const edge = container.querySelector('.vue-flow__edge-path');
|
||||||
|
|
||||||
|
expect(edge).toHaveAttribute(
|
||||||
|
'd',
|
||||||
|
'M0 0L 32,0Q 40,0 40,8L 40,132Q 40,140 32,140L1 140L0 140M0 140L-40 140L -132,140Q -140,140 -140,132L -140,-92Q -140,-100 -132,-100L-100 -100',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
/* eslint-disable vue/no-multiple-template-root */
|
||||||
|
import type { ConnectionLineProps } from '@vue-flow/core';
|
||||||
|
import { BaseEdge } from '@vue-flow/core';
|
||||||
|
import { computed, useCssModule } from 'vue';
|
||||||
|
import { getCustomPath } from './utils/edgePath';
|
||||||
|
|
||||||
|
const props = defineProps<ConnectionLineProps>();
|
||||||
|
|
||||||
|
const $style = useCssModule();
|
||||||
|
|
||||||
|
const edgeStyle = computed(() => ({
|
||||||
|
strokeWidth: 2,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const path = computed(() => getCustomPath(props));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BaseEdge :class="$style.edge" :style="edgeStyle" :path="path[0]" :marker-end="markerEnd" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.edge {
|
||||||
|
transition: stroke 0.3s ease;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,18 +1,25 @@
|
||||||
import { getBezierPath, getSmoothStepPath, Position, type EdgeProps } from '@vue-flow/core';
|
import type { EdgeProps } from '@vue-flow/core';
|
||||||
|
import { getBezierPath, getSmoothStepPath, Position } from '@vue-flow/core';
|
||||||
|
|
||||||
const EDGE_PADDING_Y = 140;
|
const EDGE_PADDING_Y = 140;
|
||||||
const EDGE_PADDING_Y_TOP = 80;
|
const EDGE_PADDING_Y_TOP = 80;
|
||||||
const EDGE_BORDER_RADIUS = 8;
|
const EDGE_BORDER_RADIUS = 8;
|
||||||
const EDGE_OFFSET = 40;
|
const EDGE_OFFSET = 40;
|
||||||
|
const HANDLE_SIZE = 16;
|
||||||
|
|
||||||
export function getCustomPath(props: EdgeProps) {
|
export function getCustomPath(
|
||||||
|
props: Pick<
|
||||||
|
EdgeProps,
|
||||||
|
'sourceX' | 'sourceY' | 'sourcePosition' | 'targetX' | 'targetY' | 'targetPosition'
|
||||||
|
>,
|
||||||
|
) {
|
||||||
const { targetX, targetY, sourceX, sourceY, sourcePosition, targetPosition } = props;
|
const { targetX, targetY, sourceX, sourceY, sourcePosition, targetPosition } = props;
|
||||||
const xDiff = targetX - sourceX;
|
const xDiff = targetX - sourceX;
|
||||||
const yDiff = targetY - sourceY;
|
const yDiff = targetY - sourceY;
|
||||||
|
|
||||||
// Connection is backwards and the source is on the right side
|
// Connection is backwards and the source is on the right side
|
||||||
// -> We need to avoid overlapping the source node
|
// -> We need to avoid overlapping the source node
|
||||||
if (xDiff < 0 && sourcePosition === Position.Right) {
|
if (xDiff < -HANDLE_SIZE && sourcePosition === Position.Right) {
|
||||||
const direction = yDiff < -EDGE_PADDING_Y || yDiff > 0 ? 'up' : 'down';
|
const direction = yDiff < -EDGE_PADDING_Y || yDiff > 0 ? 'up' : 'down';
|
||||||
const firstSegmentTargetX = sourceX;
|
const firstSegmentTargetX = sourceX;
|
||||||
const firstSegmentTargetY =
|
const firstSegmentTargetY =
|
||||||
|
@ -41,5 +48,6 @@ export function getCustomPath(props: EdgeProps) {
|
||||||
path[0] = firstSegmentPath + path[0];
|
path[0] = firstSegmentPath + path[0];
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getBezierPath(props);
|
return getBezierPath(props);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue