Skip to content

Commit

Permalink
feat(esf): add initial 'load on demand' POC #5448
Browse files Browse the repository at this point in the history
  • Loading branch information
tachojelev committed Aug 2, 2019
1 parent 03daa14 commit 8cab60a
Show file tree
Hide file tree
Showing 13 changed files with 306 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,33 @@
</igx-icon>
</igx-input-group>

<igx-list [displayDensity]="displayDensity" [style.height.px]="250">
<div [style.overflow]="'hidden'" [style.position]="'relative'">
<igx-list-item
*igxFor="let item of data | excelStyleSearchFilter: searchValue; scrollOrientation : 'vertical'; containerSize: '250px'; itemSize: itemSize">
<igx-checkbox
[value]="item"
tabindex="-1"
[checked]="item.isSelected"
[disableRipple]="true"
[indeterminate]="item.indeterminate"
[disableTransitions]="true"
(change)="onCheckboxChange($event)">
{{ column.formatter && !item.isSpecial ? column.formatter(item.label) : column.dataType === 'number' ? (item.label | igxdecimal:
column.grid.locale) : column.dataType === 'date' ? (item.label | igxdate: column.grid.locale) : item.label }}
</igx-checkbox>
</igx-list-item>
</div>
</igx-list>
<igx-list [displayDensity]="displayDensity" [style.height.px]="250" [isLoading]="isLoading">
<div [style.overflow]="'hidden'" [style.position]="'relative'">
<igx-list-item
*igxFor="let item of data | excelStyleSearchFilter: searchValue; scrollOrientation : 'vertical'; containerSize: '250px'; itemSize: itemSize">
<igx-checkbox
[value]="item"
tabindex="-1"
[checked]="item.isSelected"
[disableRipple]="true"
[indeterminate]="item.indeterminate"
[disableTransitions]="true"
(change)="onCheckboxChange($event)">
{{ column.formatter && !item.isSpecial ? column.formatter(item.label) : column.dataType === 'number' ? (item.label | igxdecimal:
column.grid.locale) : column.dataType === 'date' ? (item.label | igxdate: column.grid.locale) : item.label }}
</igx-checkbox>
</igx-list-item>
</div>

<ng-template igxDataLoading>
<div style="display: flex; align-items: center;" class="esf-loading-indicator">
<ng-container *ngTemplateOutlet="grid.esfLoadingIndicatorTemplate ? grid.esfLoadingIndicatorTemplate : defaultEsfLoadingIndicatorTemplate">
</ng-container>
</div>
</ng-template>
</igx-list>

