diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts index 2aea43704ed..4c588fc5e98 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts @@ -1918,6 +1918,51 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => { verifyChildrenSelection(GridFunctions.getAdvancedFilteringTreeItem(fix, [1]), false); })); + it('Should remove all empty groups when clicking `delete` on a group\'s operator line\'s context menu.', fakeAsync(() => { + // Apply advanced filter through API. + const rootTree = new FilteringExpressionsTree(FilteringLogic.And); + rootTree.filteringOperands.push({ + fieldName: 'Downloads', searchVal: 100, condition: IgxNumberFilteringOperand.instance().condition('greaterThan') + }); + const firstTree = new FilteringExpressionsTree(FilteringLogic.And); + const secondTree = new FilteringExpressionsTree(FilteringLogic.Or); + const thirdTree = new FilteringExpressionsTree(FilteringLogic.And); + thirdTree.filteringOperands.push({ + fieldName: 'ProductName', searchVal: 'a', condition: IgxStringFilteringOperand.instance().condition('contains'), + ignoreCase: true + }); + thirdTree.filteringOperands.push({ + fieldName: 'ProductName', searchVal: 's', condition: IgxStringFilteringOperand.instance().condition('contains'), + ignoreCase: true + }); + secondTree.filteringOperands.push(thirdTree); + firstTree.filteringOperands.push(secondTree); + rootTree.filteringOperands.push(firstTree); + grid.advancedFilteringExpressionsTree = rootTree; + fix.detectChanges(); + + // Open Advanced Filtering dialog. + grid.openAdvancedFilteringDialog(); + fix.detectChanges(); + + // Click group's outer operator line. + let middleGroupOperatorLine = GridFunctions.getAdvancedFilteringTreeGroupOperatorLine(fix, [1]); + middleGroupOperatorLine.click(); + tick(200); + fix.detectChanges(); + + // Click on `delete` in the context menu. + let deleteBtn = fix.nativeElement.querySelector('.igx-filter-contextual-menu__delete-btn'); + deleteBtn.click(); + tick(200); + fix.detectChanges(); + + // Verify tree layout and remaining chip content + let rootGroup = GridFunctions.getAdvancedFilteringTreeRootGroup(fix); + expect(GridFunctions.getAdvancedFilteringTreeChildItems(rootGroup, true).length).toBe(1); + verifyExpressionChipContent(fix, [0], 'Downloads', 'Greater Than', '100'); + })); + it('Should open the operator dropdown below its respective input-group.', fakeAsync(() => { // Open Advanced Filtering dialog. grid.openAdvancedFilteringDialog(); diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.ts index 8c6f70c4653..03152bbf88d 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.ts @@ -771,14 +771,29 @@ export class IgxQueryBuilderComponent extends DisplayDensityBase implements Afte */ public deleteGroup() { const selectedGroup = this.contextualGroup; - const parent = selectedGroup.parent; + let parent = selectedGroup.parent; if (parent) { - const index = parent.children.indexOf(selectedGroup); + let index = parent.children.indexOf(selectedGroup); parent.children.splice(index, 1); + + if (parent.children.length === 0) { + let childGroup = parent; + parent = parent.parent; + while (parent && parent.children.length === 1) { + childGroup = parent; + parent = parent.parent; + } + + if (parent) { + index = parent.children.indexOf(childGroup); + parent.children.splice(index, 1); + } else { + this.rootGroup = null; + } + } } else { this.rootGroup = null; } - this.clearSelection(); this.commitOperandEdit(); }