diff --git a/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.spec.ts b/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.spec.ts index c212722314d..663f4a7e49e 100644 --- a/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.spec.ts +++ b/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.spec.ts @@ -818,4 +818,40 @@ describe("JointGraphWrapperService", () => { expect(emitted).toEqual([false, true, false]); }); }); + + it( + "should ignore position change events when old position is missing and continue emitting future events", + marbles(m => { + const operator = jointUIService.getJointOperatorElement(mockScanPredicate, mockPoint); + jointGraph.addCell(operator); + + const events: any[] = []; + const subscription = jointGraphWrapper.getElementPositionChangeEvent().subscribe(event => events.push(event)); + + // remove operator position from the internal map to force bug condition + (jointGraphWrapper as any).elementPositions.delete(mockScanPredicate.operatorID); + + // trigger position change with missing oldPosition + operator.position(150, 150); + + // restore position tracking + (jointGraphWrapper as any).elementPositions.set(mockScanPredicate.operatorID, { + currPos: { x: 100, y: 100 }, + lastPos: undefined, + }); + + // trigger another valid position change + operator.position(200, 200); + + // the first event should be skipped,but the second event should still emit + expect(events.length).toBe(1); + expect(events[0].elementID).toBe(mockScanPredicate.operatorID); + expect(events[0].newPosition).toEqual({ + x: 200, + y: 200, + }); + + subscription.unsubscribe(); + }) + ); }); diff --git a/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.ts b/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.ts index b7a2bf05b51..4816a5dc588 100644 --- a/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.ts +++ b/frontend/src/app/workspace/service/workflow-graph/model/joint-graph-wrapper.ts @@ -307,7 +307,7 @@ export class JointGraphWrapper { const oldPosition = this.elementPositions.get(elementID); const newPosition = { x: e[1].x, y: e[1].y }; if (!oldPosition) { - throw new Error(`internal error: cannot find element position for ${elementID}`); + return undefined; } if ( !oldPosition.lastPos || @@ -325,7 +325,8 @@ export class JointGraphWrapper { oldPosition: oldPosition.lastPos, newPosition: newPosition, }; - }) + }), + filter((event): event is { elementID: string; oldPosition: Point; newPosition: Point } => event !== undefined) ); }