From 6e258907f69db0047a8026e53a26f929239fd9ff Mon Sep 17 00:00:00 2001 From: skrustev Date: Wed, 25 Mar 2020 16:29:36 +0200 Subject: [PATCH 01/21] feat(igxHiearchicalGrid): Initial implementation of row pinning. --- .../components/grid/_grid-component.scss | 5 + .../styles/components/grid/_grid-theme.scss | 5 + .../src/lib/grids/cell.component.html | 2 +- .../src/lib/grids/cell.component.ts | 2 +- .../src/lib/grids/common/row.interface.ts | 1 + .../lib/grids/grid-mrl-navigation.service.ts | 4 +- .../src/lib/grids/grid-navigation.service.ts | 11 +- .../hierarchical-cell.component.html | 32 ++++++ .../hierarchical-cell.component.ts | 2 +- .../hierarchical-grid.component.html | 47 ++++++-- .../hierarchical-grid.component.ts | 29 ++++- .../hierarchical-grid.module.ts | 8 +- .../hierarchical-grid.pipes.ts | 31 ++++- .../hierarchical-row-ghost.component.html | 106 ++++++++++++++++++ .../hierarchical-row-ghost.component.ts | 105 +++++++++++++++++ .../hierarchical-row.component.html | 4 +- .../hierarchical-row.component.ts | 30 ++++- .../src/lib/grids/row.directive.ts | 13 ++- .../grid-row-pinning.sample.html | 18 +++ .../grid-row-pinning.sample.ts | 54 ++++++++- 20 files changed, 476 insertions(+), 33 deletions(-) create mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html create mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html create mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index e63e1533227..c487b0d1dcf 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -553,6 +553,11 @@ @extend %igx-grid__hierarchical-expander !optional; } + @include e(hierarchical-expander, $m: empty) { + @extend %igx-grid__hierarchical-expander !optional; + @extend %igx-grid__hierarchical-expander--empty !optional; + } + @include e(hierarchical-expander, $m: header) { @extend %igx-grid__hierarchical-expander--header !optional; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 040a5d689fc..5ea65024f52 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -2454,6 +2454,11 @@ @include if-rtl() { transform: scaleX(-1); } + + &--empty { + cursor: default; + pointer-events: none; + } } %igx-grid__hierarchical-expander--cosy { diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.html b/projects/igniteui-angular/src/lib/grids/cell.component.html index 943f236bf00..386817c2047 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/cell.component.html @@ -1,5 +1,5 @@ -
{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 3ed25765e3a..1fa49250db1 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -524,7 +524,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy { * Returns whether the cell is editable. */ get editable(): boolean { - return this.column.editable; + return (this.column.editable && (this.row.editable === undefined || this.row.editable)) || this.row.editable; } /** diff --git a/projects/igniteui-angular/src/lib/grids/common/row.interface.ts b/projects/igniteui-angular/src/lib/grids/common/row.interface.ts index 4b372aa57b8..e42e5c96112 100644 --- a/projects/igniteui-angular/src/lib/grids/common/row.interface.ts +++ b/projects/igniteui-angular/src/lib/grids/common/row.interface.ts @@ -5,6 +5,7 @@ export interface RowType { checkboxElement: IgxCheckboxComponent; rowID: any; rowData: any; + editable: boolean; rowSelectable: boolean; index: number; gridID: string; diff --git a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts index 61dc523e3f5..ff9e217a561 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts @@ -219,7 +219,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } else if (prevRow) { prevRow.nativeElement.focus({ preventScroll: true }); } else { - const prevElem = this.getRowByIndex(rowIndex, '') as any; + const prevElem = this.getRowByIndex(rowIndex) as any; prevElem.focus({ preventScroll: true }); } }; @@ -264,7 +264,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } else if (nextRow) { nextRow.nativeElement.focus({ preventScroll: true }); } else { - const nextElem = this.getRowByIndex(rowIndex, '') as any; + const nextElem = this.getRowByIndex(rowIndex) as any; nextElem.focus({ preventScroll: true }); } }; diff --git a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts index 3f06b867112..14994a3ce55 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts @@ -323,8 +323,7 @@ export class IgxGridNavigationService { this.grid.verticalScrollContainer.onChunkLoad .pipe(first()) .subscribe(() => { - const tag = rowElement.tagName.toLowerCase(); - rowElement = this.getRowByIndex(currentRowIndex, tag); + rowElement = this.getRowByIndex(currentRowIndex); this.focusPreviousElement(rowElement, visibleColumnIndex); }); } else { @@ -594,7 +593,7 @@ export class IgxGridNavigationService { if (visibleColumnIndex === 0 && prevIsDetailRow) { let target = currentRowEl.previousElementSibling; const applyFocusFunc = () => { - target = this.getRowByIndex(rowIndex - 1, ''); + target = this.getRowByIndex(rowIndex - 1); target.focus({ preventScroll: true }); }; if (target) { @@ -628,7 +627,7 @@ export class IgxGridNavigationService { public shouldPerformVerticalScroll(targetRowIndex: number, visibleColumnIndex: number): boolean { const containerTopOffset = parseInt(this.verticalDisplayContainerElement.style.top, 10); - const targetRow = this.getRowByIndex(targetRowIndex, '') as any; + const targetRow = this.getRowByIndex(targetRowIndex) as any; const rowHeight = this.grid.verticalScrollContainer.getSizeAt(targetRowIndex); const containerHeight = this.grid.calcHeight ? Math.ceil(this.grid.calcHeight) : 0; const targetEndTopOffset = targetRow ? targetRow.offsetTop + rowHeight + containerTopOffset : @@ -672,10 +671,10 @@ export class IgxGridNavigationService { return this.grid; } - protected getRowByIndex(index, selector = this.getRowSelector()) { + protected getRowByIndex(index) { const gridTag = this.grid.nativeElement.tagName.toLocaleLowerCase(); const row = Array.from(this.grid.tbody.nativeElement.querySelectorAll( - `${selector}[data-rowindex="${index}"]`)) + `[data-rowindex="${index}"]`)) .find(x => this.getClosestElemByTag(x, gridTag).getAttribute('id') === this.grid.id); return row; } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html new file mode 100644 index 00000000000..d56167268c8 --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html @@ -0,0 +1,32 @@ + +
Pinned
+
{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: + grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }}
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts index 7e290dfb0c3..4f75d0fa5ac 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts @@ -11,7 +11,7 @@ import { PlatformUtil } from '../../core/utils'; changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: 'igx-hierarchical-grid-cell', - templateUrl: './../cell.component.html', + templateUrl: './hierarchical-cell.component.html', providers: [HammerGesturesManager] }) export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent implements OnInit { diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index b703acbf4f4..aaed46ad016 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -84,16 +84,38 @@
+ [style.height.px]='totalHeight' [style.width.px]='calcWidth' #tbody (scroll)='scrollHandler($event)'> + + +
+ + + + + + + + + +
+
+
+ + - + + + + +
-
+ + @@ -130,9 +158,12 @@
-
- +
+
+
+ +
+
diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index a44c0844218..1fbcccc22d3 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -494,6 +494,9 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti * @hidden */ public isHierarchicalRecord(record: any): boolean { + if (this.isGhostRecord(record)) { + record = record.recordData; + } return this.childLayoutList.length !== 0 && record[this.childLayoutList.first.key]; } @@ -505,6 +508,10 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti return record.childGridsData !== undefined; } + public isGhostRecord(record: any): boolean { + return record.ghostRec !== undefined; + } + /** * @hidden */ @@ -519,7 +526,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti /** * @hidden */ - public getContext(rowData): any { + public getContext(rowData, rowIndex, pinned): any { if (this.isChildGridRecord(rowData)) { const cachedData = this.childGridTemplates.get(rowData.rowID); if (cachedData) { @@ -540,15 +547,33 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti index: this.dataView.indexOf(rowData) }; } + } else if (this.isGhostRecord(rowData)) { + return { + $implicit: rowData.recordData, + templateID: 'ghostRow', + index: this.getRowIndex(rowIndex, pinned) + }; } else { return { $implicit: rowData, templateID: 'dataRow', - index: this.dataView.indexOf(rowData) + index: this.getRowIndex(rowIndex, pinned) }; } } + /** + * @hidden + */ + public getRowIndex(rowIndex, pinned) { + if (pinned && !this.isRowPinningToTop) { + rowIndex = rowIndex + this.dataView.length; + } else if (!pinned && this.isRowPinningToTop) { + rowIndex = rowIndex + this.pinnedRecordsCount; + } + return rowIndex; + } + /** * @hidden */ diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts index a445d485ec2..657f4aaf338 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts @@ -2,12 +2,13 @@ import { NgModule } from '@angular/core'; import { IgxGridModule } from '../grid/grid.module'; import { IgxHierarchicalGridComponent } from './hierarchical-grid.component'; import { IgxHierarchicalRowComponent } from './hierarchical-row.component'; -import { IgxGridHierarchicalPipe, IgxGridHierarchicalPagingPipe } from './hierarchical-grid.pipes'; +import { IgxGridHierarchicalPipe, IgxGridHierarchicalPagingPipe, IgxGridHierarchicalRowPinning } from './hierarchical-grid.pipes'; import { IgxRowIslandComponent } from './row-island.component'; import { IgxChildGridRowComponent } from './child-grid-row.component'; import { IgxHierarchicalGridCellComponent } from './hierarchical-cell.component'; import { IgxGridComponent } from '../grid/grid.component'; import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.directive'; +import { IgxHierarchicalRowGhostComponent } from './hierarchical-row-ghost.component'; /** * @hidden @@ -17,16 +18,19 @@ import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.direc IgxHierarchicalGridBaseDirective, IgxHierarchicalGridComponent, IgxHierarchicalRowComponent, + IgxHierarchicalRowGhostComponent, IgxRowIslandComponent, IgxChildGridRowComponent, IgxHierarchicalGridCellComponent, IgxGridHierarchicalPipe, - IgxGridHierarchicalPagingPipe + IgxGridHierarchicalPagingPipe, + IgxGridHierarchicalRowPinning ], exports: [ IgxGridModule, IgxHierarchicalGridComponent, IgxHierarchicalRowComponent, + IgxHierarchicalRowGhostComponent, IgxHierarchicalGridCellComponent, IgxRowIslandComponent, IgxChildGridRowComponent diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts index b86fa37aa3f..4852fb0f1bd 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts @@ -35,8 +35,12 @@ export class IgxGridHierarchicalPipe implements PipeTransform { public addHierarchy(grid, data: T[], state, primaryKey, childKeys: string[]): T[] { const result = []; - data.forEach((v) => { + data.forEach((v: any) => { result.push(v); + if (v.ghostRec !== undefined) { + v = v.recordData; + } + const childGridsData = {}; childKeys.forEach((childKey) => { const childData = v[childKey] ? v[childKey] : null; @@ -77,3 +81,28 @@ export class IgxGridHierarchicalPagingPipe implements PipeTransform { return result; } } + +/** + *@hidden + */ +@Pipe({ + name: 'gridHierarchicalRowPinning', + pure: true +}) +export class IgxGridHierarchicalRowPinning implements PipeTransform { + + constructor(private gridAPI: GridBaseAPIService) { } + + public transform(collection: any[], pinnedArea: boolean, pipeTrigger: number): any[] { + const grid = this.gridAPI.grid; + + if (grid.hasPinnedRecords && pinnedArea) { + return collection.filter(rec => grid.isRecordPinned(rec)); + } + + const result = collection.map((value) => { + return grid.isRecordPinned(value) ? { recordData: value, ghostRec: true} : value; + }); + return result; + } +} diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html new file mode 100644 index 00000000000..51520b69b9f --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html @@ -0,0 +1,106 @@ +
+ + +
+ + expand_more + + + + chevron_right + + + + + + + +
+ +
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + +
+ + +
+
+ + + + + \ No newline at end of file diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts new file mode 100644 index 00000000000..1f690c3272e --- /dev/null +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts @@ -0,0 +1,105 @@ +import { + ChangeDetectionStrategy, + Component, + HostBinding, + forwardRef, + HostListener, + Input +} from '@angular/core'; +import { IgxHierarchicalRowComponent } from './hierarchical-row.component'; +import { IgxRowDirective } from '../grid'; + +@Component({ + changeDetection: ChangeDetectionStrategy.OnPush, + preserveWhitespaces: false, + selector: 'igx-hierarchical-grid-row-ghost', + templateUrl: './hierarchical-row-ghost.component.html', + providers: [{ provide: IgxRowDirective, useExisting: forwardRef(() => IgxHierarchicalRowGhostComponent) }] +}) +export class IgxHierarchicalRowGhostComponent extends IgxHierarchicalRowComponent { + public editable = false; + + /** + * @hidden + */ + public get expanderClassResolved() { + return { [this.expanderClass]: true }; + } + + /** + * The data passed to the row component. + * + * ```typescript + * // get the row data for the first selected row + * let selectedRowData = this.grid.selectedRows[0].rowData; + * ``` + */ + @Input() + public get rowData(): any { + return this._rowData.recordData; + } + + public set rowData(v: any) { + this._rowData = v; + } + + public get realRowID() { + const primaryKey = this.grid.primaryKey; + return primaryKey ? this._rowData.recordData[primaryKey] : this._rowData.recordData; + } + + /** + * @hidden + */ + public getIconTemplate() { + let expandable = true; + if (this.grid.hasChildrenKey) { + expandable = this.rowData[this.grid.hasChildrenKey]; + } + if (!expandable) { + return this.defaultEmptyTemplate; + } + if (this.expanded) { + return this.grid.rowExpandedIndicatorTemplate || this.defaultExpandedTemplate; + } else { + return this.grid.rowCollapsedIndicatorTemplate || this.defaultCollapsedTemplate; + } + } + + /** + * Toggles the hierarchical row. + * ```typescript + * this.grid1.rowList.first.toggle() + * ``` + */ + public toggle() { + if (this.added) { + return; + } + const grid = this.gridAPI.grid; + this.endEdit(grid.rootGrid); + this.gridAPI.set_row_expansion_state(this.realRowID, !this.expanded); + grid.cdr.detectChanges(); + } + + /** + * @hidden + */ + @Input() + @HostBinding('attr.aria-selected') + get selected(): boolean { + return this.selectionService.isRowSelected(this.realRowID); + } + + /** + * @hidden + * @internal + */ + @HostListener('click', ['$event']) + public onClick(event: MouseEvent) { } + + /** + * @hidden + */ + public onRowSelectorClick(event) { } +} diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html index 24a491649fd..bc33eccf423 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html @@ -1,5 +1,5 @@ -
- +
+
diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts index e9933d50176..59f73b9fb9c 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts @@ -21,6 +21,19 @@ import { IgxHierarchicalGridCellComponent } from './hierarchical-cell.component' providers: [{ provide: IgxRowDirective, useExisting: forwardRef(() => IgxHierarchicalRowComponent) }] }) export class IgxHierarchicalRowComponent extends IgxRowDirective { + + protected expanderClass = 'igx-grid__hierarchical-expander'; + + /** + * @hidden + */ + public get expanderClassResolved() { + return { + [this.expanderClass]: !this.pinned, + [`${this.expanderClass}--empty`]: this.pinned + }; + } + /** * The rendered cells in the row component. * @@ -63,17 +76,24 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective implements DoCheck { - private _rowData: any; + protected _rowData: any; + /** * The data passed to the row component. * @@ -58,6 +59,16 @@ export class IgxRowDirective implemen @Input() public index: number; + /** + * Sets whether this specific row can be editable. + * Default value is `false`. + * ```typescript + * this.grid.selectedRows[0].pinned = true; + * ``` + */ + @Input() + public editable: boolean; + /** * Gets whether the row is pinned. * ```typescript diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.html b/src/app/grid-row-pinning/grid-row-pinning.sample.html index 184cd8fa447..c46fd56df64 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.html +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.html @@ -8,6 +8,7 @@
Bottom Row Pinning toggle Right Column Pinning toggle +
@@ -27,5 +28,22 @@
+
+ + + + + {{cell.row.pinned ? 'lock' : 'lock_open'}} + + + + + + + + + + +
diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.ts b/src/app/grid-row-pinning/grid-row-pinning.sample.ts index 24c7b90300d..f77057a086f 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.ts +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.ts @@ -1,5 +1,5 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import { IgxGridComponent, ColumnPinningPosition, RowPinningPosition, IgxGridRowComponent, IgxTransactionService, IgxGridTransaction } from 'igniteui-angular'; +import { IgxGridComponent, ColumnPinningPosition, RowPinningPosition, IgxGridRowComponent, IgxTransactionService, IgxGridTransaction, IgxHierarchicalRowComponent, IgxHierarchicalGridComponent } from 'igniteui-angular'; import { IPinningConfig } from 'projects/igniteui-angular/src/lib/grids/common/grid.interface'; @Component({ @@ -15,6 +15,9 @@ export class GridRowPinningSampleComponent implements OnInit { @ViewChild('grid1', { static: true }) grid1: IgxGridComponent; + @ViewChild('hGrid', { static: true }) + hGrid: IgxHierarchicalGridComponent; + onRowChange() { if (this.pinningConfig.rows === RowPinningPosition.Bottom) { this.pinningConfig = { columns: this.pinningConfig.columns, rows: RowPinningPosition.Top }; @@ -32,7 +35,9 @@ export class GridRowPinningSampleComponent implements OnInit { } data: any[]; + hierarchicalData: any[]; columns: any[]; + hColumns: any[]; ngOnInit(): void { this.columns = [ @@ -48,6 +53,18 @@ export class GridRowPinningSampleComponent implements OnInit { { field: 'Fax', width: '200px' } ]; + this.hColumns = [ + { field: 'ID', width: '200px' }, + { field: 'ChildLevels', width: '200px' }, + { field: 'ProductName', width: '200px' }, + { field: 'Col1', width: '200px' }, + { field: 'Col2', width: '200px' }, + { field: 'Col3', width: '200px' }, + { field: 'childData', width: '200px' }, + { field: 'childData2', width: '200px' }, + { field: 'hasChild', width: '200px' } + ] + this.data = [ // tslint:disable:max-line-length { 'ID': 'ALFKI', 'CompanyName': 'Alfreds Futterkiste', 'ContactName': 'Maria Anders', 'ContactTitle': 'Sales Representative', 'Address': 'Obere Str. 57', 'City': 'Berlin', 'Region': null, 'PostalCode': '12209', 'Country': 'Germany', 'Phone': '030-0074321', 'Fax': '030-0076545' }, @@ -78,6 +95,8 @@ export class GridRowPinningSampleComponent implements OnInit { { 'ID': 'FRANR', 'CompanyName': 'France restauration', 'ContactName': 'Carine Schmitt', 'ContactTitle': 'Marketing Manager', 'Address': '54, rue Royale', 'City': 'Nantes', 'Region': null, 'PostalCode': '44000', 'Country': 'France', 'Phone': '40.32.21.21', 'Fax': '40.32.21.20' }, { 'ID': 'FRANS', 'CompanyName': 'Franchi S.p.A.', 'ContactName': 'Paolo Accorti', 'ContactTitle': 'Sales Representative', 'Address': 'Via Monte Bianco 34', 'City': 'Torino', 'Region': null, 'PostalCode': '10100', 'Country': 'Italy', 'Phone': '011-4988260', 'Fax': '011-4988261' } ]; + this.hierarchicalData = this.generateDataUneven(100, 3); + this // tslint:enable:max-line-length } @@ -97,4 +116,37 @@ export class GridRowPinningSampleComponent implements OnInit { } } + clickUnpin() { + this.grid1.unpinRow('aaaa'); + } + + generateDataUneven(count: number, level: number, parendID: string = null) { + const prods = []; + const currLevel = level; + let children; + for (let i = 0; i < count; i++) { + const rowID = parendID ? parendID + i : i.toString(); + if (level > 0) { + // Have child grids for row with even id less rows by not multiplying by 2 + children = this.generateDataUneven(((i % 2) + 1) * Math.round(count / 3), currLevel - 1, rowID); + } + prods.push({ + ID: rowID, + ChildLevels: currLevel, + ProductName: 'Product: A' + i, + Col1: i, + Col2: i, + Col3: i, + childData: children, + childData2: children, + hasChild: true + }); + } + return prods; + } + + public isPinned(cell) { + console.log(cell); + return true; + } } From 47b8af29c8bf2a193fe4140a0052815d0a91fe3c Mon Sep 17 00:00:00 2001 From: skrustev Date: Thu, 26 Mar 2020 18:06:24 +0200 Subject: [PATCH 02/21] feat(igxHierarchicalGrid): Remove hierarchical ghost row and add instead ghostRecord input. --- .../components/grid/_grid-component.scss | 4 + .../styles/components/grid/_grid-theme.scss | 3 + .../src/lib/grids/cell.component.html | 2 +- .../src/lib/grids/common/row.interface.ts | 1 + .../hierarchical-cell.component.html | 11 +- .../hierarchical-cell.component.ts | 28 ++++- .../hierarchical-grid.component.html | 10 +- .../hierarchical-grid.component.ts | 8 +- .../hierarchical-grid.module.ts | 3 - .../hierarchical-row-ghost.component.html | 106 ------------------ .../hierarchical-row-ghost.component.ts | 105 ----------------- .../hierarchical-row.component.html | 2 +- .../hierarchical-row.component.ts | 42 ++++++- .../hierarchical-row.interface.ts | 5 + 14 files changed, 89 insertions(+), 241 deletions(-) delete mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html delete mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts create mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.interface.ts diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index c487b0d1dcf..58ab90c56d0 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -392,6 +392,10 @@ @extend %grid-cell--pinned--column-selected !optional; } + @include e(td, $m: pinned-chip) { + @extend %grid-cell--pinned-chip !optional; + } + @include e(td-text) { @extend %grid-cell-text !optional; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 5ea65024f52..1b36c97475f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -1371,6 +1371,9 @@ } } + %grid-cell--pinned-chip { + margin-right: rem(4px); + } %grid-cell-header { flex-flow: row nowrap; diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.html b/projects/igniteui-angular/src/lib/grids/cell.component.html index 386817c2047..943f236bf00 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/cell.component.html @@ -1,5 +1,5 @@ -
{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: diff --git a/projects/igniteui-angular/src/lib/grids/common/row.interface.ts b/projects/igniteui-angular/src/lib/grids/common/row.interface.ts index e42e5c96112..351d92a7a20 100644 --- a/projects/igniteui-angular/src/lib/grids/common/row.interface.ts +++ b/projects/igniteui-angular/src/lib/grids/common/row.interface.ts @@ -10,6 +10,7 @@ export interface RowType { index: number; gridID: string; added: boolean; + pinned: boolean; deleted: boolean; selected: boolean; focused: boolean; diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html index d56167268c8..44e72a621ab 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html @@ -1,11 +1,10 @@ -
Pinned
-
Pinned +
{{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: - grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }}
+ [row]="rowData" [column]="this.column.field" [containerClass]="textClasses" [ngClass]="textClasses"> + {{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }} +
diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts index 4f75d0fa5ac..dfac2f2937c 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts @@ -1,11 +1,12 @@ import { IgxGridCellComponent } from '../cell.component'; import { GridBaseAPIService } from '../api.service'; import { ChangeDetectorRef, ElementRef, ChangeDetectionStrategy, Component, - OnInit, HostListener, NgZone } from '@angular/core'; + OnInit, HostListener, NgZone, HostBinding } from '@angular/core'; import { IgxHierarchicalGridComponent } from './hierarchical-grid.component'; import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/selection.service'; import { HammerGesturesManager } from '../../core/touch'; import { PlatformUtil } from '../../core/utils'; +import { HierarchicalRowType } from './hierarchical-row.interface'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -16,6 +17,31 @@ import { PlatformUtil } from '../../core/utils'; }) export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent implements OnInit { + /** + * @hidden + */ + public get displayPinnedChip() { + return this.hierarchicalRow.ghostRow && + (!this.grid.visibleColumns[this.visibleColumnIndex - 1] || this.grid.visibleColumns[this.visibleColumnIndex - 1].cellTemplate); + } + + /** + * @hidden + */ + public get hierarchicalRow(): HierarchicalRowType { + return this.row as HierarchicalRowType; + } + + /** + * @hidden + */ + public get textClasses() { + return { + ['igx-grid__td-text']: !this.hierarchicalRow.ghostRow, + ['igx-grid__td-text--disabled']: this.hierarchicalRow.ghostRow + }; + } + // protected hSelection; protected _rootGrid; diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index aaed46ad016..f1845c03b43 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -124,13 +124,9 @@ [igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" [igxForTrackBy]='trackChanges' #verticalScrollContainer (onChunkPreload)="dataLoading($event)"> - + - - - -
--> diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index 1fbcccc22d3..d8007efaad8 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -547,15 +547,9 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti index: this.dataView.indexOf(rowData) }; } - } else if (this.isGhostRecord(rowData)) { - return { - $implicit: rowData.recordData, - templateID: 'ghostRow', - index: this.getRowIndex(rowIndex, pinned) - }; } else { return { - $implicit: rowData, + $implicit: this.isGhostRecord(rowData) ? rowData.recordData : rowData, templateID: 'dataRow', index: this.getRowIndex(rowIndex, pinned) }; diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts index 657f4aaf338..ba6f296d18f 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.module.ts @@ -8,7 +8,6 @@ import { IgxChildGridRowComponent } from './child-grid-row.component'; import { IgxHierarchicalGridCellComponent } from './hierarchical-cell.component'; import { IgxGridComponent } from '../grid/grid.component'; import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.directive'; -import { IgxHierarchicalRowGhostComponent } from './hierarchical-row-ghost.component'; /** * @hidden @@ -18,7 +17,6 @@ import { IgxHierarchicalRowGhostComponent } from './hierarchical-row-ghost.compo IgxHierarchicalGridBaseDirective, IgxHierarchicalGridComponent, IgxHierarchicalRowComponent, - IgxHierarchicalRowGhostComponent, IgxRowIslandComponent, IgxChildGridRowComponent, IgxHierarchicalGridCellComponent, @@ -30,7 +28,6 @@ import { IgxHierarchicalRowGhostComponent } from './hierarchical-row-ghost.compo IgxGridModule, IgxHierarchicalGridComponent, IgxHierarchicalRowComponent, - IgxHierarchicalRowGhostComponent, IgxHierarchicalGridCellComponent, IgxRowIslandComponent, IgxChildGridRowComponent diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html deleted file mode 100644 index 51520b69b9f..00000000000 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.html +++ /dev/null @@ -1,106 +0,0 @@ -
- - -
- - expand_more - - - - chevron_right - - - - - - - -
- -
-
- -
- - -
-
- - - - - - - - - - - - - - - -
- - -
-
- - - - - \ No newline at end of file diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts deleted file mode 100644 index 1f690c3272e..00000000000 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row-ghost.component.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { - ChangeDetectionStrategy, - Component, - HostBinding, - forwardRef, - HostListener, - Input -} from '@angular/core'; -import { IgxHierarchicalRowComponent } from './hierarchical-row.component'; -import { IgxRowDirective } from '../grid'; - -@Component({ - changeDetection: ChangeDetectionStrategy.OnPush, - preserveWhitespaces: false, - selector: 'igx-hierarchical-grid-row-ghost', - templateUrl: './hierarchical-row-ghost.component.html', - providers: [{ provide: IgxRowDirective, useExisting: forwardRef(() => IgxHierarchicalRowGhostComponent) }] -}) -export class IgxHierarchicalRowGhostComponent extends IgxHierarchicalRowComponent { - public editable = false; - - /** - * @hidden - */ - public get expanderClassResolved() { - return { [this.expanderClass]: true }; - } - - /** - * The data passed to the row component. - * - * ```typescript - * // get the row data for the first selected row - * let selectedRowData = this.grid.selectedRows[0].rowData; - * ``` - */ - @Input() - public get rowData(): any { - return this._rowData.recordData; - } - - public set rowData(v: any) { - this._rowData = v; - } - - public get realRowID() { - const primaryKey = this.grid.primaryKey; - return primaryKey ? this._rowData.recordData[primaryKey] : this._rowData.recordData; - } - - /** - * @hidden - */ - public getIconTemplate() { - let expandable = true; - if (this.grid.hasChildrenKey) { - expandable = this.rowData[this.grid.hasChildrenKey]; - } - if (!expandable) { - return this.defaultEmptyTemplate; - } - if (this.expanded) { - return this.grid.rowExpandedIndicatorTemplate || this.defaultExpandedTemplate; - } else { - return this.grid.rowCollapsedIndicatorTemplate || this.defaultCollapsedTemplate; - } - } - - /** - * Toggles the hierarchical row. - * ```typescript - * this.grid1.rowList.first.toggle() - * ``` - */ - public toggle() { - if (this.added) { - return; - } - const grid = this.gridAPI.grid; - this.endEdit(grid.rootGrid); - this.gridAPI.set_row_expansion_state(this.realRowID, !this.expanded); - grid.cdr.detectChanges(); - } - - /** - * @hidden - */ - @Input() - @HostBinding('attr.aria-selected') - get selected(): boolean { - return this.selectionService.isRowSelected(this.realRowID); - } - - /** - * @hidden - * @internal - */ - @HostListener('click', ['$event']) - public onClick(event: MouseEvent) { } - - /** - * @hidden - */ - public onRowSelectorClick(event) { } -} diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html index bc33eccf423..c01766bff39 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html @@ -71,7 +71,7 @@ [readonly]="true" [checked]="selected" disableRipple="true" - [disabled]="deleted" + [disabled]="ghostRow || deleted" [disableTransitions]="grid.disableTransitions" [aria-label]="rowCheckboxAriaLabel"> diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts index 59f73b9fb9c..0c2d44cb962 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts @@ -7,7 +7,9 @@ import { ViewChildren, QueryList, ViewChild, - TemplateRef + TemplateRef, + Input, + HostListener } from '@angular/core'; import { IgxHierarchicalGridComponent } from './hierarchical-grid.component'; import { IgxRowDirective } from '../row.directive'; @@ -22,15 +24,29 @@ import { IgxHierarchicalGridCellComponent } from './hierarchical-cell.component' }) export class IgxHierarchicalRowComponent extends IgxRowDirective { + protected _ghostRow = false; protected expanderClass = 'igx-grid__hierarchical-expander'; + /** + * @hidden + */ + @Input() + public set ghostRow(value: boolean) { + this.editable = !value; + this._ghostRow = value; + } + + public get ghostRow() { + return this._ghostRow; + } + /** * @hidden */ public get expanderClassResolved() { return { - [this.expanderClass]: !this.pinned, - [`${this.expanderClass}--empty`]: this.pinned + [this.expanderClass]: !this.pinned || this.ghostRow, + [`${this.expanderClass}--empty`]: this.pinned && !this.ghostRow }; } @@ -154,7 +170,7 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective Date: Thu, 26 Mar 2020 20:07:45 +0200 Subject: [PATCH 03/21] feat(igxHierarchicalGrid): Improve ghost row styling., --- .../core/styles/components/grid/_grid-component.scss | 4 ++++ .../lib/core/styles/components/grid/_grid-theme.scss | 12 +++++++++++- .../lib/core/styles/themes/schemas/light/_grid.scss | 5 +++++ .../hierarchical-cell.component.html | 4 ++-- .../hierarchical-grid/hierarchical-cell.component.ts | 10 ---------- .../hierarchical-grid/hierarchical-row.component.ts | 4 ++++ 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index 58ab90c56d0..29569c56fdc 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -358,6 +358,10 @@ @extend %igx-grid__td--editing !optional; } + @include e(tr, $m: ghost-copy) { + @extend %igx-grid__tr--ghost-copy !optional; + } + @include e(td, $m: number) { @extend %grid-cell-number !optional; } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 1b36c97475f..8b482dddb5e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -47,7 +47,8 @@ /// @param {Color} $cell-selected-background [null] - The selected cell background color. /// @param {Color} $cell-selected-text-color [null] - The selected cell text color. /// @param {Color} $cell-editing-background [null] - The background color of the cell being edited. -/// @param {Color} $cell-edited-value-color [null] - The text color of a sell that has been edited. +/// @param {Color} $cell-edited-value-color [null] - The text color of a cell that has been edited. +/// @param {Color} $cell-ghost-copy-color [null] - The text color of a cell that is ghost of another row. /// /// @param {Color} $edit-mode-color [null] - The color applied around the row when in editing mode. /// @param {Color} $edited-row-indicator [null] - The color applied to the edited row indicator line. @@ -155,6 +156,7 @@ $cell-selected-text-color: null, $cell-editing-background: null, $cell-edited-value-color: null, + $cell-ghost-copy-color: null, $edit-mode-color: null, $edited-row-indicator: null, @@ -479,6 +481,8 @@ edited-row-indicator: $edited-row-indicator, cell-edited-value-color: $cell-edited-value-color, + cell-ghost-copy-color: $cell-ghost-copy-color, + resize-line-color: $resize-line-color, drop-indicator-color: $drop-indicator-color, @@ -1316,6 +1320,12 @@ } } + %igx-grid__tr--ghost-copy { + %grid-cell-text { + color: --var($theme, 'cell-ghost-copy-color'); + } + } + %igx-grid__td--editing { background: --var($theme, 'cell-editing-background') !important; box-shadow: inset 0 0 0 rem(2px) --var($theme, 'edit-mode-color'); diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss index d3de7b24411..7d48bcbe9af 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss @@ -45,6 +45,7 @@ /// @prop {Map} edit-mode-color [igx-color: ('secondary', 500)] - The text color in edit mode. /// @prop {Map} edited-row-indicator [igx-color: ('grays', 400)] - The indicator's color of edited row. /// @prop {Map} cell-edited-value-color [igx-color: ('grays', 600)] - The color of cell edited value. +/// @prop {Map} cell-ghost-copy-color [igx-color: ('grays', 600)] - The color of cell ghost text. /// @prop {Map} resize-line-color [igx-color: ('secondary', 500)] - The table header resize line color. /// @prop {Map} drop-indicator-color [igx-color: ('secondary', 500)] - The color of the drop indicator. /// @prop {Map} grouparea-background [igx-color: ('grays', 100), hexrgba: #fff] - The grid group area background color. @@ -221,6 +222,10 @@ $_light-grid: extend( igx-color: ('grays', 600) ), + cell-ghost-copy-color: ( + igx-color: ('grays', 400) + ), + resize-line-color: ( igx-color: ('secondary', 500) ), diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html index 44e72a621ab..5aaf3526d41 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html @@ -1,8 +1,8 @@ Pinned -
+ [row]="rowData" [column]="this.column.field" [containerClass]="'igx-grid__td-text'" class="igx-grid__td-text"> {{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }}
diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts index dfac2f2937c..2af8fbcacd4 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts @@ -32,16 +32,6 @@ export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent imple return this.row as HierarchicalRowType; } - /** - * @hidden - */ - public get textClasses() { - return { - ['igx-grid__td-text']: !this.hierarchicalRow.ghostRow, - ['igx-grid__td-text--disabled']: this.hierarchicalRow.ghostRow - }; - } - // protected hSelection; protected _rootGrid; diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts index 0c2d44cb962..446a4a83634 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts @@ -31,6 +31,10 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective Date: Fri, 27 Mar 2020 19:53:04 +0200 Subject: [PATCH 04/21] fix(rowPinning): Fix issues with styling and reverse navigation changes. Simplify grid template. --- .../components/grid/_grid-component.scss | 10 ++++ .../lib/grids/grid-mrl-navigation.service.ts | 4 +- .../src/lib/grids/grid-navigation.service.ts | 11 ++-- .../hierarchical-cell.component.ts | 3 +- .../hierarchical-grid.component.html | 54 +++++++++---------- .../hierarchical-grid.component.ts | 3 +- .../grid-row-pinning.sample.html | 7 ++- .../grid-row-pinning.sample.ts | 31 +++++++++-- 8 files changed, 79 insertions(+), 44 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index 29569c56fdc..63d22a3ae14 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -681,6 +681,11 @@ @extend %igx-grid__hierarchical-expander--cosy !optional; } + @include e(hierarchical-expander, $m: empty) { + @extend %igx-grid__hierarchical-expander--cosy !optional; + @extend %igx-grid__hierarchical-expander--empty !optional; + } + @include e(hierarchical-expander, $m: push) { @extend %igx-grid__hierarchical-expander--push--cosy !optional; } @@ -780,6 +785,11 @@ @include e(hierarchical-expander) { @extend %igx-grid__hierarchical-expander--compact !optional; } + + @include e(hierarchical-expander, $m: empty) { + @extend %igx-grid__hierarchical-expander--compact !optional; + @extend %igx-grid__hierarchical-expander--empty !optional; + } @include e(hierarchical-expander, $m: push) { @extend %igx-grid__hierarchical-expander--push--compact !optional; diff --git a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts index ff9e217a561..61dc523e3f5 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-mrl-navigation.service.ts @@ -219,7 +219,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } else if (prevRow) { prevRow.nativeElement.focus({ preventScroll: true }); } else { - const prevElem = this.getRowByIndex(rowIndex) as any; + const prevElem = this.getRowByIndex(rowIndex, '') as any; prevElem.focus({ preventScroll: true }); } }; @@ -264,7 +264,7 @@ export class IgxGridMRLNavigationService extends IgxGridNavigationService { } else if (nextRow) { nextRow.nativeElement.focus({ preventScroll: true }); } else { - const nextElem = this.getRowByIndex(rowIndex) as any; + const nextElem = this.getRowByIndex(rowIndex, '') as any; nextElem.focus({ preventScroll: true }); } }; diff --git a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts index 14994a3ce55..3f06b867112 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts @@ -323,7 +323,8 @@ export class IgxGridNavigationService { this.grid.verticalScrollContainer.onChunkLoad .pipe(first()) .subscribe(() => { - rowElement = this.getRowByIndex(currentRowIndex); + const tag = rowElement.tagName.toLowerCase(); + rowElement = this.getRowByIndex(currentRowIndex, tag); this.focusPreviousElement(rowElement, visibleColumnIndex); }); } else { @@ -593,7 +594,7 @@ export class IgxGridNavigationService { if (visibleColumnIndex === 0 && prevIsDetailRow) { let target = currentRowEl.previousElementSibling; const applyFocusFunc = () => { - target = this.getRowByIndex(rowIndex - 1); + target = this.getRowByIndex(rowIndex - 1, ''); target.focus({ preventScroll: true }); }; if (target) { @@ -627,7 +628,7 @@ export class IgxGridNavigationService { public shouldPerformVerticalScroll(targetRowIndex: number, visibleColumnIndex: number): boolean { const containerTopOffset = parseInt(this.verticalDisplayContainerElement.style.top, 10); - const targetRow = this.getRowByIndex(targetRowIndex) as any; + const targetRow = this.getRowByIndex(targetRowIndex, '') as any; const rowHeight = this.grid.verticalScrollContainer.getSizeAt(targetRowIndex); const containerHeight = this.grid.calcHeight ? Math.ceil(this.grid.calcHeight) : 0; const targetEndTopOffset = targetRow ? targetRow.offsetTop + rowHeight + containerTopOffset : @@ -671,10 +672,10 @@ export class IgxGridNavigationService { return this.grid; } - protected getRowByIndex(index) { + protected getRowByIndex(index, selector = this.getRowSelector()) { const gridTag = this.grid.nativeElement.tagName.toLocaleLowerCase(); const row = Array.from(this.grid.tbody.nativeElement.querySelectorAll( - `[data-rowindex="${index}"]`)) + `${selector}[data-rowindex="${index}"]`)) .find(x => this.getClosestElemByTag(x, gridTag).getAttribute('id') === this.grid.id); return row; } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts index 2af8fbcacd4..0c4a0d7f5f5 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts @@ -21,8 +21,7 @@ export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent imple * @hidden */ public get displayPinnedChip() { - return this.hierarchicalRow.ghostRow && - (!this.grid.visibleColumns[this.visibleColumnIndex - 1] || this.grid.visibleColumns[this.visibleColumnIndex - 1].cellTemplate); + return this.hierarchicalRow.pinned && this.hierarchicalRow.ghostRow && this.visibleColumnIndex === 0 && !(this.column as any).cellTemplate; } /** diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index f1845c03b43..cfdbd9e1766 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -97,13 +97,10 @@ | gridHierarchicalRowPinning:true:pipeTrigger | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger | gridSort:sortingExpressions:sortStrategy:id:pipeTrigger as pinnedData"> -
- - - - - - +
+ @@ -112,39 +109,40 @@ - - - - - - -
- - -
-
+ [igxTemplateOutlet]='(isHierarchicalRecord(rowData) ? hierarchical_record_template : (isChildGridRecord(rowData) && isExpanded(rowData) ? child_record_template : hierarchical_record_template))' + [igxTemplateOutletContext]='getContext(rowData, rowIndex, false)' (onViewCreated)='viewCreatedHandler($event)' + (onViewMoved)='viewMovedHandler($event)' (onCachedViewLoaded)='cachedViewLoaded($event)' + (onBeforeViewDetach)='viewDetachHandler($event)'> +
+ + + + + +
+ + +
+
diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index d8007efaad8..21eba8ff565 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -551,7 +551,8 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti return { $implicit: this.isGhostRecord(rowData) ? rowData.recordData : rowData, templateID: 'dataRow', - index: this.getRowIndex(rowIndex, pinned) + index: this.getRowIndex(rowIndex, pinned), + ghostRow: this.isGhostRecord(rowData) }; } } diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.html b/src/app/grid-row-pinning/grid-row-pinning.sample.html index c46fd56df64..108a7c6cd3b 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.html +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.html @@ -5,10 +5,13 @@
+
+ + Current: {{displayDensityOptions.displayDensity}} +
Bottom Row Pinning toggle Right Column Pinning toggle -
@@ -29,7 +32,7 @@
- + diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.ts b/src/app/grid-row-pinning/grid-row-pinning.sample.ts index f77057a086f..4202ce1d5aa 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.ts +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.ts @@ -1,12 +1,25 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { IgxGridComponent, ColumnPinningPosition, RowPinningPosition, IgxGridRowComponent, IgxTransactionService, IgxGridTransaction, IgxHierarchicalRowComponent, IgxHierarchicalGridComponent } from 'igniteui-angular'; +import { Component, OnInit, ViewChild, Input, Inject } from '@angular/core'; +import { + IgxGridComponent, + ColumnPinningPosition, + RowPinningPosition, + IgxGridRowComponent, + IgxTransactionService, + IgxGridTransaction, + IgxHierarchicalGridComponent, + DisplayDensityToken, + DisplayDensity, + IDisplayDensityOptions } from 'igniteui-angular'; import { IPinningConfig } from 'projects/igniteui-angular/src/lib/grids/common/grid.interface'; @Component({ - providers: [{ provide: IgxGridTransaction, useClass: IgxTransactionService }], selector: 'app-grid-row-pinning-sample', styleUrls: ['grid-row-pinning.sample.css'], - templateUrl: 'grid-row-pinning.sample.html' + templateUrl: 'grid-row-pinning.sample.html', + providers: [ + { provide: IgxGridTransaction, useClass: IgxTransactionService }, + { provide: DisplayDensityToken, useValue: { displayDensity: DisplayDensity.comfortable} } + ], }) export class GridRowPinningSampleComponent implements OnInit { @@ -18,6 +31,8 @@ export class GridRowPinningSampleComponent implements OnInit { @ViewChild('hGrid', { static: true }) hGrid: IgxHierarchicalGridComponent; + constructor(@Inject(DisplayDensityToken) public displayDensityOptions: IDisplayDensityOptions) {} + onRowChange() { if (this.pinningConfig.rows === RowPinningPosition.Bottom) { this.pinningConfig = { columns: this.pinningConfig.columns, rows: RowPinningPosition.Top }; @@ -149,4 +164,12 @@ export class GridRowPinningSampleComponent implements OnInit { console.log(cell); return true; } + + toggleDensity() { + switch (this.displayDensityOptions.displayDensity ) { + case DisplayDensity.comfortable: this.displayDensityOptions.displayDensity = DisplayDensity.compact; break; + case DisplayDensity.compact: this.displayDensityOptions.displayDensity = DisplayDensity.cosy; break; + case DisplayDensity.cosy: this.displayDensityOptions.displayDensity = DisplayDensity.comfortable; break; + } + } } From aff72cd5eeff16a8e9c6c9a46d21e667678af3de Mon Sep 17 00:00:00 2001 From: skrustev Date: Tue, 31 Mar 2020 15:00:21 +0300 Subject: [PATCH 05/21] chore(*): Replace editable input with disabled input containing logic for preveinting row selection as wel. Update hierarchical grid. --- .../src/lib/grids/cell.component.ts | 2 +- .../src/lib/grids/common/row.interface.ts | 2 +- .../lib/grids/grid/grid-row.component.html | 2 +- .../hierarchical-grid.component.ts | 6 ++--- .../hierarchical-grid.pipes.ts | 6 ++--- .../hierarchical-row.component.html | 2 +- .../hierarchical-row.component.ts | 23 +------------------ .../src/lib/grids/row.directive.ts | 7 +++--- .../grid-row-pinning.sample.html | 15 +++++++++--- 9 files changed, 27 insertions(+), 38 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 1fa49250db1..50577633f50 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -524,7 +524,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy { * Returns whether the cell is editable. */ get editable(): boolean { - return (this.column.editable && (this.row.editable === undefined || this.row.editable)) || this.row.editable; + return (this.column.editable && !this.row.disabled) || !this.row.disabled; } /** diff --git a/projects/igniteui-angular/src/lib/grids/common/row.interface.ts b/projects/igniteui-angular/src/lib/grids/common/row.interface.ts index 351d92a7a20..a5ddd400707 100644 --- a/projects/igniteui-angular/src/lib/grids/common/row.interface.ts +++ b/projects/igniteui-angular/src/lib/grids/common/row.interface.ts @@ -5,7 +5,7 @@ export interface RowType { checkboxElement: IgxCheckboxComponent; rowID: any; rowData: any; - editable: boolean; + disabled: boolean; rowSelectable: boolean; index: number; gridID: string; diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html index f616d85ced1..d7b589ee8c2 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-row.component.html @@ -76,7 +76,7 @@ diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index 21eba8ff565..752b6dbc862 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -495,7 +495,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti */ public isHierarchicalRecord(record: any): boolean { if (this.isGhostRecord(record)) { - record = record.recordData; + record = record.recordRef; } return this.childLayoutList.length !== 0 && record[this.childLayoutList.first.key]; } @@ -509,7 +509,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti } public isGhostRecord(record: any): boolean { - return record.ghostRec !== undefined; + return record.ghostRecord !== undefined; } /** @@ -549,7 +549,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti } } else { return { - $implicit: this.isGhostRecord(rowData) ? rowData.recordData : rowData, + $implicit: this.isGhostRecord(rowData) ? rowData.recordRef : rowData, templateID: 'dataRow', index: this.getRowIndex(rowIndex, pinned), ghostRow: this.isGhostRecord(rowData) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts index 4852fb0f1bd..820c08eec58 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts @@ -37,8 +37,8 @@ export class IgxGridHierarchicalPipe implements PipeTransform { data.forEach((v: any) => { result.push(v); - if (v.ghostRec !== undefined) { - v = v.recordData; + if (v.ghostRecord !== undefined) { + v = v.recordRef; } const childGridsData = {}; @@ -101,7 +101,7 @@ export class IgxGridHierarchicalRowPinning implements PipeTransform { } const result = collection.map((value) => { - return grid.isRecordPinned(value) ? { recordData: value, ghostRec: true} : value; + return grid.isRecordPinned(value) ? { recordRef: value, ghostRecord: true} : value; }); return result; } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html index c01766bff39..bab88eb20cf 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.html @@ -71,7 +71,7 @@ [readonly]="true" [checked]="selected" disableRipple="true" - [disabled]="ghostRow || deleted" + [disabled]="disabled || deleted" [disableTransitions]="grid.disableTransitions" [aria-label]="rowCheckboxAriaLabel"> diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts index 446a4a83634..d8723a77d99 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts @@ -31,12 +31,9 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective implemen public index: number; /** - * Sets whether this specific row can be editable. + * Sets whether this specific row has disabled functionality for editing and row selection. * Default value is `false`. * ```typescript * this.grid.selectedRows[0].pinned = true; * ``` */ @Input() - public editable: boolean; + public disabled = false; /** * Gets whether the row is pinned. @@ -320,7 +320,7 @@ export class IgxRowDirective implemen */ @HostListener('click', ['$event']) public onClick(event: MouseEvent) { - if (this.grid.rowSelection === 'none' || this.deleted) { return; } + if (this.grid.rowSelection === 'none' || this.deleted || this.disabled) { return; } if (event.shiftKey && this.grid.rowSelection === 'multiple') { this.selectionService.selectMultipleRows(this.rowID, this.rowData, event); return; @@ -332,6 +332,7 @@ export class IgxRowDirective implemen * @hidden */ public onRowSelectorClick(event) { + if (this.disabled) { return; } event.stopPropagation(); if (event.shiftKey && this.grid.rowSelection === 'multiple') { this.selectionService.selectMultipleRows(this.rowID, this.rowData, event); diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.html b/src/app/grid-row-pinning/grid-row-pinning.sample.html index 108a7c6cd3b..80c73eb4c74 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.html +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.html @@ -13,7 +13,7 @@ Bottom Row Pinning toggle Right Column Pinning toggle
- + @@ -32,7 +32,11 @@
- + + + + @@ -40,7 +44,12 @@ - + + + + + + From 197bd53ee46451d1884a4f08e650ca53824aa857 Mon Sep 17 00:00:00 2001 From: skrustev Date: Wed, 1 Apr 2020 13:23:01 +0300 Subject: [PATCH 06/21] chore(*): Move disabled styling to grid row. Remove ghostRow input and related code. --- .../components/grid/_grid-component.scss | 4 ++-- .../styles/components/grid/_grid-theme.scss | 10 ++++----- .../styles/themes/schemas/light/_grid.scss | 4 ++-- .../hierarchical-cell.component.ts | 10 +-------- .../hierarchical-grid.component.html | 6 +++--- .../hierarchical-grid.component.ts | 2 +- .../hierarchical-grid.pipes.ts | 13 +++++++----- .../hierarchical-row.component.ts | 21 +++---------------- .../hierarchical-row.interface.ts | 5 ----- .../src/lib/grids/row.directive.ts | 1 + 10 files changed, 26 insertions(+), 50 deletions(-) delete mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.interface.ts diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index a9f26b3f23a..64b12d968b9 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -358,8 +358,8 @@ @extend %igx-grid__td--editing !optional; } - @include e(tr, $m: ghost-copy) { - @extend %igx-grid__tr--ghost-copy !optional; + @include e(tr, $m: disabled) { + @extend %igx-grid__tr--disabled !optional; } @include e(td, $m: number) { diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index b824fb99238..9065876ea66 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -48,7 +48,7 @@ /// @param {Color} $cell-selected-text-color [null] - The selected cell text color. /// @param {Color} $cell-editing-background [null] - The background color of the cell being edited. /// @param {Color} $cell-edited-value-color [null] - The text color of a cell that has been edited. -/// @param {Color} $cell-ghost-copy-color [null] - The text color of a cell that is ghost of another row. +/// @param {Color} $cell-disabled-color [null] - The text color of a cell that is ghost of another row. /// /// @param {Color} $edit-mode-color [null] - The color applied around the row when in editing mode. /// @param {Color} $edited-row-indicator [null] - The color applied to the edited row indicator line. @@ -156,7 +156,7 @@ $cell-selected-text-color: null, $cell-editing-background: null, $cell-edited-value-color: null, - $cell-ghost-copy-color: null, + $cell-disabled-color: null, $edit-mode-color: null, $edited-row-indicator: null, @@ -481,7 +481,7 @@ edited-row-indicator: $edited-row-indicator, cell-edited-value-color: $cell-edited-value-color, - cell-ghost-copy-color: $cell-ghost-copy-color, + cell-disabled-color: $cell-disabled-color, resize-line-color: $resize-line-color, @@ -1320,9 +1320,9 @@ } } - %igx-grid__tr--ghost-copy { + %igx-grid__tr--disabled { %grid-cell-text { - color: --var($theme, 'cell-ghost-copy-color'); + color: --var($theme, 'cell-disabled-color'); } } diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss index 7d48bcbe9af..8df61713af3 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss @@ -45,7 +45,7 @@ /// @prop {Map} edit-mode-color [igx-color: ('secondary', 500)] - The text color in edit mode. /// @prop {Map} edited-row-indicator [igx-color: ('grays', 400)] - The indicator's color of edited row. /// @prop {Map} cell-edited-value-color [igx-color: ('grays', 600)] - The color of cell edited value. -/// @prop {Map} cell-ghost-copy-color [igx-color: ('grays', 600)] - The color of cell ghost text. +/// @prop {Map} cell-disabled-color [igx-color: ('grays', 600)] - The color of cell ghost text. /// @prop {Map} resize-line-color [igx-color: ('secondary', 500)] - The table header resize line color. /// @prop {Map} drop-indicator-color [igx-color: ('secondary', 500)] - The color of the drop indicator. /// @prop {Map} grouparea-background [igx-color: ('grays', 100), hexrgba: #fff] - The grid group area background color. @@ -222,7 +222,7 @@ $_light-grid: extend( igx-color: ('grays', 600) ), - cell-ghost-copy-color: ( + cell-disabled-color: ( igx-color: ('grays', 400) ), diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts index 0c4a0d7f5f5..893d54ac0ef 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts @@ -6,7 +6,6 @@ import { IgxHierarchicalGridComponent } from './hierarchical-grid.component'; import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/selection.service'; import { HammerGesturesManager } from '../../core/touch'; import { PlatformUtil } from '../../core/utils'; -import { HierarchicalRowType } from './hierarchical-row.interface'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -21,14 +20,7 @@ export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent imple * @hidden */ public get displayPinnedChip() { - return this.hierarchicalRow.pinned && this.hierarchicalRow.ghostRow && this.visibleColumnIndex === 0 && !(this.column as any).cellTemplate; - } - - /** - * @hidden - */ - public get hierarchicalRow(): HierarchicalRowType { - return this.row as HierarchicalRowType; + return this.row.pinned && this.row.disabled && this.visibleColumnIndex === 0 && !(this.column as any).cellTemplate; } // protected hSelection; diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index 76489985b39..84c0f7aa19a 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -112,8 +112,8 @@ - - + + diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index 1164ac8be51..58a08db2bfb 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -552,7 +552,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti $implicit: this.isGhostRecord(rowData) ? rowData.recordRef : rowData, templateID: 'dataRow', index: this.getRowIndex(rowIndex, pinned), - ghostRow: this.isGhostRecord(rowData) + disabled: this.isGhostRecord(rowData) }; } } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts index 6d174dd457f..bab9bb0f79d 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts @@ -71,9 +71,10 @@ export class IgxGridHierarchicalPagingPipe implements PipeTransform { return collection; } + const _perPage = Math.max(0, perPage - this.gridAPI.grid.pinnedRecordsCount); const state = { index: page, - recordsPerPage: perPage + recordsPerPage: _perPage }; const result: any[] = DataUtil.page(cloneArray(collection), state); @@ -100,9 +101,11 @@ export class IgxGridHierarchicalRowPinning implements PipeTransform { return collection.filter(rec => grid.isRecordPinned(rec)); } - const result = collection.map((value) => { - return grid.isRecordPinned(value) ? { recordRef: value, ghostRecord: true} : value; - }); - return result; + if (grid.childLayoutKeys.length) { + return collection.map((rec) => { + return grid.isRecordPinned(rec) ? { recordRef: rec, ghostRecord: true} : rec; + }); + } + return collection.filter(rec => !grid.isRecordPinned(rec)); } } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts index ed0c1e54ad1..b7453ea2ada 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts @@ -24,30 +24,15 @@ import { IgxHierarchicalGridCellComponent } from './hierarchical-cell.component' }) export class IgxHierarchicalRowComponent extends IgxRowDirective { - protected _ghostRow = false; protected expanderClass = 'igx-grid__hierarchical-expander'; - /** - * @hidden - */ - @Input() - @HostBinding('class.igx-grid__tr--ghost-copy') - public set ghostRow(value: boolean) { - this.disabled = value; - this._ghostRow = value; - } - - public get ghostRow() { - return this._ghostRow; - } - /** * @hidden */ public get expanderClassResolved() { return { - [this.expanderClass]: !this.pinned || this.ghostRow, - [`${this.expanderClass}--empty`]: this.pinned && !this.ghostRow + [this.expanderClass]: !this.pinned || this.disabled, + [`${this.expanderClass}--empty`]: this.pinned && !this.disabled }; } @@ -171,7 +156,7 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective implemen * ``` */ @Input() + @HostBinding('class.igx-grid__tr--disabled') public disabled = false; /** From afdc785395c3d009400d77dbb401253ecd04aa88 Mon Sep 17 00:00:00 2001 From: skrustev Date: Wed, 1 Apr 2020 13:56:26 +0300 Subject: [PATCH 07/21] chore(*): Fix lint in hierarchical grid --- .../lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts | 2 +- .../lib/grids/hierarchical-grid/hierarchical-row.component.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts index bab9bb0f79d..133dc8f385e 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts @@ -84,7 +84,7 @@ export class IgxGridHierarchicalPagingPipe implements PipeTransform { } /** - *@hidden + * @hidden */ @Pipe({ name: 'gridHierarchicalRowPinning', diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts index b7453ea2ada..ce046e2fef5 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-row.component.ts @@ -27,8 +27,8 @@ export class IgxHierarchicalRowComponent extends IgxRowDirective Date: Mon, 6 Apr 2020 10:42:34 +0300 Subject: [PATCH 08/21] fix(igxGrid): Fix paging calculation with row pinning. Small fixes to hierarchical grid row pinning. --- .../src/lib/grids/cell.component.ts | 2 +- .../src/lib/grids/grid-base.directive.ts | 7 +++++- .../src/lib/grids/grid/row-pinning.spec.ts | 25 +++++++++++++++---- .../hierarchical-grid.component.ts | 12 +++++++++ .../grid-row-pinning.sample.html | 4 +-- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 50577633f50..2e0e77c21a2 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -524,7 +524,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy { * Returns whether the cell is editable. */ get editable(): boolean { - return (this.column.editable && !this.row.disabled) || !this.row.disabled; + return this.column.editable && !this.row.disabled; } /** diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 7e27ba6d6f5..463c00e87c8 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -3602,7 +3602,12 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements */ get totalRecords(): number { if (this.pagingState) { - return this.pagingState.metadata.countRecords; + const countRecords = this.pagingState.metadata.countRecords + if (this.hasPinnedRecords) { + // When there are pinned records they fill space on the page and that's why we need to add the pinned rows for each page. + return countRecords + this.pinnedRecordsCount * (countRecords / this.pagingState.recordsPerPage); + } + return countRecords; } } diff --git a/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts index a83ca7cf40c..15ea2d10d1e 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts @@ -15,6 +15,7 @@ import { IgxGridTransaction } from '../tree-grid'; import { IgxTransactionService } from '../../services'; import { GridSummaryFunctions } from '../../test-utils/grid-functions.spec'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; +import { IgxPaginatorComponent } from '../../paginator/paginator.component'; describe('Row Pinning #grid', () => { const FIXED_ROW_CONTAINER = '.igx-grid__tr--pinned '; @@ -401,19 +402,32 @@ describe('Row Pinning #grid', () => { grid.paging = true; grid.perPage = 5; fix.detectChanges(); - let row = grid.getRowByIndex(1); - row.pin(); + let paginator = fix.debugElement.query(By.directive(IgxPaginatorComponent)); + expect(paginator.componentInstance.totalPages).toEqual(6); + + grid.getRowByIndex(1).pin(); fix.detectChanges(); expect(grid.pinnedRows.length).toBe(1); let pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); expect(pinRowContainer.length).toBe(1); - expect(grid.dataView.length).toBe(4); + expect(paginator.componentInstance.totalPages).toEqual(7); + + grid.getRowByIndex(3).pin(); + fix.detectChanges(); + + expect(grid.pinnedRows.length).toBe(2); + pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer.length).toBe(1); + expect(grid.dataView.length).toBe(3); + expect(paginator.componentInstance.totalPages).toEqual(9); // unpin - row = grid.getRowByIndex(0); - row.unpin(); + grid.getRowByIndex(0).unpin(); + fix.detectChanges(); + + grid.getRowByIndex(0).unpin(); fix.detectChanges(); expect(grid.pinnedRows.length).toBe(0); @@ -421,6 +435,7 @@ describe('Row Pinning #grid', () => { expect(pinRowContainer.length).toBe(0); expect(grid.dataView.length).toBe(5); + expect(paginator.componentInstance.totalPages).toEqual(6); }); it('should apply sorting to both pinned and unpinned rows.', () => { diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index 58a08db2bfb..d15aae8c9ff 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -111,6 +111,18 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti return this._data; } + /** + * Gets an array of the pinned `IgxRowComponent`s. + * @example + * ```typescript + * const pinnedRow = this.grid.pinnedRows; + * ``` + * @memberof IgxHierarchicalGridComponent + */ + get pinnedRows() { + return this.rowList.filter(x => x.pinned && !x.disabled); + } + /** * @hidden * @deprecated diff --git a/src/app/grid-row-pinning/grid-row-pinning.sample.html b/src/app/grid-row-pinning/grid-row-pinning.sample.html index b30359a8ee7..d95c7771a70 100644 --- a/src/app/grid-row-pinning/grid-row-pinning.sample.html +++ b/src/app/grid-row-pinning/grid-row-pinning.sample.html @@ -40,7 +40,7 @@
- @@ -57,7 +57,7 @@ - + From 9c71be77d0ae4d447b468d405c9f15e2d5580189 Mon Sep 17 00:00:00 2001 From: skrustev Date: Mon, 6 Apr 2020 10:43:10 +0300 Subject: [PATCH 09/21] tests(igxHierarchicalGrid): Add tests for hierarchical grid row pinning --- .../hierarchical-grid.integration.spec.ts | 204 +++++++++++++++++- 1 file changed, 197 insertions(+), 7 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index b2d329eab7b..15ffef3ee67 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -1,5 +1,5 @@ import { configureTestSuite } from '../../test-utils/configure-suite'; -import { async, TestBed, tick, fakeAsync } from '@angular/core/testing'; +import { async, TestBed, tick, fakeAsync, ComponentFixture } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { IgxHierarchicalGridModule } from './index'; @@ -18,12 +18,14 @@ import { take } from 'rxjs/operators'; import { IgxHierarchicalTransactionServiceFactory } from './hierarchical-grid-base.directive'; import { IgxIconModule } from '../../icon'; import { IgxHierarchicalGridCellComponent } from './hierarchical-cell.component'; -import { GridSelectionMode } from '../common/enums'; +import { GridSelectionMode, ColumnPinningPosition, RowPinningPosition } from '../common/enums'; import { GridFunctions } from '../../test-utils/grid-functions.spec'; +import { IPinningConfig } from '../common/grid.interface'; +import { IgxPaginatorComponent } from '../../paginator/paginator.component'; describe('IgxHierarchicalGrid Integration #hGrid', () => { configureTestSuite(); - let fixture; + let fixture: ComponentFixture; let hierarchicalGrid: IgxHierarchicalGridComponent; beforeAll(async(() => { TestBed.configureTestingModule({ @@ -988,11 +990,191 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { expect(leftMostRightPinnedCellsPart + Number.parseInt(pinnedCellWidth, 10) < rightMostGridPart).toBeTruthy(); })); }); + + describe('Row Pinning', () => { + const FIXED_ROW_CONTAINER = '.igx-grid__tr--pinned'; + const FIXED_ROW_CONTAINER_TOP = 'igx-grid__tr--pinned-top'; + const FIXED_ROW_CONTAINER_BOTTOM = 'igx-grid__tr--pinned-bottom'; + beforeEach(() => { + hierarchicalGrid.width = '800px'; + hierarchicalGrid.height = '500px'; + fixture.detectChanges(); + }); + + it('should pin rows to top ', (() => { + hierarchicalGrid.pinRow('0'); + fixture.detectChanges(); + + expect(hierarchicalGrid.pinnedRows.length).toBe(1); + let pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer.length).toBe(1); + expect(pinRowContainer[0].nativeElement.classList.contains(FIXED_ROW_CONTAINER_TOP)).toBeTruthy(); + expect(pinRowContainer[0].nativeElement.classList.contains(FIXED_ROW_CONTAINER_BOTTOM)).toBeFalsy(); + + expect(pinRowContainer[0].children[0].context.rowID).toBe('0'); + expect(hierarchicalGrid.getRowByIndex(1).rowID).toBe('0'); + expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('1'); + expect(hierarchicalGrid.getRowByIndex(3).rowID).toBe('2'); + + hierarchicalGrid.pinRow('2'); + fixture.detectChanges(); + + pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer[0].children.length).toBe(2); + + expect(pinRowContainer[0].children[0].context.rowID).toBe('0'); + expect(pinRowContainer[0].children[1].context.rowID).toBe('2'); + expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('0'); + expect(hierarchicalGrid.getRowByIndex(3).rowID).toBe('1'); + expect(hierarchicalGrid.getRowByIndex(4).rowID).toBe('2'); + + expect(hierarchicalGrid.pinnedRowHeight).toBe(2 * hierarchicalGrid.renderedRowHeight + 2); + const expectedHeight = parseInt(hierarchicalGrid.height, 10) - hierarchicalGrid.pinnedRowHeight - 18 - hierarchicalGrid.theadRow.nativeElement.offsetHeight; + expect(hierarchicalGrid.calcHeight - expectedHeight).toBeLessThanOrEqual(1); + })); + + it('should pin rows to bottom', (() => { + fixture.componentInstance.pinningConfig = { columns: ColumnPinningPosition.Start, rows: RowPinningPosition.Bottom }; + fixture.detectChanges(); + + // Pin 2nd row + hierarchicalGrid.pinRow('1'); + fixture.detectChanges(); + + expect(hierarchicalGrid.pinnedRows.length).toBe(1); + let pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer.length).toBe(1); + expect(pinRowContainer[0].nativeElement.classList.contains(FIXED_ROW_CONTAINER_TOP)).toBeFalsy(); + expect(pinRowContainer[0].nativeElement.classList.contains(FIXED_ROW_CONTAINER_BOTTOM)).toBeTruthy(); + + expect(pinRowContainer[0].children.length).toBe(1); + expect(pinRowContainer[0].children[0].context.rowID).toBe('1'); + expect(pinRowContainer[0].children[0].context.index).toBe(fixture.componentInstance.data.length); + expect(pinRowContainer[0].children[0].nativeElement) + .toBe(hierarchicalGrid.getRowByIndex(fixture.componentInstance.data.length).nativeElement); + + expect(hierarchicalGrid.getRowByIndex(0).rowID).toBe('0'); + expect(hierarchicalGrid.getRowByIndex(1).rowID).toBe('1'); + expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('2'); + + // Pin 1st row + hierarchicalGrid.pinRow('0'); + fixture.detectChanges(); + + pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer[0].children.length).toBe(2); + expect(pinRowContainer[0].children[0].context.rowID).toBe('0'); + expect(pinRowContainer[0].children[1].context.rowID).toBe('1'); + expect(hierarchicalGrid.getRowByIndex(0).rowID).toBe('0'); + expect(hierarchicalGrid.getRowByIndex(1).rowID).toBe('1'); + expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('2'); + + // Check last pinned is fully in view + const last = pinRowContainer[0].children[1].context.nativeElement; + expect(last.getBoundingClientRect().bottom - hierarchicalGrid.tbody.nativeElement.getBoundingClientRect().bottom).toBe(0); + + // 2 records pinned + 2px border + expect(hierarchicalGrid.pinnedRowHeight).toBe(2 * hierarchicalGrid.renderedRowHeight + 2); + const expectedHeight = parseInt(hierarchicalGrid.height, 10) - hierarchicalGrid.pinnedRowHeight - 18 - hierarchicalGrid.theadRow.nativeElement.offsetHeight; + expect(hierarchicalGrid.calcHeight - expectedHeight).toBeLessThanOrEqual(1); + })); + + xit('should search in both pinned and unpinned rows.', () => { + let findCount = hierarchicalGrid.findNext('Product: A0'); + fixture.detectChanges(); + + let spans = fixture.debugElement.queryAll(By.css('.igx-highlight')); + expect(spans.length).toBe(1); + expect(findCount).toEqual(1); + + // Pin 3rd row + hierarchicalGrid.pinRow('2'); + fixture.detectChanges(); + expect(hierarchicalGrid.pinnedRows.length).toBe(2); + + findCount = hierarchicalGrid.findNext('Product: A0'); + fixture.detectChanges(); + + spans = fixture.debugElement.queryAll(By.css('.igx-highlight')); + expect(spans.length).toBe(2); + expect(findCount).toEqual(2); + }); + + it('should apply filtering to both pinned and unpinned rows.', () => { + hierarchicalGrid.pinRow('1'); + fixture.detectChanges(); + hierarchicalGrid.pinRow('5'); + fixture.detectChanges(); + + let pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer[0].children.length).toBe(2); + expect(pinRowContainer[0].children[0].context.rowID).toBe('1'); + expect(pinRowContainer[0].children[1].context.rowID).toBe('5'); + + hierarchicalGrid.filter('ID', '5', IgxStringFilteringOperand.instance().condition('contains'), false); + fixture.detectChanges(); + + const allRows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); + expect(pinRowContainer[0].children.length).toBe(1); + expect(pinRowContainer[0].children[0].context.rowID).toBe('5'); + expect(allRows[1].componentInstance.rowID).toEqual('5'); + }); + + it('should render paging with correct data and rows be correctly paged.', () => { + hierarchicalGrid.paging = true; + hierarchicalGrid.perPage = 5; + fixture.detectChanges(); + + let rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + const paginator = fixture.debugElement.query(By.directive(IgxPaginatorComponent)); + expect(rows.length).toEqual(5); + expect(paginator.componentInstance.perPage).toEqual(5); + expect(paginator.componentInstance.totalPages).toEqual(8); + + hierarchicalGrid.pinRow('1'); + fixture.detectChanges(); + + rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + expect(rows.length).toEqual(5); + expect(paginator.componentInstance.perPage).toEqual(5); + expect(paginator.componentInstance.totalPages).toEqual(10); + + hierarchicalGrid.pinRow('3'); + fixture.detectChanges(); + + rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + expect(rows.length).toEqual(5); + expect(paginator.componentInstance.perPage).toEqual(5); + expect(paginator.componentInstance.totalPages).toEqual(14); + }); + + it('should apply sorting to both pinned and unpinned rows.', () => { + hierarchicalGrid.pinRow('1'); + hierarchicalGrid.pinRow('3'); + fixture.detectChanges(); + + expect(hierarchicalGrid.getRowByIndex(0).rowID).toBe('1'); + expect(hierarchicalGrid.getRowByIndex(1).rowID).toBe('3'); + + hierarchicalGrid.sort({ fieldName: 'ID', dir: SortingDirection.Desc, ignoreCase: false }); + fixture.detectChanges(); + + // check pinned rows data is sorted + expect(hierarchicalGrid.getRowByIndex(0).rowID).toBe('3'); + expect(hierarchicalGrid.getRowByIndex(1).rowID).toBe('1'); + + // check unpinned rows data is sorted + const lastIndex = fixture.componentInstance.data.length - 1; + // Expect 9 since it is a string. + expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('9'); + }); + }); }); @Component({ template: ` - @@ -1025,10 +1207,18 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { providers: [ IgxHierarchicalTransactionServiceFactory ] }) export class IgxHierarchicalGridTestBaseComponent { + + @ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true }) + public hgrid: IgxHierarchicalGridComponent; + + @ViewChild('rowIsland', { read: IgxRowIslandComponent, static: true }) + public rowIsland: IgxRowIslandComponent; + + @ViewChild('rowIsland2', { read: IgxRowIslandComponent, static: true }) + public rowIsland2: IgxRowIslandComponent; + public data; - @ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true }) public hgrid: IgxHierarchicalGridComponent; - @ViewChild('rowIsland', { read: IgxRowIslandComponent, static: true }) public rowIsland: IgxRowIslandComponent; - @ViewChild('rowIsland2', { read: IgxRowIslandComponent, static: true }) public rowIsland2: IgxRowIslandComponent; + public pinningConfig: IPinningConfig = { columns: ColumnPinningPosition.Start, rows: RowPinningPosition.Top }; constructor() { // 3 level hierarchy From 2247f0b7da6884ea73c6de66c183eef784f105e1 Mon Sep 17 00:00:00 2001 From: skrustev Date: Mon, 6 Apr 2020 14:43:13 +0300 Subject: [PATCH 10/21] fix(igxGrid): Fix selection range of both unpinned and pinned cells. --- .../src/lib/grids/grid-base.directive.ts | 17 ++++++++++++++--- .../hierarchical-grid.integration.spec.ts | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 6bf7829b1f2..c7b684f91fc 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -5153,6 +5153,17 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements return this.verticalScrollContainer.igxForOf; } + /** + * Returns the currently transformed paged/filtered/sorted/grouped pinned data, displayed in the grid. + * @example + * ```typescript + * const pinnedDataView = this.grid.pinnedDataView; + * ``` + */ + get pinnedDataView(): any[] { + return this.pinnedRows.map(row => row.rowData); + } + /** * Get current selection state. * @example @@ -5358,8 +5369,8 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements columnsArray.forEach((col) => { if (col) { const key = headers ? col.header || col.field : col.field; - record[key] = formatters && col.formatter ? col.formatter(source[row][col.field]) - : source[row][col.field]; + const value = source[row].ghostRecord ? source[row].recordRef[col.field] : source[row][col.field]; + record[key] = formatters && col.formatter ? col.formatter(value) : value; } }); } @@ -5394,7 +5405,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements * If `headers` is enabled, it will use the column header (if any) instead of the column field. */ public getSelectedData(formatters = false, headers = false) { - const source = this.dataView; + const source = this.pinnedDataView.concat(this.dataView); return this.extractDataFromSelection(source, formatters, headers); } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index e35c148beeb..65a3a0e77a9 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -934,5 +934,16 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { // Expect 9 since it is a string. expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('9'); }); + + it('should return pinned rows as well on multiple cell selection in both pinned and unpinned areas', () => { + hierarchicalGrid.pinRow('1'); + fixture.detectChanges(); + + const range = { rowStart: 0, rowEnd: 2, columnStart: 'ID', columnEnd: 'ChildLevels' }; + hierarchicalGrid.selectRange(range); + + const selectedData = hierarchicalGrid.getSelectedData(); + expect(selectedData).toEqual([{ID: "1", ChildLevels: 3}, {ID: "0", ChildLevels: 3}, {ID: "1", ChildLevels: 3}]); + }); }); }); From 1fe82643f28d9b60392f2587c4230f15d042c5c9 Mon Sep 17 00:00:00 2001 From: skrustev Date: Mon, 6 Apr 2020 15:21:46 +0300 Subject: [PATCH 11/21] feat(igxHierarchicalGrid): Move pinned chip to base cell template and add missing gridTransaction to pinned area. --- .../src/lib/grids/cell.component.html | 1 + .../src/lib/grids/cell.component.ts | 7 +++++ .../hierarchical-cell.component.html | 31 ------------------- .../hierarchical-cell.component.ts | 10 +----- .../hierarchical-grid.component.html | 1 + 5 files changed, 10 insertions(+), 40 deletions(-) delete mode 100644 projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.html diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.html b/projects/igniteui-angular/src/lib/grids/cell.component.html index 943f236bf00..11ffb2dffbc 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.html +++ b/projects/igniteui-angular/src/lib/grids/cell.component.html @@ -1,4 +1,5 @@ + Pinned
- Pinned -
- {{ formatter ? formatter(value) : column.dataType === 'number' ? (value | igxdecimal: grid.locale) : column.dataType === 'date' ? (value | igxdate: grid.locale) : value }} -
- - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts index 893d54ac0ef..2caf0480473 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-cell.component.ts @@ -11,18 +11,10 @@ import { PlatformUtil } from '../../core/utils'; changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: 'igx-hierarchical-grid-cell', - templateUrl: './hierarchical-cell.component.html', + templateUrl: '../cell.component.html', providers: [HammerGesturesManager] }) export class IgxHierarchicalGridCellComponent extends IgxGridCellComponent implements OnInit { - - /** - * @hidden - */ - public get displayPinnedChip() { - return this.row.pinned && this.row.disabled && this.visibleColumnIndex === 0 && !(this.column as any).cellTemplate; - } - // protected hSelection; protected _rootGrid; diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index 9e2ac72e2a6..893490ac9fa 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -93,6 +93,7 @@ class="igx-grid__scroll-on-drag-pinned" [style.left.px]="pinnedWidth"> Date: Mon, 6 Apr 2020 17:44:04 +0300 Subject: [PATCH 13/21] chore(*): Update failing test and fix filterData in hierarchical grid with row pinning. --- .../hierarchical-grid.component.html | 2 +- .../hierarchical-grid.integration.spec.ts | 24 +++++++++++++++++++ .../hierarchical-grid.virtualization.spec.ts | 6 ++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index 893490ac9fa..4a895353395 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -96,7 +96,7 @@ | gridTransaction:id:pipeTrigger | visibleColumns:hasVisibleColumns | gridHierarchicalRowPinning:true:pipeTrigger - | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger + | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger:true | gridSort:sortingExpressions:sortStrategy:id:pipeTrigger as pinnedData">
{ const selectedData = hierarchicalGrid.getSelectedData(); expect(selectedData).toEqual([{ID: '1', ChildLevels: 3}, {ID: '0', ChildLevels: 3}, {ID: '1', ChildLevels: 3}]); }); + + it('should return correct filterData collection after filtering.', () => { + hierarchicalGrid.pinRow('1'); + hierarchicalGrid.pinRow('11'); + fixture.detectChanges(); + + hierarchicalGrid.filter('ID', '1', IgxStringFilteringOperand.instance().condition('contains'), false); + fixture.detectChanges(); + + let gridFilterData = hierarchicalGrid.filteredData; + expect(gridFilterData.length).toBe(15); + expect(gridFilterData[0].ID).toBe('1'); + expect(gridFilterData[1].ID).toBe('11'); + expect(gridFilterData[2].ID).toBe('1'); + + fixture.componentInstance.pinningConfig = { columns: ColumnPinningPosition.Start, rows: RowPinningPosition.Bottom }; + fixture.detectChanges(); + + gridFilterData = hierarchicalGrid.filteredData; + expect(gridFilterData.length).toBe(15); + expect(gridFilterData[0].ID).toBe('1'); + expect(gridFilterData[1].ID).toBe('11'); + expect(gridFilterData[2].ID).toBe('1'); + }); }); }); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts index c1e0f16d925..f09cf81ab56 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts @@ -388,7 +388,7 @@ describe('IgxHierarchicalGrid Virtualization Custom Scenarios #hGrid', () => { const hierarchicalGrid = fixture.componentInstance.hgrid; const initialBodyWidth = hierarchicalGrid.tbody.nativeElement.offsetWidth; - expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.hidden).toBeTruthy(); + expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.parentElement.hidden).toBeTruthy(); // expand 1st row const row = hierarchicalGrid.dataRowList.toArray()[0]; @@ -396,13 +396,13 @@ describe('IgxHierarchicalGrid Virtualization Custom Scenarios #hGrid', () => { fixture.detectChanges(); await wait(200); - expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.hidden).toBeTruthy(); + expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.parentElement.hidden).toBeTruthy(); expect(hierarchicalGrid.tbody.nativeElement.offsetWidth).toEqual(initialBodyWidth); const childGrid = hierarchicalGrid.hgridAPI.getChildGrids(false)[0]; childGrid.data = fixture.componentInstance.generateData(10, 0); fixture.detectChanges(); await wait(200); - expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.hidden).toBeFalsy(); + expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.parentElement.hidden).toBeFalsy(); expect(hierarchicalGrid.tbody.nativeElement.offsetWidth).toBeLessThan(initialBodyWidth); }); }); From 0e0bf535c8700f92dd5f66c1c50e7d42d7bb98a2 Mon Sep 17 00:00:00 2001 From: skrustev Date: Tue, 7 Apr 2020 13:14:19 +0300 Subject: [PATCH 14/21] chore(*): Fix geting selected data when using bottom row pinning and revert back paging changes. --- .../src/lib/grids/grid-base.directive.ts | 9 ++---- .../hierarchical-grid.integration.spec.ts | 30 ++++++++++++++----- .../hierarchical-grid.pipes.ts | 3 +- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 3cd1a80f7d8..3c6ae85716f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -3602,12 +3602,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements */ get totalRecords(): number { if (this.pagingState) { - const countRecords = this.pagingState.metadata.countRecords; - if (this.hasPinnedRecords) { - // When there are pinned records they fill space on the page and that's why we need to add the pinned rows for each page. - return countRecords + this.pinnedRecordsCount * (countRecords / this.pagingState.recordsPerPage); - } - return countRecords; + return this.pagingState.metadata.countRecords; } } @@ -5405,7 +5400,7 @@ export class IgxGridBaseDirective extends DisplayDensityBase implements * If `headers` is enabled, it will use the column header (if any) instead of the column field. */ public getSelectedData(formatters = false, headers = false) { - const source = this.pinnedDataView.concat(this.dataView); + const source = this.isRowPinningToTop ? [...this.pinnedDataView, ...this.dataView] : [...this.dataView, ...this.pinnedDataView]; return this.extractDataFromSelection(source, formatters, headers); } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index 55fb7991250..674cdb5c15c 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -891,6 +891,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { it('should render paging with correct data and rows be correctly paged.', () => { hierarchicalGrid.paging = true; hierarchicalGrid.perPage = 5; + hierarchicalGrid.height = '700px'; fixture.detectChanges(); let rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); @@ -903,17 +904,17 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { fixture.detectChanges(); rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); - expect(rows.length).toEqual(5); + expect(rows.length).toEqual(6); expect(paginator.componentInstance.perPage).toEqual(5); - expect(paginator.componentInstance.totalPages).toEqual(10); + expect(paginator.componentInstance.totalPages).toEqual(8); hierarchicalGrid.pinRow('3'); fixture.detectChanges(); rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); - expect(rows.length).toEqual(5); + expect(rows.length).toEqual(7); expect(paginator.componentInstance.perPage).toEqual(5); - expect(paginator.componentInstance.totalPages).toEqual(14); + expect(paginator.componentInstance.totalPages).toEqual(8); }); it('should apply sorting to both pinned and unpinned rows.', () => { @@ -937,15 +938,30 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { expect(hierarchicalGrid.getRowByIndex(2).rowID).toBe('9'); }); - it('should return pinned rows as well on multiple cell selection in both pinned and unpinned areas', () => { + it('should return pinned rows as well on multiple cell selection in both pinned and unpinned areas', async() => { hierarchicalGrid.pinRow('1'); fixture.detectChanges(); - const range = { rowStart: 0, rowEnd: 2, columnStart: 'ID', columnEnd: 'ChildLevels' }; + let range = { rowStart: 0, rowEnd: 2, columnStart: 'ID', columnEnd: 'ChildLevels' }; hierarchicalGrid.selectRange(range); + fixture.detectChanges(); - const selectedData = hierarchicalGrid.getSelectedData(); + let selectedData = hierarchicalGrid.getSelectedData(); expect(selectedData).toEqual([{ID: '1', ChildLevels: 3}, {ID: '0', ChildLevels: 3}, {ID: '1', ChildLevels: 3}]); + + fixture.componentInstance.pinningConfig = { columns: ColumnPinningPosition.Start, rows: RowPinningPosition.Bottom }; + fixture.detectChanges(); + + hierarchicalGrid.verticalScrollContainer.getScroll().scrollTop = 5000; + await wait(); + + range = { rowStart: 38, rowEnd: 40, columnStart: 'ID', columnEnd: 'ChildLevels' }; + hierarchicalGrid.clearCellSelection(); + hierarchicalGrid.selectRange(range); + fixture.detectChanges(); + + selectedData = hierarchicalGrid.getSelectedData(); + expect(selectedData).toEqual([{ID: '38', ChildLevels: 3}, {ID: '39', ChildLevels: 3}, {ID: '1', ChildLevels: 3}]); }); it('should return correct filterData collection after filtering.', () => { diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts index 133dc8f385e..2360cb98878 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts @@ -71,10 +71,9 @@ export class IgxGridHierarchicalPagingPipe implements PipeTransform { return collection; } - const _perPage = Math.max(0, perPage - this.gridAPI.grid.pinnedRecordsCount); const state = { index: page, - recordsPerPage: _perPage + recordsPerPage: perPage }; const result: any[] = DataUtil.page(cloneArray(collection), state); From 5b4deb3c2d943d2e77d8e8ea75199ce6e63bfe19 Mon Sep 17 00:00:00 2001 From: skrustev Date: Tue, 7 Apr 2020 13:50:05 +0300 Subject: [PATCH 15/21] chore(*): Fix additional failing test --- .../igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts index a5ca0718e51..d3a7f141fcb 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/row-pinning.spec.ts @@ -412,7 +412,7 @@ describe('Row Pinning #grid', () => { let pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); expect(pinRowContainer.length).toBe(1); expect(grid.dataView.length).toBe(4); - expect(paginator.componentInstance.totalPages).toEqual(7); + expect(paginator.componentInstance.totalPages).toEqual(6); grid.getRowByIndex(3).pin(); fix.detectChanges(); @@ -421,7 +421,7 @@ describe('Row Pinning #grid', () => { pinRowContainer = fix.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); expect(pinRowContainer.length).toBe(1); expect(grid.dataView.length).toBe(3); - expect(paginator.componentInstance.totalPages).toEqual(9); + expect(paginator.componentInstance.totalPages).toEqual(5); // unpin grid.getRowByIndex(0).unpin(); From 0395b4f69c96eddf3897f7e5bf3c724d97200d51 Mon Sep 17 00:00:00 2001 From: skrustev Date: Tue, 7 Apr 2020 19:01:16 +0300 Subject: [PATCH 16/21] chore(*): Prettify hierarchical grid tests and fix disabled cell styling comments. --- .../core/styles/components/grid/_grid-theme.scss | 2 +- .../lib/core/styles/themes/schemas/light/_grid.scss | 2 +- .../hierarchical-grid.integration.spec.ts | 10 +++++----- .../hierarchical-grid.virtualization.spec.ts | 11 +++++++---- .../test-utils/hierarchical-grid-functions.spec.ts | 13 +++++++++++++ 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 9065876ea66..781635ec168 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -48,7 +48,7 @@ /// @param {Color} $cell-selected-text-color [null] - The selected cell text color. /// @param {Color} $cell-editing-background [null] - The background color of the cell being edited. /// @param {Color} $cell-edited-value-color [null] - The text color of a cell that has been edited. -/// @param {Color} $cell-disabled-color [null] - The text color of a cell that is ghost of another row. +/// @param {Color} $cell-disabled-color [null] - The text color of a disabled cell. /// /// @param {Color} $edit-mode-color [null] - The color applied around the row when in editing mode. /// @param {Color} $edited-row-indicator [null] - The color applied to the edited row indicator line. diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss index 8df61713af3..c0208ec1f3f 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss @@ -45,7 +45,7 @@ /// @prop {Map} edit-mode-color [igx-color: ('secondary', 500)] - The text color in edit mode. /// @prop {Map} edited-row-indicator [igx-color: ('grays', 400)] - The indicator's color of edited row. /// @prop {Map} cell-edited-value-color [igx-color: ('grays', 600)] - The color of cell edited value. -/// @prop {Map} cell-disabled-color [igx-color: ('grays', 600)] - The color of cell ghost text. +/// @prop {Map} cell-disabled-color [igx-color: ('grays', 600)] - The text color of a disabled cell. /// @prop {Map} resize-line-color [igx-color: ('secondary', 500)] - The table header resize line color. /// @prop {Map} drop-indicator-color [igx-color: ('secondary', 500)] - The color of the drop indicator. /// @prop {Map} grouparea-background [igx-color: ('grays', 100), hexrgba: #fff] - The grid group area background color. diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index e7b3ba29d56..2c37dabd9d3 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -166,7 +166,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { fixture.detectChanges(); hierarchicalGrid.addRow({ ID: -1, ProductName: 'Name1' }); fixture.detectChanges(); - const rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + const rows = HierarchicalGridFunctions.getHierarchicalRows(fixture); const lastRow = rows[rows.length - 1]; expect(lastRow.query(By.css('igx-icon')).nativeElement).toHaveClass('igx-icon--inactive'); hierarchicalGrid.transactions.commit(hierarchicalGrid.data); @@ -880,7 +880,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { hierarchicalGrid.filter('ID', '5', IgxStringFilteringOperand.instance().condition('contains'), false); fixture.detectChanges(); - const allRows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + const allRows = HierarchicalGridFunctions.getHierarchicalRows(fixture); pinRowContainer = fixture.debugElement.queryAll(By.css(FIXED_ROW_CONTAINER)); expect(pinRowContainer[0].children.length).toBe(1); expect(pinRowContainer[0].children[0].context.rowID).toBe('5'); @@ -893,7 +893,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { hierarchicalGrid.height = '700px'; fixture.detectChanges(); - let rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + let rows =HierarchicalGridFunctions.getHierarchicalRows(fixture); const paginator = fixture.debugElement.query(By.directive(IgxPaginatorComponent)); expect(rows.length).toEqual(5); expect(paginator.componentInstance.perPage).toEqual(5); @@ -902,7 +902,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { hierarchicalGrid.pinRow('1'); fixture.detectChanges(); - rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + rows = HierarchicalGridFunctions.getHierarchicalRows(fixture); expect(rows.length).toEqual(6); expect(paginator.componentInstance.perPage).toEqual(5); expect(paginator.componentInstance.totalPages).toEqual(8); @@ -910,7 +910,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { hierarchicalGrid.pinRow('3'); fixture.detectChanges(); - rows = fixture.debugElement.queryAll(By.directive(IgxHierarchicalRowComponent)); + rows = HierarchicalGridFunctions.getHierarchicalRows(fixture); expect(rows.length).toEqual(7); expect(paginator.componentInstance.perPage).toEqual(5); expect(paginator.componentInstance.totalPages).toEqual(8); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts index f09cf81ab56..da42fab5919 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts @@ -13,6 +13,7 @@ import { FilteringExpressionsTree } from '../../data-operations/filtering-expres import { FilteringLogic } from '../../data-operations/filtering-expression.interface'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; import { GridFunctions } from '../../test-utils/grid-functions.spec'; +import { HierarchicalGridFunctions } from '../../test-utils/hierarchical-grid-functions.spec'; describe('IgxHierarchicalGrid Virtualization #hGrid', () => { configureTestSuite(); @@ -386,9 +387,9 @@ describe('IgxHierarchicalGrid Virtualization Custom Scenarios #hGrid', () => { await wait(); const hierarchicalGrid = fixture.componentInstance.hgrid; - const initialBodyWidth = hierarchicalGrid.tbody.nativeElement.offsetWidth; - expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.parentElement.hidden).toBeTruthy(); + const verticalScrollWrapper = HierarchicalGridFunctions.getVerticalScrollWrapper(fixture, hierarchicalGrid.id); + expect(verticalScrollWrapper.hidden).toBeTruthy(); // expand 1st row const row = hierarchicalGrid.dataRowList.toArray()[0]; @@ -396,13 +397,15 @@ describe('IgxHierarchicalGrid Virtualization Custom Scenarios #hGrid', () => { fixture.detectChanges(); await wait(200); - expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.parentElement.hidden).toBeTruthy(); + expect(verticalScrollWrapper.hidden).toBeTruthy(); expect(hierarchicalGrid.tbody.nativeElement.offsetWidth).toEqual(initialBodyWidth); + const childGrid = hierarchicalGrid.hgridAPI.getChildGrids(false)[0]; childGrid.data = fixture.componentInstance.generateData(10, 0); fixture.detectChanges(); await wait(200); - expect(hierarchicalGrid.verticalScrollContainer.getScroll().parentElement.parentElement.hidden).toBeFalsy(); + + expect(verticalScrollWrapper.hidden).toBeFalsy(); expect(hierarchicalGrid.tbody.nativeElement.offsetWidth).toBeLessThan(initialBodyWidth); }); }); diff --git a/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-functions.spec.ts b/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-functions.spec.ts index 60cfded27b6..3cdbf3bb099 100644 --- a/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-functions.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/hierarchical-grid-functions.spec.ts @@ -4,7 +4,9 @@ import { By } from '@angular/platform-browser'; import { IgxHierarchicalRowComponent } from '../grids/hierarchical-grid/hierarchical-row.component'; import { IgxRowDirective } from '../grids/row.directive'; +const HIERARCHICAL_GRID_TAG = 'igx-hierarchical-grid'; const EXPANDER_CLASS = 'igx-grid__hierarchical-expander'; +const SCROLL_TBODY_CLASS = 'igx-grid__tbody-scrollbar'; export class HierarchicalGridFunctions { @@ -49,4 +51,15 @@ export class HierarchicalGridFunctions { public static isExpander(element: HTMLElement, modifier?: string): boolean { return element.classList.contains(`${EXPANDER_CLASS}${modifier || ''}`); } + + /** + * Gets the main wrapper element of the vertical scrollbar. + * @param fix the ComponentFixture to search + */ + public static getVerticalScrollWrapper(fix: ComponentFixture, gridID): HTMLElement { + const gridDebugEl = fix.debugElement.query(By.css(HIERARCHICAL_GRID_TAG + `[id='${gridID}'`)); + const scrollWrappers = gridDebugEl.queryAll(By.css('.' + SCROLL_TBODY_CLASS)); + // Return the last element since the scrollbar for the targeted grid is after all children that also have scrollbars + return scrollWrappers[scrollWrappers.length - 1].nativeElement; + } } From 9906ba0d329e03b5da98aa6076d7f102b0c7904d Mon Sep 17 00:00:00 2001 From: Svetoslav Krastev Date: Tue, 7 Apr 2020 19:14:25 +0300 Subject: [PATCH 17/21] chore(*): Fix hierarchical test lint. --- .../hierarchical-grid/hierarchical-grid.integration.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts index 2c37dabd9d3..e45b91c3d5f 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.integration.spec.ts @@ -893,7 +893,7 @@ describe('IgxHierarchicalGrid Integration #hGrid', () => { hierarchicalGrid.height = '700px'; fixture.detectChanges(); - let rows =HierarchicalGridFunctions.getHierarchicalRows(fixture); + let rows = HierarchicalGridFunctions.getHierarchicalRows(fixture); const paginator = fixture.debugElement.query(By.directive(IgxPaginatorComponent)); expect(rows.length).toEqual(5); expect(paginator.componentInstance.perPage).toEqual(5); From 368bff37e1bbc17b6b4ef09a3f0c28f1d9d26565 Mon Sep 17 00:00:00 2001 From: skrustev Date: Wed, 8 Apr 2020 22:56:49 +0300 Subject: [PATCH 18/21] fix(igxCell): Fix cell entering edit mode when disabled with enter/f2. --- projects/igniteui-angular/src/lib/grids/cell.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 315542af620..91ec1136746 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -382,7 +382,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy { */ @HostBinding('attr.aria-readonly') get readonly(): boolean { - return !this.column.editable; + return !this.editable; } get gridRowSpan(): number { @@ -1051,7 +1051,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy { if (this.isInCompositionMode) { return; } - if (this.column.editable && !this.row.deleted) { + if (this.editable && !this.row.deleted) { if (this.editMode) { this.grid.endEdit(true); this.nativeElement.focus(); From ee87527267fd7af48d4ff6515865b3e8b5703838 Mon Sep 17 00:00:00 2001 From: skrustev Date: Fri, 10 Apr 2020 17:14:49 +0300 Subject: [PATCH 19/21] chore(*): Address comments on styling. --- .../core/styles/components/grid/_grid-component.scss | 8 ++++++++ .../lib/core/styles/components/grid/_grid-theme.scss | 10 +++++++++- .../lib/core/styles/themes/schemas/light/_grid.scss | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss index 64b12d968b9..4615df9e8ca 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss @@ -706,6 +706,10 @@ @extend %igx-grid__tree-cell-cosy--padding-level-#{$i} !optional; } } + + @include e(td, $m: pinned-chip) { + @extend %grid-cell--pinned-chip--cosy !optional; + } } @include m(compact) { @@ -811,6 +815,10 @@ @extend %igx-grid__tree-cell-compact--padding-level-#{$i} !optional; } } + + @include e(td, $m: pinned-chip) { + @extend %grid-cell--pinned-chip--compact !optional; + } } @include _excel-filtering-partial(); diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index ef871886ee7..c19f9a9332b 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -1418,7 +1418,15 @@ } %grid-cell--pinned-chip { - margin-right: rem(4px); + margin-#{$right}: rem(12px); + } + + %grid-cell--pinned-chip--cosy { + margin-#{$right}: rem(8px); + } + + %grid-cell--pinned-chip--compact { + margin-#{$right}: rem(4px); } %grid-cell-header { diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss index 4e811b85126..c27700764a9 100644 --- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss +++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_grid.scss @@ -47,7 +47,7 @@ /// @prop {Map} edit-mode-color [igx-color: ('secondary', 500)] - The text color in edit mode. /// @prop {Map} edited-row-indicator [igx-color: ('grays', 400)] - The indicator's color of edited row. /// @prop {Map} cell-edited-value-color [igx-color: ('grays', 600)] - The color of cell edited value. -/// @prop {Map} cell-disabled-color [igx-color: ('grays', 600)] - The text color of a disabled cell. +/// @prop {Map} cell-disabled-color [igx-color: ('grays', 500)] - The text color of a disabled cell. /// @prop {Map} resize-line-color [igx-color: ('secondary', 500)] - The table header resize line color. /// @prop {Map} drop-indicator-color [igx-color: ('secondary', 500)] - The color of the drop indicator. /// @prop {Map} grouparea-background [igx-color: ('grays', 100), hexrgba: #fff] - The grid group area background color. @@ -235,7 +235,7 @@ $_light-grid: extend( ), cell-disabled-color: ( - igx-color: ('grays', 400) + igx-color: ('grays', 500) ), resize-line-color: ( From 10b3492ec4e01eb87499b5fceb6cd59a6df842d6 Mon Sep 17 00:00:00 2001 From: skrustev Date: Fri, 10 Apr 2020 18:22:52 +0300 Subject: [PATCH 20/21] fix(igxGrid): Fix disabled row issues related to merge. --- .../src/lib/grids/grid-navigation.service.ts | 6 +++--- .../hierarchical-grid/hierarchical-grid.component.html | 4 ++-- .../lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts | 6 +----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts index fd77fb6be9a..add01e722fe 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-navigation.service.ts @@ -102,8 +102,8 @@ export class IgxGridNavigationService { break; case 'enter': case 'f2': - if (!this.isDataRow(rowIndex)) { break; } const cell = this.grid.getCellByColumnVisibleIndex(this.activeNode.row, this.activeNode.column); + if (!this.isDataRow(rowIndex) || !cell.editable) { break; } this.grid.crudService.enterEditMode(cell); break; case 'escape': @@ -114,8 +114,8 @@ export class IgxGridNavigationService { case ' ': case 'spacebar': case 'space': - if (this.grid.isRowSelectable && this.isDataRow(rowIndex)) { - const rowObj = this.grid.getRowByIndex(this.activeNode.row); + const rowObj = this.grid.getRowByIndex(this.activeNode.row); + if (this.grid.isRowSelectable && this.isDataRow(rowIndex) && !rowObj.disabled) { rowObj && rowObj.selected ? this.grid.selectionService.deselectRow(rowObj.rowID, event) : this.grid.selectionService.selectRowById(rowObj.rowID, false, event); } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index 87a66669b18..2023112a766 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -116,10 +116,10 @@ | gridTransaction:id:pipeTrigger | visibleColumns:hasVisibleColumns | gridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger:filteringPipeTrigger - | gridHierarchicalRowPinning:false:pipeTrigger | gridSort:sortingExpressions:sortStrategy:id:pipeTrigger | gridHierarchicalPaging:page:perPage:id:pipeTrigger - | gridHierarchical:expansionStates:id:primaryKey:childLayoutKeys:pipeTrigger" + | gridHierarchical:expansionStates:id:primaryKey:childLayoutKeys:pipeTrigger + | gridHierarchicalRowPinning:false:pipeTrigger" [igxForScrollOrientation]="'vertical'" [igxForScrollContainer]='verticalScroll' [igxForContainerSize]='calcHeight' [igxForItemSize]="renderedRowHeight" [igxForTrackBy]='trackChanges' #verticalScrollContainer (onChunkPreload)="dataLoading($event)"> diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts index 2360cb98878..ac50ac977bd 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.pipes.ts @@ -35,12 +35,8 @@ export class IgxGridHierarchicalPipe implements PipeTransform { public addHierarchy(grid, data: T[], state, primaryKey, childKeys: string[]): T[] { const result = []; - data.forEach((v: any) => { + data.forEach((v) => { result.push(v); - if (v.ghostRecord !== undefined) { - v = v.recordRef; - } - const childGridsData = {}; childKeys.forEach((childKey) => { const childData = v[childKey] ? v[childKey] : null; From 5b847eb134bd54dfcb597867b7ace9a6245a9461 Mon Sep 17 00:00:00 2001 From: MKirova Date: Mon, 13 Apr 2020 19:17:55 +0300 Subject: [PATCH 21/21] chore(*): Disable test related to issue. --- .../grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts index 039d54fbcc0..990b243a7d9 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts @@ -271,6 +271,7 @@ describe('IgxHierarchicalGrid Basic Navigation #hGrid', () => { })); it('should scroll top of child grid into view when pressing Ctrl + Arrow Up when cell is selected in it.', (async () => { + pending('related to the bug #7118'); hierarchicalGrid.verticalScrollContainer.scrollTo(7); fixture.detectChanges(); await wait(DEBOUNCE_TIME);