Skip to content

Commit 6a7d3e8

Browse files
authored
Merge branch 'master' into didimmova/fix-14933
2 parents 8a5b558 + c8366c2 commit 6a7d3e8

File tree

7 files changed

+219
-14
lines changed

7 files changed

+219
-14
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes for each version of this project will be documented in this file.
44

5+
## 19.0.0
6+
### New Features
7+
- `IgxColumn`
8+
- Introduced the `disabledSummaries` property, allowing users to specify which summaries should be disabled for a given column. This property accepts an array of strings corresponding to the summary keys, enabling selective control over both default summaries (e.g., 'Count', 'Min') and any custom summaries created by the user.
9+
510
## 18.2.0
611
### General
712
- `IFilteringExpressionsTree`, `FilteringExpressionsTree`

projects/igniteui-angular/src/lib/grids/columns/column.component.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,33 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
10771077
this.grid.summaryService.resetSummaryHeight();
10781078
}
10791079
}
1080+
1081+
/**
1082+
* Sets/gets the summary operands to exclude from display.
1083+
* Accepts an array of string keys representing the summary types to disable, such as 'Min', 'Max', 'Count' etc.
1084+
* ```typescript
1085+
* let disabledSummaries = this.column.disabledSummaries;
1086+
* ```
1087+
* ```html
1088+
* <igx-column [disabledSummaries]="['min', 'max', 'average']"></igx-column>
1089+
* ```
1090+
*
1091+
* @memberof IgxColumnComponent
1092+
*/
1093+
@Input()
1094+
public get disabledSummaries(): string[] {
1095+
return this._disabledSummaries;
1096+
}
1097+
1098+
public set disabledSummaries(value: string[]) {
1099+
this._disabledSummaries = value;
1100+
if (this.grid) {
1101+
this.grid.summaryService.removeSummariesCachePerColumn(this.field);
1102+
this.grid.summaryPipeTrigger++;
1103+
this.grid.summaryService.resetSummaryHeight();
1104+
}
1105+
}
1106+
10801107
/**
10811108
* Gets the column `filters`.
10821109
* ```typescript
@@ -1743,6 +1770,10 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy
17431770
* @hidden
17441771
*/
17451772
protected _summaries = null;
1773+
/**
1774+
* @hidden
1775+
*/
1776+
private _disabledSummaries: string[] = [];
17461777
/**
17471778
* @hidden
17481779
*/

