From 5eca722edf9bbfe41059176a2056b631890b0fb3 Mon Sep 17 00:00:00 2001 From: doouding Date: Fri, 16 May 2025 09:49:22 +0000 Subject: [PATCH] fix: connector issues (#12308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes [BS-3161](https://linear.app/affine-design/issue/BS-3161/发现已连接的connector会响应对齐线) Fixes [BS-3337](https://linear.app/affine-design/issue/BS-3337/connector你肿么了) Fixes [BS-3334](https://linear.app/affine-design/issue/BS-3334/connector-不应该能够被拖拽) ## Summary by CodeRabbit - **Bug Fixes** - Corrected typos related to label editing state, ensuring more reliable label editing and display for connectors. - Fixed logic in the auto-complete overlay, improving when overlays appear during hover actions. - **New Features** - Improved connector label handling by ensuring label state is preserved and restored during editing. - Enhanced connector movement behavior, allowing connectors to be moved only when appropriate elements are selected. - **Tests** - Added end-to-end tests to verify connector movement and selection behaviors for improved reliability. --- .../src/element-transform/connector-filter.ts | 2 + .../text/edgeless-connector-label-editor.ts | 7 ++- .../model/src/elements/connector/connector.ts | 10 ++- .../src/edgeless-auto-complete.ts | 2 +- .../e2e/edgeless/connector/connector.spec.ts | 63 +++++++++++++++++++ .../blocksuite/e2e/utils/actions/edgeless.ts | 1 + 6 files changed, 80 insertions(+), 5 deletions(-) diff --git a/blocksuite/affine/gfx/connector/src/element-transform/connector-filter.ts b/blocksuite/affine/gfx/connector/src/element-transform/connector-filter.ts index 0614c8d07f..21e8a79053 100644 --- a/blocksuite/affine/gfx/connector/src/element-transform/connector-filter.ts +++ b/blocksuite/affine/gfx/connector/src/element-transform/connector-filter.ts @@ -36,6 +36,8 @@ export class ConnectorFilter extends InteractivityExtension { elements.sort((a, _) => (a instanceof ConnectorElementModel ? -1 : 1)); } + context.elements = elements; + return {}; }); } diff --git a/blocksuite/affine/gfx/connector/src/text/edgeless-connector-label-editor.ts b/blocksuite/affine/gfx/connector/src/text/edgeless-connector-label-editor.ts index b9b657a2eb..b436e2f64d 100644 --- a/blocksuite/affine/gfx/connector/src/text/edgeless-connector-label-editor.ts +++ b/blocksuite/affine/gfx/connector/src/text/edgeless-connector-label-editor.ts @@ -188,6 +188,8 @@ export class EdgelessConnectorLabelEditor extends WithDisposable( }); this._resizeObserver.observe(this.richText); + this.connector.stash('labelXYWH'); + this.updateComplete .then(() => { if (!this.inlineEditor) return; @@ -257,7 +259,8 @@ export class EdgelessConnectorLabelEditor extends WithDisposable( } } - connector.lableEditing = false; + connector.labelEditing = false; + connector.pop('labelXYWH'); selection.set({ elements: [], @@ -293,7 +296,7 @@ export class EdgelessConnectorLabelEditor extends WithDisposable( } ); - connector.lableEditing = true; + connector.labelEditing = true; }) .catch(console.error); } diff --git a/blocksuite/affine/model/src/elements/connector/connector.ts b/blocksuite/affine/model/src/elements/connector/connector.ts index c37426f708..ccc86d65d3 100644 --- a/blocksuite/affine/model/src/elements/connector/connector.ts +++ b/blocksuite/affine/model/src/elements/connector/connector.ts @@ -278,7 +278,13 @@ export class ConnectorElementModel extends GfxPrimitiveElementModel { }); } }); + + test('connector can not be moved directly if the source or target is not selected', async ({ + page, + }) => { + await commonSetup(page); + + const normalConnectorId = await createConnectorElement( + page, + [0, 0], + [100, 100] + ); + await selectElementInEdgeless(page, [normalConnectorId]); + + const normalRect1 = await getSelectedRect(page); + + // connector with no source and target can be moved + await dragBetweenViewCoords(page, [50, 50], [100, 100]); + const normalRect2 = await getSelectedRect(page); + expect(normalRect2).toEqual({ + x: normalRect1.x + 50, + y: normalRect1.y + 50, + width: normalRect1.width, + height: normalRect1.height, + }); + + const shape1 = await createShapeElement( + page, + [150, 150], + [200, 200], + Shape.Square + ); + const shape2 = await createShapeElement( + page, + [250, 250], + [300, 300], + Shape.Square + ); + const connectorWithShapes = await createConnectorElement( + page, + [190, 175], + [260, 275] + ); + await selectElementInEdgeless(page, [connectorWithShapes]); + + // cannot be moved because the source and target are not selected + const initialShapeConnectorRect = await getSelectedRect(page); + await dragBetweenViewCoords(page, [225, 200], [275, 250]); + const shapeConnectorRect1 = await getSelectedRect(page); + expect(shapeConnectorRect1).toEqual(initialShapeConnectorRect); + + // can be moved because the source and target are selected + await selectElementInEdgeless(page, [shape1, shape2, connectorWithShapes]); + await dragBetweenViewCoords(page, [225, 200], [275, 250]); + await selectElementInEdgeless(page, [connectorWithShapes]); + const shapeConnectorRect2 = await getSelectedRect(page); + expect(shapeConnectorRect2).toEqual({ + x: initialShapeConnectorRect.x + 50, + y: initialShapeConnectorRect.y + 50, + width: initialShapeConnectorRect.width, + height: initialShapeConnectorRect.height, + }); + }); }); diff --git a/tests/blocksuite/e2e/utils/actions/edgeless.ts b/tests/blocksuite/e2e/utils/actions/edgeless.ts index d8899a616e..7aa505c47f 100644 --- a/tests/blocksuite/e2e/utils/actions/edgeless.ts +++ b/tests/blocksuite/e2e/utils/actions/edgeless.ts @@ -1886,6 +1886,7 @@ export async function createConnectorElement( { x: start[0], y: start[1] }, { x: end[0], y: end[1] } ); + return (await getSelectedIds(page))[0]; } export async function createFrameElement(