diff --git a/projects/igniteui-angular-i18n/src/i18n/BG/query-builder-resources.ts b/projects/igniteui-angular-i18n/src/i18n/BG/query-builder-resources.ts index 1d40caa084b..b170cc14f9b 100644 --- a/projects/igniteui-angular-i18n/src/i18n/BG/query-builder-resources.ts +++ b/projects/igniteui-angular-i18n/src/i18n/BG/query-builder-resources.ts @@ -60,6 +60,7 @@ const QueryBuilderResourceStringsBG_: ExpandRequire, entityContainer = true, level = 0) { const exprContainer = QueryBuilderFunctions.getQueryBuilderExpressionsContainer(fix, level); const editModeContainers = Array.from(exprContainer.querySelectorAll('.igx-filter-tree__inputs')); - const entityEditModeContainer = editModeContainers.find(container => container.querySelector('igx-combo')); - const conditionEditModeContainer = editModeContainers.find(container => container.querySelector('igx-select') && !container.querySelector('igx-combo')); + const entityEditModeContainer = editModeContainers.find(container => container.children.length == 2); + const conditionEditModeContainer = editModeContainers.find(container => container.children.length >= 4); return entityContainer ? entityEditModeContainer : conditionEditModeContainer; } @@ -225,7 +225,7 @@ export class QueryBuilderFunctions { public static getQueryBuilderFieldsCombo(fix: ComponentFixture, level = 0) { const editModeContainer = QueryBuilderFunctions.getQueryBuilderEditModeContainer(fix, true, level); - const fieldCombo = editModeContainer.querySelector('igx-combo'); + const fieldCombo = level == 0 ? editModeContainer.querySelector('igx-combo') : editModeContainer.querySelectorAll('igx-select')[1]; return fieldCombo; } @@ -544,7 +544,7 @@ export class QueryBuilderFunctions { expect(!fieldInputGroup.classList.contains('igx-input-group--disabled')).toBe(fieldComboEnabled, 'incorrect fields combo state'); - if(columnSelectEnabled || operatorSelectEnabled || valueInputEnabled || commitButtonEnabled){ + if (columnSelectEnabled || operatorSelectEnabled || valueInputEnabled || commitButtonEnabled) { QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, columnSelectEnabled, operatorSelectEnabled, valueInputEnabled, commitButtonEnabled, level); } }; @@ -592,7 +592,7 @@ export class QueryBuilderFunctions { expect(entityInput.value).toBe(entityText); expect(fieldInput.value).toBe(fieldsText); - if(columnText || operatorText || valueText){ + if (columnText || operatorText || valueText) { QueryBuilderFunctions.verifyEditModeExpressionInputValues(fix, columnText, operatorText, valueText, level); } }; @@ -804,9 +804,12 @@ export class QueryBuilderFunctions { tick(); fix.detectChanges(); }); - //close combo drop-down - QueryBuilderFunctions.clickQueryBuilderFieldsCombo(fix); - fix.detectChanges(); + + if (level == 0) { + //close combo drop-down + QueryBuilderFunctions.clickQueryBuilderFieldsCombo(fix); + fix.detectChanges(); + } } public static selectColumnInEditModeExpression(fix, dropdownItemIndex: number, level = 0) { @@ -832,12 +835,17 @@ export class QueryBuilderFunctions { fix.detectChanges(); } - public static addAndValidateChildGroup(fix: ComponentFixture, groupType: number, level: number) { + public static addAndValidateChildGroup(fix: ComponentFixture, groupType: number, level: number) { // Enter values in the nested query QueryBuilderFunctions.selectEntityInEditModeExpression(fix, 0, level); // Select 'Products' entity tick(100); fix.detectChanges(); + // Select return field + QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0], level); + tick(100); + fix.detectChanges(); + // Click the initial 'Add Or Group' button. QueryBuilderFunctions.clickQueryBuilderInitialAddGroupButton(fix, groupType, level); tick(100); @@ -863,7 +871,7 @@ export class QueryBuilderFunctions { // Verify all inputs QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, true, true, false, false, level - 1); // Parent commit button should be disabled QueryBuilderFunctions.verifyEditModeQueryExpressionInputStates(fix, true, true, true, true, true, true, level); - QueryBuilderFunctions.verifyQueryEditModeExpressionInputValues(fix, 'Products', 'Id, ProductName, OrderId, Released', 'ProductName', 'Contains', 'a', level); + QueryBuilderFunctions.verifyQueryEditModeExpressionInputValues(fix, 'Products', 'Id', 'ProductName', 'Contains', 'a', level); //Commit the populated expression. QueryBuilderFunctions.clickQueryBuilderExpressionCommitButton(fix, level); @@ -890,7 +898,7 @@ export class QueryBuilderFunctions { } public static selectEntityAndClickInitialAddGroup(fix: ComponentFixture, entityIndex: number, groupIndex: number) { - QueryBuilderFunctions.selectEntityInEditModeExpression(fix, entityIndex); + QueryBuilderFunctions.selectEntityInEditModeExpression(fix, entityIndex); tick(100); fix.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html index 0d4176d6835..88bebe5a129 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.html @@ -21,40 +21,57 @@ - - -
- - -
- {{ this.resourceStrings.igx_query_builder_select_all }} + @if(!parentExpression) { + + +
+ + +
+ {{ this.resourceStrings.igx_query_builder_select_all }} +
-
- - - + + + + } + @else { + + + + {{ field.field }} + + + }
diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts index 53ea1c8eaf7..9f88962fd01 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder-tree.component.ts @@ -305,9 +305,12 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { @ViewChild('entitySelect', { read: IgxSelectComponent }) protected entitySelect: IgxSelectComponent; + + @ViewChild('returnFieldsCombo', { read: IgxComboComponent }) + private returnFieldsCombo: IgxComboComponent; - @ViewChild('selectedReturnFieldsCombo', { read: IgxComboComponent }) - private selectedReturnFieldsCombo: IgxComboComponent; + @ViewChild('returnFieldSelect', { read: IgxSelectComponent }) + protected returnFieldSelect: IgxSelectComponent; @ViewChild('fieldSelect', { read: IgxSelectComponent }) private fieldSelect: IgxSelectComponent; @@ -627,7 +630,8 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this._selectedEntity.fields = []; } this.fields = this._entityNewValue ? this._entityNewValue.fields : []; - this._selectedReturnFields = this._entityNewValue.fields?.map(f => f.field); + + this._selectedReturnFields = this.parentExpression ? [] : this._entityNewValue.fields?.map(f => f.field); if (this._expressionTree) { this._expressionTree.entity = this._entityNewValue.name; @@ -667,7 +671,6 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this._expressionTree.returnFields = value; this.expressionTreeChange.emit(this._expressionTree); } - } } @@ -992,10 +995,12 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this.entitySelectOverlaySettings.target = this.entitySelect.element; this.entitySelectOverlaySettings.excludeFromOutsideClick = [this.entitySelect.element as HTMLElement]; this.entitySelectOverlaySettings.positionStrategy = new AutoPositionStrategy(); - this.returnFieldSelectOverlaySettings.target = this.selectedReturnFieldsCombo.getEditElement(); - this.returnFieldSelectOverlaySettings.excludeFromOutsideClick = [this.selectedReturnFieldsCombo.getEditElement() as HTMLElement]; - this.returnFieldSelectOverlaySettings.positionStrategy = new AutoPositionStrategy(); + if (this.returnFieldSelect) { + this.returnFieldSelectOverlaySettings.target = this.returnFieldSelect.element; + this.returnFieldSelectOverlaySettings.excludeFromOutsideClick = [this.returnFieldSelect.element as HTMLElement]; + this.returnFieldSelectOverlaySettings.positionStrategy = new AutoPositionStrategy(); + } if (this.fieldSelect) { this.fieldSelectOverlaySettings.target = this.fieldSelect.element; this.fieldSelectOverlaySettings.excludeFromOutsideClick = [this.fieldSelect.element as HTMLElement]; @@ -1007,7 +1012,6 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { this.conditionSelectOverlaySettings.positionStrategy = new AutoPositionStrategy(); } - if (!this.selectedField) { this.fieldSelect.input.nativeElement.focus(); } else if (this.selectedField.filters.condition(this.selectedCondition)?.isUnary) { @@ -1353,14 +1357,22 @@ export class IgxQueryBuilderTreeComponent implements AfterViewInit, OnDestroy { (this._selectedReturnFields.length > 0 && this._selectedReturnFields.length < this._selectedEntity.fields.length) || this._selectedReturnFields.length == this._selectedEntity.fields.length ) { - this.selectedReturnFieldsCombo.deselectAllItems(); + this.returnFieldsCombo.deselectAllItems(); } else { - this.selectedReturnFieldsCombo.selectAllItems(); + this.returnFieldsCombo.selectAllItems(); } } - public onReturnFieldSelectChanging(event: IComboSelectionChangingEventArgs) { - this.initExpressionTree(this.selectedEntity.name, event.newSelection.map(item => item.field)) + public onReturnFieldSelectChanging(event: IComboSelectionChangingEventArgs | ISelectionEventArgs) { + let newSelection = []; + if (event.newSelection instanceof Array) { + newSelection = event.newSelection.map(item => item.field) + } else { + newSelection.push(event.newSelection.value); + this._selectedReturnFields = newSelection; + } + + this.initExpressionTree(this.selectedEntity.name, newSelection); } public initExpressionTree(selectedEntityName: string, selectedReturnFields: string[]) { diff --git a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts index fd2f8441a91..f27428d6905 100644 --- a/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts +++ b/projects/igniteui-angular/src/lib/query-builder/query-builder.component.spec.ts @@ -114,6 +114,19 @@ describe('IgxQueryBuilder', () => { ControlsFunction.verifyButtonIsDisabled(button as HTMLElement, false); } })); + + it('Should render combo for main entity return fields and select for nested entity return field.', fakeAsync(() => { + QueryBuilderFunctions.selectEntityAndClickInitialAddGroup(fix, 1, 0); + + QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0); // Select 'OrderId' column. + QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 10); // Select 'In' operator. + + const mainEntityContainer = QueryBuilderFunctions.getQueryBuilderEditModeContainer(fix, true, 0); + const nestedEntityContainer = QueryBuilderFunctions.getQueryBuilderEditModeContainer(fix, true, 1); + + expect(mainEntityContainer.children[1].tagName).toBe('IGX-COMBO'); + expect(nestedEntityContainer.children[1].tagName).toBe('IGX-SELECT'); + })); }); describe('Interactions', () => { @@ -872,10 +885,7 @@ describe('IgxQueryBuilder', () => { "operator": 1, "entity": "Products", "returnFields": [ - "Id", - "ProductName", - "OrderId", - "Released" + "Id" ] } } @@ -947,10 +957,7 @@ describe('IgxQueryBuilder', () => { "operator": 1, "entity": "Products", "returnFields": [ - "Id", - "ProductName", - "OrderId", - "Released" + "Id" ] } } @@ -1240,7 +1247,7 @@ describe('IgxQueryBuilder', () => { fix.detectChanges(); // Verify tree layout and remaining chip content - let rootGroup = QueryBuilderFunctions.getQueryBuilderTreeRootGroup(fix) as HTMLElement; + let rootGroup = QueryBuilderFunctions.getQueryBuilderTreeRootGroup(fix) as HTMLElement; expect(QueryBuilderFunctions.getQueryBuilderTreeChildItems(rootGroup as HTMLElement).length).toBe(1); QueryBuilderFunctions.verifyExpressionChipContent(fix, [0], 'Downloads', 'Greater Than', '100'); })); @@ -1542,32 +1549,7 @@ describe('IgxQueryBuilder', () => { // Verify parent is enabled parentCommitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); ControlsFunction.verifyButtonIsDisabled(parentCommitBtn as HTMLElement, false); - })); - - it(`'In' condition 'commit' button should be disabled if there are no return fields in the nested query.`, fakeAsync(() => { - queryBuilder.expressionTree = QueryBuilderFunctions.generateExpressionTree(); - fix.detectChanges(); - tick(100); - fix.detectChanges(); - - // Double-click the parent chip 'Products' to enter edit mode. - QueryBuilderFunctions.clickQueryBuilderTreeExpressionChip(fix, [0], true); - tick(50); - fix.detectChanges(); - - let commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); - ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement, false); - - // Deselect all fields - QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0], 1); - commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); - ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement); - - // Select all fields - QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0], 1); - commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); - ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement, false); - })); + })); it('Should collapse nested query when it is committed.', fakeAsync(() => { QueryBuilderFunctions.selectEntityAndClickInitialAddGroup(fix, 1, 0); @@ -2008,11 +1990,25 @@ describe('IgxQueryBuilder', () => { QueryBuilderFunctions.selectColumnInEditModeExpression(fix, 0); // Select 'OrderId' column. QueryBuilderFunctions.selectOperatorInEditModeExpression(fix, 10); // Select 'In' operator. + let commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); + ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement, true); + // Enter values in the nested query QueryBuilderFunctions.selectEntityInEditModeExpression(fix, 0, 1); // Select 'Products' entity tick(100); fix.detectChanges(); + commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); + ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement, true); + + // Select return field + QueryBuilderFunctions.selectFieldsInEditModeExpression(fix, [0], 1); + tick(100); + fix.detectChanges(); + + commitBtn = QueryBuilderFunctions.getQueryBuilderExpressionCommitButton(fix); + ControlsFunction.verifyButtonIsDisabled(commitBtn as HTMLElement, false); + QueryBuilderFunctions.verifyEditModeExpressionInputStates(fix, true, true, false, true); // Parent commit button should be enabled QueryBuilderFunctions.clickQueryBuilderExpressionCommitButton(fix); fix.detectChanges(); @@ -2037,10 +2033,7 @@ describe('IgxQueryBuilder', () => { "operator": 0, "entity": "Products", "returnFields": [ - "Id", - "ProductName", - "OrderId", - "Released" + "Id" ] } }