<ng-template #defaultEsfLoadingIndicatorTemplate>
<igx-circular-bar [indeterminate]="true">
</igx-circular-bar>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
Component,
ChangeDetectionStrategy,
Input,
ViewChild
ViewChild,
ChangeDetectorRef
} from '@angular/core';
import { IgxColumnComponent } from '../../column.component';
import { IgxFilterOptions } from '../../../directives/filter/filter.directive';
Expand All @@ -24,8 +25,22 @@ import { FilterListItem } from './grid.excel-style-filtering.component';
})
export class IgxExcelStyleSearchComponent implements AfterViewInit {

private _isLoading;

public get isLoading() {
return this._isLoading;
}

public set isLoading(value: boolean) {
this._isLoading = value;
this._cdr.detectChanges();
}

public searchValue: any;

@Input()
public grid: any;

@Input()
public data: FilterListItem[];

Expand All @@ -41,7 +56,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit {
@ViewChild(IgxForOfDirective, { static: true })
protected virtDir: IgxForOfDirective<any>;

constructor() { }
constructor(private _cdr: ChangeDetectorRef) { }

public ngAfterViewInit() {
requestAnimationFrame(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ <h4>{{ column.header || column.field }}</h4>
#excelStyleSearch
[column]="column"
[data]="listData"
[grid]="grid"
[displayDensity]="grid.displayDensity">
</igx-excel-style-search>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,29 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, AfterView
}

public populateColumnData() {
if (this.grid.loadColumnValuesOnDemand) {
this.loadValuesOnDemand();
} else {
this.loadValuesFromGridData();
}
}

private loadValuesOnDemand() {
this.excelStyleSearch.isLoading = true;
this.grid.loadColumnValuesOnDemand(this.column.field, (columnUniqueValues: any[]) => {
if (this.column.dataType === DataType.Date) {
this.uniqueValues = Array.from(new Set(columnUniqueValues.map(val => val ? val.toDateString() : val)));
this.generateFilterValues(true);
} else {
this.uniqueValues = Array.from(new Set(columnUniqueValues));
this.generateFilterValues();
}
this.generateListData();
this.excelStyleSearch.isLoading = false;
});
}

public loadValuesFromGridData() {
let data = this.column.gridAPI.get_all_data(this.grid.id);
const gridExpressionsTree: IFilteringExpressionsTree = this.grid.filteringExpressionsTree;
const expressionsTree = new FilteringExpressionsTree(gridExpressionsTree.operator, gridExpressionsTree.fieldName);
Expand All @@ -354,6 +377,16 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, AfterView
if (this.column.dataType === DataType.Date) {
this.uniqueValues = Array.from(new Set(data.map(record =>
record[this.column.field] ? record[this.column.field].toDateString() : record[this.column.field])));
this.generateFilterValues(true);
} else {
this.uniqueValues = Array.from(new Set(data.map(record => record[this.column.field])));
this.generateFilterValues();
}
this.generateListData();
}

private generateFilterValues(isDateColumn: boolean = false) {
if (isDateColumn) {
this.filterValues = new Set<any>(this.expressionsList.reduce((arr, e) => {
if (e.expression.condition.name === 'in') {
return [ ...arr, ...Array.from((e.expression.searchVal as Set<any>).values()).map(v =>
Expand All @@ -362,14 +395,16 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, AfterView
return [ ...arr, ...[e.expression.searchVal ? e.expression.searchVal.toDateString() : e.expression.searchVal] ];
}, []));
} else {
this.uniqueValues = Array.from(new Set(data.map(record => record[this.column.field])));
this.filterValues = new Set<any>(this.expressionsList.reduce((arr, e) => {
if (e.expression.condition.name === 'in') {
return [ ...arr, ...Array.from((e.expression.searchVal as Set<any>).values()) ];
}
return [ ...arr, ...[e.expression.searchVal] ];
}, []));
}
}

private generateListData() {
this.listData = new Array<FilterListItem>();

const shouldUpdateSelection = this.areExpressionsSelectable() && this.areExpressionsValuesInTheList();
Expand All @@ -395,6 +430,72 @@ export class IgxGridExcelStyleFilteringComponent implements OnDestroy, AfterView
this.cdr.detectChanges();
}



// public populateColumnData() {
// let data = this.column.gridAPI.get_all_data(this.grid.id);
// const gridExpressionsTree: IFilteringExpressionsTree = this.grid.filteringExpressionsTree;
// const expressionsTree = new FilteringExpressionsTree(gridExpressionsTree.operator, gridExpressionsTree.fieldName);

// for (const operand of gridExpressionsTree.filteringOperands) {
// if (operand instanceof FilteringExpressionsTree) {
// const columnExprTree = operand as FilteringExpressionsTree;
// if (columnExprTree.fieldName === this.column.field) {
// break;
// }
// }
// expressionsTree.filteringOperands.push(operand);
// }

// if (expressionsTree.filteringOperands.length) {
// const state = { expressionsTree: expressionsTree };
// data = DataUtil.filter(cloneArray(data), state);
// }

// if (this.column.dataType === DataType.Date) {
// this.uniqueValues = Array.from(new Set(data.map(record =>
// record[this.column.field] ? record[this.column.field].toDateString() : record[this.column.field])));
// this.filterValues = new Set<any>(this.expressionsList.reduce((arr, e) => {
// if (e.expression.condition.name === 'in') {
// return [ ...arr, ...Array.from((e.expression.searchVal as Set<any>).values()).map(v =>
// new Date(v).toDateString()) ];
// }
// return [ ...arr, ...[e.expression.searchVal ? e.expression.searchVal.toDateString() : e.expression.searchVal] ];
// }, []));
// } else {
// this.uniqueValues = Array.from(new Set(data.map(record => record[this.column.field])));
// this.filterValues = new Set<any>(this.expressionsList.reduce((arr, e) => {
// if (e.expression.condition.name === 'in') {
// return [ ...arr, ...Array.from((e.expression.searchVal as Set<any>).values()) ];
// }
// return [ ...arr, ...[e.expression.searchVal] ];
// }, []));
// }
// this.listData = new Array<FilterListItem>();

// const shouldUpdateSelection = this.areExpressionsSelectable() && this.areExpressionsValuesInTheList();

// if (this.column.dataType === DataType.Boolean) {
// this.addBooleanItems();
// } else {
// this.addItems(shouldUpdateSelection);
// }

// this.listData.sort((a, b) => this.sortData(a, b));

// if (this.column.dataType === DataType.Date) {
// this.uniqueValues = this.uniqueValues.map(value => new Date(value));
// }

// if (this.containsNullOrEmpty) {
// this.addBlanksItem(shouldUpdateSelection);
// }

// this.addSelectAllItem();

// this.cdr.detectChanges();
// }

private addBooleanItems() {
this.selectAllSelected = true;
this.selectAllIndeterminate = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { IgxFilterModule } from '../../../directives/filter/filter.directive';
import { IgxToggleModule } from '../../../directives/toggle/toggle.directive';
import { IgxListModule } from '../../../list/list.component';
import { IgxExcelStyleSearchFilterPipe } from './excel-style-search.pipe';
import { IgxProgressBarModule } from '../../../progressbar/progressbar.component';

/**
* @hidden
Expand Down Expand Up @@ -71,7 +72,8 @@ import { IgxExcelStyleSearchFilterPipe } from './excel-style-search.pipe';
IgxCheckboxModule,
IgxFilterModule,
IgxToggleModule,
IgxListModule
IgxListModule,
IgxProgressBarModule
],
entryComponents: [
IgxGridExcelStyleFilteringComponent
Expand Down
14 changes: 14 additions & 0 deletions projects/igniteui-angular/src/lib/grids/grid-base.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
return this._scrollWidth;
}

private _esfLoadingIndicatorTemplate: TemplateRef<any>;
private _resourceStrings = CurrentResourceStrings.GridResStrings;
private _emptyGridMessage = null;
private _emptyFilteredGridMessage = null;
Expand Down Expand Up @@ -1000,6 +1001,19 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements
}
}

@Input()
public get esfLoadingIndicatorTemplate(): TemplateRef<any> {
return this._esfLoadingIndicatorTemplate;
}

public set esfLoadingIndicatorTemplate(value: TemplateRef<any>) {
this._esfLoadingIndicatorTemplate = value;
this.cdr.markForCheck();
}

@Input()
public loadColumnValuesOnDemand: (field: string, done: (values: any[]) => void) => void;

/**
* Emitted when `IgxGridCellComponent` is clicked. Returns the `IgxGridCellComponent`.
* ```html
Expand Down
5 changes: 5 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ export class AppComponent implements OnInit {
icon: 'view_column',
name: 'Grid Filter Template'
},
{
link: '/gridEsfLoadOnDemand',
icon: 'view_column',
name: 'Grid ESF Load On Demand'
},
{
link: '/gridColumnMoving',
icon: 'view_column',
Expand Down
4 changes: 3 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import { GridFilterTemplateSampleComponent } from './grid-filter-template/grid-f
import { GridMRLConfigSampleComponent } from './grid-multi-row-layout-config/grid-mrl-config.sample';
import { GridMRLCustomNavigationSampleComponent } from './grid-mrl-custom-navigation/grid-mrl-custom-navigation';
import { GridClipboardSampleComponent } from './grid-clipboard/grid-clipboard.sample';
import { GridEsfLoadOnDemandComponent } from './grid-esf-load-on-demand/grid-esf-load-on-demand.component';



Expand Down Expand Up @@ -204,7 +205,8 @@ const components = [
GridSearchBoxComponent,
GridSearchComponent,
GridFilterTemplateSampleComponent,
GridClipboardSampleComponent
GridClipboardSampleComponent,
GridEsfLoadOnDemandComponent
];

@NgModule({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<div class="wrapper">
<app-page-header title="Grid Excel Style Filtering - Load on demand">
Allows loading unique column values into the Excel Style Filtering on demand.
</app-page-header>

<div class="sample-content">
<div class="sample-column">
<div class="density-chooser">
<igx-buttongroup [values]="displayDensities" (onSelect)="selectDensity($event)"></igx-buttongroup>
</div>
<igx-grid #grid1 [data]="data" [displayDensity]="density" [showToolbar]="true"
[columnHiding]="true" [allowFiltering]="true" [rowSelectable]="true"
[filterMode]="'excelStyleFilter'" [width]="'900px'"
[height]="'800px'" [style.zIndex]="'1'"

[loadColumnValuesOnDemand]="loadColumnValues"
[esfLoadingIndicatorTemplate]="loadTemplate"
>

<igx-column [field]="'ID'" [filterable]="true" [sortable]="true" [movable]="true" [dataType]="'string'"></igx-column>
<igx-column [field]="'CompanyName'" [filterable]="true" [sortable]="true" [movable]="true" [dataType]="'string'"></igx-column>
<igx-column [field]="'Employees'" [filterable]="true" [sortable]="true" [movable]="true" [dataType]="'number'"></igx-column>
<igx-column [field]="'Contract'" [filterable]="true" [sortable]="true" [movable]="true" [dataType]="'boolean'"></igx-column>
<igx-column [field]="'DateCreated'" [filterable]="true" [sortable]="true" [movable]="true" [dataType]="'date'"></igx-column>
</igx-grid>
</div>
</div>
</div>

<ng-template #loadTemplate>
Loading ...
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.density-chooser {
margin-bottom: 16px;
max-width: 900px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, ViewChild, OnInit } from '@angular/core';
import { IgxGridComponent } from 'igniteui-angular';
import { SAMPLE_DATA } from '../shared/sample-data';
import { GridESFLoadOnDemandService } from './grid-esf-load-on-demand.service';

@Component({
selector: 'app-grid-esf-load-on-demand',
templateUrl: './grid-esf-load-on-demand.component.html',
styleUrls: ['./grid-esf-load-on-demand.component.scss']
})
export class GridEsfLoadOnDemandComponent implements OnInit {

private esfService = new GridESFLoadOnDemandService();

public data: Array<any>;
public density = 'comfortable';
public displayDensities;

@ViewChild('grid1', { static: true })
public grid1: IgxGridComponent;

public loadColumnValues = (columnField: string, done: (uniqueValues: string[]) => void) => {
this.esfService.getData(columnField, uniqueValues => done(uniqueValues));
}

public ngOnInit(): void {
this.displayDensities = [
{ label: 'comfortable', selected: this.density === 'comfortable', togglable: true },
{ label: 'cosy', selected: this.density === 'cosy', togglable: true },
{ label: 'compact', selected: this.density === 'compact', togglable: true }
];

this.data = SAMPLE_DATA.slice(0);
}

public selectDensity(event) {
this.density = this.displayDensities[event.index].label;
}
}
Loading

0 comments on commit 8cab60a

Please sign in to comment.