ngm-tree-grid
Version:
A tree grid that supports editable fields like Inputs and Checkboxes.
289 lines (279 loc) • 31.6 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Directive, EventEmitter, Component, Input, Output, ViewChildren, ContentChildren, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from 'ngm-live-search';
import { NgmLiveSearchModule } from 'ngm-live-search';
class NgmTreeGridService {
constructor() { }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: function () { return []; } });
class CellHostDirective {
viewContainerRef;
constructor(viewContainerRef) {
this.viewContainerRef = viewContainerRef;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellHostDirective, deps: [{ token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: CellHostDirective, selector: "[ngmCellHost]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CellHostDirective, decorators: [{
type: Directive,
args: [{
selector: '[ngmCellHost]'
}]
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }]; } });
class TreeGridItemComponent {
/** The level of node */
level = 1;
data = [];
config = {
hasSearch: true,
columns: [],
searchFn: (obj, txt) => {
return Object.values(obj)
.filter((x) => (typeof x === 'string' || typeof x === 'number'))
.map(x => String(x))
.some((y) => y.includes(txt));
}
};
getChildrenFn = (obj) => {
return obj['children'];
};
expand = new EventEmitter();
collapse = new EventEmitter();
cellInputs;
cellPanes;
constructor() { }
openItem(item) {
item['isOpen'] = true;
this.expand.emit({
item,
level: this.level
});
}
closeItem(item) {
item['isOpen'] = false;
this.collapse.emit({
item,
level: this.level
});
}
onExpand(e) {
this.expand.emit(e);
}
onCollapse(e) {
this.collapse.emit(e);
}
ngAfterContentInit() {
setTimeout(() => {
this.cellPanes.forEach((x, i) => {
x.viewContainerRef.clear();
x.viewContainerRef.createEmbeddedView(this.cellInputs.get(i % this.cellInputs.length), {
$implicit: this.data[Math.floor(i / this.cellInputs.length)]
});
});
}, 10);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeGridItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TreeGridItemComponent, selector: "ngm-tree-grid-item", inputs: { level: "level", data: "data", config: "config", getChildrenFn: "getChildrenFn", cellInputs: "cellInputs" }, outputs: { expand: "expand", collapse: "collapse" }, viewQueries: [{ propertyName: "cellPanes", predicate: CellHostDirective, descendants: true }], ngImport: i0, template: "<ng-container>\r\n <div *ngFor=\"let item of data\">\r\n <div class=\"ngm-tree-grid-row\">\r\n <div class=\"ngm-tree-grid-items\">\r\n <div\r\n class=\"ngm-tree-grid-cell\"\r\n *ngFor=\"let column of cellInputs.toArray(); let first = first; let index = index\"\r\n [ngStyle]=\"{\r\n width: config.columns[index].width ? config.columns[index].width + '%' : 100 / (cellInputs.toArray().length) + '%'\r\n }\"\r\n >\r\n <div\r\n class=\"ngm-tree-grid-main\"\r\n *ngIf=\"first\"\r\n [ngStyle]=\"{ 'margin-left': level * 20 + 'px' }\"\r\n >\r\n <div\r\n class=\"ngm-tree-grid-main-icon arrow_up\"\r\n *ngIf=\"\r\n getChildrenFn(item) &&\r\n getChildrenFn(item).length > 0 &&\r\n item.isOpen\r\n \"\r\n (click)=\"closeItem(item)\"\r\n ></div>\r\n <div\r\n *ngIf=\"\r\n getChildrenFn(item) &&\r\n getChildrenFn(item).length > 0 &&\r\n !item.isOpen\r\n \"\r\n (click)=\"openItem(item)\"\r\n class=\"ngm-tree-grid-main-icon arrow_right\"\r\n ></div>\r\n <div\r\n *ngIf=\"!getChildrenFn(item) || getChildrenFn(item).length == 0\"\r\n class=\"ngm-tree-grid-main-icon dash\"\r\n ></div>\r\n <ng-template ngmCellHost></ng-template>\r\n <!-- </span> -->\r\n </div>\r\n <ng-template ngmCellHost *ngIf=\"!first\"></ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"getChildrenFn(item) && item.isOpen\">\r\n <ngm-tree-grid-item\r\n [data]=\"getChildrenFn(item)\"\r\n [config]=\"config\"\r\n [level]=\"level + 1\"\r\n [getChildrenFn]=\"getChildrenFn\"\r\n (expand)=\"onExpand($event)\"\r\n (collapse)=\"onCollapse($event)\"\r\n [cellInputs]=\"cellInputs\"\r\n ></ngm-tree-grid-item>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [".child{margin-left:20px}.ngm-tree-grid-row{width:100%;display:flex;justify-content:space-between;align-items:center;flex-direction:row}.ngm-tree-grid-row .ngm-tree-grid-items{width:100%;display:flex;justify-content:flex-start;align-items:center;flex-direction:row}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell{min-width:100px;padding:2px;border:1px solid rgba(0,0,0,.1215686275);display:flex;justify-content:flex-start;align-items:center;flex-direction:row;height:40px}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main{display:flex;justify-content:flex-start;align-items:center;flex-direction:row;overflow:hidden}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .ngm-tree-grid-main-icon{cursor:pointer;width:13px;height:13px}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .arrow_right{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAABcCAMAAADUMSJqAAAASFBMVEX///9RUVFDQ0PR0dFAQEBJSUmRkZFGRkaOjo7U1NT39/dOTk6bm5vBwcHKysp/f3/l5eVtbW11dXVkZGQ4ODjc3NyhoaHr6+ufeXG1AAABQUlEQVRoge2ZW27DIBREgUATP/JonLb732kt5SNJGf7OyErFLOBoNFwDHkLo6urqamocjqcfE/s75pTT+WJAj59piqtK2RnYJd417Wn6g73Sae/XB3ulJ5R+zPFZrPdliq/0DNJfjbOrOlZwMvdUwUHv10nQKe9DnQtIn0UwXDIf0js1kYcNvN8Ghn6QdLN3Knevd7mq1Mx4J1J79yZjXlVo3qX3iHnfIPc32cUknTo9tPf0xdC194WBa3o+QXSVTJkheJhLDT+/A9wZi3NBnaPY2ACQj8h5IDk3rsaWixxGDd8Iu3FEG30Xo29r3sYZTMZMmKPTedlyXnG1b2gGFTs6vx1r3gi78XuOsHWxAF08ZSVCXWqFcaxE89ZQdYEGln/W6s9aWv6pW0nfwVwUWytubzkfrM8Kwfsg0tXV9T/1CwfjDrXg523+AAAAAElFTkSuQmCC);background-size:cover}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .arrow_up{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIUAAACFCAMAAABCBMsOAAAAYFBMVEX///9RUVFLS0tOTk5ISEjo6Ojl5eXi4uJbW1vR0dFYWFjv7+9CQkLY2Njb29vs7Oz29vZycnI7OzttbW1oaGiTk5N+fn69vb2MjIzDw8OlpaV4eHhgYGAvLy+dnZ00NDQZisxwAAACwUlEQVR4nO2Z3XqqMBBFJQk/DfSAsVDbevT93/KIxFPBZGaCAW5mXUO+RbaZrbLbMQzDMAzDMAzDMEwUyq+267rjZ72hQ/MtjRJCKKPaZiuJOqmSO6r6s41EnojkFynetpDIikeJXuN9Awk5lrhqmNU1MiGTKVKtHEpeTHfipiFX1UgTl0QfyoonJa2e47BUq+1Grr0S64WSanccVmOd8QXEMWBW2A0ojtVCycA4rIZaeHylCpe4alwW1cgTLA6rsWS1TQsM0lhsNzJBlVgwFFeBARrLVJu7wACNJQ6sr8AAjfjVlqmQOCyxqy0nDCvHbsQNBS4wQCNmtaEF5ideteEFBuxGrFDmxmE14lQbFoesYMkoPxCwAhNF9qNgjderDSswobNdecA0XtwNrMBEcfvP4APReK3aMonEocvbdc0e0Xil2rACE6fMXlliGvMPLFZgQqf/r22wUOZWG1Zg9zgsyEd0ZrVhBSZO6ej6Ejuwc0LBJmZ/RMegoYRXW2qwYVU+34RoBFcbVmBCu/5bjHxS0DiKaRxWAwtFBYSCFZgzjgH0wJKnKF5gXoldE+uklKfQ0zG6G6s2mZMskKexBeYHCUUUFIm3Cl5E++MYwKrNfBIsjuAa04npAjmwsiNYgGX+WGB+kCkq8PcYjQElsDgs4EeUUK81YCEKyk70gKEQZgawF7Q47DJAKIZwVr0NAg0rB4AG4f1W67kbnRMTvKEIyhl5d88LeGI6NTy7Yb4od7cujcA4Bpwaak97BsdWhsYx4Jqi5JXqpzoLj2PgudqkJn/DaE7jm+ftxI1JKFIGPE49egbyxHQwDkVoWq3fNR6eQREKzE/58/Dqtwj9Fn406tprUqq/xxdfXp8vdqVLF76n+fmgE304B+2hk/p736/Uzvvh3tRpHeclfryVGIZhGIZhGIZhGIZhGIZhGIbOP2L7Hmn0yzsaAAAAAElFTkSuQmCC);background-size:cover}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .dash{background:url(data:image/png;base64,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);background-size:cover}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell:first-child{padding:2px 1px;width:30%}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: TreeGridItemComponent, selector: "ngm-tree-grid-item", inputs: ["level", "data", "config", "getChildrenFn", "cellInputs"], outputs: ["expand", "collapse"] }, { kind: "directive", type: CellHostDirective, selector: "[ngmCellHost]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeGridItemComponent, decorators: [{
type: Component,
args: [{ selector: 'ngm-tree-grid-item', template: "<ng-container>\r\n <div *ngFor=\"let item of data\">\r\n <div class=\"ngm-tree-grid-row\">\r\n <div class=\"ngm-tree-grid-items\">\r\n <div\r\n class=\"ngm-tree-grid-cell\"\r\n *ngFor=\"let column of cellInputs.toArray(); let first = first; let index = index\"\r\n [ngStyle]=\"{\r\n width: config.columns[index].width ? config.columns[index].width + '%' : 100 / (cellInputs.toArray().length) + '%'\r\n }\"\r\n >\r\n <div\r\n class=\"ngm-tree-grid-main\"\r\n *ngIf=\"first\"\r\n [ngStyle]=\"{ 'margin-left': level * 20 + 'px' }\"\r\n >\r\n <div\r\n class=\"ngm-tree-grid-main-icon arrow_up\"\r\n *ngIf=\"\r\n getChildrenFn(item) &&\r\n getChildrenFn(item).length > 0 &&\r\n item.isOpen\r\n \"\r\n (click)=\"closeItem(item)\"\r\n ></div>\r\n <div\r\n *ngIf=\"\r\n getChildrenFn(item) &&\r\n getChildrenFn(item).length > 0 &&\r\n !item.isOpen\r\n \"\r\n (click)=\"openItem(item)\"\r\n class=\"ngm-tree-grid-main-icon arrow_right\"\r\n ></div>\r\n <div\r\n *ngIf=\"!getChildrenFn(item) || getChildrenFn(item).length == 0\"\r\n class=\"ngm-tree-grid-main-icon dash\"\r\n ></div>\r\n <ng-template ngmCellHost></ng-template>\r\n <!-- </span> -->\r\n </div>\r\n <ng-template ngmCellHost *ngIf=\"!first\"></ng-template>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"getChildrenFn(item) && item.isOpen\">\r\n <ngm-tree-grid-item\r\n [data]=\"getChildrenFn(item)\"\r\n [config]=\"config\"\r\n [level]=\"level + 1\"\r\n [getChildrenFn]=\"getChildrenFn\"\r\n (expand)=\"onExpand($event)\"\r\n (collapse)=\"onCollapse($event)\"\r\n [cellInputs]=\"cellInputs\"\r\n ></ngm-tree-grid-item>\r\n </div>\r\n </div>\r\n</ng-container>\r\n", styles: [".child{margin-left:20px}.ngm-tree-grid-row{width:100%;display:flex;justify-content:space-between;align-items:center;flex-direction:row}.ngm-tree-grid-row .ngm-tree-grid-items{width:100%;display:flex;justify-content:flex-start;align-items:center;flex-direction:row}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell{min-width:100px;padding:2px;border:1px solid rgba(0,0,0,.1215686275);display:flex;justify-content:flex-start;align-items:center;flex-direction:row;height:40px}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main{display:flex;justify-content:flex-start;align-items:center;flex-direction:row;overflow:hidden}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .ngm-tree-grid-main-icon{cursor:pointer;width:13px;height:13px}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .arrow_right{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAABcCAMAAADUMSJqAAAASFBMVEX///9RUVFDQ0PR0dFAQEBJSUmRkZFGRkaOjo7U1NT39/dOTk6bm5vBwcHKysp/f3/l5eVtbW11dXVkZGQ4ODjc3NyhoaHr6+ufeXG1AAABQUlEQVRoge2ZW27DIBREgUATP/JonLb732kt5SNJGf7OyErFLOBoNFwDHkLo6urqamocjqcfE/s75pTT+WJAj59piqtK2RnYJd417Wn6g73Sae/XB3ulJ5R+zPFZrPdliq/0DNJfjbOrOlZwMvdUwUHv10nQKe9DnQtIn0UwXDIf0js1kYcNvN8Ghn6QdLN3Knevd7mq1Mx4J1J79yZjXlVo3qX3iHnfIPc32cUknTo9tPf0xdC194WBa3o+QXSVTJkheJhLDT+/A9wZi3NBnaPY2ACQj8h5IDk3rsaWixxGDd8Iu3FEG30Xo29r3sYZTMZMmKPTedlyXnG1b2gGFTs6vx1r3gi78XuOsHWxAF08ZSVCXWqFcaxE89ZQdYEGln/W6s9aWv6pW0nfwVwUWytubzkfrM8Kwfsg0tXV9T/1CwfjDrXg523+AAAAAElFTkSuQmCC);background-size:cover}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .arrow_up{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIUAAACFCAMAAABCBMsOAAAAYFBMVEX///9RUVFLS0tOTk5ISEjo6Ojl5eXi4uJbW1vR0dFYWFjv7+9CQkLY2Njb29vs7Oz29vZycnI7OzttbW1oaGiTk5N+fn69vb2MjIzDw8OlpaV4eHhgYGAvLy+dnZ00NDQZisxwAAACwUlEQVR4nO2Z3XqqMBBFJQk/DfSAsVDbevT93/KIxFPBZGaCAW5mXUO+RbaZrbLbMQzDMAzDMAzDMEwUyq+267rjZ72hQ/MtjRJCKKPaZiuJOqmSO6r6s41EnojkFynetpDIikeJXuN9Awk5lrhqmNU1MiGTKVKtHEpeTHfipiFX1UgTl0QfyoonJa2e47BUq+1Grr0S64WSanccVmOd8QXEMWBW2A0ojtVCycA4rIZaeHylCpe4alwW1cgTLA6rsWS1TQsM0lhsNzJBlVgwFFeBARrLVJu7wACNJQ6sr8AAjfjVlqmQOCyxqy0nDCvHbsQNBS4wQCNmtaEF5ideteEFBuxGrFDmxmE14lQbFoesYMkoPxCwAhNF9qNgjderDSswobNdecA0XtwNrMBEcfvP4APReK3aMonEocvbdc0e0Xil2rACE6fMXlliGvMPLFZgQqf/r22wUOZWG1Zg9zgsyEd0ZrVhBSZO6ej6Ejuwc0LBJmZ/RMegoYRXW2qwYVU+34RoBFcbVmBCu/5bjHxS0DiKaRxWAwtFBYSCFZgzjgH0wJKnKF5gXoldE+uklKfQ0zG6G6s2mZMskKexBeYHCUUUFIm3Cl5E++MYwKrNfBIsjuAa04npAjmwsiNYgGX+WGB+kCkq8PcYjQElsDgs4EeUUK81YCEKyk70gKEQZgawF7Q47DJAKIZwVr0NAg0rB4AG4f1W67kbnRMTvKEIyhl5d88LeGI6NTy7Yb4od7cujcA4Bpwaak97BsdWhsYx4Jqi5JXqpzoLj2PgudqkJn/DaE7jm+ftxI1JKFIGPE49egbyxHQwDkVoWq3fNR6eQREKzE/58/Dqtwj9Fn406tprUqq/xxdfXp8vdqVLF76n+fmgE304B+2hk/p736/Uzvvh3tRpHeclfryVGIZhGIZhGIZhGIZhGIZhGIbOP2L7Hmn0yzsaAAAAAElFTkSuQmCC);background-size:cover}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell .ngm-tree-grid-main .dash{background:url(data:image/png;base64,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);background-size:cover}.ngm-tree-grid-row .ngm-tree-grid-items .ngm-tree-grid-cell:first-child{padding:2px 1px;width:30%}\n"] }]
}], ctorParameters: function () { return []; }, propDecorators: { level: [{
type: Input
}], data: [{
type: Input
}], config: [{
type: Input
}], getChildrenFn: [{
type: Input
}], expand: [{
type: Output
}], collapse: [{
type: Output
}], cellInputs: [{
type: Input
}], cellPanes: [{
type: ViewChildren,
args: [CellHostDirective]
}] } });
class TreeGridComponent {
/** When user clicks on arrow to expand a row, this emitter emits an event */
expand = new EventEmitter();
/** When user clicks on arrow to collapse a row, this emitter emits an event */
collapse = new EventEmitter();
dataSource;
config = {
hasSearch: true,
columns: [],
searchPlaceHolder: 'Search',
searchFn: (obj, txt) => {
return Object.values(obj)
.filter((x) => (typeof x === 'string' || typeof x === 'number'))
.map(x => String(x))
.some((y) => y.includes(txt));
}
};
cellContents;
headerContents;
headerPanes;
filterText = '';
filteredData = [];
showGrid = true;
constructor() { }
ngAfterContentInit() {
setTimeout(() => {
if (this.headerContents) {
this.headerPanes.forEach((x, i) => {
x.viewContainerRef.clear();
x.viewContainerRef.createEmbeddedView(this.headerContents.get(i % this.headerContents.length));
});
}
}, 10);
}
onExpand(e) {
this.expand.emit(e);
}
onCollapse(e) {
this.collapse.emit(e);
}
refreshGrid() {
this.showGrid = false;
setTimeout(() => {
this.showGrid = true;
}, 0);
}
onSearch(text) {
if (typeof text === 'string' && text != '') {
this.filterText = text;
}
else {
this.filterText = '';
}
if (!this.config.searchFn) {
throw new Error('You should Provide searchFn');
}
this.refreshGrid();
this.filterTree();
}
///////////////////////////////////////////////////////////////////////////
/////////////////////********************************/////////////////////
///////////********** Start Filtering **********///////////
/**
* There are two important things to consider in a tree search..
* If a node contains that search, It should be in final result.
* If a node doesn't contain the searched text, but its children do, It should also be in final result.
* Otherwise it should be filtered out of the result.
*/
filterTree() {
if (this.dataSource.data && this.filterText) {
this.filteredData = [...this.dataSource.data]
.filter((item) => this.hasIncludedSearchTextInChildren(item, this.filterText))
.map((item) => this.filtering(item, this.filterText));
}
else {
this.filteredData = [...this.dataSource.data];
}
}
filtering(node, text) {
return {
...node,
isOpen: true,
show: true,
nodes: this.dataSource.getChildrenFn(node)
?.filter((item) => this.hasIncludedSearchTextInChildren(item, text))
.map((item) => this.filtering(item, text)),
};
}
hasIncludedSearchTextInChildren(node, searchText) {
if (this.config.searchFn(node, searchText)) {
return true;
}
if (this.dataSource.getChildrenFn(node)) {
return this.dataSource.getChildrenFn(node).some((child) => this.hasIncludedSearchTextInChildren(child, searchText));
}
return false;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: TreeGridComponent, selector: "ngm-tree-grid", inputs: { dataSource: "dataSource", config: "config" }, outputs: { expand: "expand", collapse: "collapse" }, queries: [{ propertyName: "cellContents", predicate: ["treeGridCell"] }, { propertyName: "headerContents", predicate: ["treeGridHeader"] }], viewQueries: [{ propertyName: "headerPanes", predicate: CellHostDirective, descendants: true }], ngImport: i0, template: "<div class=\"ngm-tree-grid\">\r\n <header>\r\n <div class=\"tree-grid-search\" *ngIf=\"config.hasSearch\">\r\n <ngm-live-search\r\n [searchLabel]=\"config.searchPlaceHolder ?? 'Search'\"\r\n (search)=\"onSearch($event)\"\r\n >\r\n </ngm-live-search>\r\n </div>\r\n </header>\r\n <main>\r\n <div class=\"tree-grid-titles\">\r\n <ng-container *ngIf=\"headerContents\">\r\n <div *ngFor=\"let head of headerContents; index as i\"\r\n [ngStyle]=\"{\r\n width: config.columns[i].width\r\n ? config.columns[i].width + '%'\r\n : 100 / config.columns.length + '%'\r\n }\">\r\n <ng-template ngmCellHost></ng-template>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!headerContents\">\r\n <div\r\n *ngFor=\"let head of config.columns; let first = first\"\r\n [ngStyle]=\"{\r\n width: head.width\r\n ? head.width + '%'\r\n : 100 / config.columns.length + '%'\r\n }\"\r\n >\r\n {{ head.header }}\r\n </div>\r\n </ng-container>\r\n </div>\r\n <ngm-tree-grid-item\r\n *ngIf=\"showGrid\"\r\n [data]=\"filterText === '' ? dataSource.data : filteredData\"\r\n [config]=\"config\"\r\n (expand)=\"onExpand($event)\"\r\n (collapse)=\"onCollapse($event)\"\r\n [getChildrenFn]=\"dataSource.getChildrenFn\"\r\n [cellInputs]=\"cellContents\"\r\n >\r\n </ngm-tree-grid-item>\r\n </main>\r\n <footer></footer>\r\n</div>\r\n", styles: [".ngm-tree-grid{border:1px solid rgba(0,0,0,.1215686275)}.tree-grid-titles{width:100%;display:flex;flex-direction:row;justify-content:flex-start;align-items:center}.tree-grid-titles div{padding:2px;border:1px solid rgba(0,0,0,.1215686275);min-width:100px;height:40px}.tree-grid-titles>div:first-child{padding:2px 1px;width:30%}.tree-grid-search{max-width:200px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.NgmLiveSearchComponent, selector: "ngm-live-search", inputs: ["config", "searchLabel"], outputs: ["search", "searchClosed"] }, { kind: "component", type: TreeGridItemComponent, selector: "ngm-tree-grid-item", inputs: ["level", "data", "config", "getChildrenFn", "cellInputs"], outputs: ["expand", "collapse"] }, { kind: "directive", type: CellHostDirective, selector: "[ngmCellHost]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: TreeGridComponent, decorators: [{
type: Component,
args: [{ selector: 'ngm-tree-grid', template: "<div class=\"ngm-tree-grid\">\r\n <header>\r\n <div class=\"tree-grid-search\" *ngIf=\"config.hasSearch\">\r\n <ngm-live-search\r\n [searchLabel]=\"config.searchPlaceHolder ?? 'Search'\"\r\n (search)=\"onSearch($event)\"\r\n >\r\n </ngm-live-search>\r\n </div>\r\n </header>\r\n <main>\r\n <div class=\"tree-grid-titles\">\r\n <ng-container *ngIf=\"headerContents\">\r\n <div *ngFor=\"let head of headerContents; index as i\"\r\n [ngStyle]=\"{\r\n width: config.columns[i].width\r\n ? config.columns[i].width + '%'\r\n : 100 / config.columns.length + '%'\r\n }\">\r\n <ng-template ngmCellHost></ng-template>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"!headerContents\">\r\n <div\r\n *ngFor=\"let head of config.columns; let first = first\"\r\n [ngStyle]=\"{\r\n width: head.width\r\n ? head.width + '%'\r\n : 100 / config.columns.length + '%'\r\n }\"\r\n >\r\n {{ head.header }}\r\n </div>\r\n </ng-container>\r\n </div>\r\n <ngm-tree-grid-item\r\n *ngIf=\"showGrid\"\r\n [data]=\"filterText === '' ? dataSource.data : filteredData\"\r\n [config]=\"config\"\r\n (expand)=\"onExpand($event)\"\r\n (collapse)=\"onCollapse($event)\"\r\n [getChildrenFn]=\"dataSource.getChildrenFn\"\r\n [cellInputs]=\"cellContents\"\r\n >\r\n </ngm-tree-grid-item>\r\n </main>\r\n <footer></footer>\r\n</div>\r\n", styles: [".ngm-tree-grid{border:1px solid rgba(0,0,0,.1215686275)}.tree-grid-titles{width:100%;display:flex;flex-direction:row;justify-content:flex-start;align-items:center}.tree-grid-titles div{padding:2px;border:1px solid rgba(0,0,0,.1215686275);min-width:100px;height:40px}.tree-grid-titles>div:first-child{padding:2px 1px;width:30%}.tree-grid-search{max-width:200px}\n"] }]
}], ctorParameters: function () { return []; }, propDecorators: { expand: [{
type: Output
}], collapse: [{
type: Output
}], dataSource: [{
type: Input
}], config: [{
type: Input
}], cellContents: [{
type: ContentChildren,
args: ['treeGridCell']
}], headerContents: [{
type: ContentChildren,
args: ['treeGridHeader']
}], headerPanes: [{
type: ViewChildren,
args: [CellHostDirective]
}] } });
class NgmTreeGridModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridModule, declarations: [TreeGridComponent,
TreeGridItemComponent,
CellHostDirective], imports: [CommonModule,
NgmLiveSearchModule], exports: [TreeGridComponent,
TreeGridItemComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridModule, imports: [CommonModule,
NgmLiveSearchModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NgmTreeGridModule, decorators: [{
type: NgModule,
args: [{
declarations: [
TreeGridComponent,
TreeGridItemComponent,
CellHostDirective
],
imports: [
CommonModule,
NgmLiveSearchModule
],
exports: [
TreeGridComponent,
TreeGridItemComponent
]
}]
}] });
class NgmDataSource {
data = [];
getChildrenFn = (obj) => {
return obj['children'];
};
constructor(data, getChildrenFn) {
if (isNotFalsy(data))
this.data = data;
if (isNotFalsy(getChildrenFn))
this.getChildrenFn = getChildrenFn;
}
}
function isNotFalsy(value) {
return !!value;
}
/*
* Public API Surface of ngm-tree-grid
*/
/**
* Generated bundle index. Do not edit.
*/
export { CellHostDirective, NgmDataSource, NgmTreeGridModule, NgmTreeGridService, TreeGridComponent, TreeGridItemComponent, isNotFalsy };
//# sourceMappingURL=ngm-tree-grid.mjs.map