UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

694 lines 90.9 kB
import { __decorate, __extends, __metadata, __read, __spread, __values } from "tslib"; import { ChangeDetectionStrategy, Component, HostBinding, Input, Output, EventEmitter, forwardRef, TemplateRef, ContentChild, ViewChild } from '@angular/core'; import { IgxTreeGridAPIService } from './tree-grid-api.service'; import { IgxGridBaseDirective } from '../grid-base.directive'; import { GridBaseAPIService } from '../api.service'; import { TransactionType } from '../../services/transaction/transaction'; import { IgxFilteringService } from '../filtering/grid-filtering.service'; import { IgxTreeGridNavigationService } from './tree-grid-navigation.service'; import { IgxGridSummaryService } from '../summaries/grid-summary.service'; import { IgxGridSelectionService, IgxGridCRUDService } from '../selection/selection.service'; import { mergeObjects } from '../../core/utils'; import { first, takeUntil } from 'rxjs/operators'; import { IgxRowLoadingIndicatorTemplateDirective } from './tree-grid.directives'; import { IgxForOfSyncService, IgxForOfScrollSyncService } from '../../directives/for-of/for_of.sync.service'; import { IgxGridNavigationService } from '../grid-navigation.service'; import { IgxRowIslandAPIService } from '../hierarchical-grid/row-island-api.service'; var NEXT_ID = 0; /** * **Ignite UI for Angular Tree Grid** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid.html) * * The Ignite UI Tree Grid displays and manipulates hierarchical data with consistent schema formatted as a table and * provides features such as sorting, filtering, editing, column pinning, paging, column moving and hiding. * * Example: * ```html * <igx-tree-grid [data]="employeeData" primaryKey="employeeID" foreignKey="PID" autoGenerate="false"> * <igx-column field="first" header="First Name"></igx-column> * <igx-column field="last" header="Last Name"></igx-column> * <igx-column field="role" header="Role"></igx-column> * </igx-tree-grid> * ``` */ var IgxTreeGridComponent = /** @class */ (function (_super) { __extends(IgxTreeGridComponent, _super); function IgxTreeGridComponent() { var _this = _super !== null && _super.apply(this, arguments) || this; _this._id = "igx-tree-grid-" + NEXT_ID++; /** * Returns a map of all `ITreeGridRecord`s. * ```typescript * // gets the record with primaryKey=2 * const states = this.grid.records.get(2); * ``` * @memberof IgxTreeGridComponent */ _this.records = new Map(); /** * Returns a map of all processed (filtered and sorted) `ITreeGridRecord`s. * ```typescript * // gets the processed record with primaryKey=2 * const states = this.grid.processedRecords.get(2); * ``` * @memberof IgxTreeGridComponent */ _this.processedRecords = new Map(); /** * An @Input property indicating whether child records should be deleted when their parent gets deleted. * By default it is set to true and deletes all children along with the parent. * ```html * <igx-tree-grid [data]="employeeData" [primaryKey]="'employeeID'" [foreignKey]="'parentID'" cascadeOnDelete="false"> * </igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ _this.cascadeOnDelete = true; _this._expansionDepth = Infinity; _this._expansionStates = new Map(); /** *@hidden */ _this.expansionStatesChange = new EventEmitter(); /** * Emitted when the expanded state of a row gets changed. * ```typescript * rowToggle(event: IRowToggleEventArgs){ * // the id of the row * const rowID = event.rowID; * // the new expansion state * const newExpandedState = event.expanded; * // the original event that triggered onRowToggle * const originalEvent = event.event; * // whether the event should be cancelled * event.cancel = true; * } * ``` * ```html * <igx-tree-grid [data]="employeeData" (onRowToggle)="rowToggle($event)" [autoGenerate]="true"></igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ _this.onRowToggle = new EventEmitter(); /** * @hidden */ _this.loadingRows = new Set(); _this._filteredData = null; return _this; } IgxTreeGridComponent_1 = IgxTreeGridComponent; Object.defineProperty(IgxTreeGridComponent.prototype, "id", { /** * An @Input property that sets the value of the `id` attribute. If not provided it will be automatically generated. * ```html * <igx-tree-grid [id]="'igx-tree-grid-1'"></igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ get: function () { return this._id; }, set: function (value) { this._id = value; }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "data", { /** * An @Input property that lets you fill the `IgxTreeGridComponent` with an array of data. * ```html * <igx-tree-grid [data]="Data" [autoGenerate]="true"></igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ get: function () { return this._data; }, set: function (value) { this._data = value || []; this.summaryService.clearSummaryCache(); if (this.shouldGenerate) { this.setupColumns(); } this.cdr.markForCheck(); }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "filteredData", { /** * Returns an array of objects containing the filtered data in the `IgxGridComponent`. * ```typescript * let filteredData = this.grid.filteredData; * ``` * @memberof IgxTreeGridComponent */ get: function () { return this._filteredData; }, /** * Sets an array of objects containing the filtered data in the `IgxGridComponent`. * ```typescript * this.grid.filteredData = [{ * ID: 1, * Name: "A" * }]; * ``` * @memberof IgxTreeGridComponent */ set: function (value) { this._filteredData = value; }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "transactions", { /** * Get transactions service for the grid. * @experimental @hidden */ get: function () { return this._transactions; }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "expansionDepth", { /** * An @Input property that sets the count of levels to be expanded in the `IgxTreeGridComponent`. By default it is * set to `Infinity` which means all levels would be expanded. * ```html * <igx-tree-grid #grid [data]="employeeData" [childDataKey]="'employees'" expansionDepth="1" [autoGenerate]="true"></igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ get: function () { return this._expansionDepth; }, set: function (value) { this._expansionDepth = value; this.notifyChanges(); }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "expansionStates", { /** * Returns a list of key-value pairs [row ID, expansion state]. Includes only states that differ from the default one. * ```typescript * const expansionStates = this.grid.expansionStates; * ``` * @memberof IgxTreeGridComponent */ get: function () { return this._expansionStates; }, /** * Sets a list of key-value pairs [row ID, expansion state]. * ```typescript * const states = new Map<any, boolean>(); * states.set(1, true); * this.grid.expansionStates = states; * ``` * * Two-way data binding. * ```html * <igx-tree-grid #grid [data]="employeeData" [childDataKey]="'employees'" [(expansionStates)]="model.expansionStates"> * </igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ set: function (value) { this._expansionStates = this.cloneMap(value); this.expansionStatesChange.emit(this._expansionStates); if (this.gridAPI.grid) { this.cdr.detectChanges(); } }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "rowLoadingIndicatorTemplate", { /** * An @Input property that provides a template for the row loading indicator when load on demand is enabled. * ```html * <ng-template #rowLoadingTemplate> * <igx-icon fontSet="material">loop</igx-icon> * </ng-template> * * <igx-tree-grid #grid [data]="employeeData" [primaryKey]="'ID'" [foreignKey]="'parentID'" * [loadChildrenOnDemand]="loadChildren" * [rowLoadingIndicatorTemplate]="rowLoadingTemplate"> * </igx-tree-grid> * ``` * @memberof IgxTreeGridComponent */ get: function () { return this._rowLoadingIndicatorTemplate; }, set: function (value) { this._rowLoadingIndicatorTemplate = value; this.notifyChanges(); }, enumerable: true, configurable: true }); Object.defineProperty(IgxTreeGridComponent.prototype, "_gridAPI", { // Kind of stupid get: function () { return this.gridAPI; }, enumerable: true, configurable: true }); /** * @hidden */ IgxTreeGridComponent.prototype.ngOnInit = function () { var _this = this; _super.prototype.ngOnInit.call(this); this.onRowToggle.pipe(takeUntil(this.destroy$)).subscribe(function (args) { _this.loadChildrenOnRowExpansion(args); }); }; IgxTreeGridComponent.prototype.ngDoCheck = function () { _super.prototype.ngDoCheck.call(this); }; /** * @hidden */ IgxTreeGridComponent.prototype.ngAfterContentInit = function () { if (this.rowLoadingTemplate) { this._rowLoadingIndicatorTemplate = this.rowLoadingTemplate.template; } _super.prototype.ngAfterContentInit.call(this); }; IgxTreeGridComponent.prototype.loadChildrenOnRowExpansion = function (args) { var _this = this; if (this.loadChildrenOnDemand) { var parentID_1 = args.rowID; if (args.expanded && !this._expansionStates.has(parentID_1)) { this.loadingRows.add(parentID_1); this.loadChildrenOnDemand(parentID_1, function (children) { _this.loadingRows.delete(parentID_1); _this.addChildRows(children, parentID_1); _this.notifyChanges(); requestAnimationFrame(function () { var cellID = _this.selectionService.activeElement; if (cellID) { var cell = _this._gridAPI.get_cell_by_index(cellID.row, cellID.column); if (cell) { cell.nativeElement.focus(); } } }); }); } } }; IgxTreeGridComponent.prototype.addChildRows = function (children, parentID) { var e_1, _a, _b; var _this = this; if (this.primaryKey && this.foreignKey) { try { for (var children_1 = __values(children), children_1_1 = children_1.next(); !children_1_1.done; children_1_1 = children_1.next()) { var child = children_1_1.value; child[this.foreignKey] = parentID; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (children_1_1 && !children_1_1.done && (_a = children_1.return)) _a.call(children_1); } finally { if (e_1) throw e_1.error; } } (_b = this.data).push.apply(_b, __spread(children)); } else if (this.childDataKey) { var parent_1 = this.records.get(parentID); var parentData = parent_1.data; if (this.transactions.enabled && this.transactions.getAggregatedChanges(true).length) { var path = []; while (parent_1) { path.push(parent_1.rowID); parent_1 = parent_1.parent; } var collection = this.data; var record = void 0; var _loop_1 = function (i) { var pid = path[i]; record = collection.find(function (r) { return r[_this.primaryKey] === pid; }); if (!record) { return "break"; } collection = record[this_1.childDataKey]; }; var this_1 = this; for (var i = path.length - 1; i >= 0; i--) { var state_1 = _loop_1(i); if (state_1 === "break") break; } if (record) { parentData = record; } } parentData[this.childDataKey] = children; } this.selectionService.clearHeaderCBState(); this._pipeTrigger++; }; IgxTreeGridComponent.prototype.cloneMap = function (mapIn) { var mapCloned = new Map(); mapIn.forEach(function (value, key, mapObj) { mapCloned.set(key, value); }); return mapCloned; }; /** * Expands the `IgxTreeGridRowComponent` with the specified rowID. * @param rowID The identifier of the row to be expanded. * ```typescript * this.grid.expandRow(2); * ``` * @memberof IgxTreeGridComponent */ IgxTreeGridComponent.prototype.expandRow = function (rowID) { this._gridAPI.expand_row(rowID); }; /** * Collapses the `IgxTreeGridRowComponent` with the specified rowID. * @param rowID The identifier of the row to be collapsed. * ```typescript * this.grid.collapseRow(2); * ``` * @memberof IgxTreeGridComponent */ IgxTreeGridComponent.prototype.collapseRow = function (rowID) { this._gridAPI.collapse_row(rowID); }; /** * Toggles the expansion state of the `IgxTreeGridRowComponent` with the specified rowID. * @param rowID The identifier of the row to be toggled. * ```typescript * this.grid.toggleRow(2); * ``` * @memberof IgxTreeGridComponent */ IgxTreeGridComponent.prototype.toggleRow = function (rowID) { this._gridAPI.toggle_row_expansion(rowID); }; /** * Expands all rows. * ```typescript * this.grid.expandAll(); * ``` * @memberof IgxTreeGridComponent */ IgxTreeGridComponent.prototype.expandAll = function () { this._expansionDepth = Infinity; this.expansionStates = new Map(); }; /** * Collapses all rows. * ```typescript * this.grid.collapseAll(); * ``` * @memberof IgxTreeGridComponent */ IgxTreeGridComponent.prototype.collapseAll = function () { this._expansionDepth = 0; this.expansionStates = new Map(); }; /** * Creates a new `IgxTreeGridRowComponent` with the given data. If a parentRowID is not specified, the newly created * row would be added at the root level. Otherwise, it would be added as a child of the row whose primaryKey matches * the specified parentRowID. If the parentRowID does not exist, an error would be thrown. * ```typescript * const record = { * ID: this.grid.data[this.grid1.data.length - 1].ID + 1, * Name: this.newRecord * }; * this.grid.addRow(record, 1); // Adds a new child row to the row with ID=1. * ``` * @param data * @param parentRowID * @memberof IgxTreeGridComponent */ IgxTreeGridComponent.prototype.addRow = function (data, parentRowID) { if (parentRowID !== undefined && parentRowID !== null) { _super.prototype.endEdit.call(this, true); var state = this.transactions.getState(parentRowID); // we should not allow adding of rows as child of deleted row if (state && state.type === TransactionType.DELETE) { throw Error("Cannot add child row to deleted parent row"); } var parentRecord = this.records.get(parentRowID); if (!parentRecord) { throw Error('Invalid parent row ID!'); } this.summaryService.clearSummaryCache({ rowID: parentRecord.rowID }); if (this.primaryKey && this.foreignKey) { data[this.foreignKey] = parentRowID; _super.prototype.addRow.call(this, data); } else { var parentData = parentRecord.data; var childKey = this.childDataKey; if (this.transactions.enabled) { var rowId = this.primaryKey ? data[this.primaryKey] : data; var path = []; path.push.apply(path, __spread(this.generateRowPath(parentRowID))); path.push(parentRowID); this.transactions.add({ id: rowId, path: path, newValue: data, type: TransactionType.ADD }, null); } else { if (!parentData[childKey]) { parentData[childKey] = []; } parentData[childKey].push(data); } this.onRowAdded.emit({ data: data }); this._pipeTrigger++; this.notifyChanges(); } } else { if (this.primaryKey && this.foreignKey) { var rowID = data[this.foreignKey]; this.summaryService.clearSummaryCache({ rowID: rowID }); } _super.prototype.addRow.call(this, data); } }; /** @hidden */ IgxTreeGridComponent.prototype.deleteRowById = function (rowId) { // if this is flat self-referencing data, and CascadeOnDelete is set to true // and if we have transactions we should start pending transaction. This allows // us in case of delete action to delete all child rows as single undo action this._gridAPI.deleteRowById(rowId); }; /** @hidden */ IgxTreeGridComponent.prototype.generateRowPath = function (rowId) { var path = []; var record = this.records.get(rowId); while (record.parent) { path.push(record.parent.rowID); record = record.parent; } return path.reverse(); }; /** * @hidden @internal */ IgxTreeGridComponent.prototype.getDataBasedBodyHeight = function () { return !this.flatData || (this.flatData.length < this._defaultTargetRecordNumber) ? 0 : this.defaultTargetBodyHeight; }; /** * @hidden */ IgxTreeGridComponent.prototype.scrollTo = function (row, column) { var _this = this; var delayScrolling = false; var record; if (typeof (row) !== 'number') { var rowData = row; var rowID = this._gridAPI.get_row_id(rowData); record = this.processedRecords.get(rowID); this._gridAPI.expand_path_to_record(record); if (this.paging) { var rowIndex = this.processedExpandedFlatData.indexOf(rowData); var page = Math.floor(rowIndex / this.perPage); if (this.page !== page) { delayScrolling = true; this.page = page; } } } if (delayScrolling) { this.verticalScrollContainer.onDataChanged.pipe(first()).subscribe(function () { _this.scrollDirective(_this.verticalScrollContainer, typeof (row) === 'number' ? row : _this.dataView.indexOf(record)); }); } else { this.scrollDirective(this.verticalScrollContainer, typeof (row) === 'number' ? row : this.dataView.indexOf(record)); } this.scrollToHorizontally(column); }; /** * @hidden */ IgxTreeGridComponent.prototype.getContext = function (rowData, rowIndex) { return { $implicit: rowData, index: rowIndex, templateID: this.isSummaryRow(rowData) ? 'summaryRow' : 'dataRow' }; }; /** * @inheritdoc */ IgxTreeGridComponent.prototype.getSelectedData = function (formatters, headers) { if (formatters === void 0) { formatters = false; } if (headers === void 0) { headers = false; } var source = []; var process = function (record) { if (record.summaries) { source.push(null); return; } source.push(record.data); }; this.dataView.forEach(process); return this.extractDataFromSelection(source, formatters, headers); }; Object.defineProperty(IgxTreeGridComponent.prototype, "template", { /** * @hidden */ get: function () { if (this.filteredData && this.filteredData.length === 0) { return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyFilteredGridTemplate; } if (this.isLoading && (!this.data || this.dataLength === 0)) { return this.loadingGridTemplate ? this.loadingGridTemplate : this.loadingGridDefaultTemplate; } if (this.dataLength === 0) { return this.emptyGridTemplate ? this.emptyGridTemplate : this.emptyGridDefaultTemplate; } }, enumerable: true, configurable: true }); IgxTreeGridComponent.prototype.writeToData = function (rowIndex, value) { mergeObjects(this.flatData[rowIndex], value); }; /** * @hidden */ IgxTreeGridComponent.prototype.initColumns = function (collection, cb) { if (cb === void 0) { cb = null; } if (this.hasColumnLayouts) { // invalid configuration - tree grid should not allow column layouts // remove column layouts var nonColumnLayoutColumns = this.columnList.filter(function (col) { return !col.columnLayout && !col.columnLayoutChild; }); this.columnList.reset(nonColumnLayoutColumns); } _super.prototype.initColumns.call(this, collection, cb); }; var IgxTreeGridComponent_1; __decorate([ HostBinding('attr.id'), Input(), __metadata("design:type", String), __metadata("design:paramtypes", [String]) ], IgxTreeGridComponent.prototype, "id", null); __decorate([ Input(), __metadata("design:type", Array), __metadata("design:paramtypes", [Array]) ], IgxTreeGridComponent.prototype, "data", null); __decorate([ Input(), __metadata("design:type", Object) ], IgxTreeGridComponent.prototype, "childDataKey", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxTreeGridComponent.prototype, "foreignKey", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxTreeGridComponent.prototype, "hasChildrenKey", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxTreeGridComponent.prototype, "cascadeOnDelete", void 0); __decorate([ Input(), __metadata("design:type", Number), __metadata("design:paramtypes", [Number]) ], IgxTreeGridComponent.prototype, "expansionDepth", null); __decorate([ Input(), __metadata("design:type", Object), __metadata("design:paramtypes", [Object]) ], IgxTreeGridComponent.prototype, "expansionStates", null); __decorate([ Output(), __metadata("design:type", Object) ], IgxTreeGridComponent.prototype, "expansionStatesChange", void 0); __decorate([ ContentChild(IgxRowLoadingIndicatorTemplateDirective, { read: IgxRowLoadingIndicatorTemplateDirective }), __metadata("design:type", IgxRowLoadingIndicatorTemplateDirective) ], IgxTreeGridComponent.prototype, "rowLoadingTemplate", void 0); __decorate([ Input(), __metadata("design:type", TemplateRef), __metadata("design:paramtypes", [TemplateRef]) ], IgxTreeGridComponent.prototype, "rowLoadingIndicatorTemplate", null); __decorate([ Input(), __metadata("design:type", Function) ], IgxTreeGridComponent.prototype, "loadChildrenOnDemand", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxTreeGridComponent.prototype, "onRowToggle", void 0); __decorate([ ViewChild('dragIndicatorIconBase', { read: TemplateRef, static: true }), __metadata("design:type", TemplateRef) ], IgxTreeGridComponent.prototype, "dragIndicatorIconBase", void 0); IgxTreeGridComponent = IgxTreeGridComponent_1 = __decorate([ Component({ changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: 'igx-tree-grid', template: "<igx-grid-toolbar role=\"rowgroup\" [style.flex-basis.px]='outerWidth' *ngIf=\"showToolbar\" [gridID]=\"id\"\n [displayDensity]=\"displayDensity\" #toolbar>\n</igx-grid-toolbar>\n\n<div class=\"igx-grid__thead\">\n <div class=\"igx-grid__thead-wrapper\" role=\"rowgroup\" [style.width.px]='calcWidth' #theadRow>\n <div class=\"igx-grid__tr\" [style.width.px]='calcWidth' role=\"row\">\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length <= 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-left\" [style.left.px]=\"featureColumnsWidth\"></span>\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length > 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-pinned\" [style.left.px]=\"pinnedWidth\"></span>\n <ng-container *ngIf=\"rowDraggable\">\n <div class=\"igx-grid__drag-indicator\" #headerDragContainer>\n <div style=\"visibility: hidden;\">\n <ng-container\n *ngTemplateOutlet=\"this.dragIndicatorIconTemplate ? this.dragIndicatorIconTemplate : this.dragIndicatorIconBase\">\n </ng-container>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"showRowSelectors\">\n <div class=\"igx-grid__cbx-selection\" (click)=\"onHeaderSelectorClick($event)\" #headerSelectorContainer [ngClass]=\"{\n 'igx-grid__cbx-selection--push': filteringService.isFilterRowVisible }\">\n <ng-template #headSelector\n *ngTemplateOutlet=\"\n this.headSelectorTemplate ? this.headSelectorTemplate : headSelectorBaseTemplate;\n context: { $implicit: {\n selectedCount: this.selectionService.filteredSelectedRowIds.length,\n totalCount: this.totalRowsCountAfterFilter }}\">\n </ng-template>\n </div>\n </ng-container>\n <ng-container *ngIf=\"pinnedColumns.length > 0\">\n <ng-template ngFor let-col [ngForOf]=\"pinnedColumns | igxTopLevel\">\n <igx-grid-header-group [column]=\"col\" [gridID]=\"id\" [style.min-width]=\"getHeaderGroupWidth(col)\"\n [style.flex-basis]=\"getHeaderGroupWidth(col)\"></igx-grid-header-group>\n </ng-template>\n </ng-container>\n <ng-template igxGridFor let-col [igxGridForOf]=\"unpinnedColumns | igxTopLevel\"\n [igxForScrollOrientation]=\"'horizontal'\" [igxForScrollContainer]=\"parentVirtDir\"\n [igxForContainerSize]='unpinnedWidth' [igxForTrackBy]='trackColumnChanges'\n [igxForSizePropName]=\"'calcPixelWidth'\" #hContainer>\n <igx-grid-header-group [column]=\"col\" [gridID]=\"id\" [style.min-width]=\"getHeaderGroupWidth(col)\"\n [style.flex-basis]=\"getHeaderGroupWidth(col)\"></igx-grid-header-group>\n </ng-template>\n </div>\n <igx-grid-filtering-row #filteringRow *ngIf=\"filteringService.isFilterRowVisible\"\n [column]=\"filteringService.filteredColumn\"></igx-grid-filtering-row>\n </div>\n <div class=\"igx-grid__thead-thumb\" [hidden]='!hasVerticalSroll()' [style.width.px]=\"scrollWidth\"></div>\n <div [style.display]=\"shouldOverlayLoading ? 'flex' : 'none'\" #loadingOverlay>\n <igx-circular-bar [indeterminate]=\"true\">\n </igx-circular-bar>\n </div>\n <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n</div>\n\n<div igxGridBody (keydown.control.c)=\"copyHandlerIE()\" (copy)=\"copyHandler($event)\" class=\"igx-grid__tbody\">\n <div class=\"igx-grid__tbody-content\" role=\"rowgroup\" (onDragStop)=\"selectionService.dragMode = $event\"\n (onDragScroll)=\"dragScroll($event)\" [igxGridDragSelect]=\"selectionService.dragMode\"\n [style.height.px]='calcHeight' [style.width.px]='calcWidth' #tbody (scroll)='scrollHandler($event)'\n (wheel)=\"wheelHandler()\">\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length <= 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-left\"></span>\n <span *ngIf=\"hasMovableColumns && draggedColumn && pinnedColumns.length > 0\"\n [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\" id=\"left\"\n class=\"igx-grid__scroll-on-drag-pinned\" [style.left.px]=\"pinnedWidth\"></span>\n <ng-template igxGridFor let-rowData\n [igxGridForOf]=\"data\n | treeGridTransaction:id:pipeTrigger\n | visibleColumns:hasVisibleColumns\n | treeGridHierarchizing:primaryKey:foreignKey:childDataKey:id:pipeTrigger\n | treeGridFiltering:filteringExpressionsTree:filterStrategy:advancedFilteringExpressionsTree:id:pipeTrigger\n | treeGridSorting:sortingExpressions:sortStrategy:id:pipeTrigger\n | treeGridFlattening:id:expansionDepth:expansionStates:pipeTrigger\n | treeGridPaging:page:perPage:id:pipeTrigger\n | treeGridSummary:hasSummarizedColumns:summaryCalculationMode:summaryPosition:id:pipeTrigger:summaryPipeTrigger\" let-rowIndex=\"index\"\n [igxForScrollOrientation]=\"'vertical'\" [igxForScrollContainer]='verticalScroll'\n [igxForContainerSize]='calcHeight' [igxForItemSize]=\"renderedRowHeight\" #verticalScrollContainer\n (onChunkPreload)=\"dataLoading($event)\">\n <ng-template #record_template>\n <igx-tree-grid-row [gridID]=\"id\" [index]=\"rowIndex\" [treeRow]=\"rowData\" #row>\n </igx-tree-grid-row>\n </ng-template>\n <ng-template #summary_template>\n <igx-grid-summary-row [gridID]=\"id\" [summaries]=\"rowData.summaries\"\n [firstCellIndentation]=\"rowData.cellIndentation\" [index]=\"rowIndex\"\n class=\"igx-grid__summaries--body\" #summaryRow>\n </igx-grid-summary-row>\n </ng-template>\n\n <ng-template [igxTemplateOutlet]='isSummaryRow(rowData) ? summary_template : record_template'\n [igxTemplateOutletContext]='getContext(rowData, rowIndex)'\n (onCachedViewLoaded)='cachedViewLoaded($event)'\n (onBeforeViewDetach)='viewDetachHandler($event)'>\n </ng-template>\n </ng-template>\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n <div class=\"igx-grid__row-editing-outlet\" igxOverlayOutlet #igxRowEditingOverlayOutlet></div>\n </div>\n <span *ngIf=\"hasMovableColumns && draggedColumn\" [igxColumnMovingDrop]=\"headerContainer\" [attr.droppable]=\"true\"\n id=\"right\" class=\"igx-grid__scroll-on-drag-right\"></span>\n <div [hidden]='!hasVerticalSroll()' class=\"igx-grid__tbody-scrollbar\" [style.width.px]=\"scrollWidth\"\n [style.height.px]='calcHeight'>\n <ng-template igxGridFor [igxGridForOf]='[]' #verticalScrollHolder></ng-template>\n </div>\n</div>\n\n<div class=\"igx-grid__tfoot\" role=\"rowgroup\" [style.height.px]='summariesHeight' #tfoot>\n <igx-grid-summary-row [style.width.px]='calcWidth' [style.height.px]='summariesHeight'\n *ngIf=\"hasSummarizedColumns && rootSummariesEnabled\" [gridID]=\"id\"\n [summaries]=\"id | igxGridSummaryDataPipe:summaryService.retriggerRootPipe\" [index]=\"0\"\n class=\"igx-grid__summaries\" #summaryRow>\n </igx-grid-summary-row>\n <div class=\"igx-grid__tfoot-thumb\" [hidden]='!hasVerticalSroll()' [style.height.px]='summariesHeight'\n [style.width.px]=\"scrollWidth\"></div>\n</div>\n\n<div class=\"igx-grid__scroll\" [style.height]=\"'18px'\" #scr [hidden]=\"isHorizontalScrollHidden\">\n <div class=\"igx-grid__scroll-start\" [style.width.px]='pinnedWidth' [hidden]=\"pinnedWidth === 0\"></div>\n <div class=\"igx-grid__scroll-main\" [style.width.px]='unpinnedWidth'>\n <ng-template igxGridFor [igxGridForOf]='[]' #scrollContainer>\n </ng-template>\n </div>\n</div>\n\n<div class=\"igx-grid__footer\" #footer>\n <ng-content select=\"igx-grid-footer\"></ng-content>\n <ng-container *ngIf=\"paging && totalRecords\">\n <ng-container\n *ngTemplateOutlet=\"paginationTemplate ? paginationTemplate : defaultPaginator; context: {$implicit: this}\">\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #defaultPaginator>\n <igx-paginator [displayDensity]=\"displayDensity\" [(page)]=\"page\" [totalRecords]=\"processedExpandedFlatData.length\"\n [(perPage)]=\"perPage\">\n </igx-paginator>\n</ng-template>\n\n<ng-template #emptyFilteredGrid>\n <span class=\"igx-grid__tbody-message\">{{emptyFilteredGridMessage}}</span>\n</ng-template>\n\n<ng-template #defaultEmptyGrid>\n <span class=\"igx-grid__tbody-message\">{{emptyGridMessage}}</span>\n</ng-template>\n\n<ng-template #defaultLoadingGrid>\n <div class=\"igx-grid__loading\">\n <igx-circular-bar [indeterminate]=\"true\">\n </igx-circular-bar>\n </div>\n</ng-template>\n\n<div *ngIf=\"rowEditable\" igxToggle>\n <div [className]=\"bannerClass\">\n <ng-container\n *ngTemplateOutlet=\"rowEditContainer; context: { rowChangesCount: rowChangesCount, endEdit: endEdit.bind(this) }\">\n </ng-container>\n </div>\n</div>\n\n<ng-template #defaultRowEditText>\n You have {{ rowChangesCount }} changes in this row\n</ng-template>\n\n<ng-template #defaultRowEditActions>\n <button igxButton igxRowEditTabStop (click)=\"endEdit(false, $event)\">Cancel</button>\n <button igxButton igxRowEditTabStop (click)=\"endEdit(true, $event)\">Done</button>\n</ng-template>\n\n<ng-template #defaultRowEditTemplate>\n <div class=\"igx-banner__message\">\n <span class=\"igx-banner__text\">\n <ng-container\n *ngTemplateOutlet=\"rowEditText ? rowEditText : defaultRowEditText; context: { $implicit: rowChangesCount }\">\n </ng-container>\n </span>\n </div>\n <div class=\"igx-banner__actions\">\n <div class=\"igx-banner__row\">\n <ng-container\n *ngTemplateOutlet=\"rowEditActions ? rowEditActions : defaultRowEditActions; context: { $implicit: endEdit.bind(this) }\">\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dragIndicatorIconBase>\n <igx-icon fontSet=\"material\">drag_indicator</igx-icon>\n</ng-template>\n\n<ng-template #headSelectorBaseTemplate igxHeadSelector let-context>\n <div class=\"igx-grid__cbx-padding\">\n <igx-checkbox\n [checked]=\"context.selectedCount > 0 && context.totalCount === context.selectedCount\"\n [ngStyle]=\"{'visibility': isMultiRowSelectionEnabled? 'visible' : 'hidden' }\"\n [readonly]=\"true\"\n disableRipple=\"true\"\n [indeterminate]=\"context.selectedCount > 0 && context.selectedCount !== context.totalCount\"\n [aria-label]=\"headSelectorBaseAriaLabel\"\n #headerCheckbox>\n </igx-checkbox>\n </div>\n</ng-template>\n\n<igx-grid-column-resizer *ngIf=\"colResizingService.showResizer\"></igx-grid-column-resizer>\n<div class=\"igx-grid__loading-outlet\" #igxLoadingOverlayOutlet igxOverlayOutlet></div>\n<div class=\"igx-grid__outlet\" #igxFilteringOverlayOutlet igxOverlayOutlet></div>\n", providers: [ IgxGridSelectionService, IgxGridCRUDService, IgxGridSummaryService, { provide: IgxGridNavigationService, useClass: IgxTreeGridNavigationService }, { provide: GridBaseAPIService, useClass: IgxTreeGridAPIService }, { provide: IgxGridBaseDirective, useExisting: forwardRef(function () { return IgxTreeGridComponent_1; }) }, IgxFilteringService, IgxForOfSyncService, IgxForOfScrollSyncService, IgxRowIslandAPIService ] }) ], IgxTreeGridComponent); return IgxTreeGridComponent; }(IgxGridBaseDirective)); export { IgxTreeGridComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZ3JpZHMvdHJlZS1ncmlkL3RyZWUtZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFdBQVcsRUFDWCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksRUFDWixVQUFVLEVBRVYsV0FBVyxFQUVYLFlBQVksRUFFWixTQUFTLEVBRVosTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHcEQsT0FBTyxFQUE4QyxlQUFlLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUVySCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsdUNBQXVDLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUU3RyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0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