Skip to content

Commit cb3367c

Browse files
Merge branch 'master' into ganastasov/fix-14174-master
2 parents f161b59 + 37578ef commit cb3367c

File tree

15 files changed

+171
-32
lines changed

15 files changed

+171
-32
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ All notable changes for each version of this project will be documented in this
3030
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`
3131
- Enhanced the advanced filtering to emit the `filtering` event when filters are applied.
3232

33+
### General
34+
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`
35+
- The `contextMenu` event now fires when the end-user clicks to the right of the right-most cell in the grid in case the grid's columns don't span its full width. For this reason the event argument of the event is now of type `IGridContextMenuEventArgs` which contains the row object as well as the cell one. The latter will be `null` if the event didn't originate from a cell. **This is not a breaking change** as the new type extends the old.
36+
3337
## 17.1.0
3438
### New Features
3539
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`

projects/igniteui-angular/src/lib/grids/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ A list of the events emitted by the **igx-grid**:
238238
|`dataPreLoad`| Emitted when a new chunk of data is loaded from virtualization. |
239239
|`columnPin`|Emitted when a column is pinned or unpinned through the grid API. The index that the column is inserted at may be changed through the `insertAtIndex` property. Use `isPinned` to check whether the column is pinned or unpinned.|
240240
|`columnResized`|Emitted when a column is resized. Returns the column object, previous and new column width.|
241-
|`contextMenu`|Emitted when a cell is right clicked. Returns the cell object.|
241+
|`contextMenu`|Emitted when a cell or row is right clicked. Returns the cell or row object.|
242242
|`doubleClick`|Emitted when a cell is double clicked. Returns the cell object.|
243243
|`columnVisibilityChanged`| Emitted when `IgxColumnComponent` visibility is changed. Args: { column: any, newValue: boolean } |
244244
|`groupingDone`|Emitted when the grouping state changes as a result of grouping columns, ungrouping columns or a combination of both. Provides an array of `ISortingExpression`, an array of the **newly** grouped columns as `IgxColumnComponent` references and an array of the **newly** ungrouped columns as `IgxColumnComponent` references.|

projects/igniteui-angular/src/lib/grids/cell.component.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -834,18 +834,6 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT
834834
});
835835
}
836836

837-
/**
838-
* @hidden
839-
* @internal
840-
*/
841-
@HostListener('contextmenu', ['$event'])
842-
public onContextMenu(event: MouseEvent) {
843-
this.grid.contextMenu.emit({
844-
cell: this.getCellType(),
845-
event
846-
});
847-
}
848-
849837
/**
850838
* @hidden
851839
* @internal

projects/igniteui-angular/src/lib/grids/common/events.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export interface IGridRowEventArgs extends IBaseEventArgs {
4141
event: Event;
4242
}
4343

44+
/** Represents an event argument for the grid contextMenu output */
45+
export interface IGridContextMenuEventArgs extends IGridCellEventArgs, IGridRowEventArgs {}
46+
4447
/** Represents event arguments related to grid editing completion. */
4548
export interface IGridEditDoneEventArgs extends IBaseEventArgs {
4649
/**

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
IColumnMovingEventArgs, IPinColumnEventArgs,
88
IActiveNodeChangeEventArgs,
99
ICellPosition, IFilteringEventArgs, IColumnResizeEventArgs, IRowToggleEventArgs, IGridToolbarExportEventArgs, IPinRowEventArgs,
10-
IGridRowEventArgs, IGridEditEventArgs, IRowDataCancelableEventArgs, IGridEditDoneEventArgs
10+
IGridRowEventArgs, IGridEditEventArgs, IRowDataCancelableEventArgs, IGridEditDoneEventArgs,
11+
IGridContextMenuEventArgs
1112
} from '../common/events';
1213
import { DisplayDensity, IDensityChangedEventArgs } from '../../core/density';
1314
import { ChangeDetectorRef, ElementRef, EventEmitter, InjectionToken, QueryList, TemplateRef, ViewContainerRef } from '@angular/core';
@@ -1028,7 +1029,7 @@ export interface GridType extends IGridDataBindable {
10281029
cellClick: EventEmitter<IGridCellEventArgs>;
10291030
rowClick: EventEmitter<IGridRowEventArgs>;
10301031
doubleClick: EventEmitter<IGridCellEventArgs>;
1031-
contextMenu: EventEmitter<IGridCellEventArgs>;
1032+
contextMenu: EventEmitter<IGridContextMenuEventArgs>;
10321033
selected: EventEmitter<IGridCellEventArgs>;
10331034
rangeSelected: EventEmitter<GridSelectionRange>;
10341035
rowSelectionChanging: EventEmitter<IRowSelectionEventArgs>;
@@ -1269,6 +1270,7 @@ export interface PivotGridType extends GridType {
12691270
/** Move value from its currently at specified index or at the end.
12701271
* If the parameter is not set, it will add it to the end of the collection. */
12711272
moveValue(value: IPivotValue, index?: number);
1273+
rowDimensionWidth(dim: IPivotDimension): string;
12721274
rowDimensionWidthToPixels(dim: IPivotDimension): number;
12731275
/** Emits an event when the dimensions in the pivot grid change. */
12741276
dimensionsChange: EventEmitter<IDimensionsChange>;

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ import {
121121
IGridEditEventArgs,
122122
IRowDataCancelableEventArgs,
123123
IGridEditDoneEventArgs,
124-
IGridRowEventArgs
124+
IGridRowEventArgs,
125+
IGridContextMenuEventArgs
125126
} from './common/events';
126127
import { IgxAdvancedFilteringDialogComponent } from './filtering/advanced-filtering/advanced-filtering-dialog.component';
127128
import {
@@ -836,16 +837,16 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
836837
public columnResized = new EventEmitter<IColumnResizeEventArgs>();
837838

838839
/**
839-
* Emitted when a cell is right clicked.
840+
* Emitted when a cell or row is right clicked.
840841
*
841842
* @remarks
842-
* Returns the `IgxGridCell` object.
843+
* Returns the `IgxGridCell` object if the immediate context menu target is a cell or an `IgxGridRow` otherwise.
843844
* ```html
844845
* <igx-grid #grid [data]="localData" (contextMenu)="contextMenu($event)" [autoGenerate]="true"></igx-grid>
845846
* ```
846847
*/
847848
@Output()
848-
public contextMenu = new EventEmitter<IGridCellEventArgs>();
849+
public contextMenu = new EventEmitter<IGridContextMenuEventArgs>();
849850

850851
/**
851852
* Emitted when a cell is double clicked.

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,15 @@ describe('IgxGrid - Cell component #grid', () => {
124124

125125
it('Should trigger contextMenu event when right click into cell', () => {
126126
spyOn(grid.contextMenu, 'emit').and.callThrough();
127-
const event = new Event('contextmenu');
127+
const event = new Event('contextmenu', { bubbles: true });
128128
cellElem.nativeElement.dispatchEvent(event);
129-
const args: IGridCellEventArgs = {
130-
cell: grid.getCellByColumn(0, 'ID'),
131-
event
132-
};
133129

134130
fix.detectChanges();
135131
expect(grid.contextMenu.emit).toHaveBeenCalledTimes(1);
136-
expect(grid.contextMenu.emit).toHaveBeenCalledWith(args);
132+
expect(grid.contextMenu.emit).toHaveBeenCalledWith(jasmine.objectContaining({
133+
cell: jasmine.anything(),
134+
row: jasmine.anything()
135+
}));
137136
});
138137

139138
it('Should trigger doubleClick event when double click into cell', () => {

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2083,7 +2083,35 @@ describe('IgxGrid Component Tests #grid', () => {
20832083
fix.detectChanges();
20842084
expect(grid.rowClick.emit).toHaveBeenCalledTimes(2);
20852085
expect(grid.rowClick.emit).toHaveBeenCalledWith(args);
2086-
})
2086+
});
2087+
2088+
it('Should emit contextMenu when clicking outside of the columns area', () => {
2089+
const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent);
2090+
fix.componentInstance.initColumnsRows(5, 5);
2091+
//fix.componentInstance.columns.forEach(c => c.width = '100px');
2092+
fix.componentInstance.grid.width = '900px';
2093+
fix.detectChanges();
2094+
const grid = fix.componentInstance.grid;
2095+
grid.columnList.forEach(c => c.width = '100px');
2096+
fix.detectChanges();
2097+
const spy = spyOn(grid.contextMenu, 'emit').and.callThrough();
2098+
const event = new Event('contextmenu', { bubbles: true });
2099+
const row = grid.rowList.get(0);
2100+
const cell = row.cells.get(0);
2101+
cell.nativeElement.dispatchEvent(event);
2102+
fix.detectChanges();
2103+
expect(grid.contextMenu.emit).toHaveBeenCalledTimes(1);
2104+
expect(grid.contextMenu.emit).toHaveBeenCalledWith(jasmine.objectContaining({
2105+
cell: jasmine.anything()
2106+
}));
2107+
spy.calls.reset();
2108+
row.nativeElement.dispatchEvent(event);
2109+
fix.detectChanges();
2110+
expect(grid.contextMenu.emit).toHaveBeenCalledTimes(1);
2111+
expect(grid.contextMenu.emit).toHaveBeenCalledWith(jasmine.objectContaining({
2112+
row: jasmine.anything()
2113+
}));
2114+
});
20872115

20882116
it(`Verify that getRowData returns correct data`, () => {
20892117
const fix = TestBed.createComponent(IgxGridDefaultRenderingComponent);

projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
} from '@angular/core';
3030
import { DOCUMENT, NgTemplateOutlet, NgIf, NgClass, NgStyle, NgFor } from '@angular/common';
3131

32+
import { first} from 'rxjs/operators';
3233
import { IgxGridBaseDirective } from '../grid-base.directive';
3334
import { IgxFilteringService } from '../filtering/grid-filtering.service';
3435
import { IgxGridSelectionService } from '../selection/selection.service';
@@ -1156,6 +1157,18 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
11561157
this.rowDimensionWidthToPixels(this.emptyRowDimension);
11571158
}
11581159

1160+
/**
1161+
* @hidden @internal
1162+
*/
1163+
public rowDimensionWidth(dim, ignoreBeforeInit = false ): string {
1164+
const isAuto = dim.width && dim.width.indexOf('auto') !== -1;
1165+
if (isAuto) {
1166+
return dim.autoWidth ? dim.autoWidth + 'px' : 'fit-content';
1167+
} else {
1168+
return this.rowDimensionWidthToPixels(dim, ignoreBeforeInit) + 'px';
1169+
}
1170+
}
1171+
11591172
/**
11601173
* @hidden @internal
11611174
*/
@@ -1168,8 +1181,11 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
11681181
return MINIMUM_COLUMN_WIDTH;
11691182
}
11701183
const isPercent = dim.width && dim.width.indexOf('%') !== -1;
1184+
const isAuto = dim.width && dim.width.indexOf('auto') !== -1;
11711185
if (isPercent) {
11721186
return parseFloat(dim.width) / 100 * this.calcWidth;
1187+
} else if (isAuto) {
1188+
return dim.autoWidth;
11731189
} else {
11741190
return parseInt(dim.width, 10);
11751191
}
@@ -2035,6 +2051,41 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
20352051
return columns;
20362052
}
20372053

2054+
protected override calculateGridSizes(recalcFeatureWidth = true) {
2055+
super.calculateGridSizes(recalcFeatureWidth);
2056+
if (this.hasDimensionsToAutosize) {
2057+
this.cdr.detectChanges();
2058+
this.zone.onStable.pipe(first()).subscribe(() => {
2059+
this.autoSizeDimensionsInView();
2060+
});
2061+
}
2062+
}
2063+
2064+
protected autoSizeDimensionsInView() {
2065+
if (!this.hasDimensionsToAutosize) return;
2066+
for (const dim of this.rowDimensions) {
2067+
if (dim.width === 'auto') {
2068+
const contentWidths = [];
2069+
const relatedDims = PivotUtil.flatten([dim]).map(x => x.memberName);
2070+
const content = this.rowDimensionContentCollection.filter(x => relatedDims.indexOf(x.dimension.memberName) !== -1);
2071+
const headers = content.map(x => x.headerGroups.toArray()).flat().map(x => x.header && x.header.refInstance);
2072+
headers.forEach((header) => contentWidths.push(header?.nativeElement?.offsetWidth || 0));
2073+
const max = Math.max(...contentWidths);
2074+
if (max === 0) {
2075+
// cells not in DOM yet...
2076+
continue;
2077+
}
2078+
const maxSize = Math.ceil(Math.max(...contentWidths));
2079+
dim.autoWidth = maxSize;
2080+
}
2081+
}
2082+
}
2083+
2084+
/** @hidden @internal */
2085+
public get hasDimensionsToAutosize() {
2086+
return this.rowDimensions.some(x => x.width === 'auto' && !x.autoWidth);
2087+
}
2088+
20382089
protected generateFromData(fields: string[]) {
20392090
const separator = this.pivotKeys.columnDimensionSeparator;
20402091
const dataArr = fields.map(x => x.split(separator)).sort(x => x.length);
@@ -2158,13 +2209,14 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
21582209
const count = this.values.length;
21592210
const childWidth = parseInt(parentWidth, 10) / count;
21602211
const isPercent = parentWidth && parentWidth.indexOf('%') !== -1;
2212+
const isAuto = parentWidth && parentWidth.indexOf('auto') !== -1;
21612213
this.values.forEach(val => {
21622214
const ref = createComponent(IgxColumnComponent, { environmentInjector: this.envInjector, elementInjector: this.injector });
21632215
ref.instance.header = val.displayName || val.member;
21642216
ref.instance.field = parent.field + this.pivotKeys.columnDimensionSeparator + val.member;
21652217
ref.instance.parent = parent;
21662218
if (parentWidth) {
2167-
ref.instance.width = isPercent ? childWidth + '%' : childWidth + 'px';
2219+
ref.instance.width = isAuto ? 'auto' : isPercent ? childWidth + '%' : childWidth + 'px';
21682220
}
21692221
ref.instance.hidden = hidden;
21702222
ref.instance.sortable = true;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,12 @@ export interface IPivotDimension {
124124
* The dataType of the related data field.
125125
*/
126126
dataType?: GridColumnDataType;
127-
/** The width of the dimension cells to be rendered.Can be pixel or %. */
127+
/** The width of the dimension cells to be rendered.Can be pixel, % or "auto". */
128128
width?: string;
129129
/** Level of the dimension. */
130130
level?: number;
131+
/** hidden */
132+
autoWidth?: number;
131133
}
132134
/**
133135
* Configuration of a pivot value aggregation.

0 commit comments

Comments
 (0)