UNPKG

@bi8/am-data-table

Version:

ng update @angular/cli --migrate-only --from=1.7.4 ng update @angular/core yarn add ng-packagr yarn add @angular/material yarn add core-js yarn add @angular/flex-layout yarn add lodash yarn add material-design-icons yarn add roboto-fontface yarn

1,134 lines (1,131 loc) 58.1 kB
import { __decorate, __metadata, __extends, __param, __values } from 'tslib'; import { InjectionToken, ViewContainerRef, Directive, TemplateRef, ComponentFactoryResolver, ElementRef, Renderer2, ViewChild, Component, ViewEncapsulation, EventEmitter, ChangeDetectorRef, Output, ViewChildren, QueryList, IterableDiffers, Input, Optional, Inject, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Subject } from 'rxjs/Subject'; import { DataSource } from '@angular/cdk/collections'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { kebabCase, isNil, find, without, remove, startCase, get, defaultsDeep, chunk } from 'lodash'; import { takeUntil } from 'rxjs/operator/takeUntil'; import { MatIconModule, MatPaginatorModule } from '@angular/material'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import 'rxjs/Rx'; var AM_GRID_DATE_FORMAT = new InjectionToken('am.grid.date.format'); var AM_GRID_DATE_DEFAULT = { format: 'fullDate' }; //=====[ UTILS ]====================================================================================================================================== function toCssFriendly(value) { // the string value is typically generated from the column key that may contain '.' return value ? value.split('.').map(function (item) { return kebabCase(item); }).join('-') : value; } //=====[ OUTLETS ]==================================================================================================================================== var HeaderRowOutlet = /** @class */ (function () { function HeaderRowOutlet(viewContainer) { this.viewContainer = viewContainer; } HeaderRowOutlet.ctorParameters = function () { return [ { type: ViewContainerRef } ]; }; HeaderRowOutlet = __decorate([ Directive({ selector: '[headerRowOutlet]' }), __metadata("design:paramtypes", [ViewContainerRef]) ], HeaderRowOutlet); return HeaderRowOutlet; }()); var DataRowOutlet = /** @class */ (function () { function DataRowOutlet(viewContainer) { this.viewContainer = viewContainer; } DataRowOutlet.ctorParameters = function () { return [ { type: ViewContainerRef } ]; }; DataRowOutlet = __decorate([ Directive({ selector: '[dataRowOutlet]' }), __metadata("design:paramtypes", [ViewContainerRef]) ], DataRowOutlet); return DataRowOutlet; }()); var RowOutlet = /** @class */ (function () { function RowOutlet(viewContainer) { this.viewContainer = viewContainer; } RowOutlet.ctorParameters = function () { return [ { type: ViewContainerRef } ]; }; RowOutlet = __decorate([ Directive({ selector: '[rowOutlet]' }), __metadata("design:paramtypes", [ViewContainerRef]) ], RowOutlet); return RowOutlet; }()); var ExpanderOutlet = /** @class */ (function () { function ExpanderOutlet(viewContainer) { this.viewContainer = viewContainer; } ExpanderOutlet.ctorParameters = function () { return [ { type: ViewContainerRef } ]; }; ExpanderOutlet = __decorate([ Directive({ selector: '[expanderOutlet]' }), __metadata("design:paramtypes", [ViewContainerRef]) ], ExpanderOutlet); return ExpanderOutlet; }()); var CellOutlet = /** @class */ (function () { function CellOutlet(viewContainer) { this.viewContainer = viewContainer; } CellOutlet.ctorParameters = function () { return [ { type: ViewContainerRef } ]; }; CellOutlet = __decorate([ Directive({ selector: '[cellOutlet]' }), __metadata("design:paramtypes", [ViewContainerRef]) ], CellOutlet); return CellOutlet; }()); //=====[ HEADER ROW ]================================================================================================================================= var HeaderRowDef = /** @class */ (function () { function HeaderRowDef(templateRef, viewContainer) { this.templateRef = templateRef; this.viewContainer = viewContainer; } HeaderRowDef.ctorParameters = function () { return [ { type: TemplateRef }, { type: ViewContainerRef } ]; }; HeaderRowDef = __decorate([ Directive({ selector: '[headerRowDef]', inputs: ['model: headerRowDef'] }), __metadata("design:paramtypes", [TemplateRef, ViewContainerRef]) ], HeaderRowDef); return HeaderRowDef; }()); var HeaderCellDef = /** @class */ (function () { function HeaderCellDef(templateRef, viewContainer) { this.templateRef = templateRef; this.viewContainer = viewContainer; } HeaderCellDef.ctorParameters = function () { return [ { type: TemplateRef }, { type: ViewContainerRef } ]; }; HeaderCellDef = __decorate([ Directive({ selector: '[headerCellDef]', inputs: ['column: column'] }), __metadata("design:paramtypes", [TemplateRef, ViewContainerRef]) ], HeaderCellDef); return HeaderCellDef; }()); var HeaderCell = /** @class */ (function () { function HeaderCell(componentFactoryResolver, elementRef, renderer) { this.componentFactoryResolver = componentFactoryResolver; this.elementRef = elementRef; this.renderer = renderer; } HeaderCell.prototype.ngOnInit = function () { var _this = this; this.renderer.addClass(this.elementRef.nativeElement, "am-header-cell-" + toCssFriendly(this.column.config.key)); this.renderer.setStyle(this.elementRef.nativeElement, 'flex', this.column.styles.flex || 1); if (this.column && this.column.styles.minWidth) { this.renderer.setStyle(this.elementRef.nativeElement, 'min-width', this.column.styles.minWidth); } else if (this.column && this.column.model) { if (this.column.model.styles.minColumnWidth) { this.renderer.setStyle(this.elementRef.nativeElement, 'min-width', this.column.model.styles.minColumnWidth); } } if (this.column.styles.headerCellStyleClasses) { this.column.styles.headerCellStyleClasses.forEach(function (cls, index) { _this.renderer.addClass(_this.elementRef.nativeElement, cls); }); } }; HeaderCell.prototype.ngOnChanges = function (changes) { }; HeaderCell.prototype.ngOnDestroy = function () { }; HeaderCell.prototype.ngAfterContentInit = function () { this.renderCell(); }; HeaderCell.prototype.renderCell = function () { this._cellOutlet.viewContainer.clear(); if (this.column.config.headingTemplate) { this._cellOutlet.viewContainer.createEmbeddedView(this.column.config.headingTemplate, { column: this.column }); } else { var formatter = this.column.config.headingFormatter; if (formatter) { var componentFactory = this.componentFactoryResolver.resolveComponentFactory(formatter); var viewContainerRef = this._cellOutlet.viewContainer; viewContainerRef.clear(); var componentRef = viewContainerRef.createComponent(componentFactory); componentRef.instance.column = this.column; } else { console.warn("Could not find header formatter for column with key '" + this.column.config.key + "'."); } } }; HeaderCell.ctorParameters = function () { return [ { type: ComponentFactoryResolver }, { type: ElementRef }, { type: Renderer2 } ]; }; __decorate([ ViewChild(CellOutlet, { static: true }), __metadata("design:type", CellOutlet) ], HeaderCell.prototype, "_cellOutlet", void 0); HeaderCell = __decorate([ Component({ selector: 'header-cell', inputs: ['column: column'], template: "\n <ng-container cellOutlet></ng-container>\n ", host: { 'class': 'am-header-cell', 'role': 'row', }, encapsulation: ViewEncapsulation.None }), __metadata("design:paramtypes", [ComponentFactoryResolver, ElementRef, Renderer2]) ], HeaderCell); return HeaderCell; }()); var HeaderRow = /** @class */ (function () { function HeaderRow(_changeDetectorRef) { this._changeDetectorRef = _changeDetectorRef; this.events$ = new EventEmitter(); } HeaderRow.prototype.ngAfterContentInit = function () { var _this = this; // first we clear the row container this._rowOutlet.viewContainer.clear(); // then render each column this.model.columns.forEach(function (column, index) { _this.renderHeaderCell(column); }); }; HeaderRow.prototype.renderHeaderCell = function (column, index) { this._rowOutlet.viewContainer.createEmbeddedView(this._headerCellDef.templateRef, { $implicit: column }, index); }; HeaderRow.prototype.clearCells = function () { this._rowOutlet.viewContainer.clear(); }; /** * Iterate the changes and apply add/remove/insert operations to the collection of header cells (columns) * @todo - can still do the TODO one for moving a column (look at material2 data table sort for an example * */ HeaderRow.prototype.applyColumnChanges = function (changes) { var _this = this; if (!changes) { return; } // remove changes.forEachRemovedItem(function (record) { //console.log("removing existing cell", record); _this._rowOutlet.viewContainer.remove(record.previousIndex); _this.events$.emit({ type: GridEventType.ColumnRemoved, data: record }); }); // add, insert changes.forEachAddedItem(function (record) { //console.log("adding/inserting new cell for new column", record); _this.renderHeaderCell(record.item, record.currentIndex); _this.events$.emit({ type: GridEventType.ColumnAdded, data: record }); }); // then tell Angular to do it's checks this._changeDetectorRef.markForCheck(); }; HeaderRow.ctorParameters = function () { return [ { type: ChangeDetectorRef } ]; }; __decorate([ Output('events'), __metadata("design:type", Object) ], HeaderRow.prototype, "events$", void 0); __decorate([ ViewChild(RowOutlet, { static: true }), __metadata("design:type", RowOutlet) ], HeaderRow.prototype, "_rowOutlet", void 0); __decorate([ ViewChild(HeaderCellDef, { static: true }), __metadata("design:type", HeaderCellDef) ], HeaderRow.prototype, "_headerCellDef", void 0); __decorate([ ViewChildren(HeaderCell), __metadata("design:type", QueryList) ], HeaderRow.prototype, "headerCells", void 0); HeaderRow = __decorate([ Component({ selector: 'header-row', inputs: ['model: model'], template: "\n <div *ngIf=\"model.config.showExpander\" class=\"am-header-expander-column\"></div>\n <ng-container rowOutlet></ng-container>\n <ng-container>\n <header-cell *headerCellDef=\"let column;\" [column]=\"column\"></header-cell>\n <!--<header-cell *headerCellDef=\"let column as column;\" [column]=\"column\"></header-cell>-->\n </ng-container>\n ", host: { 'class': 'am-header-row', 'role': 'row', }, encapsulation: ViewEncapsulation.None }), __metadata("design:paramtypes", [ChangeDetectorRef]) ], HeaderRow); return HeaderRow; }()); var DataRowDef = /** @class */ (function () { function DataRowDef(templateRef, viewContainer) { this.templateRef = templateRef; this.viewContainer = viewContainer; } DataRowDef.ctorParameters = function () { return [ { type: TemplateRef }, { type: ViewContainerRef } ]; }; DataRowDef = __decorate([ Directive({ selector: '[dataRowDef]', }), __metadata("design:paramtypes", [TemplateRef, ViewContainerRef]) ], DataRowDef); return DataRowDef; }()); var DataCellDef = /** @class */ (function () { function DataCellDef(templateRef, viewContainer) { this.templateRef = templateRef; this.viewContainer = viewContainer; } DataCellDef.ctorParameters = function () { return [ { type: TemplateRef }, { type: ViewContainerRef } ]; }; DataCellDef = __decorate([ Directive({ selector: '[dataCellDef]', }), __metadata("design:paramtypes", [TemplateRef, ViewContainerRef]) ], DataCellDef); return DataCellDef; }()); var DataCell = /** @class */ (function () { function DataCell(componentFactoryResolver, elementRef, renderer) { this.componentFactoryResolver = componentFactoryResolver; this.elementRef = elementRef; this.renderer = renderer; } DataCell.prototype.ngOnInit = function () { var _this = this; this.renderer.addClass(this.elementRef.nativeElement, "am-data-cell-" + toCssFriendly(this.column.config.key)); this.renderer.setStyle(this.elementRef.nativeElement, 'flex', this.column.styles.flex || 1); if (this.column && this.column.styles.minWidth) { this.renderer.setStyle(this.elementRef.nativeElement, 'min-width', this.column.styles.minWidth); } else if (this.column && this.column.model) { if (this.column.model.styles.minColumnWidth) { this.renderer.setStyle(this.elementRef.nativeElement, 'min-width', this.column.model.styles.minColumnWidth); } } if (this.column.styles.dataCellStyleClasses) { this.column.styles.dataCellStyleClasses.forEach(function (cls, index) { _this.renderer.addClass(_this.elementRef.nativeElement, cls); }); } }; DataCell.prototype.ngAfterContentInit = function () { this.renderCell(); }; DataCell.prototype.renderCell = function () { /////////////console.log('DataCell: row:', this.row); /////////////console.log('DataCell: column:', this.column); //console.log(`rendering: ${this.column.config.key}`); this._cellOutlet.viewContainer.clear(); if (this.column.config.dataTemplate) { this._cellOutlet.viewContainer.createEmbeddedView(this.column.config.dataTemplate, { column: this.column, row: this.row }); } else { var formatter = this.column.config.formatter; if (formatter) { var componentFactory = this.componentFactoryResolver.resolveComponentFactory(formatter); var viewContainerRef = this._cellOutlet.viewContainer; viewContainerRef.clear(); var componentRef = viewContainerRef.createComponent(componentFactory); componentRef.instance.column = this.column; componentRef.instance.row = this.row; } else { console.warn("Could not find data formatter for column with key '" + this.column.config.key + "'."); } } }; DataCell.ctorParameters = function () { return [ { type: ComponentFactoryResolver }, { type: ElementRef }, { type: Renderer2 } ]; }; __decorate([ ViewChild(CellOutlet, { static: true }), __metadata("design:type", CellOutlet) ], DataCell.prototype, "_cellOutlet", void 0); DataCell = __decorate([ Component({ selector: 'data-cell', inputs: ['column: column', 'row: row'], template: "\n <ng-container cellOutlet></ng-container>\n ", host: { 'class': 'am-data-cell', 'role': 'row', }, encapsulation: ViewEncapsulation.None }), __metadata("design:paramtypes", [ComponentFactoryResolver, ElementRef, Renderer2]) ], DataCell); return DataCell; }()); var EXPANDER_ICON_CLOSED = 'keyboard_arrow_right'; var EXPANDER_ICON_OPEN = 'keyboard_arrow_down'; var DataRow = /** @class */ (function () { function DataRow(_changeDetectorRef) { this._changeDetectorRef = _changeDetectorRef; this.events$ = new EventEmitter(); this.selected = false; this.expanderIcon = EXPANDER_ICON_CLOSED; } DataRow.prototype.rowClicked = function (event) { this.events$.emit({ type: GridEventType.RowClicked, data: this }); }; DataRow.prototype.selectRow = function () { this.row.selected = true; }; DataRow.prototype.deselectRow = function () { this.row.selected = false; }; DataRow.prototype.isSelected = function () { return this.row.selected; }; DataRow.prototype.rowClass = function () { if (this.row.model.styles.dataRowStyleResolver) { return this.row.model.styles.dataRowStyleResolver(this.row); } else { return this.row.selected ? ['default-selected-row'] : null; } }; DataRow.prototype.cellClass = function (column) { if (column.styles.dataCellStyleResolver) { return column.styles.dataCellStyleResolver(this.row, column); } else { return null; } }; DataRow.prototype.ngAfterContentInit = function () { /////////////console.log("DataRow: model:", this.row.model); /////////////console.log("DataRow: row:", this.row.data); var _this = this; // first we clear the row container this._rowOutlet.viewContainer.clear(); // then render each column this.row.model.columns.forEach(function (column, index) { _this.renderDataCell(column); }); }; DataRow.prototype.renderDataCell = function (column, index) { this._rowOutlet.viewContainer.createEmbeddedView(this._dataCellDef.templateRef, { $implicit: column, row: this.row }, index); }; /** * Iterate the changes and apply add/remove/insert operations to the collection of header cells (columns) * @todo - can still do the TODO one for moving a column (look at material2 data table sort for an example * */ DataRow.prototype.applyColumnChanges = function (changes) { var _this = this; if (!changes) { return; } // add, insert changes.forEachAddedItem(function (record) { /////////////console.log("adding/inserting new cell for new column", record); _this.renderDataCell(record.item, record.currentIndex); }); // remove changes.forEachRemovedItem(function (record) { /////////////console.log("removing existing cell", record); _this._rowOutlet.viewContainer.remove(record.previousIndex); }); // then tell Angular to do it's checks this._changeDetectorRef.markForCheck(); }; DataRow.prototype.toggleExpander = function () { this._expanderOutlet.viewContainer.clear(); if (this.row.expanded) { this.row.expanded = false; this.expanderIcon = EXPANDER_ICON_CLOSED; } else { this.row.expanded = true; this.expanderIcon = EXPANDER_ICON_OPEN; if (this.row.model.config.expanderTemplate) { this._expanderOutlet.viewContainer.createEmbeddedView(this.row.model.config.expanderTemplate, { row: this.row }); } } this.events$.emit({ type: this.row.expanded ? GridEventType.RowExpanded : GridEventType.RowContracted, data: this.row }); }; DataRow.ctorParameters = function () { return [ { type: ChangeDetectorRef } ]; }; __decorate([ Output('events'), __metadata("design:type", Object) ], DataRow.prototype, "events$", void 0); __decorate([ ViewChild(RowOutlet, { static: true }), __metadata("design:type", RowOutlet) ], DataRow.prototype, "_rowOutlet", void 0); __decorate([ ViewChild(DataCellDef, { static: true }), __metadata("design:type", DataCellDef) ], DataRow.prototype, "_dataCellDef", void 0); __decorate([ ViewChildren(DataCell), __metadata("design:type", QueryList) ], DataRow.prototype, "dataCells", void 0); __decorate([ ViewChild(ExpanderOutlet, { static: true }), __metadata("design:type", ExpanderOutlet) ], DataRow.prototype, "_expanderOutlet", void 0); DataRow = __decorate([ Component({ selector: 'data-row', inputs: ['row: row'], template: "\n <!-- \n \n Expander Status - show/hide/disable (also with a tooltip)\n Expander Type - Chevron (expand/contract), Slider (slide-in/slide-out) \n \n rowDataFormatter {\n span: [\n ['firstName','lastName'] \n ]\n \n colSpan: ['firstName','lastName']\n }\n \n GridColumn\n StackedGridColumn\n \n \n \n emit({\n type: RowExpanded / RowContracted,\n data: record\n })\n \n emit({\n type: RowAdded, RowRemoved\n data: record\n })\n \n \n I would also like the ability \n \n [ wildcard search ] - across all columns \n --------------------------------------------------------------------- \n | | First Name | Mobile | Birth Date |\n | | Surname | Email | Age |\n ---------------------------------------------------------------------\n ===================================================================== \n [F]: | [ First Name ] | [ Mobile ] | [DATE-FORM] [DATE-TO] |\n [ Last Name ] | [ Email ] | |\n =====================================================================\n | Manie | Coetzee | 77/05/05 |\n > | Coetzee | mc@bla.com | 40 |\n ---------------------------------------------------------------------\n | | 13 Pioneer Road |\n | [ADDRESS] | Durbanville |\n | | 7550 |\n ---------------------------------------------------------------------\n EXPANDER\n =====================================================================\n =====================================================================\n -->\n\n <div style=\"flex: 1 1 auto; cursor: pointer;\" [ngClass]=\"rowClass()\" (click)=\"rowClicked($event)\">\n <div style=\"display: flex; flex: 1 1 auto;\" [ngClass]=\"{'am-expanded-row': row.expanded && !rowClass()}\">\n <div *ngIf=\"row.model.config.showExpander\" class=\"am-header-expander-column\">\n <mat-icon (click)=\"toggleExpander()\">{{expanderIcon}}</mat-icon>\n </div>\n <ng-container rowOutlet></ng-container>\n </div>\n <div style=\"flex: 1 1 auto;\" [ngClass]=\"{'am-expander-row': row.expanded}\">\n <ng-container expanderOutlet></ng-container>\n </div>\n </div>\n <ng-container>\n <data-cell *dataCellDef=\"let column; \" [column]=\"column\" [row]=\"row\" [ngClass]=\"cellClass(column)\"></data-cell>\n </ng-container>\n ", host: { 'class': 'am-data-row', 'role': 'row', }, encapsulation: ViewEncapsulation.None }), __metadata("design:paramtypes", [ChangeDetectorRef]) ], DataRow); return DataRow; }()); //=====[ GRID COMPONENT ]============================================================================================================================= var GridComponent = /** @class */ (function () { function GridComponent(_differs, _changeDetectorRef) { this._differs = _differs; this._changeDetectorRef = _changeDetectorRef; this.events$ = new EventEmitter(); this.data = []; this.onDestroy = new Subject(); this.viewChange = new BehaviorSubject({ start: 0, end: Number.MAX_VALUE }); this.gridDefaults = new GridDefaults(); } Object.defineProperty(GridComponent.prototype, "dataSource", { get: function () { return this._dataSource; }, set: function (dataSource) { if (this._dataSource !== dataSource) { this.switchDataSource(dataSource); } }, enumerable: true, configurable: true }); GridComponent.prototype.toggleRowExpander = function (index) { try { this.dataRows.toArray()[index].toggleExpander(); } catch (error) { console.log(error); } }; GridComponent.prototype.emit = function (event) { var _this = this; if (event.type == GridEventType.RowClicked) { this.events$.emit(event); var clickedDataRow_1 = event.data; var isCurrentselected_1 = false; this.dataRows.forEach(function (dataRow) { if (dataRow.isSelected()) { if (dataRow == clickedDataRow_1) { isCurrentselected_1 = true; } // first we deselect it dataRow.deselectRow(); // then we notify _this.events$.emit({ type: GridEventType.RowDeselected, data: dataRow }); } }); if (!isCurrentselected_1) { clickedDataRow_1.selectRow(); this.events$.emit({ type: GridEventType.RowSelected, data: clickedDataRow_1 }); } } //console.log(`Grid Event ${GridEventType[event.type]}:`, event); this.events$.emit(event); }; GridComponent.prototype.ngOnInit = function () { // create the columns differ to track changes to the column array this.columnsDiffer = this._differs.find(this.model.columns).create(); this.dataDiffer = this._differs.find([]).create(); this.model.grid = this; }; GridComponent.prototype.ngAfterContentInit = function () { // make sure that all the column override/default templates/formatters are applied this.gridDefaults.applyDefaults(this.model.columns); // do the initial diff so that the next one will show any changes when doing the next diff this.columnsDiffer.diff(this.model.columns); // ok, lets setup/render the header row this.setupHeader(); this.observeModel(); this.observeDataSource(); }; GridComponent.prototype.ngAfterContentChecked = function () { }; GridComponent.prototype.ngAfterViewInit = function () { //this.toggleRowExpander(this.model.config.expandRowIndex); //console.log("GridComponent: ngAfterViewInit"); //this.model.grid = this; this.emit({ type: GridEventType.Initialized, data: this.model }); }; GridComponent.prototype.ngAfterViewChecked = function () { //this.toggleRowExpander(this.model.config.expandRowIndex); this._changeDetectorRef.detectChanges(); }; GridComponent.prototype.ngOnChanges = function (changes) { //console.log("GridComponent: ngOnChanges", this.model); }; GridComponent.prototype.ngOnDestroy = function () { this.onDestroy.next(); this.onDestroy.complete(); if (this.dataSource) { this.dataSource.disconnect(this); } // clean up the subscription to the grid model when we are destroyed if (this.modelSubscription) { this.modelSubscription.unsubscribe(); this.modelSubscription = null; } }; GridComponent.prototype.setupHeader = function () { // lets clear the row outlet container to make sure everything is squeeky clean this._headerRowOutlet.viewContainer.clear(); // render the template that contains the header row component this._headerRowOutlet.viewContainer.createEmbeddedView(this._headerRowDef.templateRef, { $implicit: this.model }); }; GridComponent.prototype.gridModelChanged = function (event) { // always apply defaults (default data and header formatter if none specified) this.gridDefaults.applyDefaults(this.model.columns); // first we do the diff to get the changes (if any) var changes = this.columnsDiffer.diff(this.model.columns); //@todo - need a way to update columns - could basically just add /*if (event && event.type == GridModelEventType.UPDATE){ // if this is an update this.columnsDiffer.diff([]); changes = this.columnsDiffer.diff(this.model.columns); this.headerRow.clearCells(); }*/ // tell header row to look at the changes to insert/update/remove where required this.headerRow.applyColumnChanges(changes); this.dataRows.forEach(function (dataRow, index) { dataRow.applyColumnChanges(changes); }); // make sure that our component is checked for any other changes this._changeDetectorRef.markForCheck(); }; GridComponent.prototype.dataSourceDataChanged = function () { var _this = this; var changes = this.dataDiffer.diff(this.data); if (!changes) { return; } // remove changes.forEachRemovedItem(function (record) { //console.log("removing existing row", record); _this._dataRowOutlet.viewContainer.remove(record.previousIndex); _this.emit({ type: GridEventType.RowRemoved, data: record }); }); // add, insert changes.forEachAddedItem(function (record) { //console.log("adding/inserting new row", record); var rowContext = { data: record.item, model: _this.model, expanded: false }; _this._dataRowOutlet.viewContainer.createEmbeddedView(_this._dataRowDef.templateRef, { $implicit: rowContext }, record.currentIndex); _this.emit({ type: GridEventType.RowAdded, data: record }); }); //@Todo - not the right place - just a temporary work around this.emit({ type: GridEventType.Reloaded, data: this.data }); // we need to wait one tick for the rows to be rendered before trying to toggle them setTimeout(function () { // we just want to do this once. We can always call the toggleExpander manually but you would have to do it after the data has been loaded if (_this.model.config.expandRowIndex > -1) { _this.toggleRowExpander(_this.model.config.expandRowIndex); _this.model.config.expandRowIndex = -1; } }, 0); // then tell Angular to do it's checks this._changeDetectorRef.markForCheck(); }; GridComponent.prototype.switchDataSource = function (dataSource) { this.data = []; if (this._dataSource) { this._dataSource.disconnect(this); } // Stop listening for data from the previous data source. if (this.dataSubscription) { this.dataSubscription.unsubscribe(); this.dataSubscription = null; } this._dataSource = dataSource; }; GridComponent.prototype.observeModel = function () { var _this = this; this.modelSubscription = this.model._changes.subscribe(function (event) { _this.gridModelChanged(event); }); }; GridComponent.prototype.observeDataSource = function () { var _this = this; if (this.dataSource && !this.dataSubscription) { this.dataSubscription = takeUntil.call(this.dataSource.connect(this), this.onDestroy).subscribe(function (data) { _this.data = data; _this.dataSourceDataChanged(); }); } }; GridComponent.ctorParameters = function () { return [ { type: IterableDiffers }, { type: ChangeDetectorRef } ]; }; __decorate([ Output('events'), __metadata("design:type", Object) ], GridComponent.prototype, "events$", void 0); __decorate([ Input(), __metadata("design:type", GridModel) ], GridComponent.prototype, "model", void 0); __decorate([ Input(), __metadata("design:type", DataSource), __metadata("design:paramtypes", [DataSource]) ], GridComponent.prototype, "dataSource", null); __decorate([ ViewChild(HeaderRowOutlet, { static: true }), __metadata("design:type", HeaderRowOutlet) ], GridComponent.prototype, "_headerRowOutlet", void 0); __decorate([ ViewChild(HeaderRowDef, { static: true }), __metadata("design:type", HeaderRowDef) ], GridComponent.prototype, "_headerRowDef", void 0); __decorate([ ViewChild('headerRow', { static: true }), __metadata("design:type", TemplateRef) ], GridComponent.prototype, "headerRowTemplate", void 0); __decorate([ ViewChild(HeaderRow, { static: false }), __metadata("design:type", HeaderRow) ], GridComponent.prototype, "headerRow", void 0); __decorate([ ViewChild(DataRowOutlet, { static: true }), __metadata("design:type", DataRowOutlet) ], GridComponent.prototype, "_dataRowOutlet", void 0); __decorate([ ViewChild(DataRowDef, { static: true }), __metadata("design:type", DataRowDef) ], GridComponent.prototype, "_dataRowDef", void 0); __decorate([ ViewChildren(DataRow), __metadata("design:type", QueryList) ], GridComponent.prototype, "dataRows", void 0); GridComponent = __decorate([ Component({ selector: 'am-data-grid', template: "\n <div class=\"am-grid\">\n <ng-container headerRowOutlet></ng-container>\n <ng-container dataRowOutlet></ng-container>\n <ng-container>\n <header-row *headerRowDef=\"let model\" [model]=\"model\" (events)=\"emit($event)\"></header-row>\n <data-row *dataRowDef=\"let row\" [row]=\"row\" (events)=\"emit($event)\"></data-row>\n </ng-container>\n </div>\n ", encapsulation: ViewEncapsulation.None }), __metadata("design:paramtypes", [IterableDiffers, ChangeDetectorRef]) ], GridComponent); return GridComponent; }()); var GridEventType; (function (GridEventType) { GridEventType[GridEventType["RowExpanded"] = 0] = "RowExpanded"; GridEventType[GridEventType["RowContracted"] = 1] = "RowContracted"; GridEventType[GridEventType["RowRemoved"] = 2] = "RowRemoved"; GridEventType[GridEventType["RowAdded"] = 3] = "RowAdded"; GridEventType[GridEventType["Reloaded"] = 4] = "Reloaded"; GridEventType[GridEventType["ColumnRemoved"] = 5] = "ColumnRemoved"; GridEventType[GridEventType["ColumnAdded"] = 6] = "ColumnAdded"; GridEventType[GridEventType["DataChange"] = 7] = "DataChange"; GridEventType[GridEventType["Initialized"] = 8] = "Initialized"; GridEventType[GridEventType["RowClicked"] = 9] = "RowClicked"; GridEventType[GridEventType["RowSelected"] = 10] = "RowSelected"; GridEventType[GridEventType["RowDeselected"] = 11] = "RowDeselected"; })(GridEventType || (GridEventType = {})); var GridModelEventType; (function (GridModelEventType) { GridModelEventType[GridModelEventType["ADD"] = 0] = "ADD"; GridModelEventType[GridModelEventType["REMOVE"] = 1] = "REMOVE"; GridModelEventType[GridModelEventType["UPDATE"] = 2] = "UPDATE"; })(GridModelEventType || (GridModelEventType = {})); var GridModel = /** @class */ (function () { function GridModel(config, styles) { if (styles === void 0) { styles = {}; } this.columns = []; this._changes = new Subject(); this.config = { selection: !isNil(config.selection) ? config.selection : false, showExpander: !isNil(config.showExpander) ? config.showExpander : false, expanderFormatter: !isNil(config.expanderFormatter) ? config.expanderFormatter : null, expanderTemplate: !isNil(config.expanderTemplate) ? config.expanderTemplate : null, expandRowIndex: config.expandRowIndex }; this.styles = { containerClasses: !isNil(styles.containerClasses) ? styles.containerClasses : [], gridClasses: !isNil(styles.containerClasses) ? styles.containerClasses : [], scrollX: !isNil(styles.scrollX) ? styles.scrollX : false, minColumnWidth: !isNil(styles.minColumnWidth) ? styles.minColumnWidth : null, dataRowStyleResolver: styles.dataRowStyleResolver || null }; } GridModel.prototype.toggleExpander = function (index) { this.grid.toggleRowExpander(index); }; GridModel.prototype.addColumn = function (column) { column.model = this; this.columns.push(column); this.notifyChanges(GridModelEventType.ADD); }; GridModel.prototype.getColumnByKey = function (key) { return find(this.columns, { config: { key: key } }); }; GridModel.prototype.insertColumn = function (column, index) { //column.model = this; this.columns.splice(index, 0, column); this.notifyChanges(GridModelEventType.ADD); }; GridModel.prototype.removeColumn = function (column) { this.columns = without(this.columns, column); this.notifyChanges(GridModelEventType.REMOVE); }; GridModel.prototype.removeColumnByIndex = function (index) { this.columns.splice(index, 1); this.notifyChanges(GridModelEventType.REMOVE); }; GridModel.prototype.removeColumnsByKey = function (key) { remove(this.columns, function (column) { return column.config.key == key; }); this.notifyChanges(GridModelEventType.REMOVE); }; GridModel.prototype.updateStyles = function () { this.notifyChanges(GridModelEventType.UPDATE, null); }; GridModel.prototype.updateColumn = function (column) { var index = this.columns.indexOf(column); if (index > -1) { this.columns[index] = column; } this.notifyChanges(GridModelEventType.UPDATE, column); }; GridModel.prototype.removeAll = function () { this.columns = []; this.notifyChanges(GridModelEventType.REMOVE); }; GridModel.prototype.notifyChanges = function (type, column) { this._changes.next({ type: type, column: column, columns: this.columns }); }; return GridModel; }()); var GridColumn = /** @class */ (function () { function GridColumn(config, styles, options) { var _this = this; if (styles === void 0) { styles = {}; } if (options === void 0) { options = {}; } this.refresh = false; this.config = { key: config.key, type: config.type || 'text', heading: config.heading, sortable: !isNil(config.sortable) ? config.sortable : false, noHeading: config.noHeading, headingFormatter: config.headingFormatter || GridKeyHeaderFormatter, formatter: config.formatter, context: config.context || {}, headingTemplate: config.headingTemplate, dataTemplate: config.dataTemplate }; this.styles = { headerCellStyleClasses: !isNil(styles.headerCellStyleClasses) ? styles.headerCellStyleClasses : [], filterCellStyleClasses: !isNil(styles.filterCellStyleClasses) ? styles.filterCellStyleClasses : [], dataCellStyleClasses: !isNil(styles.dataCellStyleClasses) ? styles.dataCellStyleClasses : [], flex: !isNil(styles.flex) ? styles.flex : 1, minWidth: !isNil(styles.minWidth) ? styles.minWidth : null, maxWidth: !isNil(styles.maxWidth) ? styles.maxWidth : null, dataCellStyleResolver: styles.dataCellStyleResolver || null }; if (!this.config.heading && !this.config.noHeading) { var tempHeading = this.config.key; this.config.heading = ''; tempHeading.split('.').forEach(function (name, index) { _this.config.heading += startCase(name) + ' '; }); } this.options = options; } return GridColumn; }()); var GridPropertyFormatter = /** @class */ (function () { function GridPropertyFormatter() { } GridPropertyFormatter.prototype.getValue = function () { return get(this.row.data, this.column.config.key); /* try { return eval(`this.row.data.${this.column.config.key}`); } catch (error){ return null; } */ }; __decorate([ Input(), __metadata("design:type", GridColumn) ], GridPropertyFormatter.prototype, "column", void 0); __decorate([ Input(), __metadata("design:type", Object) ], GridPropertyFormatter.prototype, "row", void 0); GridPropertyFormatter = __decorate([ Component({ template: "{{getValue()}}" }) ], GridPropertyFormatter); return GridPropertyFormatter; }()); var GridDateFormatter = /** @class */ (function (_super) { __extends(GridDateFormatter, _super); function GridDateFormatter(gridDateFormat) { var _this = _super.call(this) || this; _this.gridDateFormat = gridDateFormat; //console.log("=======================***> ", this.gridDateFormat); if (!gridDateFormat) { //console.log("DHO!!@ ", this.gridDateFormat); _this.gridDateFormat = { format: 'fullDate' }; } return _this; } GridDateFormatter.prototype.getFormat = function () { return this.column.options.dateFormat || this.gridDateFormat.format; }; GridDateFormatter.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [AM_GRID_DATE_FORMAT,] }] } ]; }; __decorate([ Input(), __metadata("design:type", GridColumn) ], GridDateFormatter.prototype, "column", void 0); __decorate([ Input(), __metadata("design:type", Object) ], GridDateFormatter.prototype, "row", void 0); GridDateFormatter = __decorate([ Component({ template: "{{getValue() || '' | date : getFormat()}}" }), __param(0, Optional()), __param(0, Inject(AM_GRID_DATE_FORMAT)), __metadata("design:paramtypes", [Object]) ], GridDateFormatter); return GridDateFormatter; }(GridPropertyFormatter)); var GridKeyHeaderFormatter = /** @class */ (function () { function GridKeyHeaderFormatter() { } __decorate([ Input(), __metadata("design:type", GridColumn) ], GridKeyHeaderFormatter.prototype, "column", void 0); GridKeyHeaderFormatter = __decorate([ Component({ template: "{{column.config.heading}}" }) ], GridKeyHeaderFormatter); return GridKeyHeaderFormatter; }()); //=====[ GRID DEFAULTS ]============================================================================================================================== var GridDefaults = /** @class */ (function () { function GridDefaults() { this.columns = new Map(); var dateCol = new GridColumn({ type: 'date', key: 'date', formatter: GridDateFormatter }, {}, { //dateFormat: 'fullDate' }); var textCol = new GridColumn({ type: 'text', key: 'text', formatter: GridPropertyFormatter }); this.setDefaultColumn(dateCol.config.type, dateCol); this.setDefaultColumn(textCol.config.type, textCol); } GridDefaults.prototype.setDefaultColumn = function (type, column) { this.columns.set(type, column); }; GridDefaults.prototype.getDefaultColumn = function (type) { return this.columns.get(type); }; GridDefaults.prototype.applyDefaults = function (columns) { var _this = this; if (!columns || columns.length == 0) { return; } columns.forEach(function (column, index) { var defaultColumn = _this.getDefaultColumn(column.config.type); if (defaultColumn) { defaultsDeep(column, defaultColumn); //console.log(column); } }); }; return GridDefaults; }()); var ɵ0 = AM_GRID_DATE_DEFAULT; var AmDataTableModule = /** @class */ (function () { function AmDataTableModule() { } AmDataTableModule = __decorate([ NgModule({ imports: [ CommonModule, BrowserAnimationsModule, MatIconModule, MatPaginatorModule, ], exports: [ GridComponent ], declarations: [ GridComponent, HeaderRowDef, HeaderRow, HeaderCellDef, HeaderCell, DataRowDef, DataRow, DataCellDef, DataCell, HeaderRowOutlet, DataRowOutlet, RowOutlet, ExpanderOutlet, CellOutlet, GridKeyHeaderFormatter, GridPropertyFormatter, GridDateFormatter ], entryComponents: [ GridKeyHeaderFormatter, GridPropertyFormatter, GridDateFormatter ], providers: [ { provide: AM_GRID_DATE_FORMAT, useValue: ɵ0 } ] }) ], AmDataTableModule); return AmDataTableModule; }()); var ArrayDS = /** @class */ (function (_super) { __extends(ArrayDS, _super); function ArrayDS(paginator) { var _this = _super.call(this) || this; _this.paginator = paginator; _this.itemSource$ = new BehaviorSubject([]); _this.items = []; _this.pageSize = 5; _this.pageIndex = 0; _this.totalSize = 0; if (_this.paginator) { _this.paginator.page.subscribe(function (event) { _this.pageSize = event.pageSize; _this.pageIndex = event.pageIndex; _this.reload(); }); } return _this; } ArrayDS.prototype.connect = function () { return this.itemSource$.asObservable(); }; ArrayDS.prototype.disconnect = function () { }; ArrayDS.prototype.reload = function () { this.totalSize = this.items.length; var pages = chunk(this.items, this.pageSize); this.itemSource$.next(pages[this.pageIndex]); }; ArrayDS.prototype.addAll = function (items) { this.items = this.items.concat(items); this.reload(); }; ArrayDS.prototype.addItem = function (item) { this.items.push(item); this.reload(); }; ArrayDS.prototype.insertItem = function (item, index) { this.items.splice(index, 0, item); this.reload(); }; ArrayDS.prototype.removeColumn = function (item) { this.items = without(this.items, item); this.reload(); }; ArrayDS.prototype.removeItemByIndex = function (index) { this.items.splice(index, 1); this.reload(); }; ArrayDS.prototype.removeAll = funct