@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
630 lines • 85.8 kB
JavaScript
var IgxTreeGridComponent_1;
import { __decorate, __metadata } 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';
let 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>
* ```
*/
let IgxTreeGridComponent = IgxTreeGridComponent_1 = class IgxTreeGridComponent extends IgxGridBaseDirective {
constructor() {
super(...arguments);
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;
}
/**
* 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 id() {
return this._id;
}
set id(value) {
this._id = value;
}
/**
* 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 data() {
return this._data;
}
set data(value) {
this._data = value || [];
this.summaryService.clearSummaryCache();
if (this.shouldGenerate) {
this.setupColumns();
}
this.cdr.markForCheck();
}
/**
* Returns an array of objects containing the filtered data in the `IgxGridComponent`.
* ```typescript
* let filteredData = this.grid.filteredData;
* ```
* @memberof IgxTreeGridComponent
*/
get filteredData() {
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 filteredData(value) {
this._filteredData = value;
}
/**
* Get transactions service for the grid.
* @experimental @hidden
*/
get transactions() {
return this._transactions;
}
/**
* 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 expansionDepth() {
return this._expansionDepth;
}
set expansionDepth(value) {
this._expansionDepth = value;
this.notifyChanges();
}
/**
* 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 expansionStates() {
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 expansionStates(value) {
this._expansionStates = this.cloneMap(value);
this.expansionStatesChange.emit(this._expansionStates);
if (this.gridAPI.grid) {
this.cdr.detectChanges();
}
}
/**
* 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 rowLoadingIndicatorTemplate() {
return this._rowLoadingIndicatorTemplate;
}
set rowLoadingIndicatorTemplate(value) {
this._rowLoadingIndicatorTemplate = value;
this.notifyChanges();
}
// Kind of stupid
get _gridAPI() {
return this.gridAPI;
}
/**
* @hidden
*/
ngOnInit() {
super.ngOnInit();
this.onRowToggle.pipe(takeUntil(this.destroy$)).subscribe((args) => {
this.loadChildrenOnRowExpansion(args);
});
}
ngDoCheck() {
super.ngDoCheck();
}
/**
* @hidden
*/
ngAfterContentInit() {
if (this.rowLoadingTemplate) {
this._rowLoadingIndicatorTemplate = this.rowLoadingTemplate.template;
}
super.ngAfterContentInit();
}
loadChildrenOnRowExpansion(args) {
if (this.loadChildrenOnDemand) {
const parentID = args.rowID;
if (args.expanded && !this._expansionStates.has(parentID)) {
this.loadingRows.add(parentID);
this.loadChildrenOnDemand(parentID, children => {
this.loadingRows.delete(parentID);
this.addChildRows(children, parentID);
this.notifyChanges();
requestAnimationFrame(() => {
const cellID = this.selectionService.activeElement;
if (cellID) {
const cell = this._gridAPI.get_cell_by_index(cellID.row, cellID.column);
if (cell) {
cell.nativeElement.focus();
}
}
});
});
}
}
}
addChildRows(children, parentID) {
if (this.primaryKey && this.foreignKey) {
for (const child of children) {
child[this.foreignKey] = parentID;
}
this.data.push(...children);
}
else if (this.childDataKey) {
let parent = this.records.get(parentID);
let parentData = parent.data;
if (this.transactions.enabled && this.transactions.getAggregatedChanges(true).length) {
const path = [];
while (parent) {
path.push(parent.rowID);
parent = parent.parent;
}
let collection = this.data;
let record;
for (let i = path.length - 1; i >= 0; i--) {
const pid = path[i];
record = collection.find(r => r[this.primaryKey] === pid);
if (!record) {
break;
}
collection = record[this.childDataKey];
}
if (record) {
parentData = record;
}
}
parentData[this.childDataKey] = children;
}
this.selectionService.clearHeaderCBState();
this._pipeTrigger++;
}
cloneMap(mapIn) {
const mapCloned = new Map();
mapIn.forEach((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
*/
expandRow(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
*/
collapseRow(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
*/
toggleRow(rowID) {
this._gridAPI.toggle_row_expansion(rowID);
}
/**
* Expands all rows.
* ```typescript
* this.grid.expandAll();
* ```
* @memberof IgxTreeGridComponent
*/
expandAll() {
this._expansionDepth = Infinity;
this.expansionStates = new Map();
}
/**
* Collapses all rows.
* ```typescript
* this.grid.collapseAll();
* ```
* @memberof IgxTreeGridComponent
*/
collapseAll() {
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
*/
addRow(data, parentRowID) {
if (parentRowID !== undefined && parentRowID !== null) {
super.endEdit(true);
const 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`);
}
const 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.addRow(data);
}
else {
const parentData = parentRecord.data;
const childKey = this.childDataKey;
if (this.transactions.enabled) {
const rowId = this.primaryKey ? data[this.primaryKey] : data;
const path = [];
path.push(...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 });
this._pipeTrigger++;
this.notifyChanges();
}
}
else {
if (this.primaryKey && this.foreignKey) {
const rowID = data[this.foreignKey];
this.summaryService.clearSummaryCache({ rowID: rowID });
}
super.addRow(data);
}
}
/** @hidden */
deleteRowById(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 */
generateRowPath(rowId) {
const path = [];
let record = this.records.get(rowId);
while (record.parent) {
path.push(record.parent.rowID);
record = record.parent;
}
return path.reverse();
}
/**
* @hidden @internal
*/
getDataBasedBodyHeight() {
return !this.flatData || (this.flatData.length < this._defaultTargetRecordNumber) ?
0 : this.defaultTargetBodyHeight;
}
/**
* @hidden
*/
scrollTo(row, column) {
let delayScrolling = false;
let record;
if (typeof (row) !== 'number') {
const rowData = row;
const rowID = this._gridAPI.get_row_id(rowData);
record = this.processedRecords.get(rowID);
this._gridAPI.expand_path_to_record(record);
if (this.paging) {
const rowIndex = this.processedExpandedFlatData.indexOf(rowData);
const page = Math.floor(rowIndex / this.perPage);
if (this.page !== page) {
delayScrolling = true;
this.page = page;
}
}
}
if (delayScrolling) {
this.verticalScrollContainer.onDataChanged.pipe(first()).subscribe(() => {
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
*/
getContext(rowData, rowIndex) {
return {
$implicit: rowData,
index: rowIndex,
templateID: this.isSummaryRow(rowData) ? 'summaryRow' : 'dataRow'
};
}
/**
* @inheritdoc
*/
getSelectedData(formatters = false, headers = false) {
const source = [];
const process = (record) => {
if (record.summaries) {
source.push(null);
return;
}
source.push(record.data);
};
this.dataView.forEach(process);
return this.extractDataFromSelection(source, formatters, headers);
}
/**
* @hidden
*/
get template() {
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;
}
}
writeToData(rowIndex, value) {
mergeObjects(this.flatData[rowIndex], value);
}
/**
* @hidden
*/
initColumns(collection, cb = null) {
if (this.hasColumnLayouts) {
// invalid configuration - tree grid should not allow column layouts
// remove column layouts
const nonColumnLayoutColumns = this.columnList.filter((col) => !col.columnLayout && !col.columnLayoutChild);
this.columnList.reset(nonColumnLayoutColumns);
}
super.initColumns(collection, cb);
}
};
__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(() => IgxTreeGridComponent_1) },
IgxFilteringService,
IgxForOfSyncService,
IgxForOfScrollSyncService,
IgxRowIslandAPIService
]
})
], IgxTreeGridComponent);
export { IgxTreeGridComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZ3JpZHMvdHJlZS1ncmlkL3RyZWUtZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQ0gsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxXQUFXLEVBQ1gsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osVUFBVSxFQUVWLFdBQVcsRUFFWCxZQUFZLEVBRVosU0FBUyxFQUVaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzlELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR3BELE9BQU8sRUFBOEMsZUFBZSxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFFckgsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDOUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDMUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDN0YsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEQsT0FBTyxFQUFFLHVDQUF1QyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLHlCQUF5QixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFFN0csT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0s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