UNPKG

ngm-tree-grid

Version:

A tree grid that supports editable fields like Inputs and Checkboxes.

289 lines (279 loc) 31.6 kB
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,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAWmSURBVHhe7d2hclRBEIbRdcjIyEhkJI+ARCKRyEgkb4CMREYiIyORSCQSicRC/1uJ2KoOJAtV2e05p+p7hPTmzp2ZuwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANjTWXVRfaxubvsl6cm6+zu8qt5V5xXAf5Mf/a9VN4AkHVbfqvfVSQWwl1dVhkk3ZCQddt+rtxXAgz2rLqtuqEg6rj5VVgOAv8qg+Fx1g0TScZZXeNnDA9DKk78ff2lmeZ1nJQBoZXd/NzgkzSgnBgB2vK66gSFpVjnVA7CVpf/sGO6GhaRZ/axOK4DtE0E3KCTN7EMF4Ky/tFhZBcjKH7Cw51U3ICTN7mUFLCxXhnbDQdLscuoHWFhuCeuGg6TZfamAhbn4R1qznPwBFmYDoLRuwMKc/5fWDVhY3gN2g0HS7H5UwMKuq244SJpdvhAILCw3gnXDQdLscgIIWFguA+mGg6TZvamAheU60LwL7AaEpLn5IBCwuay6ASFpZpb/ga08CeTjIN2gkDSv8wpgyzcBpDXyDQBgR/YCuBZYml1u/jypAHacVW4GlGaW13yW/oF7ZUA4FSDNKj/+OfIL8EdZCXBFsDSjLPt78gceLHsC3BIoHXdXlXf+wF6yGpAzw91wkXSY3VQvKoB/lrsCcnVo/hnIkmI3dCQ9Tdm8mw97XVT5px0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOARNpvfpzEBEbv4ysQAAAAASUVORK5CYII=);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