diff --git a/src/sql/parts/connection/common/connectionProfileGroup.ts b/src/sql/parts/connection/common/connectionProfileGroup.ts index 3e9aa1708b..a7266ca1df 100644 --- a/src/sql/parts/connection/common/connectionProfileGroup.ts +++ b/src/sql/parts/connection/common/connectionProfileGroup.ts @@ -153,6 +153,19 @@ export class ConnectionProfileGroup implements IConnectionProfileGroup { return this.parent; } + public isAncestorOf(node: ConnectionProfileGroup | ConnectionProfile): boolean { + let isAncestor = false; + let currentNode = node; + while (currentNode) { + if (currentNode.parent && currentNode.parent.id === this.id) { + isAncestor = true; + break; + } + currentNode = currentNode.parent; + } + return isAncestor; + } + public static getGroupFullNameParts(groupFullName: string): string[] { groupFullName = groupFullName ? groupFullName : ''; let groupNames: string[] = groupFullName.split(ConnectionProfileGroup.GroupNameSeparator); diff --git a/src/sql/parts/objectExplorer/viewlet/dragAndDropController.ts b/src/sql/parts/objectExplorer/viewlet/dragAndDropController.ts index 2676ef17ed..1c1b2ac978 100644 --- a/src/sql/parts/objectExplorer/viewlet/dragAndDropController.ts +++ b/src/sql/parts/objectExplorer/viewlet/dragAndDropController.ts @@ -68,12 +68,16 @@ export class ServerTreeDragAndDrop implements IDragAndDrop { let canDragOver: boolean = true; if (targetElement instanceof ConnectionProfile || targetElement instanceof ConnectionProfileGroup) { let targetConnectionProfileGroup = this.getTargetGroup(targetElement); - //Verify if the connection can be moved to the target group + // Verify if the connection can be moved to the target group const source = data.getData()[0]; if (source instanceof ConnectionProfile) { if (!this._connectionManagementService.canChangeConnectionConfig(source, targetConnectionProfileGroup.id)) { canDragOver = false; } + } else if (source instanceof ConnectionProfileGroup) { + // Dropping a group to itself or its descendants nodes is not allowed + // to avoid creating a circular structure. + canDragOver = source.id !== targetElement.id && !source.isAncestorOf(targetElement); } } else { @@ -148,7 +152,7 @@ export class ServerTreeDragAndDrop implements IDragAndDrop { */ export class RecentConnectionsDragAndDrop implements IDragAndDrop { - constructor( @IConnectionManagementService private connectionManagementService: IConnectionManagementService, + constructor(@IConnectionManagementService private connectionManagementService: IConnectionManagementService, @IInstantiationService private instantiationService: IInstantiationService ) { }