projects/igniteui-angular/src/lib/grids/common/grid.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ export interface ColumnType extends FieldType {
443443
filteringExpressionsTree: FilteringExpressionsTree;
444444
hasSummary: boolean;
445445
summaries: any;
446+
disabledSummaries?: string[];
446447
/**
447448
* The template reference for a summary of the column
448449
* It is of type TemplateRef, which represents an embedded template, used to instantiate embedded views

projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,52 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => {
19181918
verifyChildrenSelection(GridFunctions.getAdvancedFilteringTreeItem(fix, [1]), false);
19191919
}));
19201920

1921+
1922+
it('Should remove all empty groups when clicking `delete` on a group\'s operator line\'s context menu.', fakeAsync(() => {
1923+
// Apply advanced filter through API.
1924+
const rootTree = new FilteringExpressionsTree(FilteringLogic.And);
1925+
rootTree.filteringOperands.push({
1926+
fieldName: 'Downloads', searchVal: 100, condition: IgxNumberFilteringOperand.instance().condition('greaterThan')
1927+
});
1928+
const firstTree = new FilteringExpressionsTree(FilteringLogic.And);
1929+
const secondTree = new FilteringExpressionsTree(FilteringLogic.Or);
1930+
const thirdTree = new FilteringExpressionsTree(FilteringLogic.And);
1931+
thirdTree.filteringOperands.push({
1932+
fieldName: 'ProductName', searchVal: 'a', condition: IgxStringFilteringOperand.instance().condition('contains'),
1933+
ignoreCase: true
1934+
});
1935+
thirdTree.filteringOperands.push({
1936+
fieldName: 'ProductName', searchVal: 's', condition: IgxStringFilteringOperand.instance().condition('contains'),
1937+
ignoreCase: true
1938+
});
1939+
secondTree.filteringOperands.push(thirdTree);
1940+
firstTree.filteringOperands.push(secondTree);
1941+
rootTree.filteringOperands.push(firstTree);
1942+
grid.advancedFilteringExpressionsTree = rootTree;
1943+
fix.detectChanges();
1944+
1945+
// Open Advanced Filtering dialog.
1946+
grid.openAdvancedFilteringDialog();
1947+
fix.detectChanges();
1948+
1949+
// Click group's outer operator line.
1950+
let middleGroupOperatorLine = GridFunctions.getAdvancedFilteringTreeGroupOperatorLine(fix, [1]);
1951+
middleGroupOperatorLine.click();
1952+
tick(200);
1953+
fix.detectChanges();
1954+
1955+
// Click on `delete` in the context menu.
1956+
let deleteBtn = fix.nativeElement.querySelector('.igx-filter-contextual-menu__delete-btn');
1957+
deleteBtn.click();
1958+
tick(200);
1959+
fix.detectChanges();
1960+
1961+
// Verify tree layout and remaining chip content
1962+
let rootGroup = GridFunctions.getAdvancedFilteringTreeRootGroup(fix);
1963+
expect(GridFunctions.getAdvancedFilteringTreeChildItems(rootGroup, true).length).toBe(1);
1964+
verifyExpressionChipContent(fix, [0], 'Downloads', 'Greater Than', '100');
1965+
}));
1966+
19211967
it('Should open the operator dropdown below its respective input-group.', fakeAsync(() => {
19221968
// Open Advanced Filtering dialog.
19231969
grid.openAdvancedFilteringDialog();

projects/igniteui-angular/src/lib/grids/grid/grid-summary.spec.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,77 @@ describe('IgxGrid - Summaries #grid', () => {
134134
fixture.detectChanges();
135135
}).not.toThrow();
136136
});
137+
138+
it('should not display initially disabled summaries in the summary output', fakeAsync(() => {
139+
grid.enableSummaries([{ fieldName: 'UnitsInStock' }]);
140+
fixture.detectChanges();
141+
tick();
142+
143+
const column = grid.getColumnByName('UnitsInStock');
144+
145+
column.disabledSummaries = ['count', 'min', 'max'];
146+
fixture.detectChanges();
147+
tick();
148+
149+
GridSummaryFunctions.verifyColumnSummaries(
150+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
151+
['Sum', 'Avg'],
152+
['39,004', '3,900.4']
153+
);
154+
}));
155+
156+
it('should apply disabled summaries dynamically at runtime', fakeAsync(() => {
157+
grid.enableSummaries([{ fieldName: 'UnitsInStock' }]);
158+
fixture.detectChanges();
159+
tick();
160+
161+
const column = grid.getColumnByName('UnitsInStock');
162+
163+
column.disabledSummaries = [];
164+
fixture.detectChanges();
165+
tick();
166+
GridSummaryFunctions.verifyColumnSummaries(
167+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
168+
['Count', 'Min', 'Max', 'Sum', 'Avg'],
169+
['10', '0', '20,000', '39,004', '3,900.4']
170+
);
171+
172+
column.disabledSummaries = ['count'];
173+
fixture.detectChanges();
174+
tick();
175+
GridSummaryFunctions.verifyColumnSummaries(
176+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
177+
['Min', 'Max', 'Sum', 'Avg'],
178+
['0', '20,000', '39,004', '3,900.4']
179+
);
180+
181+
column.disabledSummaries = ['count', 'sum'];
182+
fixture.detectChanges();
183+
tick();
184+
GridSummaryFunctions.verifyColumnSummaries(
185+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
186+
['Min', 'Max', 'Avg'],
187+
['0', '20,000', '3,900.4']
188+
);
189+
190+
column.disabledSummaries = ['count', 'sum', 'average'];
191+
fixture.detectChanges();
192+
tick();
193+
GridSummaryFunctions.verifyColumnSummaries(
194+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
195+
['Min', 'Max'],
196+
['0', '20,000']
197+
);
198+
199+
column.disabledSummaries = ['min', 'max'];
200+
fixture.detectChanges();
201+
tick();
202+
GridSummaryFunctions.verifyColumnSummaries(
203+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
204+
['Count', 'Sum', 'Avg'],
205+
['10', '39,004', '3,900.4']
206+
);
207+
}));
137208
});
138209

139210
describe('custom summaries: ', () => {
@@ -238,6 +309,33 @@ describe('IgxGrid - Summaries #grid', () => {
238309
expect(lastColumnSummaryCellRect.right).toBe(lastColumnNormalCellRect.right,
239310
'summary cell and data cell are not right aligned');
240311
});
312+
313+
it('should apply disabledSummaries with custom summary', fakeAsync(() => {
314+
grid.enableSummaries([{ fieldName: 'UnitsInStock' }]);
315+
fixture.detectChanges();
316+
tick();
317+
318+
const column = grid.getColumnByName('UnitsInStock');
319+
column.summaries = fixture.componentInstance.inStockSummary;
320+
fixture.detectChanges();
321+
tick();
322+
323+
GridSummaryFunctions.verifyColumnSummaries(
324+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
325+
['Count', 'Min', 'Max', 'Sum', 'Avg', 'Items InStock'],
326+
['10', '0', '20,000', '39,004', '3,900.4', '6']
327+
);
328+
329+
column.disabledSummaries = ['test'];
330+
fixture.detectChanges();
331+
tick();
332+
333+
GridSummaryFunctions.verifyColumnSummaries(
334+
GridSummaryFunctions.getRootSummaryRow(fixture), 3,
335+
['Count', 'Min', 'Max', 'Sum', 'Avg'],
336+
['10', '0', '20,000', '39,004', '3,900.4']
337+
);
338+
}));
241339
});
242340

243341
describe('specific data: ', () => {

projects/igniteui-angular/src/lib/grids/summaries/grid-summary.service.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class IgxGridSummaryService {
1010
public grid: GridType;
1111
public rootSummaryID = 'igxGridRootSummary';
1212
public summaryHeight = 0;
13-
public maxSummariesLenght = 0;
13+
public maxSummariesLength = 0;
1414
public groupingExpressions = [];
1515
public retriggerRootPipe = 0;
1616
public deleteOperation = false;
@@ -98,14 +98,16 @@ export class IgxGridSummaryService {
9898
}
9999
let maxSummaryLength = 0;
100100
this.grid.columns.filter((col) => col.hasSummary && !col.hidden).forEach((column) => {
101-
const getCurrentSummaryColumn = column.summaries.operate([], [], column.field).length;
102-
if (getCurrentSummaryColumn) {
103-
if (maxSummaryLength < getCurrentSummaryColumn) {
104-
maxSummaryLength = getCurrentSummaryColumn;
105-
}
101+
const getCurrentSummary = column.summaries.operate([], [], column.field);
102+
const getCurrentSummaryColumn = column.disabledSummaries.length > 0
103+
? getCurrentSummary.filter(s => !column.disabledSummaries.includes(s.key)).length
104+
: getCurrentSummary.length;
105+
106+
if (maxSummaryLength < getCurrentSummaryColumn) {
107+
maxSummaryLength = getCurrentSummaryColumn;
106108
}
107109
});
108-
this.maxSummariesLenght = maxSummaryLength;
110+
this.maxSummariesLength = maxSummaryLength;
109111
this.summaryHeight = maxSummaryLength * this.grid.defaultSummaryHeight;
110112
return this.summaryHeight;
111113
}
@@ -116,16 +118,30 @@ export class IgxGridSummaryService {
116118
rowSummaries = new Map<string, IgxSummaryResult[]>();
117119
this.summaryCacheMap.set(rowID, rowSummaries);
118120
}
121+
119122
if (!this.hasSummarizedColumns || !data) {
120123
return rowSummaries;
121124
}
125+
122126
this.grid.columns.filter(col => col.hasSummary).forEach((column) => {
123127
if (!rowSummaries.get(column.field)) {
124-
const summaryResult = column.summaries.operate(data.map(r => resolveNestedPath(r, column.field)),
125-
data, column.field, groupRecord, this.grid.locale, column.pipeArgs);
128+
let summaryResult = column.summaries.operate(
129+
data.map(r => resolveNestedPath(r, column.field)),
130+
data,
131+
column.field,
132+
groupRecord,
133+
this.grid.locale,
134+
column.pipeArgs
135+
);
136+
137+
summaryResult = column.disabledSummaries.length > 0
138+
? summaryResult.filter(s => !column.disabledSummaries.includes(s.key))
139+
: summaryResult;
140+
126141
rowSummaries.set(column.field, summaryResult);
127142
}
128143
});
144+
129145
return rowSummaries;
130146
}
131147

projects/igniteui-angular/src/lib/query-builder/query-builder.component.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -767,12 +767,20 @@ export class IgxQueryBuilderComponent implements AfterViewInit, OnDestroy {
767767
* @hidden @internal
768768
*/
769769
public deleteGroup() {
770-
const selectedGroup = this.contextualGroup;
771-
const parent = selectedGroup.parent;
772-
if (parent) {
773-
const index = parent.children.indexOf(selectedGroup);
770+
let selectedGroup = this.contextualGroup;
771+
let parent = selectedGroup.parent;
772+
if (!parent) {
773+
this.rootGroup = null;
774+
}
775+
776+
while (parent) {
777+
let index = parent.children.indexOf(selectedGroup);
774778
parent.children.splice(index, 1);
775-
} else {
779+
selectedGroup = parent;
780+
parent = parent.children.length === 0 ? parent.parent : null;
781+
}
782+
783+
if (this.rootGroup?.children.length === 0) {
776784
this.rootGroup = null;
777785
}
778786

0 commit comments

Comments
 (0)