tree-ngx
Version:
A highly customizable Angular Tree Component, usable with minimal implementation.
714 lines (702 loc) • 34.7 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Component, Input, ViewChild, EventEmitter, ContentChild, Output, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import { BehaviorSubject, timer } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
var NodeSelectedState;
(function (NodeSelectedState) {
NodeSelectedState[NodeSelectedState["checked"] = 0] = "checked";
NodeSelectedState[NodeSelectedState["unChecked"] = 1] = "unChecked";
NodeSelectedState[NodeSelectedState["indeterminate"] = 2] = "indeterminate";
})(NodeSelectedState || (NodeSelectedState = {}));
var TreeMode;
(function (TreeMode) {
TreeMode[TreeMode["NoSelect"] = 0] = "NoSelect";
TreeMode[TreeMode["SingleSelect"] = 1] = "SingleSelect";
TreeMode[TreeMode["MultiSelect"] = 2] = "MultiSelect";
TreeMode[TreeMode["HideSelected"] = 3] = "HideSelected";
})(TreeMode || (TreeMode = {}));
class TreeUtil {
static initState(parent, nodeItem, options) {
const nodeState = {
parent: parent,
children: [],
filteredChildren: [],
hasFilteredChildren: false,
nodeItem: nodeItem,
expanded: nodeItem.expanded === false ? false : true,
disabled: nodeItem.disabled === true ? true : false,
markSelected: this.getMarkSelected(nodeItem, options),
selectedState: NodeSelectedState.unChecked,
selected: false,
showCheckBox: options.checkboxes
};
return nodeState;
}
static getMarkSelected(nodeItem, options) {
if (((!nodeItem.children || nodeItem.children.length === 0) || options.mode === TreeMode.SingleSelect) && !options.checkboxes) {
return true;
}
else {
return false;
}
}
}
class TreeService {
constructor() {
this.callbacks = {};
this.treeState = [];
this.selectedItems = [];
this.selectedStates = [];
this.filterValue = '';
this.selectedItemsSubject = new BehaviorSubject(this.selectedItems);
this.filterChangeSubject = new BehaviorSubject(this.filterValue);
this.filterChangeSubject.pipe(debounceTime(300), distinctUntilChanged()).subscribe(it => {
this.filterTraverse(this.treeState, this.filterValue);
});
}
toggleSelected(state) {
this.toggleSelectedState(state, false);
if (this.callbacks.toggle) {
this.callbacks.toggle(state.nodeItem);
}
}
toggleSelectedState(state, ignoreDisabled) {
if (this.isDisabled(state, ignoreDisabled)) {
return;
}
if (state.selectedState === NodeSelectedState.unChecked) {
if (this.options.mode === TreeMode.SingleSelect) {
this.clear();
this.setChecked(state, false, true, ignoreDisabled);
}
else {
this.setChecked(state, true, false, ignoreDisabled);
}
}
else if (state.selectedState === NodeSelectedState.checked) {
if (this.options.mode === TreeMode.SingleSelect) {
this.setUnchecked(state, false, true, ignoreDisabled);
}
else {
this.setUnchecked(state, true, false, ignoreDisabled);
}
}
else {
if (this.anyActiveSelected(state) && !state.selected) {
this.setUnchecked(state, true, false, ignoreDisabled);
}
else {
this.setChecked(state, true, false, ignoreDisabled);
}
}
if (state.parent && this.options.mode !== TreeMode.SingleSelect) {
this.childStateChanged(state.parent);
}
}
setInitialState() {
this.setInitialSelectedState(this.treeState);
}
childStateChanged(state) {
if (this.anyChildSelected(state)) {
if (this.allChildrenSelected(state)) {
this.setChecked(state, false);
}
else {
this.setIndeterminate(state);
}
}
else {
this.setUnchecked(state, false);
}
if (state.parent) {
this.childStateChanged(state.parent);
}
}
checkBoxClick(state) {
if (this.options.mode !== TreeMode.HideSelected) {
this.toggleSelected(state);
}
}
nameClick(state) {
if (this.callbacks.nameClick) {
this.callbacks.nameClick(state.nodeItem);
}
if (this.canToggleChildrenOnName()) {
this.toggleSelected(state);
}
}
toggleExpanded(value) {
this.toggleExpandedTraverse(this.treeState, value);
}
clear() {
for (let state of this.selectedStates) {
state.selected = false;
state.selectedState = NodeSelectedState.unChecked;
}
this.selectedItems.length = 0;
this.selectedStates.length = 0;
}
addNodeById(nodeState, id) {
let result = this.getNodeState(this.treeState, id, this.findById);
if (result) {
if (!result.children) {
result.children = [];
}
this.addNewNode(nodeState, result);
if (result.nodeItem.item && this.options.mode === TreeMode.MultiSelect) {
this.removeSelected(result.nodeItem.item);
}
}
}
selectById(id) {
let result = this.getNodeState(this.treeState, id, this.findById);
if (result) {
this.toggleSelected(result);
}
}
editNameById(id, name) {
const nodeState = this.getNodeState(this.treeState, id, this.findById);
if (nodeState && nodeState.nodeItem) {
nodeState.nodeItem.name = name;
}
}
editItemById(id, item) {
const nodeState = this.getNodeState(this.treeState, id, this.findById);
if (nodeState && nodeState.nodeItem) {
if (this.selectedItems.includes(nodeState.nodeItem.item)) {
this.removeSelected(nodeState.nodeItem.item);
this.selectedItems.push(item);
this.selectedItemsSubject.next(this.selectedItems);
}
nodeState.nodeItem.item = item;
}
}
deleteById(id) {
let result = this.getNodeState(this.treeState, id, this.findById);
if (result) {
this.deleteByState(result);
}
}
deleteByState(state) {
this.delete(state);
this.childStateChanged(state);
this.filterTraverse(this.treeState, this.filterValue);
}
expandById(id) {
const result = this.getNodeState(this.treeState, id, this.findById);
if (result) {
this.toggleExpandedTraverseAsc(result, true);
}
}
collapseById(id) {
const result = this.getNodeState(this.treeState, id, this.findById);
if (result) {
result.expanded = false;
}
}
reEvaluateSelectedState(state) {
if (this.options.mode !== TreeMode.SingleSelect) {
if (!this.hasNoChildren(state)) {
this.childStateChanged(state);
for (const child of state.children) {
this.reEvaluateSelectedState(child);
}
}
}
}
filterChanged(value) {
this.filterValue = value;
this.filterChangeSubject.next(value);
}
canToggleChildrenOnName() {
if (this.options.checkboxes === false) {
if (this.options.mode === TreeMode.SingleSelect || this.options.mode === TreeMode.MultiSelect) {
return true;
}
}
return false;
}
getParentById(id) {
const result = this.getNodeState(this.treeState, id, this.findById);
if (result) {
return result.parent.nodeItem;
}
return null;
}
forceFilterTraverse() {
this.filterTraverse(this.treeState, this.filterValue);
}
setInitialSelectedState(nodeStates) {
for (const state of nodeStates) {
if (this.options.mode === TreeMode.MultiSelect) {
if (state.nodeItem.selected && (!state.children || state.children.length === 0)) {
this.toggleSelectedState(state, true);
}
}
else {
if (state.nodeItem.selected) {
this.toggleSelectedState(state, true);
}
}
this.setInitialSelectedState(state.children);
}
}
delete(state) {
while (state.children.length > 0) {
this.delete(state.children.pop());
}
this.removeSelected(state.nodeItem.item);
this.remove(state);
if (!state.parent) {
this.deleteRoot(state, this.treeState, this.nodeItems);
}
}
toggleExpandedTraverse(nodeStates, value) {
for (let state of nodeStates) {
state.expanded = value;
this.toggleExpandedTraverse(state.children, value);
}
}
deleteRoot(state, nodeStates, nodeItems) {
let itemIndex = nodeItems.indexOf(state.nodeItem);
if (itemIndex !== -1) {
nodeItems.splice(itemIndex, 1);
}
let index = nodeStates.indexOf(state);
if (index !== -1) {
nodeStates.splice(index, 1);
}
}
isDisabled(state, ignoreDisabled) {
return (this.options.mode === TreeMode.NoSelect || (state.disabled && !ignoreDisabled));
}
addNewNode(nodeState, parent) {
nodeState.parent = parent;
parent.children.push(nodeState);
parent.nodeItem.children.push(nodeState.nodeItem);
parent.markSelected = TreeUtil.getMarkSelected(parent.nodeItem, this.options);
if (this.options.mode === TreeMode.MultiSelect) {
this.childStateChanged(parent);
}
this.filterTraverse(this.treeState, this.filterValue);
}
remove(state) {
if (state.parent) {
state.parent.hasFilteredChildren = false;
let itemIndex = state.parent.nodeItem.children.indexOf(state.nodeItem);
if (itemIndex !== -1) {
state.parent.nodeItem.children.splice(itemIndex, 1);
}
let index = state.parent.children.indexOf(state);
if (index !== -1) {
state.parent.children.splice(index, 1);
}
let filteredIndex = state.parent.filteredChildren.indexOf(state);
if (filteredIndex !== -1) {
state.parent.filteredChildren.splice(filteredIndex, 1);
}
}
}
anyChildSelected(state) {
return state.children.find(it => {
return it.selectedState === NodeSelectedState.checked || it.selectedState === NodeSelectedState.indeterminate;
}) != null ? true : false;
}
allChildrenSelected(state) {
return state.children.every(it => it.selectedState === NodeSelectedState.checked)
&& state.children.length === state.nodeItem.children.length;
}
toggleExpandedTraverseAsc(nodeState, value) {
nodeState.expanded = value;
if (nodeState.parent) {
this.toggleExpandedTraverseAsc(nodeState.parent, value);
}
}
setUnchecked(state, propogate, force, ignoreDisabled) {
if (state.disabled && !ignoreDisabled) {
return;
}
state.selectedState = NodeSelectedState.unChecked;
state.selected = false;
if (this.hasNoChildren(state) || force) {
this.removeSelected(state.nodeItem.item);
if (this.options.alwaysEmitSelected === true) {
this.selectedItemsSubject.next(this.selectedItems);
}
if (this.callbacks.unSelect) {
this.callbacks.unSelect(state.nodeItem);
}
}
else if (propogate === true) {
for (const child of state.children) {
this.setUnchecked(child, propogate, force, ignoreDisabled);
}
}
}
setIndeterminate(state) {
state.selectedState = NodeSelectedState.indeterminate;
state.selected = false;
}
anyActiveSelected(state) {
let result = state.children.filter(it => !it.disabled && it.selected).length > 0;
for (const child of state.children) {
if (!this.hasNoChildren(child) && this.anyActiveSelected(child)) {
result = true;
}
}
return result;
}
hasNoChildren(state) {
return (!state.children || state.children.length === 0);
}
setChecked(state, propogate, force, ignoreDisabled) {
if (state.disabled && !ignoreDisabled) {
return;
}
state.selectedState = NodeSelectedState.checked;
state.selected = true;
if (this.hasNoChildren(state) || force) {
this.addSelected(state);
}
else if (propogate === true) {
for (const child of state.children) {
this.setChecked(child, propogate, force, ignoreDisabled);
}
}
}
addSelected(state) {
this.selectedItems.push(state.nodeItem.item);
this.selectedStates.push(state);
if (this.options.alwaysEmitSelected === true) {
this.selectedItemsSubject.next(this.selectedItems);
}
if (this.callbacks.select) {
this.callbacks.select(state.nodeItem);
}
}
removeSelected(item) {
let index = this.selectedItems.indexOf(item);
if (index !== -1) {
this.selectedItems.splice(index, 1);
}
}
findById(state, arg) {
return state.nodeItem.id === arg;
}
getNodeState(nodeStates, arg, compare) {
let result = nodeStates.find(it => compare(it, arg));
if (result) {
return result;
}
else {
for (let state of nodeStates) {
result = this.getNodeState(state.children, arg, compare);
if (result) {
return result;
}
}
}
return result;
}
connect() {
return this.selectedItemsSubject.asObservable();
}
applyFilter(state, filter) {
state.filteredChildren = this.filter(state.children, filter);
return state.filteredChildren.length > 0;
}
filter(states, value) {
return states.filter(it => {
if (this.options.mode === TreeMode.HideSelected && !it.selected) {
return false;
}
if ((it.hasFilteredChildren || value === '' || it.nodeItem.name.toLowerCase().indexOf(value) !== -1)) {
return true;
}
});
}
filterTraverse(states, filter) {
let results = [];
for (let state of states) {
if (state.children.length > 0) {
state.hasFilteredChildren = false;
state.hasFilteredChildren = this.filterTraverse(state.children, filter);
let res = this.applyFilter(state, filter);
if (res) {
state.hasFilteredChildren = true;
}
results.push(state.hasFilteredChildren);
}
}
return results.some(it => it === true);
}
}
TreeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
TreeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeService, decorators: [{
type: Injectable
}], ctorParameters: function () { return []; } });
class NodeIconWrapperComponent {
constructor() {
this._this = this;
}
toggleExpand() {
this.state.expanded = !this.state.expanded;
}
}
NodeIconWrapperComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: NodeIconWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
NodeIconWrapperComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: NodeIconWrapperComponent, selector: "node-icon-wrapper", inputs: { state: "state", nodeCollapsibleTemplate: "nodeCollapsibleTemplate" }, ngImport: i0, template: "<div class=\"node-icon-wrapper\" [class.disabled]=\"state.nodeItem?.children?.length == 0\" [class.collapsable]=\"state.nodeItem?.children?.length > 0\"\r\n [class.iconCheckbox]=\"state.showCheckBox\" (click)=\"state.expanded = !state.expanded;\">\r\n <ng-container *ngIf=\"!nodeCollapsibleTemplate\">\r\n <ng-container *ngIf=\"state.nodeItem?.children?.length > 0\">\r\n <i *ngIf=\"!state.expanded\" class=\"arrow-right\"></i>\r\n <i *ngIf=\"state.expanded\" class=\"arrow-down\"></i>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"state.nodeItem?.children?.length > 0\">\r\n <ng-container *ngTemplateOutlet=\"nodeCollapsibleTemplate; context: { expanded: state.expanded, context: _this }\">\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n", directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: NodeIconWrapperComponent, decorators: [{
type: Component,
args: [{ selector: 'node-icon-wrapper', template: "<div class=\"node-icon-wrapper\" [class.disabled]=\"state.nodeItem?.children?.length == 0\" [class.collapsable]=\"state.nodeItem?.children?.length > 0\"\r\n [class.iconCheckbox]=\"state.showCheckBox\" (click)=\"state.expanded = !state.expanded;\">\r\n <ng-container *ngIf=\"!nodeCollapsibleTemplate\">\r\n <ng-container *ngIf=\"state.nodeItem?.children?.length > 0\">\r\n <i *ngIf=\"!state.expanded\" class=\"arrow-right\"></i>\r\n <i *ngIf=\"state.expanded\" class=\"arrow-down\"></i>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"state.nodeItem?.children?.length > 0\">\r\n <ng-container *ngTemplateOutlet=\"nodeCollapsibleTemplate; context: { expanded: state.expanded, context: _this }\">\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n" }]
}], ctorParameters: function () { return []; }, propDecorators: { state: [{
type: Input
}], nodeCollapsibleTemplate: [{
type: Input
}] } });
class NodeNameComponent {
constructor(treeService) {
this.treeService = treeService;
this._this = this;
this.active = false;
}
ngOnChanges(changes) {
if (changes.state) {
this.active = this.treeService.canToggleChildrenOnName();
}
}
nameClick() {
this.treeService.nameClick(this.state);
}
delete() {
this.treeService.deleteByState(this.state);
}
}
NodeNameComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: NodeNameComponent, deps: [{ token: TreeService }], target: i0.ɵɵFactoryTarget.Component });
NodeNameComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: NodeNameComponent, selector: "node-name", inputs: { state: "state", nodeNameTemplate: "nodeNameTemplate" }, usesOnChanges: true, ngImport: i0, template: "<div (click)=\"nameClick()\" [class.markSelected]=\"state.markSelected && state.selected\" [class.nodeDisabled]=\"state.disabled\" class=\"node-name\">\r\n <ng-container *ngIf=\"!nodeNameTemplate\">\r\n <span [class.active]=\"active\">{{state.nodeItem.name}}</span>\r\n </ng-container>\r\n\r\n <ng-container *ngTemplateOutlet=\"nodeNameTemplate; context: { $implicit: state.nodeItem, node: state.nodeItem, context: _this }\">\r\n </ng-container>\r\n</div>\r\n", directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: NodeNameComponent, decorators: [{
type: Component,
args: [{ selector: 'node-name', template: "<div (click)=\"nameClick()\" [class.markSelected]=\"state.markSelected && state.selected\" [class.nodeDisabled]=\"state.disabled\" class=\"node-name\">\r\n <ng-container *ngIf=\"!nodeNameTemplate\">\r\n <span [class.active]=\"active\">{{state.nodeItem.name}}</span>\r\n </ng-container>\r\n\r\n <ng-container *ngTemplateOutlet=\"nodeNameTemplate; context: { $implicit: state.nodeItem, node: state.nodeItem, context: _this }\">\r\n </ng-container>\r\n</div>\r\n" }]
}], ctorParameters: function () { return [{ type: TreeService }]; }, propDecorators: { state: [{
type: Input
}], nodeNameTemplate: [{
type: Input
}] } });
class NodeComponent {
constructor(treeService) {
this.treeService = treeService;
this._this = this;
}
ngOnChanges(changes) {
if (changes.selectedState) {
this.selectedStateChanged();
}
}
ngAfterViewInit() {
this.selectedStateChanged();
}
selectedStateChanged() {
if (this.nodeCheckbox) {
if (this.selectedState === NodeSelectedState.indeterminate) {
this.nodeCheckbox.nativeElement.indeterminate = true;
}
else {
this.nodeCheckbox.nativeElement.indeterminate = false;
}
if (this.selectedState === NodeSelectedState.checked) {
this.nodeCheckbox.nativeElement.checked = true;
}
else if (this.selectedState === NodeSelectedState.unChecked) {
this.nodeCheckbox.nativeElement.checked = false;
}
}
}
checkBoxClick() {
this.treeService.checkBoxClick(this.state);
setTimeout(() => {
this.treeService.reEvaluateSelectedState(this.state);
}, 1);
}
}
NodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: NodeComponent, deps: [{ token: TreeService }], target: i0.ɵɵFactoryTarget.Component });
NodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: NodeComponent, selector: "node", inputs: { state: "state", selectedState: "selectedState", nodeNameTemplate: "nodeNameTemplate", nodeCollapsibleTemplate: "nodeCollapsibleTemplate" }, viewQueries: [{ propertyName: "nodeCheckbox", first: true, predicate: ["nodeCheckbox"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"node\">\r\n <div class=\"node-container\">\r\n <node-icon-wrapper [state]=\"state\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\"></node-icon-wrapper>\r\n\r\n <input #nodeCheckbox class=\"node-checkbox\" *ngIf=\"state.showCheckBox\" (click)=\"checkBoxClick()\" [disabled]=\"state.disabled\" [checked]=\"state.selected\" type=\"checkbox\" />\r\n <node-name [state]=\"state\" [nodeNameTemplate]=\"nodeNameTemplate\"></node-name>\r\n </div>\r\n <div *ngIf=\"state.nodeItem.children\" class=\"collapsible-wrapper\" [class.collapsed]=\"!state.expanded && state.nodeItem.children.length > 0 && state.filteredChildren.length > 0\">\r\n <div class=\"collapsible\">\r\n <node class=\"node-offset\" [state]=\"child\" [selectedState]=\"child.selectedState\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\" [nodeNameTemplate]=\"nodeNameTemplate\" *ngFor=\"let child of state.filteredChildren\"></node>\r\n </div>\r\n </div>\r\n</div>\r\n", components: [{ type: NodeIconWrapperComponent, selector: "node-icon-wrapper", inputs: ["state", "nodeCollapsibleTemplate"] }, { type: NodeNameComponent, selector: "node-name", inputs: ["state", "nodeNameTemplate"] }, { type: NodeComponent, selector: "node", inputs: ["state", "selectedState", "nodeNameTemplate", "nodeCollapsibleTemplate"] }], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: NodeComponent, decorators: [{
type: Component,
args: [{ selector: 'node', template: "<div class=\"node\">\r\n <div class=\"node-container\">\r\n <node-icon-wrapper [state]=\"state\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\"></node-icon-wrapper>\r\n\r\n <input #nodeCheckbox class=\"node-checkbox\" *ngIf=\"state.showCheckBox\" (click)=\"checkBoxClick()\" [disabled]=\"state.disabled\" [checked]=\"state.selected\" type=\"checkbox\" />\r\n <node-name [state]=\"state\" [nodeNameTemplate]=\"nodeNameTemplate\"></node-name>\r\n </div>\r\n <div *ngIf=\"state.nodeItem.children\" class=\"collapsible-wrapper\" [class.collapsed]=\"!state.expanded && state.nodeItem.children.length > 0 && state.filteredChildren.length > 0\">\r\n <div class=\"collapsible\">\r\n <node class=\"node-offset\" [state]=\"child\" [selectedState]=\"child.selectedState\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\" [nodeNameTemplate]=\"nodeNameTemplate\" *ngFor=\"let child of state.filteredChildren\"></node>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
}], ctorParameters: function () { return [{ type: TreeService }]; }, propDecorators: { nodeCheckbox: [{
type: ViewChild,
args: ['nodeCheckbox', { static: false }]
}], state: [{
type: Input
}], selectedState: [{
type: Input
}], nodeNameTemplate: [{
type: Input
}], nodeCollapsibleTemplate: [{
type: Input
}] } });
class TreeNgxComponent {
constructor(treeService) {
this.treeService = treeService;
this.defaultOptions = {
mode: TreeMode.SingleSelect,
checkboxes: false,
alwaysEmitSelected: false
};
this.options = this.defaultOptions;
this.callbacks = this.treeService.callbacks;
this.filter = '';
this.selectedItems = new EventEmitter();
}
ngOnInit() {
this.subscription = this.treeService.connect().subscribe(it => {
const sub = timer(0).subscribe(() => {
this.selectedItems.emit(it);
sub.unsubscribe();
});
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnChanges(changes) {
if (changes.filter) {
this.treeService.filterChanged(this.filter.toLowerCase());
}
if (changes.options) {
this.setOptions();
if (this.treeService.nodeItems) {
this.treeService.treeState = this.initTreeStructure(null, this.treeService.nodeItems, this.treeService.options);
this.treeService.clear();
this.treeService.setInitialState();
this.treeService.forceFilterTraverse();
}
}
if (changes.callbacks) {
this.treeService.callbacks = this.callbacks;
}
if (changes.nodeItems) {
this.initialize();
}
}
addNodeById(nodeItem, id) {
const newNodeState = TreeUtil.initState(null, nodeItem, this.options);
this.treeService.addNodeById(newNodeState, id);
}
deleteById(id) {
this.treeService.deleteById(id);
}
editNameById(id, name) {
this.treeService.editNameById(id, name);
}
editItemById(id, item) {
this.treeService.editItemById(id, item);
}
getParentById(id) {
return this.treeService.getParentById(id);
}
expandAll() {
this.treeService.toggleExpanded(true);
}
collapseAll() {
this.treeService.toggleExpanded(false);
}
expandById(id) {
this.treeService.expandById(id);
}
collapseById(id) {
this.treeService.collapseById(id);
}
selectById(id) {
this.treeService.selectById(id);
}
initialize() {
this.setOptions();
this.treeService.callbacks = this.callbacks;
this.treeService.nodeItems = this.nodeItems;
this.treeService.treeState = this.initTreeStructure(null, this.treeService.nodeItems, this.treeService.options);
this.treeService.clear();
this.treeService.setInitialState();
}
initTreeStructure(parent, nodeItems, options) {
let treeStructure = [];
for (let nodeItem of nodeItems) {
const nodeState = TreeUtil.initState(parent, nodeItem, options);
if (nodeItem.children) {
nodeState.children = this.initTreeStructure(nodeState, nodeItem.children, options);
nodeState.filteredChildren = nodeState.children;
}
treeStructure.push(nodeState);
}
return treeStructure;
}
setOptions() {
if (this.options.mode === TreeMode.NoSelect) {
this.treeService.options = { ...this.options, checkboxes: false };
}
else {
this.treeService.options = { ...this.options };
}
}
}
TreeNgxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxComponent, deps: [{ token: TreeService }], target: i0.ɵɵFactoryTarget.Component });
TreeNgxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: TreeNgxComponent, selector: "tree-ngx", inputs: { options: "options", callbacks: "callbacks", nodeItems: "nodeItems", filter: "filter" }, outputs: { selectedItems: "selectedItems" }, providers: [TreeService], queries: [{ propertyName: "nodeNameTemplate", first: true, predicate: ["nodeNameTemplate"], descendants: true }, { propertyName: "nodeCollapsibleTemplate", first: true, predicate: ["nodeCollapsibleTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"tree-ngx\">\r\n <node class=\"node-root\" [state]=\"state\" [selectedState]=\"state.selectedState\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\"\r\n [nodeNameTemplate]=\"nodeNameTemplate\" *ngFor=\"let state of treeService.treeState\"></node>\r\n</div>\r\n", components: [{ type: NodeComponent, selector: "node", inputs: ["state", "selectedState", "nodeNameTemplate", "nodeCollapsibleTemplate"] }], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxComponent, decorators: [{
type: Component,
args: [{ selector: 'tree-ngx', providers: [TreeService], template: "<div class=\"tree-ngx\">\r\n <node class=\"node-root\" [state]=\"state\" [selectedState]=\"state.selectedState\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\"\r\n [nodeNameTemplate]=\"nodeNameTemplate\" *ngFor=\"let state of treeService.treeState\"></node>\r\n</div>\r\n" }]
}], ctorParameters: function () { return [{ type: TreeService }]; }, propDecorators: { nodeNameTemplate: [{
type: ContentChild,
args: ['nodeNameTemplate', { static: false }]
}], nodeCollapsibleTemplate: [{
type: ContentChild,
args: ['nodeCollapsibleTemplate', { static: false }]
}], options: [{
type: Input
}], callbacks: [{
type: Input
}], nodeItems: [{
type: Input
}], filter: [{
type: Input
}], selectedItems: [{
type: Output
}] } });
class TreeNgxModule {
}
TreeNgxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
TreeNgxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxModule, declarations: [TreeNgxComponent,
NodeComponent,
NodeNameComponent,
NodeIconWrapperComponent], imports: [CommonModule], exports: [TreeNgxComponent] });
TreeNgxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxModule, providers: [
TreeService
], imports: [[
CommonModule
]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxModule, decorators: [{
type: NgModule,
args: [{
imports: [
CommonModule
],
declarations: [
TreeNgxComponent,
NodeComponent,
NodeNameComponent,
NodeIconWrapperComponent,
],
providers: [
TreeService
],
exports: [
TreeNgxComponent
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { TreeMode, TreeNgxComponent, TreeNgxModule };
//# sourceMappingURL=tree-ngx.mjs.map