UNPKG

ngx-bootstrap-treeview

Version:

Ngx Bootstrap Treeview - Simple library to visualize, search and interact with tree data

1,229 lines (1,214 loc) 119 kB
import { __extends, __assign, __spread } from 'tslib'; import { Injectable, NgModule, defineInjectable, Inject, NgZone, inject, EventEmitter, Component, Renderer2, Input, Output, ViewChild, ElementRef, ChangeDetectorRef, ViewChildren } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { faSquare, faCheckSquare, faFolder, faFolderOpen, faMinus, faCheck } from '@fortawesome/free-solid-svg-icons'; import { trigger, style, transition, animate, keyframes } from '@angular/animations'; import { EVENT_MANAGER_PLUGINS, EventManager } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var Tree = /** @class */ (function () { function Tree() { } return Tree; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var Leaf = /** @class */ (function () { function Leaf(tree) { this.value = tree.value; this.label = tree.label; this.data = tree.data; } return Leaf; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var LeafClickedEvent = /** @class */ (function () { function LeafClickedEvent(leaf, selectedLeaves) { this.leaf = leaf; this.selectedLeaves = selectedLeaves; } return LeafClickedEvent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @template TreeSourceType, LeafSourceType */ var /** * @template TreeSourceType, LeafSourceType */ NgxBootstrapTreeviewMapper = /** @class */ (function () { function NgxBootstrapTreeviewMapper(treeMap, leafMap) { this.treeMap = treeMap; this.leafMap = leafMap; } /** * @param {?} item * @return {?} */ NgxBootstrapTreeviewMapper.prototype.mapTree = /** * @param {?} item * @return {?} */ function (item) { var _this = this; var _a = { value: item[this.treeMap.value], label: item[this.treeMap.label], children: item[this.treeMap.children], leaves: item[this.treeMap.leavesKey], data: item }, value = _a.value, label = _a.label, children = _a.children, leaves = _a.leaves, data = _a.data; /** @type {?} */ var result = { value: value, label: label, data: data, children: __spread(children.map(function (child) { return _this.mapTree(child); }), leaves.map(function (leaf) { return _this.mapLeaf(leaf); })) }; return result; }; /** * @param {?} item * @return {?} */ NgxBootstrapTreeviewMapper.prototype.mapLeaf = /** * @param {?} item * @return {?} */ function (item) { return { value: item[this.leafMap.value], label: item[this.leafMap.label], data: item }; }; return NgxBootstrapTreeviewMapper; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var ContextMenuService = /** @class */ (function () { function ContextMenuService() { this.lastContextMenuEvent = new BehaviorSubject(null); } /** * @param {?} event * @return {?} */ ContextMenuService.prototype.fire = /** * @param {?} event * @return {?} */ function (event) { this.lastContextMenuEvent.next(event); }; ContextMenuService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ ContextMenuService.ctorParameters = function () { return []; }; /** @nocollapse */ ContextMenuService.ngInjectableDef = defineInjectable({ factory: function ContextMenuService_Factory() { return new ContextMenuService(); }, token: ContextMenuService, providedIn: "root" }); return ContextMenuService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var NgxBootstrapTreeviewComponent = /** @class */ (function () { function NgxBootstrapTreeviewComponent(_host, _renderer, _zone, _changeDetector, _contextMenuService) { this._host = _host; this._renderer = _renderer; this._zone = _zone; this._changeDetector = _changeDetector; this._contextMenuService = _contextMenuService; this.contextMenus = { leafMenu: {}, branchMenu: {}, rootMenu: {} }; this.disableSelectedElements = false; this.emptyFolderLabel = 'This folder is empty'; this.isAnimationDisabled = false; this.isFirstLevel = true; // This one is true IF AND ONLY IF we're at the top level, be it a root or a branch. // This is because a branch where isFirstLevel = true is not always our first treeview instance this.isFirstInstance = true; this.preselectedItems = []; // Icons inputs this.openedFolderIcon = faFolderOpen; this.closedFolderIcon = faFolder; this.unselectedLeafIcon = faSquare; this.selectedLeafIcon = faCheckSquare; this.anyChildrenSelectedIcon = faMinus; this.allChildrenSelectedIcon = faCheck; this.filterString = ''; this.matchBranches = true; this.branchClicked = new EventEmitter(); this.leafClicked = new EventEmitter(); this.selectedLeaves = []; } /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.ngOnInit = /** * @return {?} */ function () { var _this = this; // We throw an exception if we have item or items but no mapper indicating how to handle them if (!this.mapper && (this.item || this.items)) { throw new Error('"item" or "items" are invalid parameters if you don\'t provide a mapper'); } // If we have a mapper, it will handle "item" and "items" if (this.mapper) { if (this.items) { this.trees = this.items.map(function (item) { return _this.mapper.mapTree(item); }); } if (this.item) { this.tree = this.mapper.mapTree(this.item); } } // If we want to display one or more trees if (this.trees && this.trees.length > 1) { this.isRoot = true; this.isBranch = this.isLeaf = false; // return; } else if (this.trees) { // Otherwise, we have trees but with less than 2 elements, we assign it to tree // So ngOnInit() can keep going normaly this.tree = this.trees[0]; } if (this.tree && (this.tree.children || this.tree.loadChildren)) { this.isBranch = true; } else { this.isBranch = false; } this._resetDisplayedData(); if (!this.isRoot) { this.isLeaf = !this.isBranch; } this.leavesCount = this.countLeaves(this.tree); if (this.preselectedItems) { this.preselectedItems.forEach(function (value) { _this.select(value); }); } }; /** * @param {?} changes * @return {?} */ NgxBootstrapTreeviewComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { var _this = this; // The this.tree || this.trees is used to avoid anerror since ngOnChanges is called before ngOnInit() if ('filterString' in changes && (this.displayedTree || this.displayedTrees)) { this._zone.runOutsideAngular(function () { if (_this._filterTrigger) { clearTimeout(_this._filterTrigger); _this._filterTrigger = null; } _this._filterTrigger = setTimeout(function () { _this._zone.run(function () { if (_this.displayedTrees) { _this.displayedTrees = _this._filterTrees(); } else if (_this.displayedTree) { _this.displayedTree = _this._filterTree(_this.displayedTree); } _this._changeDetector.detectChanges(); if (_this.filterString) { _this.unfoldAll(); } else { _this._resetDisplayedData(); _this.foldAll(); } }); }, 250); }); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onClick = /** * @return {?} */ function () { if (this.isLeaf) { this.onLeafClicked(); } if (this.isBranch) { if (this.loggingService) { this.loggingService.log("\uD83C\uDF34 Branche cliqu\u00E9e: " + this.tree.label); } this.onBranchClicked(); } }; /** * @param {?} leafClickedEvent * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onChildLeafClicked = /** * @param {?} leafClickedEvent * @return {?} */ function (leafClickedEvent) { if (this.loggingService && this.isBranch) { this.loggingService.log("\u27A1 Event entrant dans le parent " + this.tree.label + ":", leafClickedEvent); } else if (this.loggingService && this.isRoot) { this.loggingService.log("\u27A1 Event entrant dans la racine:", leafClickedEvent); } // When a child leaf is clicked, we check our selectedLeaves to select or unselect the clicked one if (!this._leafExistsIn(this.selectedLeaves, leafClickedEvent.leaf)) { this._selectLeaf(leafClickedEvent.leaf); } else { this._unselectLeaf(leafClickedEvent.leaf); } // Now that the leaf is selected/unselected, we merge our selectedLeaves with the ones of the event leafClickedEvent.selectedLeaves = this.selectedLeaves; if (this.isBranch && this.loggingService) { this.loggingService.log("\u2B05 Event sortant de " + this.tree.label + " vers un parent:", leafClickedEvent); } else if (this.loggingService && this.isRoot) { this.loggingService.log("\u2B05 Event sortant de la racine:", leafClickedEvent); } this.leafClicked.emit(leafClickedEvent); }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onLeafClicked = /** * @return {?} */ function () { if (this.loggingService) { this.loggingService.log('🍂 Feuille cliqué:', this.tree.label); } if (!this.disableSelectedElements || !this.isOpened) { this._leafToggle(); } }; /** * @param {?} tree * @return {?} */ NgxBootstrapTreeviewComponent.prototype.countLeaves = /** * @param {?} tree * @return {?} */ function (tree) { var _this = this; /** @type {?} */ var leavesCount = 0; if (tree && (!tree.children || tree.loadChildren)) { leavesCount = 1; } else if (tree) { tree.children.forEach(function (child) { leavesCount += _this.countLeaves(child); }); } return leavesCount; }; /** * @param {?} value * @return {?} */ NgxBootstrapTreeviewComponent.prototype.select = /** * @param {?} value * @return {?} */ function (value) { if (this.isLeaf && this.tree.value === value && !this.isOpened) { this._leafToggle(); } else if (this.isRoot || this.isBranch) { this.children.forEach(function (child) { child.select(value); }); } }; /** * @param {?} value * @return {?} */ NgxBootstrapTreeviewComponent.prototype.unselect = /** * @param {?} value * @return {?} */ function (value) { if (this.isLeaf && this.tree.value === value && this.isOpened) { this._leafToggle(); } else if (this.isRoot || this.isBranch) { this.children.forEach(function (child) { child.unselect(value); }); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onBranchClicked = /** * @return {?} */ function () { this._branchToggle(); this.branchClicked.emit(this.tree); }; /** * @param {?} branch * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onChildBranchClicked = /** * @param {?} branch * @return {?} */ function (branch) { var _this = this; this.branchClicked.emit(branch); if (this.rootsContainer) { requestAnimationFrame(function () { // We use requestAnimationFrame because we want this to be processed once rerendering is complete _this.rootsContainer.nativeElement.style.height = _this.computeHeight() + 'px'; }); } }; /** * @param {?} event * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onContextMenu = /** * @param {?} event * @return {?} */ function (event) { event.stopPropagation(); event.preventDefault(); this._contextMenuService.fire({ target: this.tree, event: event }); }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onElementAdded = /** * @return {?} */ function () { this.leavesCount = this.countLeaves(this.tree); return true; }; /** * @param {?} event * @return {?} */ NgxBootstrapTreeviewComponent.prototype.onRootContextMenu = /** * @param {?} event * @return {?} */ function (event) { event.stopPropagation(); event.preventDefault(); this._contextMenuService.fire({ event: event, target: null }); }; /** * @param {?=} id * @return {?} */ NgxBootstrapTreeviewComponent.prototype.fold = /** * @param {?=} id * @return {?} */ function (id) { if (!id) { this._fold(); } else { this._foldId(id); } }; /** * @param {?=} id * @return {?} */ NgxBootstrapTreeviewComponent.prototype.unfold = /** * @param {?=} id * @return {?} */ function (id) { if (!id) { this._unfold(); } else { this._unfoldId(id); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.show = /** * @return {?} */ function () { /** @type {?} */ var domElement = this._host.nativeElement; this._renderer.removeClass(domElement, 'd-none'); }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.hide = /** * @return {?} */ function () { /** @type {?} */ var domElement = this._host.nativeElement; this._renderer.addClass(domElement, 'd-none'); }; /** * @param {?} filterString * @param {?=} item * @return {?} */ NgxBootstrapTreeviewComponent.prototype.filter = /** * @param {?} filterString * @param {?=} item * @return {?} */ function (filterString, item) { var _this = this; if (this.isRoot) { this.children.forEach(function (child) { child.filter(_this.filterString); }); } else { if (!item) { item = this.tree; } /** @type {?} */ var matchingElementsCount = this.countFilteredItems(filterString, item); if (matchingElementsCount === 0) { this.hide(); } else { this.show(); if (filterString !== '') { this._unfold(); } else { this._fold(); } } } }; /** * @param {?} filterString * @param {?} item * @return {?} */ NgxBootstrapTreeviewComponent.prototype.countFilteredItems = /** * @param {?} filterString * @param {?} item * @return {?} */ function (filterString, item) { var _this = this; /** @type {?} */ var matchingElementsCount = 0; if (item.children) { if (!filterString.length) { return 1; } matchingElementsCount = item.children.reduce(function (acc, child) { return acc + _this.countFilteredItems(filterString, child); }, 0); } else { /** @type {?} */ var regex = new RegExp(filterString, 'i'); if (regex.test(item.label)) { matchingElementsCount++; } } return matchingElementsCount; }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.unfoldAll = /** * @return {?} */ function () { // A branch will unfold itself if (this.isBranch && !this.isOpened) { this._branchToggle(); this._changeDetector.detectChanges(); } // If we're not a leaf, we unfold all of our children if (!this.isLeaf) { this.children.forEach(function (child) { child.unfoldAll(); }); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.foldAll = /** * @return {?} */ function () { // A branch will fold itself if (this.isBranch && this.isOpened) { this._branchToggle(); } // If we're not a leaf, we unfold all of our children if (!this.isLeaf) { this.children.forEach(function (child) { child.foldAll(); }); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype.computeHeight = /** * @return {?} */ function () { if (!this.isRoot) { return this.treeview.nativeElement.scrollHeight; } return this.children.reduce(function (prevValue, currentValue) { return prevValue + currentValue.computeHeight(); }, 0); }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype._unfold = /** * @return {?} */ function () { if (this.isBranch && !this.isOpened) { this._branchToggle(); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype._fold = /** * @return {?} */ function () { if (this.isBranch && this.isOpened) { this._branchToggle(); } }; /** * @param {?} id * @return {?} */ NgxBootstrapTreeviewComponent.prototype._unfoldId = /** * @param {?} id * @return {?} */ function (id) { if (this.isBranch && this.tree.value === id && !this.isOpened) { this._branchToggle(); } else if (this.isBranch && this.children.length) { this.children.forEach(function (child) { child.unfold(id); }); } }; /** * @param {?} id * @return {?} */ NgxBootstrapTreeviewComponent.prototype._foldId = /** * @param {?} id * @return {?} */ function (id) { if (this.isBranch && this.tree.value === id && this.isOpened) { this._branchToggle(); } else if (this.isBranch && this.children.length) { this.children.forEach(function (child) { child.fold(id); }); } }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype._leafToggle = /** * @return {?} */ function () { this.isOpened = !this.isOpened; /** @type {?} */ var leaf = new Leaf(this.tree); if (this.isOpened) { this._selectLeaf(leaf); } else { this._unselectLeaf(leaf); } /** @type {?} */ var event = new LeafClickedEvent(leaf, this.selectedLeaves); this.leafClicked.emit(event); }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype._branchToggle = /** * @return {?} */ function () { this.isOpened = !this.isOpened; }; /** * @param {?} leaf * @return {?} */ NgxBootstrapTreeviewComponent.prototype._selectLeaf = /** * @param {?} leaf * @return {?} */ function (leaf) { if (!this.isRoot && this.loggingService) { this.loggingService.log("\u2714\uFE0F Feuille s\u00E9lectionn\u00E9e dans " + this.tree.label + ":", leaf); } else if (this.loggingService) { this.loggingService.log("\u2714\uFE0F Feuille s\u00E9lectionn\u00E9e dans la racine:", leaf); } if (!this._leafExistsIn(this.selectedLeaves, leaf)) { this.selectedLeaves = __spread(this.selectedLeaves, [leaf]); } }; /** * @param {?} leaf * @return {?} */ NgxBootstrapTreeviewComponent.prototype._unselectLeaf = /** * @param {?} leaf * @return {?} */ function (leaf) { if (!this.isRoot && this.loggingService) { this.loggingService.log("\u274C Feuille d\u00E9s\u00E9lectionn\u00E9e dans " + this.tree.label + ":", leaf); } else if (this.loggingService) { this.loggingService.log("\u274C Feuille d\u00E9s\u00E9lectionn\u00E9e dans la racine:", leaf); } /** @type {?} */ var index = this._leafIndex(this.selectedLeaves, leaf); if (index !== -1) { this.selectedLeaves.splice(index, 1); } }; // Function used to check if a given leaf does exist in sleectedLeaves array // We use this because of the new Leaf(), which causes reference comparison of Array.indexOf() not to work // Function used to check if a given leaf does exist in sleectedLeaves array // We use this because of the new Leaf(), which causes reference comparison of Array.indexOf() not to work /** * @param {?} leaves * @param {?} leaf * @return {?} */ NgxBootstrapTreeviewComponent.prototype._leafIndex = // Function used to check if a given leaf does exist in sleectedLeaves array // We use this because of the new Leaf(), which causes reference comparison of Array.indexOf() not to work /** * @param {?} leaves * @param {?} leaf * @return {?} */ function (leaves, leaf) { /** @type {?} */ var result = -1; leaves.forEach(function (selectedLeaf, index) { if (selectedLeaf.value === leaf.value && selectedLeaf.label === leaf.label) { result = index; } }); return result; }; /** * @param {?} leaves * @param {?} leaf * @return {?} */ NgxBootstrapTreeviewComponent.prototype._leafExistsIn = /** * @param {?} leaves * @param {?} leaf * @return {?} */ function (leaves, leaf) { return this._leafIndex(leaves, leaf) !== -1; }; /** * @param {?} tree * @return {?} */ NgxBootstrapTreeviewComponent.prototype._copyTree = /** * @param {?} tree * @return {?} */ function (tree) { var _this = this; /** @type {?} */ var isTree = !!tree.children; /** @type {?} */ var result = { value: tree.value, label: tree.label, data: tree.data }; if (isTree) { /** @type {?} */ var children = tree.children.map(function (child) { return _this._copyTree(child); }); return __assign({}, result, { children: children }); } else { return result; } }; /** * @param {?} trees * @return {?} */ NgxBootstrapTreeviewComponent.prototype._copyTrees = /** * @param {?} trees * @return {?} */ function (trees) { var _this = this; return trees.map(function (tree) { return _this._copyTree(tree); }); }; /** * @param {?=} trees * @param {?=} filterString * @return {?} */ NgxBootstrapTreeviewComponent.prototype._filterTrees = /** * @param {?=} trees * @param {?=} filterString * @return {?} */ function (trees, filterString) { var _this = this; if (trees === void 0) { trees = this.trees; } if (filterString === void 0) { filterString = this.filterString; } /** @type {?} */ var copies = this._copyTrees(trees); if (filterString !== '') { /** @type {?} */ var displayedTrees = copies .map(function (copy) { return _this._filterTree(copy, filterString); }) .filter(function (filteredCopy) { return !!filteredCopy; }); return displayedTrees; } else { return copies; } }; // This method alters tree.children and returns true if any elements matched the filter string // This method alters tree.children and returns true if any elements matched the filter string /** * @param {?} tree * @param {?=} filterString * @return {?} */ NgxBootstrapTreeviewComponent.prototype._filterTree = // This method alters tree.children and returns true if any elements matched the filter string /** * @param {?} tree * @param {?=} filterString * @return {?} */ function (tree, filterString) { var _this = this; if (filterString === void 0) { filterString = this.filterString; } /** @type {?} */ var regex = new RegExp(filterString, 'i'); if (!tree.children) { // Leaf handling return regex.test(tree.label) ? tree : null; } else if (tree.children && tree.children.length) { if (this.matchBranches && regex.test(tree.label)) { return tree; } // Non empty branches handling tree.children = tree.children.map(function (child) { return _this._filterTree(child); }).filter(function (child) { return !!child; }); return tree.children.length ? tree : null; } return null; }; /** * @return {?} */ NgxBootstrapTreeviewComponent.prototype._resetDisplayedData = /** * @return {?} */ function () { if (this.tree) { this.displayedTree = this._copyTree(this.tree); } else if (this.trees) { this.displayedTrees = this._copyTrees(this.trees); } }; NgxBootstrapTreeviewComponent.decorators = [ { type: Component, args: [{ // tslint:disable-next-line:component-selector selector: 'ngx-bootstrap-treeview', template: "<!-- This part is used if we have a single tree inputed to our component -->\r\n<ul\r\n [ngClass]=\"{\r\n branch: displayedTree.children,\r\n leaf: !displayedTree.children,\r\n opened: isOpened,\r\n 'pl-0': isFirstLevel,\r\n disabled: isLeaf && isOpened && disableSelectedElements\r\n }\"\r\n *ngIf=\"displayedTree\"\r\n class=\"mb-0\"\r\n #treeview\r\n>\r\n <li>\r\n <a [routerLink]=\"[]\" (click)=\"onClick()\" (contextmenu)=\"onContextMenu($event)\">\r\n <!-- Icons if we're reprensenting a branch -->\r\n <span class=\"icon\">\r\n <!-- Folder closed, no children selected -->\r\n <fa-icon\r\n [fixedWidth]=\"true\"\r\n [icon]=\"closedFolderIcon\"\r\n *ngIf=\"displayedTree.children && !isOpened && !selectedLeaves.length\"\r\n ></fa-icon>\r\n\r\n <!-- Folder closed, children selected but not all -->\r\n <fa-layers\r\n [fixedWidth]=\"true\"\r\n *ngIf=\"\r\n displayedTree.children &&\r\n !isOpened &&\r\n selectedLeaves.length > 0 &&\r\n selectedLeaves.length < this.leavesCount\r\n \"\r\n >\r\n <fa-icon [fixedWidth]=\"true\" [icon]=\"closedFolderIcon\"></fa-icon>\r\n <fa-icon [fixedWidth]=\"true\" [icon]=\"anyChildrenSelectedIcon\" transform=\"shrink-6 down-1\"></fa-icon>\r\n </fa-layers>\r\n\r\n <!-- Folder closed, all children selected -->\r\n <fa-layers\r\n [fixedWidth]=\"true\"\r\n *ngIf=\"\r\n displayedTree.children && !isOpened && selectedLeaves.length === leavesCount && leavesCount > 0\r\n \"\r\n >\r\n <fa-icon [fixedWidth]=\"true\" [icon]=\"closedFolderIcon\"></fa-icon>\r\n <fa-icon [fixedWidth]=\"true\" [icon]=\"allChildrenSelectedIcon\" transform=\"shrink-8 down-1\"></fa-icon>\r\n </fa-layers>\r\n\r\n <!-- Folder opened, no children selected -->\r\n <fa-icon\r\n [fixedWidth]=\"true\"\r\n [icon]=\"openedFolderIcon\"\r\n *ngIf=\"displayedTree.children && isOpened && !selectedLeaves.length\"\r\n ></fa-icon>\r\n\r\n <!-- Folder opened, children selected but not all -->\r\n <fa-layers\r\n [fixedWidth]=\"true\"\r\n *ngIf=\"\r\n displayedTree.children &&\r\n isOpened &&\r\n selectedLeaves.length > 0 &&\r\n selectedLeaves.length < this.leavesCount\r\n \"\r\n >\r\n <fa-icon [fixedWidth]=\"true\" [icon]=\"openedFolderIcon\"></fa-icon>\r\n <fa-icon\r\n [fixedWidth]=\"true\"\r\n [icon]=\"anyChildrenSelectedIcon\"\r\n transform=\"shrink-8 down-3 right-2\"\r\n class=\"opened-folder-mask\"\r\n ></fa-icon>\r\n </fa-layers>\r\n <!-- Folder opened, all children selected -->\r\n <fa-layers\r\n [fixedWidth]=\"true\"\r\n *ngIf=\"\r\n displayedTree.children && isOpened && selectedLeaves.length === leavesCount && leavesCount > 0\r\n \"\r\n >\r\n <fa-icon [fixedWidth]=\"true\" [icon]=\"openedFolderIcon\"></fa-icon>\r\n <fa-icon\r\n [fixedWidth]=\"true\"\r\n [icon]=\"allChildrenSelectedIcon\"\r\n transform=\"shrink-12 down-3 right-1\"\r\n class=\"opened-folder-mask\"\r\n ></fa-icon>\r\n </fa-layers>\r\n <!-- /branch icons -->\r\n\r\n <!-- Icons if we're reprensenting a leaf -->\r\n <fa-icon\r\n [fixedWidth]=\"true\"\r\n [icon]=\"unselectedLeafIcon\"\r\n *ngIf=\"!displayedTree.children && !isOpened\"\r\n ></fa-icon>\r\n <fa-icon\r\n [fixedWidth]=\"true\"\r\n [icon]=\"selectedLeafIcon\"\r\n *ngIf=\"!displayedTree.children && isOpened\"\r\n ></fa-icon>\r\n </span>\r\n <span class=\"label\">\r\n {{ displayedTree.label }}\r\n </span>\r\n </a>\r\n\r\n <div\r\n *ngIf=\"displayedTree.children && isOpened\"\r\n class=\"children\"\r\n [@.disabled]=\"isAnimationDisabled\"\r\n [@childrenAnimationTrigger]\r\n >\r\n <ul *ngIf=\"displayedTree.children.length === 0\">\r\n <li>\r\n <i>{{ emptyFolderLabel }}</i>\r\n </li>\r\n </ul>\r\n <ng-container *ngFor=\"let branch of displayedTree.children\">\r\n <ngx-bootstrap-treeview\r\n *ngIf=\"onElementAdded()\"\r\n [tree]=\"branch\"\r\n (branchClicked)=\"onChildBranchClicked($event)\"\r\n (leafClicked)=\"onChildLeafClicked($event)\"\r\n [selectedLeafIcon]=\"selectedLeafIcon\"\r\n [unselectedLeafIcon]=\"unselectedLeafIcon\"\r\n [openedFolderIcon]=\"openedFolderIcon\"\r\n [closedFolderIcon]=\"closedFolderIcon\"\r\n [canSelectBranch]=\"canSelectBranch\"\r\n [anyChildrenSelectedIcon]=\"anyChildrenSelectedIcon\"\r\n [allChildrenSelectedIcon]=\"allChildrenSelectedIcon\"\r\n [loggingService]=\"loggingService\"\r\n [isFirstInstance]=\"false\"\r\n [isFirstLevel]=\"false\"\r\n [disableSelectedElements]=\"disableSelectedElements\"\r\n [emptyFolderLabel]=\"emptyFolderLabel\"\r\n >\r\n </ngx-bootstrap-treeview>\r\n </ng-container>\r\n </div>\r\n </li>\r\n</ul>\r\n<!-- END Single tree provided -->\r\n\r\n<!-- Context menu, only shown once, so either on root or on branch if first level -->\r\n<ngx-bootstrap-treeview-context-menu\r\n *ngIf=\"contextMenus && isFirstInstance\"\r\n [config]=\"contextMenus\"\r\n [rootContextMenu]=\"contextMenus.rootMenu\"\r\n [branchContextMenu]=\"contextMenus.branchMenu\"\r\n [leafContextMenu]=\"contextMenus.leafMenu\"\r\n>\r\n</ngx-bootstrap-treeview-context-menu>\r\n\r\n<!-- If we provided an array of trees as an input, this part will be called -->\r\n<div *ngIf=\"displayedTrees\" (contextmenu)=\"onRootContextMenu($event)\" #rootsContainer>\r\n <ngx-bootstrap-treeview\r\n *ngFor=\"let displayedTree of displayedTrees\"\r\n [tree]=\"displayedTree\"\r\n (branchClicked)=\"onChildBranchClicked($event)\"\r\n (leafClicked)=\"onChildLeafClicked($event)\"\r\n [selectedLeafIcon]=\"selectedLeafIcon\"\r\n [unselectedLeafIcon]=\"unselectedLeafIcon\"\r\n [openedFolderIcon]=\"openedFolderIcon\"\r\n [closedFolderIcon]=\"closedFolderIcon\"\r\n [canSelectBranch]=\"canSelectBranch\"\r\n [anyChildrenSelectedIcon]=\"anyChildrenSelectedIcon\"\r\n [allChildrenSelectedIcon]=\"allChildrenSelectedIcon\"\r\n [loggingService]=\"loggingService\"\r\n [disableSelectedElements]=\"disableSelectedElements\"\r\n [isAnimationDisabled]=\"isAnimationDisabled\"\r\n [isFirstInstance]=\"false\"\r\n [emptyFolderLabel]=\"emptyFolderLabel\"\r\n ></ngx-bootstrap-treeview>\r\n</div>\r\n<!-- End multiple trees provided -->\r\n", animations: [ trigger('childrenAnimationTrigger', [ transition(':leave', [animate('0.25s', style({ transform: 'translateX(-100%)', display: 'none' }))]), transition(':enter', [ animate('0.25s', keyframes([ style({ transform: 'translateX(-100%)', display: 'block', offset: 0 }), style({ transform: 'translateX(0%)', offset: 1 }) ])) ]) ]) ], styles: ["ul{list-style-type:none;overflow:visible;float:left;clear:left}ul li{position:relative;display:inline-block}ul fa-icon,ul fa-layers fa-icon{color:#000}ul fa-layers fa-icon:not(:first-child) ::ng-deep svg[data-prefix=fas]{color:#fff}ul fa-layers fa-icon.opened-folder-mask ::ng-deep svg{-webkit-transform:skew(-45deg,0);transform:skew(-45deg,0)}:host{display:block}:host>div{position:relative}"] }] } ]; /** @nocollapse */ NgxBootstrapTreeviewComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: Renderer2 }, { type: NgZone }, { type: ChangeDetectorRef }, { type: ContextMenuService } ]; }; NgxBootstrapTreeviewComponent.propDecorators = { canSelectBranch: [{ type: Input }], contextMenus: [{ type: Input }], disableSelectedElements: [{ type: Input }], emptyFolderLabel: [{ type: Input }], isAnimationDisabled: [{ type: Input }], isFirstLevel: [{ type: Input }], isFirstInstance: [{ type: Input }], isOpened: [{ type: Input }], item: [{ type: Input }], items: [{ type: Input }], loggingService: [{ type: Input }], mapper: [{ type: Input }], preselectedItems: [{ type: Input }], tree: [{ type: Input }], trees: [{ type: Input }], openedFolderIcon: [{ type: Input }], closedFolderIcon: [{ type: Input }], unselectedLeafIcon: [{ type: Input }], selectedLeafIcon: [{ type: Input }], anyChildrenSelectedIcon: [{ type: Input }], allChildrenSelectedIcon: [{ type: Input }], filterString: [{ type: Input }], matchBranches: [{ type: Input }], branchClicked: [{ type: Output }], leafClicked: [{ type: Output }], children: [{ type: ViewChildren, args: [NgxBootstrapTreeviewComponent,] }], treeview: [{ type: ViewChild, args: ['treeview',] }], rootsContainer: [{ type: ViewChild, args: ['rootsContainer',] }] }; return NgxBootstrapTreeviewComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var NgxBootstrapTreeviewContextMenuComponent = /** @class */ (function () { function NgxBootstrapTreeviewContextMenuComponent(_renderer, _zone, _contextMenuService) { this._renderer = _renderer; this._zone = _zone; this._contextMenuService = _contextMenuService; this._defaultConfig = { containerClass: '', hoveredItemClass: '', itemsClass: '' }; this.config = {}; this.rootContextMenu = null; this.branchContextMenu = null; this.leafContextMenu = null; this.hidden = new EventEmitter(); this.shown = new EventEmitter(); this._activeMenu = null; } /** * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.ngOnInit = /** * @return {?} */ function () { var _this = this; this.config = __assign({}, this._defaultConfig, this.config); this._contextMenuService.lastContextMenuEvent.subscribe(function (lastContextMenuEvent) { if (lastContextMenuEvent) { _this.show(lastContextMenuEvent); } else { _this.hide(); } }); this._renderer.listen(document, 'click.out-zone', this.onDocumentClicked.bind(this)); this._renderer.listen(document, 'keyup.out-zone', this.onKeyPressed.bind(this)); }; /** * @param {?} changes * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { if ('config' in changes) { this.config = __assign({}, this._defaultConfig, changes.config.currentValue); } }; /** * @param {?} event * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.onDocumentClicked = /** * @param {?} event * @return {?} */ function (event) { if (this.lastContextMenuEvent) { event.preventDefault(); event.stopPropagation(); this.hide(); } }; /** * @param {?} event * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.onKeyPressed = /** * @param {?} event * @return {?} */ function (event) { if (this.lastContextMenuEvent && event.key.toLowerCase() === 'escape') { this.hide(); } }; /** * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.getLabels = /** * @return {?} */ function () { return this._activeMenu ? Object.keys(this._activeMenu) : []; }; /** * @param {?} label * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.onItemClicked = /** * @param {?} label * @return {?} */ function (label) { this._activeMenu[label](this.lastContextMenuEvent.target); }; /** * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.hide = /** * @return {?} */ function () { var _this = this; this._zone.run(function () { _this._activeMenu = null; _this.lastContextMenuEvent = null; _this.hidden.emit(); }); }; /** * @param {?} contextMenuEvent * @return {?} */ NgxBootstrapTreeviewContextMenuComponent.prototype.show = /** * @param {?} contextMenuEvent * @return {?} */ function (contextMenuEvent) { this.lastContextMenuEvent = contextMenuEvent; if (!contextMenuEvent.target) { this._activeMenu = this.rootContextMenu; } else if (contextMenuEvent.target.children) { this._activeMenu = this.branchContextMenu; } else { this._activeMenu = this.leafContextMenu; } /** @type {?} */ var nativeElement = this.container.nativeElement; /** @type {?} */ var x = this.lastContextMenuEvent.event.pageX.toString(); /** @type {?} */ var y = this.lastContextMenuEvent.event.pageY.toString(); this._renderer.setStyle(nativeElement, 'top', y + 'px'); this._renderer.setStyle(nativeElement, 'left', x + 'px'); this.shown.emit(); }; NgxBootstrapTreeviewContextMenuComponent.decorators = [ { type: Component, args: [{ // tslint:disable-next-line: component-selector selector: 'ngx-bootstrap-treeview-context-menu', template: "<div\r\n class=\"context-menu list-group\"\r\n [ngClass]=\"{ 'd-none': !lastContextMenuEvent, 'd-block': lastContextMenuEvent }\"\r\n #container\r\n>\r\n <button\r\n class=\"context-menu-item {{ config.itemsClass }}\"\r\n *ngFor=\"let label of getLabels()\"\r\n (click)=\"onItemClicked(label)\"\r\n [ngClass]=\"{ 'list-group-item list-group-item-action px-3': !config.itemsClass }\"\r\n >\r\n {{ label }}\r\n </button>\r\n</div>\r\n", styles: [".context-menu{background-color:#fff;border-radius:.25rem;left:0;position:fixed;top:0;z-index:100}.context-menu .context-menu-item{border-top-width:0;border-bottom-width:0;padding-top:.0625rem;padding-bottom:.0625rem;transition:background-color .3s}.context-menu .context-menu-item:first-of-type{padding-top:.125rem;border-top-width:1px}.context-menu .context-menu-item:last-of-type{padding-bottom:.125rem;border-bottom-width:1px}.context-menu .context-menu-item:hover{background:rgba(0,0,0,.8);color:#fff}"] }] } ]; /** @nocollapse */ NgxBootstrapTreeviewContextMenuComponent.ctorParameters = function () { return [ { type: Renderer2 }, { type: NgZone }, { type: ContextMenuService } ]; }; NgxBootstrapTreeviewContextMenuComponent.propDecorators = { config: [{ type: Input }], rootContextMenu: [{ type: Input }], branchContextMenu: [{ type: Input }], leafContextMenu: [{ type: Input }], hidden: [{ type: Output }], shown: [{ type: Output }], container: [{ type: ViewChild, args: ['container',] }] }; return NgxBootstrapTreeviewContextMenuComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var NgxBootstrapTreeviewEventManagerService = /** @class */ (function (_super) { __extends(NgxBootstrapTreeviewEventManagerService, _super); function NgxBootstrapTreeviewEventManagerService(plugins, zone) { var _this = _super.call(this, plugins, zone) || this; _this.zone = zone; return _this; } /** * @param {?} element * @param {?} eventName * @param {?} handler * @return {?} */ NgxBootstrapTreeviewEventManagerService.prototype.addEventListener = /** * @param {?} element * @param {?} eventName * @param {?} handler * @return {?} */ function (element, eventName, handler) { var _this = this; if (eventName.endsWith('out-zone')) { eventName = eventName.split('.')[0]; return this.zone.runOutsideAngular(function () { return _super.prototype.addEventListener.call(_this, element, eventName, handler); }); } return _super.prototype.addEventListener.call(this, element, eventName, handler); }; NgxBootstrapTreeviewEventManagerService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgxBootstrapTreeviewEventManagerService.ctorParameters = function () { return [ { type: Array, decorators: [{ type: Inject, args: [EVENT_MANAGER_PLUGINS,] }] }, { type: NgZone } ]; }; /** @nocollapse */ NgxBootstrapTreeviewEventManagerService.ngInjectableDef = defineInjectable({ factory: function NgxBootstrapTreeviewEventManagerService_Factory() { return new NgxBootstrapTreeviewEventManagerService(inject(EVENT_MANAGER_PLUGINS), inject(NgZone)); }, token: NgxBootstrapTreeviewEventManagerService, providedIn: "root" }); return NgxBootstrapTreeviewEventManagerService; }(EventManager)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var NgxBootstrapTreeviewModule = /** @class */ (function () { function NgxBootstrapTreeviewModule() { } NgxBootstrapTreeviewModule.decorators = [ { type: NgModule, args: [{ imports: [CommonModule, FontAwesomeModule, RouterModule.forChild([])], declarations: [NgxBootstrapTreeviewComponent, NgxBootstrapTreeviewContextMenuComponent], exports: [NgxBootstrapTreeviewComponent], providers: [ContextMenuService, { provide: EventManager, useClass: NgxBootstrapTreeviewEventManagerService }] },] } ]; return NgxBootstrapTreeviewModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var TreeMap = /** @class */ (function () { function TreeMap() { } return TreeMap; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview adde