Skip to content

Commit

Permalink
tree grid grouping pipe and group area (#9625)
Browse files Browse the repository at this point in the history
* feat(grid): extracted column grouping area into a separate component
* feat(tg-grouping): added tree grid grouping pipe
* feat(tg-group-area): 2 group area components for tree grid and regular grid

Co-authored-by: Galina Edinakova <[email protected]>
Co-authored-by: Diyan Dimitrov <[email protected]>
  • Loading branch information
3 people authored Jul 2, 2021
1 parent 3adfb21 commit 4581b5d
Show file tree
Hide file tree
Showing 30 changed files with 1,456 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export class IgxSorting implements IGridSortingStrategy {

export class IgxDataRecordSorting extends IgxSorting {

protected getFieldValue(obj: any, key: string, isDate: boolean = false): any {
return isDate ? parseDate(resolveNestedPath(obj.data, key)) : resolveNestedPath(obj.data, key);
protected getFieldValue(obj: any, key: string, isDate: boolean = false, isTime: boolean = false): any {
return super.getFieldValue(obj.data, key, isDate, isTime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { IGridResourceStrings } from '../../core/i18n/grid-resources';
import { ISortingExpression } from '../../data-operations/sorting-expression.interface';
import { IGroupingExpression } from '../../data-operations/grouping-expression.interface';
import { TransactionService, Transaction, State } from '../../services/public_api';
import { ITreeGridRecord } from '../tree-grid/public_api';
import { IgxColumnComponent, ITreeGridRecord } from '../tree-grid/public_api';
import { IGroupByRecord } from '../../data-operations/groupby-record.interface';
import { IGroupByExpandState } from '../../data-operations/groupby-expand-state.interface';

export interface IGridDataBindable {
data: any[] | null;
Expand All @@ -30,6 +31,8 @@ export interface GridType extends IGridDataBindable {
id: string;
renderedRowHeight: number;
summaryPipeTrigger: number;
draggedColumn: IgxColumnComponent;
hasColumnLayouts: boolean;

filterMode: FilterMode;

Expand Down Expand Up @@ -81,9 +84,12 @@ export interface GridType extends IGridDataBindable {
* An interface describing a Flat Grid type
*/
export interface FlatGridType extends GridType {
groupingExpansionState: IGroupByExpandState[];
groupingExpressions: IGroupingExpression[];
groupingExpressionsChange: EventEmitter<IGroupingExpression[]>;
toggleGroup(groupRow: IGroupByRecord): void;
clearGrouping(field: string): void;
groupBy(expression: IGroupingExpression | Array<IGroupingExpression>): void;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2644,10 +2644,6 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
* @hidden @internal
*/
public tfootHeight: number;
/**
* @hidden @internal
*/
public chipsGoupingExpressions = [];
/**
* @hidden @internal
*/
Expand Down
10 changes: 9 additions & 1 deletion projects/igniteui-angular/src/lib/grids/grid-common.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ import { IgxGridFilteringModule } from './filtering/base/filtering.module';
import { IgxRowDirective } from './row.directive';
import {
IgxExcelStyleHeaderIconDirective,
IgxGroupAreaDropDirective,
IgxHeaderCollapseIndicatorDirective,
IgxHeaderExpandIndicatorDirective,
IgxRowCollapsedIndicatorDirective,
IgxRowExpandedIndicatorDirective
} from './grid/grid.directives';
import { IgxChipsModule } from '../chips/chips.module';
import { IgxGroupByMetaPipe } from './grouping/group-by-area.directive';
/**
* @hidden
*/
Expand All @@ -56,6 +59,8 @@ import {
IgxHeaderExpandIndicatorDirective,
IgxHeaderCollapseIndicatorDirective,
IgxExcelStyleHeaderIconDirective,
IgxGroupAreaDropDirective,
IgxGroupByMetaPipe
],
entryComponents: [
IgxAdvancedFilteringDialogComponent
Expand Down Expand Up @@ -89,6 +94,8 @@ import {
IgxHeaderExpandIndicatorDirective,
IgxHeaderCollapseIndicatorDirective,
IgxExcelStyleHeaderIconDirective,
IgxGroupAreaDropDirective,
IgxGroupByMetaPipe
],
imports: [
IgxGridColumnModule,
Expand All @@ -104,7 +111,8 @@ import {
IgxGridExcelStyleFilteringModule,
IgxRowDragModule,
IgxPaginatorModule,
IgxGridSharedModules
IgxGridSharedModules,
IgxChipsModule
],
providers: [
{ provide: IgxGridTransaction, useClass: IgxBaseTransactionService }
Expand Down
41 changes: 12 additions & 29 deletions projects/igniteui-angular/src/lib/grids/grid/grid.component.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
<ng-content select="igx-grid-toolbar"></ng-content>

<div [style.flex-basis.px]='outerWidth' class="igx-grid__grouparea"
*ngIf="showGroupArea && (groupingExpressions.length > 0 || hasGroupableColumns)" #groupArea>
<igx-chips-area (reorder)="chipsOrderChanged($event)" (moveEnd)="chipsMovingEnded()">
<ng-container *ngFor="let expr of chipsGoupingExpressions; let last = last;">
<igx-chip [id]="expr.fieldName" [title]="getGroupByChipTitle(expr)"
[removable]="getColumnGroupable(expr.fieldName)"
[draggable]="getColumnGroupable(expr.fieldName)" [displayDensity]="displayDensity"
(keyDown)="onChipKeyDown($event)" (remove)="onChipRemoved($event)"
(chipClick)="getColumnGroupable(expr.fieldName) ? onChipClicked($event): null"
[disabled]='!getColumnGroupable(expr.fieldName)'>
<span>{{ getGroupByChipTitle(expr) }}</span>
<igx-icon igxSuffix>{{ expr.dir == 1 ? 'arrow_upward' : 'arrow_downward' }}</igx-icon>
</igx-chip>
<span class="igx-grid__grouparea-connector">
<igx-icon [style.visibility]="(!last || dropAreaVisible) ? 'visible' : 'hidden'">arrow_forward
</igx-icon>
</span>
</ng-container>
<div igxGroupAreaDrop [style.visibility]="dropAreaVisible ? 'visible' : 'hidden'" [class]="groupAreaHostClass"
[attr.gridId]='this.id'>
<ng-container *ngTemplateOutlet="dropAreaTemplateResolved"></ng-container>
</div>
</igx-chips-area>
</div>
<!-- Group-by area -->
<ng-container *ngIf="showGroupArea && (groupingExpressions.length > 0 || hasGroupableColumns)">
<igx-grid-group-by-area #groupArea [style.flex-basis.px]='outerWidth'
[grid]="this"
[expressions]="groupingExpressions"
[sortingExpressions]="sortingExpressions"
[density]="displayDensity"
[dropAreaTemplate]="dropAreaTemplate"
[dropAreaMessage]="dropAreaMessage"
>
</igx-grid-group-by-area>
</ng-container>

<div class="igx-grid__thead" role="rowgroup">
<div class="igx-grid__thead-wrapper" (keydown.meta.c)="copyHandler($event)" (keydown.control.c)="copyHandler($event)" (copy)="copyHandler($event)"
Expand Down Expand Up @@ -282,11 +270,6 @@
</div>
</ng-template>

<ng-template #defaultDropArea>
<igx-icon class="igx-drop-area__icon">group_work</igx-icon>
<span class="igx-drop-area__text">{{dropAreaMessage}}</span>
</ng-template>

<ng-template #defaultExpandedTemplate>
<igx-icon role="button" class="igx-grid__group-expand-btn"
[ngClass]="{
Expand Down
115 changes: 5 additions & 110 deletions projects/igniteui-angular/src/lib/grids/grid/grid.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
Component, ChangeDetectionStrategy, Input, Output, EventEmitter, ContentChild, ViewChildren,
QueryList, ViewChild, ElementRef, TemplateRef, DoCheck, AfterContentInit, HostBinding,
QueryList, ViewChild, TemplateRef, DoCheck, AfterContentInit, HostBinding,
forwardRef, OnInit, AfterViewInit, ContentChildren
} from '@angular/core';
import { GridBaseAPIService } from '../api.service';
Expand All @@ -14,8 +14,6 @@ import { IgxGroupByRowTemplateDirective, IgxGridDetailTemplateDirective } from '
import { IgxGridGroupByRowComponent } from './groupby-row.component';
import { IGroupByExpandState } from '../../data-operations/groupby-expand-state.interface';
import { IForOfState } from '../../directives/for-of/for_of.directive';
import { IBaseChipEventArgs, IChipClickEventArgs, IChipKeyDownEventArgs } from '../../chips/chip.component';
import { IChipsAreaReorderEventArgs } from '../../chips/chips-area.component';
import { IgxColumnComponent } from '../columns/column.component';
import { takeUntil } from 'rxjs/operators';
import { IgxFilteringService } from '../filtering/grid-filtering.service';
Expand All @@ -25,12 +23,13 @@ import { IgxGridSummaryService } from '../summaries/grid-summary.service';
import { IgxGridSelectionService } from '../selection/selection.service';
import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service';
import { IgxGridMRLNavigationService } from '../grid-mrl-navigation.service';
import { FilterMode, RowPinningPosition } from '../common/enums';
import { FilterMode } from '../common/enums';
import { GridType } from '../common/grid.interface';
import { IgxGroupByRowSelectorDirective } from '../selection/row-selectors';
import { IgxGridCRUDService } from '../common/crud.service';
import { IgxGridRow, IgxGroupByRow, IgxSummaryRow } from '../grid-public-row';
import { RowType } from '../common/row.interface';
import { IgxGridGroupByAreaComponent } from '../grouping/grid-group-by-area.component';

let NEXT_ID = 0;

Expand Down Expand Up @@ -156,17 +155,11 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
@ContentChild(IgxGridDetailTemplateDirective, { read: TemplateRef, static: false })
public detailTemplate: TemplateRef<any> = null;

/**
* @hidden @internal
*/
@ViewChild('defaultDropArea', { read: TemplateRef, static: true })
public defaultDropAreaTemplate: TemplateRef<any>;

/**
* @hidden @internal
*/
@ViewChild('groupArea')
public groupArea: ElementRef;
public groupArea: IgxGridGroupByAreaComponent;

/**
* @hidden @internal
Expand Down Expand Up @@ -371,7 +364,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
const newExpressions: IGroupingExpression[] = value;
this._groupingExpressions = cloneArray(value);
this.groupingExpressionsChange.emit(this._groupingExpressions);
this.chipsGoupingExpressions = cloneArray(value);
if (this._gridAPI.grid) {
/* grouping should work in conjunction with sorting
and without overriding separate sorting expressions */
Expand Down Expand Up @@ -572,12 +564,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
public isDetailActive(rowIndex) {
return this.navigation.activeNode ? this.navigation.activeNode.row === rowIndex : false;
}
/**
* @hidden @internal
*/
public get groupAreaHostClass(): string {
return this.getComponentDensityClass('igx-drop-area');
}

/**
* Gets/Sets the template reference for the group row.
Expand Down Expand Up @@ -812,7 +798,7 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
*/
public get dropAreaVisible(): boolean {
return (this.draggedColumn && this.draggedColumn.groupable) ||
!this.chipsGoupingExpressions.length;
!this.groupingExpressions.length;
}

/**
Expand Down Expand Up @@ -878,89 +864,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
}
}

/**
* @hidden @internal
*/
public onChipRemoved(event: IBaseChipEventArgs) {
this.clearGrouping(event.owner.id);
}

/**
* @hidden @internal
*/
public chipsOrderChanged(event: IChipsAreaReorderEventArgs) {
const newGrouping = [];
for (const chip of event.chipsArray) {
const expr = this.groupingExpressions.filter((item) => item.fieldName === chip.id)[0];

if (!this.getColumnByName(expr.fieldName).groupable) {
// disallow changing order if there are columns with groupable: false
return;
}
newGrouping.push(expr);
}
this.groupingExpansionState = [];
this.chipsGoupingExpressions = newGrouping;

if (event.originalEvent instanceof KeyboardEvent) {
// When reordered using keyboard navigation, we don't have `onMoveEnd` event.
this.groupingExpressions = this.chipsGoupingExpressions;
}
this.notifyChanges();
}

/**
* @hidden @internal
*/
public chipsMovingEnded() {
this.groupingExpressions = this.chipsGoupingExpressions;
this.notifyChanges();
}

/**
* @hidden @internal
*/
public onChipClicked(event: IChipClickEventArgs) {
const sortingExpr = this.sortingExpressions;
const columnExpr = sortingExpr.find((expr) => expr.fieldName === event.owner.id);
const groupExpr = this.groupingExpressions.find((expr) => expr.fieldName === event.owner.id);
columnExpr.dir = 3 - columnExpr.dir;
groupExpr.dir = columnExpr.dir;
this.sort(columnExpr);
this.notifyChanges();
}

/**
* @hidden @internal
*/
public onChipKeyDown(event: IChipKeyDownEventArgs) {
if (event.originalEvent.key === ' ' || event.originalEvent.key === 'Spacebar' || event.originalEvent.key === 'Enter') {
const sortingExpr = this.sortingExpressions;
const columnExpr = sortingExpr.find((expr) => expr.fieldName === event.owner.id);
columnExpr.dir = 3 - columnExpr.dir;
this.sort(columnExpr);
this.notifyChanges();
}
}

/**
* @hidden @internal
*/
public get dropAreaTemplateResolved(): TemplateRef<any> {
if (this.dropAreaTemplate) {
return this.dropAreaTemplate;
} else {
return this.defaultDropAreaTemplate;
}
}

/**
* @hidden @internal
*/
public getGroupByChipTitle(expression: IGroupingExpression): string {
const column = this.getColumnByName(expression.fieldName);
return (column && column.header) || expression.fieldName;
}
/**
* @hidden @internal
*/
Expand All @@ -972,14 +875,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
}
}

/**
* @hidden @internal
*/
public getColumnGroupable(fieldName: string): boolean {
const column = this.getColumnByName(fieldName);
return column && column.groupable;
}

/**
* @hidden @internal
*/
Expand Down
30 changes: 10 additions & 20 deletions projects/igniteui-angular/src/lib/grids/grid/grid.directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Directive, ElementRef, Renderer2, NgZone, HostBinding, TemplateRef } fr
import { IgxDropDirective } from '../../directives/drag-drop/drag-drop.directive';
import { IgxColumnComponent } from '../columns/column.component';
import { IgxGridComponent } from './grid.component';
import { SortingDirection } from '../../data-operations/sorting-expression.interface';
import { IgxColumnMovingDragDirective } from '../moving/moving.drag.directive';
import { IgxGroupByAreaDirective } from '../grouping/group-by-area.directive';

/**
* @hidden
Expand Down Expand Up @@ -83,7 +83,11 @@ export class IgxGroupAreaDropDirective extends IgxDropDirective {
@HostBinding('class.igx-drop-area--hover')
public hovered = false;

constructor(private elementRef: ElementRef, private renderer: Renderer2, private zone: NgZone) {
constructor(
private groupArea: IgxGroupByAreaDirective,
private elementRef: ElementRef,
renderer: Renderer2,
zone: NgZone) {
super(elementRef, renderer, zone);
}

Expand All @@ -93,8 +97,10 @@ export class IgxGroupAreaDropDirective extends IgxDropDirective {
if (!this.columnBelongsToGrid(column)) {
return;
}
const grid = column.grid as IgxGridComponent;
const isGrouped = grid.groupingExpressions.findIndex((item) => item.fieldName === column.field) !== -1;

const isGrouped = this.groupArea.expressions
? this.groupArea.expressions.findIndex((item) => item.fieldName === column.field) !== -1
: false;
if (column.groupable && !isGrouped && !column.columnGroup && !!column.field) {
drag.icon.innerText = 'group_work';
this.hovered = true;
Expand All @@ -114,22 +120,6 @@ export class IgxGroupAreaDropDirective extends IgxDropDirective {
this.hovered = false;
}

public onDragDrop(event) {
const drag: IgxColumnMovingDragDirective = event.detail.owner;
if (drag instanceof IgxColumnMovingDragDirective) {
const column: IgxColumnComponent = drag.column;
if (!this.columnBelongsToGrid(column)) {
return;
}
const grid = column.grid as IgxGridComponent;
const isGrouped = grid.groupingExpressions.findIndex((item) => item.fieldName === column.field) !== -1;
if (column.groupable && !isGrouped && !column.columnGroup && !!column.field) {
grid.groupBy({ fieldName: column.field, dir: SortingDirection.Asc, ignoreCase: column.sortingIgnoreCase,
strategy: column.sortStrategy, groupingComparer: column.groupingComparer });
}
}
}

private closestParentByAttr(elem, attr) {
return elem.hasAttribute(attr) ?
elem :
Expand Down
Loading

0 comments on commit 4581b5d

Please sign in to comment.