eclipse-sprotty/sprotty

Edge created while dragging from a port is deleted after any model change

cjmamo opened this issue · 3 comments

cjmamo commented

Not sure if this is expected behaviour but an edge that is created while dragging from a port is deleted after any change to the model such as moving a node:

Recording 2023-10-25 at 18 56 05

The port is implemented as follows:

export class StructPort extends SPortImpl implements CreatingOnDrag {
    createAction(id: string): Action {
        const edge: SEdge = {
            id,
            type: 'edge',
            sourceId: this.id,
            targetId: this.parent.id
        };
        return CreateElementAction.create(edge, { containerId: this.root.id });
    }
}

MoveMouseListener is deleting edges that have the ID edge-in-progress but it's also deleting edges that are no longer in-progress. As a workaround, I've written a custom router that changes the edge ID edge-in-progress to a random ID :

export class CustomRouter extends PolylineEdgeRouter {
    applyReconnect(edge: SRoutableElementImpl, newSourceId?: string, newTargetId?: string) {
        let hasChanged = false;
        if (newSourceId) {
            const newSource = edge.root.index.getById(newSourceId);
            if (newSource instanceof SConnectableElementImpl) {
                edge.sourceId = newSource.id;
                hasChanged = true;
            }
        }
        if (newTargetId) {
            const newTarget = edge.root.index.getById(newTargetId);
            if (newTarget instanceof SConnectableElementImpl) {
                edge.targetId = newTarget.id;
                hasChanged = true;
            }
        }
        if (hasChanged) {
            // reset attached elements in index
            edge.index.remove(edge);
            if (edge.id === edgeInProgressID)
                edge.id = "edge-" + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
            edge.index.add(edge);
            if (this.getSelfEdgeIndex(edge) > -1) {
                edge.routingPoints = [];
                this.cleanupRoutingPoints(edge, edge.routingPoints, true, true);
            }
        }
    }
}

@spoenemann
Should the abstract-edge-router give the new connected edge a proper id after connect in applyReconnect? Or how is it supposed to work with the edgeInProgressID?

I'm not 100% sure because this feature has been done by @JanKoehnlein, but I assume generating a unique id when the edit operation is done is the correct solution.

Fixed in master