UNPKG

@circlon/angular-tree-component

Version:
1,287 lines (1,279 loc) 91.2 kB
import { Directive, TemplateRef, ViewContainerRef, Input, Injectable, ɵɵdefineInjectable, Component, ViewEncapsulation, ElementRef, EventEmitter, ContentChild, ViewChild, Output, HostListener, Renderer2, NgZone, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { autorun, reaction, computed as computed$1, observable as observable$1, action as action$1 } from 'mobx'; class TreeMobxAutorunDirective { constructor(templateRef, viewContainer) { this.templateRef = templateRef; this.viewContainer = viewContainer; this.templateBindings = {}; } ngOnInit() { this.view = this.viewContainer.createEmbeddedView(this.templateRef); if (this.dispose) { this.dispose(); } if (this.shouldDetach()) { this.view.detach(); } this.autoDetect(this.view); } shouldDetach() { return this.treeMobxAutorun && this.treeMobxAutorun.detach; } autoDetect(view) { this.dispose = autorun(() => view.detectChanges()); } ngOnDestroy() { if (this.dispose) { this.dispose(); } } } TreeMobxAutorunDirective.decorators = [ { type: Directive, args: [{ selector: '[treeMobxAutorun]' },] } ]; /** @nocollapse */ TreeMobxAutorunDirective.ctorParameters = () => [ { type: TemplateRef }, { type: ViewContainerRef } ]; TreeMobxAutorunDirective.propDecorators = { treeMobxAutorun: [{ type: Input }] }; const KEYS = { LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, ENTER: 13, SPACE: 32, CONTEXT_MENU: 32 }; const ɵ0 = (tree, node, $event) => node && node.toggleActivated(), ɵ1 = (tree, node, $event) => node && node.toggleActivated(true), ɵ2 = (tree, node, $event) => node && node.toggleSelected(), ɵ3 = (tree, node, $event) => node.setIsActive(true), ɵ4 = (tree, node, $event) => node.setIsActive(false), ɵ5 = (tree, node, $event) => node.setIsSelected(true), ɵ6 = (tree, node, $event) => node.setIsSelected(false), ɵ7 = (tree, node, $event) => node.focus(), ɵ8 = (tree, node, $event) => node.hasChildren && node.toggleExpanded(), ɵ9 = (tree, node, $event) => node.expand(), ɵ10 = (tree, node, $event) => node.collapse(), ɵ11 = (tree, node, $event) => tree.focusDrillDown(), ɵ12 = (tree, node, $event) => tree.focusDrillUp(), ɵ13 = (tree, node, $event) => tree.focusNextNode(), ɵ14 = (tree, node, $event) => tree.focusPreviousNode(), ɵ15 = (tree, node, $event, { from, to }) => { // default action assumes from = node, to = {parent, index} if ($event.ctrlKey) { tree.copyNode(from, to); } else { tree.moveNode(from, to); } }; const TREE_ACTIONS = { TOGGLE_ACTIVE: ɵ0, TOGGLE_ACTIVE_MULTI: ɵ1, TOGGLE_SELECTED: ɵ2, ACTIVATE: ɵ3, DEACTIVATE: ɵ4, SELECT: ɵ5, DESELECT: ɵ6, FOCUS: ɵ7, TOGGLE_EXPANDED: ɵ8, EXPAND: ɵ9, COLLAPSE: ɵ10, DRILL_DOWN: ɵ11, DRILL_UP: ɵ12, NEXT_NODE: ɵ13, PREVIOUS_NODE: ɵ14, MOVE_NODE: ɵ15 }; const defaultActionMapping = { mouse: { click: TREE_ACTIONS.TOGGLE_ACTIVE, dblClick: null, contextMenu: null, expanderClick: TREE_ACTIONS.TOGGLE_EXPANDED, checkboxClick: TREE_ACTIONS.TOGGLE_SELECTED, drop: TREE_ACTIONS.MOVE_NODE }, keys: { [KEYS.RIGHT]: TREE_ACTIONS.DRILL_DOWN, [KEYS.LEFT]: TREE_ACTIONS.DRILL_UP, [KEYS.DOWN]: TREE_ACTIONS.NEXT_NODE, [KEYS.UP]: TREE_ACTIONS.PREVIOUS_NODE, [KEYS.SPACE]: TREE_ACTIONS.TOGGLE_ACTIVE, [KEYS.ENTER]: TREE_ACTIONS.TOGGLE_ACTIVE } }; class TreeOptions { constructor(options = {}) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35; this.options = options; this.actionMapping = { mouse: { click: (_d = (_c = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.actionMapping) === null || _b === void 0 ? void 0 : _b.mouse) === null || _c === void 0 ? void 0 : _c.click) !== null && _d !== void 0 ? _d : defaultActionMapping.mouse.click, dblClick: (_h = (_g = (_f = (_e = this.options) === null || _e === void 0 ? void 0 : _e.actionMapping) === null || _f === void 0 ? void 0 : _f.mouse) === null || _g === void 0 ? void 0 : _g.dblClick) !== null && _h !== void 0 ? _h : defaultActionMapping.mouse.dblClick, contextMenu: (_m = (_l = (_k = (_j = this.options) === null || _j === void 0 ? void 0 : _j.actionMapping) === null || _k === void 0 ? void 0 : _k.mouse) === null || _l === void 0 ? void 0 : _l.contextMenu) !== null && _m !== void 0 ? _m : defaultActionMapping.mouse.contextMenu, expanderClick: (_r = (_q = (_p = (_o = this.options) === null || _o === void 0 ? void 0 : _o.actionMapping) === null || _p === void 0 ? void 0 : _p.mouse) === null || _q === void 0 ? void 0 : _q.expanderClick) !== null && _r !== void 0 ? _r : defaultActionMapping.mouse.expanderClick, checkboxClick: (_v = (_u = (_t = (_s = this.options) === null || _s === void 0 ? void 0 : _s.actionMapping) === null || _t === void 0 ? void 0 : _t.mouse) === null || _u === void 0 ? void 0 : _u.checkboxClick) !== null && _v !== void 0 ? _v : defaultActionMapping.mouse.checkboxClick, drop: (_z = (_y = (_x = (_w = this.options) === null || _w === void 0 ? void 0 : _w.actionMapping) === null || _x === void 0 ? void 0 : _x.mouse) === null || _y === void 0 ? void 0 : _y.drop) !== null && _z !== void 0 ? _z : defaultActionMapping.mouse.drop, dragStart: (_3 = (_2 = (_1 = (_0 = this.options) === null || _0 === void 0 ? void 0 : _0.actionMapping) === null || _1 === void 0 ? void 0 : _1.mouse) === null || _2 === void 0 ? void 0 : _2.dragStart) !== null && _3 !== void 0 ? _3 : undefined, drag: (_7 = (_6 = (_5 = (_4 = this.options) === null || _4 === void 0 ? void 0 : _4.actionMapping) === null || _5 === void 0 ? void 0 : _5.mouse) === null || _6 === void 0 ? void 0 : _6.drag) !== null && _7 !== void 0 ? _7 : undefined, dragEnd: (_11 = (_10 = (_9 = (_8 = this.options) === null || _8 === void 0 ? void 0 : _8.actionMapping) === null || _9 === void 0 ? void 0 : _9.mouse) === null || _10 === void 0 ? void 0 : _10.dragEnd) !== null && _11 !== void 0 ? _11 : undefined, dragOver: (_15 = (_14 = (_13 = (_12 = this.options) === null || _12 === void 0 ? void 0 : _12.actionMapping) === null || _13 === void 0 ? void 0 : _13.mouse) === null || _14 === void 0 ? void 0 : _14.dragOver) !== null && _15 !== void 0 ? _15 : undefined, dragLeave: (_19 = (_18 = (_17 = (_16 = this.options) === null || _16 === void 0 ? void 0 : _16.actionMapping) === null || _17 === void 0 ? void 0 : _17.mouse) === null || _18 === void 0 ? void 0 : _18.dragLeave) !== null && _19 !== void 0 ? _19 : undefined, dragEnter: (_23 = (_22 = (_21 = (_20 = this.options) === null || _20 === void 0 ? void 0 : _20.actionMapping) === null || _21 === void 0 ? void 0 : _21.mouse) === null || _22 === void 0 ? void 0 : _22.dragEnter) !== null && _23 !== void 0 ? _23 : undefined, mouseOver: (_27 = (_26 = (_25 = (_24 = this.options) === null || _24 === void 0 ? void 0 : _24.actionMapping) === null || _25 === void 0 ? void 0 : _25.mouse) === null || _26 === void 0 ? void 0 : _26.mouseOver) !== null && _27 !== void 0 ? _27 : undefined, mouseOut: (_31 = (_30 = (_29 = (_28 = this.options) === null || _28 === void 0 ? void 0 : _28.actionMapping) === null || _29 === void 0 ? void 0 : _29.mouse) === null || _30 === void 0 ? void 0 : _30.mouseOut) !== null && _31 !== void 0 ? _31 : undefined, }, keys: { [KEYS.RIGHT]: TREE_ACTIONS.DRILL_DOWN, [KEYS.LEFT]: TREE_ACTIONS.DRILL_UP, [KEYS.DOWN]: TREE_ACTIONS.NEXT_NODE, [KEYS.UP]: TREE_ACTIONS.PREVIOUS_NODE, [KEYS.SPACE]: TREE_ACTIONS.TOGGLE_ACTIVE, [KEYS.ENTER]: TREE_ACTIONS.TOGGLE_ACTIVE } }; if ((_33 = (_32 = this.options) === null || _32 === void 0 ? void 0 : _32.actionMapping) === null || _33 === void 0 ? void 0 : _33.keys) { this.actionMapping.keys = Object.assign(Object.assign({}, this.actionMapping.keys), this.options.actionMapping.keys); } if (options.rtl) { this.actionMapping.keys[KEYS.RIGHT] = ((_34 = options.actionMapping) === null || _34 === void 0 ? void 0 : _34.keys[KEYS.RIGHT]) || TREE_ACTIONS.DRILL_UP; this.actionMapping.keys[KEYS.LEFT] = ((_35 = options.actionMapping) === null || _35 === void 0 ? void 0 : _35.keys[KEYS.LEFT]) || TREE_ACTIONS.DRILL_DOWN; } } get hasChildrenField() { return this.options.hasChildrenField || 'hasChildren'; } get childrenField() { return this.options.childrenField || 'children'; } get displayField() { return this.options.displayField || 'name'; } get idField() { return this.options.idField || 'id'; } get isExpandedField() { return this.options.isExpandedField || 'isExpanded'; } get getChildren() { return this.options.getChildren; } get levelPadding() { return this.options.levelPadding || 0; } get useVirtualScroll() { return this.options.useVirtualScroll; } get animateExpand() { return this.options.animateExpand; } get animateSpeed() { return this.options.animateSpeed || 1; } get animateAcceleration() { return this.options.animateAcceleration || 1.2; } get scrollOnActivate() { return this.options.scrollOnActivate === undefined ? true : this.options.scrollOnActivate; } get rtl() { return !!this.options.rtl; } get rootId() { return this.options.rootId; } get useCheckbox() { return this.options.useCheckbox; } get useTriState() { return this.options.useTriState === undefined ? true : this.options.useTriState; } get scrollContainer() { return this.options.scrollContainer; } get allowDragoverStyling() { return this.options.allowDragoverStyling === undefined ? true : this.options.allowDragoverStyling; } getNodeClone(node) { if (this.options.getNodeClone) { return this.options.getNodeClone(node); } // remove id from clone // keeping ie11 compatibility const nodeClone = Object.assign({}, node.data); if (nodeClone.id) { delete nodeClone.id; } return nodeClone; } allowDrop(element, to, $event) { if (this.options.allowDrop instanceof Function) { return this.options.allowDrop(element, to, $event); } else { return this.options.allowDrop === undefined ? true : this.options.allowDrop; } } allowDrag(node) { if (this.options.allowDrag instanceof Function) { return this.options.allowDrag(node); } else { return this.options.allowDrag; } } nodeClass(node) { return this.options.nodeClass ? this.options.nodeClass(node) : ''; } nodeHeight(node) { if (node.data.virtual) { return 0; } let nodeHeight = this.options.nodeHeight || 22; if (typeof nodeHeight === 'function') { nodeHeight = nodeHeight(node); } // account for drop slots: return nodeHeight + (node.index === 0 ? 2 : 1) * this.dropSlotHeight; } get dropSlotHeight() { return typeof this.options.dropSlotHeight === 'number' ? this.options.dropSlotHeight : 2; } } const TREE_EVENTS = { toggleExpanded: 'toggleExpanded', activate: 'activate', deactivate: 'deactivate', nodeActivate: 'nodeActivate', nodeDeactivate: 'nodeDeactivate', select: 'select', deselect: 'deselect', focus: 'focus', blur: 'blur', initialized: 'initialized', updateData: 'updateData', moveNode: 'moveNode', copyNode: 'copyNode', event: 'event', loadNodeChildren: 'loadNodeChildren', changeFilter: 'changeFilter', stateChange: 'stateChange' }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; class TreeNode { constructor(data, parent, treeModel, index) { this.data = data; this.parent = parent; this.treeModel = treeModel; this.position = 0; this.allowDrop = (element, $event) => { return this.options.allowDrop(element, { parent: this, index: 0 }, $event); }; this.allowDragoverStyling = () => { return this.options.allowDragoverStyling; }; if (this.id === undefined || this.id === null) { this.id = uuid(); } // Make sure there's a unique id without overriding existing ids to work with immutable data structures this.index = index; if (this.getField('children')) { this._initChildren(); } this.autoLoadChildren(); } get isHidden() { return this.treeModel.isHidden(this); } ; get isExpanded() { return this.treeModel.isExpanded(this); } ; get isActive() { return this.treeModel.isActive(this); } ; get isFocused() { return this.treeModel.isNodeFocused(this); } ; get isSelected() { if (this.isSelectable()) { return this.treeModel.isSelected(this); } else { return this.children.some((node) => node.isSelected); } } ; get isAllSelected() { if (this.isSelectable()) { return this.treeModel.isSelected(this); } else { return this.children.every((node) => node.isAllSelected); } } ; get isPartiallySelected() { return this.isSelected && !this.isAllSelected; } get level() { return this.parent ? this.parent.level + 1 : 0; } get path() { return this.parent ? [...this.parent.path, this.id] : []; } get elementRef() { throw `Element Ref is no longer supported since introducing virtual scroll\n You may use a template to obtain a reference to the element`; } get originalNode() { return this._originalNode; } ; // helper get functions: get hasChildren() { return !!(this.getField('hasChildren') || (this.children && this.children.length > 0)); } get isCollapsed() { return !this.isExpanded; } get isLeaf() { return !this.hasChildren; } get isRoot() { return this.parent.data.virtual; } get realParent() { return this.isRoot ? null : this.parent; } // proxy functions: get options() { return this.treeModel.options; } fireEvent(event) { this.treeModel.fireEvent(event); } // field accessors: get displayField() { return this.getField('display'); } get id() { return this.getField('id'); } set id(value) { this.setField('id', value); } getField(key) { return this.data[this.options[`${key}Field`]]; } setField(key, value) { this.data[this.options[`${key}Field`]] = value; } // traversing: _findAdjacentSibling(steps, skipHidden = false) { const siblings = this._getParentsChildren(skipHidden); const index = siblings.indexOf(this); return siblings.length > index + steps ? siblings[index + steps] : null; } findNextSibling(skipHidden = false) { return this._findAdjacentSibling(+1, skipHidden); } findPreviousSibling(skipHidden = false) { return this._findAdjacentSibling(-1, skipHidden); } getVisibleChildren() { return this.visibleChildren; } get visibleChildren() { return (this.children || []).filter((node) => !node.isHidden); } getFirstChild(skipHidden = false) { let children = skipHidden ? this.visibleChildren : this.children; return children != null && children.length ? children[0] : null; } getLastChild(skipHidden = false) { let children = skipHidden ? this.visibleChildren : this.children; return children != null && children.length ? children[children.length - 1] : null; } findNextNode(goInside = true, skipHidden = false) { return goInside && this.isExpanded && this.getFirstChild(skipHidden) || this.findNextSibling(skipHidden) || this.parent && this.parent.findNextNode(false, skipHidden); } findPreviousNode(skipHidden = false) { let previousSibling = this.findPreviousSibling(skipHidden); if (!previousSibling) { return this.realParent; } return previousSibling._getLastOpenDescendant(skipHidden); } _getLastOpenDescendant(skipHidden = false) { const lastChild = this.getLastChild(skipHidden); return (this.isCollapsed || !lastChild) ? this : lastChild._getLastOpenDescendant(skipHidden); } _getParentsChildren(skipHidden = false) { const children = this.parent && (skipHidden ? this.parent.getVisibleChildren() : this.parent.children); return children || []; } getIndexInParent(skipHidden = false) { return this._getParentsChildren(skipHidden).indexOf(this); } isDescendantOf(node) { if (this === node) return true; else return this.parent && this.parent.isDescendantOf(node); } getNodePadding() { return this.options.levelPadding * (this.level - 1) + 'px'; } getClass() { return [this.options.nodeClass(this), `tree-node-level-${this.level}`].join(' '); } onDrop($event) { this.mouseAction('drop', $event.event, { from: $event.element, to: { parent: this, index: 0, dropOnNode: true } }); } allowDrag() { return this.options.allowDrag(this); } // helper methods: loadNodeChildren() { if (!this.options.getChildren) { return Promise.resolve(); // Not getChildren method - for using redux } return Promise.resolve(this.options.getChildren(this)) .then((children) => { if (children) { this.setField('children', children); this._initChildren(); if (this.options.useTriState && this.treeModel.isSelected(this)) { this.setIsSelected(true); } this.children.forEach((child) => { if (child.getField('isExpanded') && child.hasChildren) { child.expand(); } }); } }).then(() => { this.fireEvent({ eventName: TREE_EVENTS.loadNodeChildren, node: this }); }); } expand() { if (!this.isExpanded) { this.toggleExpanded(); } return this; } collapse() { if (this.isExpanded) { this.toggleExpanded(); } return this; } doForAll(fn) { Promise.resolve(fn(this)).then(() => { if (this.children) { this.children.forEach((child) => child.doForAll(fn)); } }); } expandAll() { this.doForAll((node) => node.expand()); } collapseAll() { this.doForAll((node) => node.collapse()); } ensureVisible() { if (this.realParent) { this.realParent.expand(); this.realParent.ensureVisible(); } return this; } toggleExpanded() { this.setIsExpanded(!this.isExpanded); return this; } setIsExpanded(value) { if (this.hasChildren) { this.treeModel.setExpandedNode(this, value); } return this; } ; autoLoadChildren() { this.handler = reaction(() => this.isExpanded, (isExpanded) => { if (!this.children && this.hasChildren && isExpanded) { this.loadNodeChildren(); } }, { fireImmediately: true }); } dispose() { if (this.children) { this.children.forEach((child) => child.dispose()); } if (this.handler) { this.handler(); } this.parent = null; this.children = null; } setIsActive(value, multi = false) { this.treeModel.setActiveNode(this, value, multi); if (value) { this.focus(this.options.scrollOnActivate); } return this; } isSelectable() { return this.isLeaf || !this.children || !this.options.useTriState; } setIsSelected(value) { if (this.isSelectable()) { this.treeModel.setSelectedNode(this, value); } else { this.visibleChildren.forEach((child) => child.setIsSelected(value)); } return this; } toggleSelected() { this.setIsSelected(!this.isSelected); return this; } toggleActivated(multi = false) { this.setIsActive(!this.isActive, multi); return this; } setActiveAndVisible(multi = false) { this.setIsActive(true, multi) .ensureVisible(); setTimeout(this.scrollIntoView.bind(this)); return this; } scrollIntoView(force = false) { this.treeModel.virtualScroll.scrollIntoView(this, force); } focus(scroll = true) { let previousNode = this.treeModel.getFocusedNode(); this.treeModel.setFocusedNode(this); if (scroll) { this.scrollIntoView(); } if (previousNode) { this.fireEvent({ eventName: TREE_EVENTS.blur, node: previousNode }); } this.fireEvent({ eventName: TREE_EVENTS.focus, node: this }); return this; } blur() { let previousNode = this.treeModel.getFocusedNode(); this.treeModel.setFocusedNode(null); if (previousNode) { this.fireEvent({ eventName: TREE_EVENTS.blur, node: this }); } return this; } setIsHidden(value) { this.treeModel.setIsHidden(this, value); } hide() { this.setIsHidden(true); } show() { this.setIsHidden(false); } mouseAction(actionName, $event, data = null) { this.treeModel.setFocus(true); const actionMapping = this.options.actionMapping.mouse; const mouseAction = actionMapping[actionName]; if (mouseAction) { mouseAction(this.treeModel, this, $event, data); } } getSelfHeight() { return this.options.nodeHeight(this); } _initChildren() { this.children = this.getField('children') .map((c, index) => new TreeNode(c, this, this.treeModel, index)); } } __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isHidden", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isExpanded", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isActive", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isFocused", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isSelected", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isAllSelected", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "isPartiallySelected", null); __decorate([ observable$1, __metadata("design:type", Array) ], TreeNode.prototype, "children", void 0); __decorate([ observable$1, __metadata("design:type", Number) ], TreeNode.prototype, "index", void 0); __decorate([ observable$1, __metadata("design:type", Object) ], TreeNode.prototype, "position", void 0); __decorate([ observable$1, __metadata("design:type", Number) ], TreeNode.prototype, "height", void 0); __decorate([ computed$1, __metadata("design:type", Number), __metadata("design:paramtypes", []) ], TreeNode.prototype, "level", null); __decorate([ computed$1, __metadata("design:type", Array), __metadata("design:paramtypes", []) ], TreeNode.prototype, "path", null); __decorate([ computed$1, __metadata("design:type", Object), __metadata("design:paramtypes", []) ], TreeNode.prototype, "visibleChildren", null); __decorate([ action$1, __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", void 0) ], TreeNode.prototype, "setIsSelected", null); __decorate([ action$1, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], TreeNode.prototype, "_initChildren", null); function uuid() { return Math.floor(Math.random() * 10000000000000); } var __decorate$1 = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata$1 = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; class TreeModel { constructor() { this.options = new TreeOptions(); this.eventNames = Object.keys(TREE_EVENTS); this.expandedNodeIds = {}; this.selectedLeafNodeIds = {}; this.activeNodeIds = {}; this.hiddenNodeIds = {}; this.focusedNodeId = null; this.firstUpdate = true; this.subscriptions = []; } // events fireEvent(event) { event.treeModel = this; this.events[event.eventName].emit(event); this.events.event.emit(event); } subscribe(eventName, fn) { const subscription = this.events[eventName].subscribe(fn); this.subscriptions.push(subscription); } // getters getFocusedNode() { return this.focusedNode; } getActiveNode() { return this.activeNodes[0]; } getActiveNodes() { return this.activeNodes; } getVisibleRoots() { return this.virtualRoot.visibleChildren; } getFirstRoot(skipHidden = false) { const root = skipHidden ? this.getVisibleRoots() : this.roots; return root != null && root.length ? root[0] : null; } getLastRoot(skipHidden = false) { const root = skipHidden ? this.getVisibleRoots() : this.roots; return root != null && root.length ? root[root.length - 1] : null; } get isFocused() { return TreeModel.focusedTree === this; } isNodeFocused(node) { return this.focusedNode === node; } isEmptyTree() { return this.roots && this.roots.length === 0; } get focusedNode() { return this.focusedNodeId ? this.getNodeById(this.focusedNodeId) : null; } get expandedNodes() { const nodes = Object.keys(this.expandedNodeIds) .filter((id) => this.expandedNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } get activeNodes() { const nodes = Object.keys(this.activeNodeIds) .filter((id) => this.activeNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } get hiddenNodes() { const nodes = Object.keys(this.hiddenNodeIds) .filter((id) => this.hiddenNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } get selectedLeafNodes() { const nodes = Object.keys(this.selectedLeafNodeIds) .filter((id) => this.selectedLeafNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } // locating nodes getNodeByPath(path, startNode = null) { if (!path) return null; startNode = startNode || this.virtualRoot; if (path.length === 0) return startNode; if (!startNode.children) return null; const childId = path.shift(); const childNode = startNode.children.find(c => c.id === childId); if (!childNode) return null; return this.getNodeByPath(path, childNode); } getNodeById(id) { const idStr = id.toString(); return this.getNodeBy((node) => node.id.toString() === idStr); } getNodeBy(predicate, startNode = null) { startNode = startNode || this.virtualRoot; if (!startNode.children) return null; const found = startNode.children.find(predicate); if (found) { // found in children return found; } else { // look in children's children for (let child of startNode.children) { const foundInChildren = this.getNodeBy(predicate, child); if (foundInChildren) return foundInChildren; } } } isExpanded(node) { return this.expandedNodeIds[node.id]; } isHidden(node) { return this.hiddenNodeIds[node.id]; } isActive(node) { return this.activeNodeIds[node.id]; } isSelected(node) { return this.selectedLeafNodeIds[node.id]; } ngOnDestroy() { this.dispose(); this.unsubscribeAll(); } dispose() { // Dispose reactions of the replaced nodes if (this.virtualRoot) { this.virtualRoot.dispose(); } } unsubscribeAll() { this.subscriptions.forEach(subscription => subscription.unsubscribe()); this.subscriptions = []; } // actions setData({ nodes, options = null, events = null }) { if (options) { this.options = new TreeOptions(options); } if (events) { this.events = events; } if (nodes) { this.nodes = nodes; } this.update(); } update() { // Rebuild tree: let virtualRootConfig = { id: this.options.rootId, virtual: true, [this.options.childrenField]: this.nodes }; this.dispose(); this.virtualRoot = new TreeNode(virtualRootConfig, null, this, 0); this.roots = this.virtualRoot.children; // Fire event: if (this.firstUpdate) { if (this.roots) { this.firstUpdate = false; this._calculateExpandedNodes(); } } else { this.fireEvent({ eventName: TREE_EVENTS.updateData }); } } setFocusedNode(node) { this.focusedNodeId = node ? node.id : null; } setFocus(value) { TreeModel.focusedTree = value ? this : null; } doForAll(fn) { this.roots.forEach((root) => root.doForAll(fn)); } focusNextNode() { let previousNode = this.getFocusedNode(); let nextNode = previousNode ? previousNode.findNextNode(true, true) : this.getFirstRoot(true); if (nextNode) nextNode.focus(); } focusPreviousNode() { let previousNode = this.getFocusedNode(); let nextNode = previousNode ? previousNode.findPreviousNode(true) : this.getLastRoot(true); if (nextNode) nextNode.focus(); } focusDrillDown() { let previousNode = this.getFocusedNode(); if (previousNode && previousNode.isCollapsed && previousNode.hasChildren) { previousNode.toggleExpanded(); } else { let nextNode = previousNode ? previousNode.getFirstChild(true) : this.getFirstRoot(true); if (nextNode) nextNode.focus(); } } focusDrillUp() { let previousNode = this.getFocusedNode(); if (!previousNode) return; if (previousNode.isExpanded) { previousNode.toggleExpanded(); } else { let nextNode = previousNode.realParent; if (nextNode) nextNode.focus(); } } setActiveNode(node, value, multi = false) { if (multi) { this._setActiveNodeMulti(node, value); } else { this._setActiveNodeSingle(node, value); } if (value) { node.focus(this.options.scrollOnActivate); this.fireEvent({ eventName: TREE_EVENTS.activate, node }); this.fireEvent({ eventName: TREE_EVENTS.nodeActivate, node }); // For IE11 } else { this.fireEvent({ eventName: TREE_EVENTS.deactivate, node }); this.fireEvent({ eventName: TREE_EVENTS.nodeDeactivate, node }); // For IE11 } } setSelectedNode(node, value) { this.selectedLeafNodeIds = Object.assign({}, this.selectedLeafNodeIds, { [node.id]: value }); if (value) { node.focus(); this.fireEvent({ eventName: TREE_EVENTS.select, node }); } else { this.fireEvent({ eventName: TREE_EVENTS.deselect, node }); } } setExpandedNode(node, value) { this.expandedNodeIds = Object.assign({}, this.expandedNodeIds, { [node.id]: value }); this.fireEvent({ eventName: TREE_EVENTS.toggleExpanded, node, isExpanded: value }); } expandAll() { this.roots.forEach((root) => root.expandAll()); } collapseAll() { this.roots.forEach((root) => root.collapseAll()); } setIsHidden(node, value) { this.hiddenNodeIds = Object.assign({}, this.hiddenNodeIds, { [node.id]: value }); } setHiddenNodeIds(nodeIds) { this.hiddenNodeIds = nodeIds.reduce((hiddenNodeIds, id) => Object.assign(hiddenNodeIds, { [id]: true }), {}); } performKeyAction(node, $event) { const keyAction = this.options.actionMapping.keys[$event.keyCode]; if (keyAction) { $event.preventDefault(); keyAction(this, node, $event); return true; } else { return false; } } filterNodes(filter, autoShow = true) { let filterFn; if (!filter) { return this.clearFilter(); } // support function and string filter if (filter && typeof filter.valueOf() === 'string') { filterFn = (node) => node.displayField.toLowerCase().indexOf(filter.toLowerCase()) !== -1; } else if (filter && typeof filter === 'function') { filterFn = filter; } else { console.error('Don\'t know what to do with filter', filter); console.error('Should be either a string or function'); return; } const ids = {}; this.roots.forEach((node) => this._filterNode(ids, node, filterFn, autoShow)); this.hiddenNodeIds = ids; this.fireEvent({ eventName: TREE_EVENTS.changeFilter }); } clearFilter() { this.hiddenNodeIds = {}; this.fireEvent({ eventName: TREE_EVENTS.changeFilter }); } moveNode(node, to) { const fromIndex = node.getIndexInParent(); const fromParent = node.parent; if (!this.canMoveNode(node, to, fromIndex)) return; const fromChildren = fromParent.getField('children'); // If node doesn't have children - create children array if (!to.parent.getField('children')) { to.parent.setField('children', []); } const toChildren = to.parent.getField('children'); const originalNode = fromChildren.splice(fromIndex, 1)[0]; // Compensate for index if already removed from parent: let toIndex = (fromParent === to.parent && to.index > fromIndex) ? to.index - 1 : to.index; toChildren.splice(toIndex, 0, originalNode); fromParent.treeModel.update(); if (to.parent.treeModel !== fromParent.treeModel) { to.parent.treeModel.update(); } this.fireEvent({ eventName: TREE_EVENTS.moveNode, node: originalNode, to: { parent: to.parent.data, index: toIndex }, from: { parent: fromParent.data, index: fromIndex } }); } copyNode(node, to) { const fromIndex = node.getIndexInParent(); if (!this.canMoveNode(node, to, fromIndex)) return; // If node doesn't have children - create children array if (!to.parent.getField('children')) { to.parent.setField('children', []); } const toChildren = to.parent.getField('children'); const nodeCopy = this.options.getNodeClone(node); toChildren.splice(to.index, 0, nodeCopy); node.treeModel.update(); if (to.parent.treeModel !== node.treeModel) { to.parent.treeModel.update(); } this.fireEvent({ eventName: TREE_EVENTS.copyNode, node: nodeCopy, to: { parent: to.parent.data, index: to.index } }); } getState() { return { expandedNodeIds: this.expandedNodeIds, selectedLeafNodeIds: this.selectedLeafNodeIds, activeNodeIds: this.activeNodeIds, hiddenNodeIds: this.hiddenNodeIds, focusedNodeId: this.focusedNodeId }; } setState(state) { if (!state) return; Object.assign(this, { expandedNodeIds: state.expandedNodeIds || {}, selectedLeafNodeIds: state.selectedLeafNodeIds || {}, activeNodeIds: state.activeNodeIds || {}, hiddenNodeIds: state.hiddenNodeIds || {}, focusedNodeId: state.focusedNodeId }); } subscribeToState(fn) { autorun(() => fn(this.getState())); } canMoveNode(node, to, fromIndex = undefined) { const fromNodeIndex = fromIndex || node.getIndexInParent(); // same node: if (node.parent === to.parent && fromIndex === to.index) { return false; } return !to.parent.isDescendantOf(node); } calculateExpandedNodes() { this._calculateExpandedNodes(); } // private methods _filterNode(ids, node, filterFn, autoShow) { // if node passes function then it's visible let isVisible = filterFn(node); if (node.children) { // if one of node's children passes filter then this node is also visible node.children.forEach((child) => { if (this._filterNode(ids, child, filterFn, autoShow)) { isVisible = true; } }); } // mark node as hidden if (!isVisible) { ids[node.id] = true; } // auto expand parents to make sure the filtered nodes are visible if (autoShow && isVisible) { node.ensureVisible(); } return isVisible; } _calculateExpandedNodes(startNode = null) { startNode = startNode || this.virtualRoot; if (startNode.data[this.options.isExpandedField]) { this.expandedNodeIds = Object.assign({}, this.expandedNodeIds, { [startNode.id]: true }); } if (startNode.children) { startNode.children.forEach((child) => this._calculateExpandedNodes(child)); } } _setActiveNodeSingle(node, value) { // Deactivate all other nodes: this.activeNodes .filter((activeNode) => activeNode !== node) .forEach((activeNode) => { this.fireEvent({ eventName: TREE_EVENTS.deactivate, node: activeNode }); this.fireEvent({ eventName: TREE_EVENTS.nodeDeactivate, node: activeNode }); // For IE11 }); if (value) { this.activeNodeIds = { [node.id]: true }; } else { this.activeNodeIds = {}; } } _setActiveNodeMulti(node, value) { this.activeNodeIds = Object.assign({}, this.activeNodeIds, { [node.id]: value }); } } TreeModel.focusedTree = null; TreeModel.decorators = [ { type: Injectable } ]; __decorate$1([ observable$1, __metadata$1("design:type", Array) ], TreeModel.prototype, "roots", void 0); __decorate$1([ observable$1, __metadata$1("design:type", Object) ], TreeModel.prototype, "expandedNodeIds", void 0); __decorate$1([ observable$1, __metadata$1("design:type", Object) ], TreeModel.prototype, "selectedLeafNodeIds", void 0); __decorate$1([ observable$1, __metadata$1("design:type", Object) ], TreeModel.prototype, "activeNodeIds", void 0); __decorate$1([ observable$1, __metadata$1("design:type", Object) ], TreeModel.prototype, "hiddenNodeIds", void 0); __decorate$1([ observable$1, __metadata$1("design:type", Object) ], TreeModel.prototype, "focusedNodeId", void 0); __decorate$1([ observable$1, __metadata$1("design:type", TreeNode) ], TreeModel.prototype, "virtualRoot", void 0); __decorate$1([ computed$1, __metadata$1("design:type", Object), __metadata$1("design:paramtypes", []) ], TreeModel.prototype, "focusedNode", null); __decorate$1([ computed$1, __metadata$1("design:type", Object), __metadata$1("design:paramtypes", []) ], TreeModel.prototype, "expandedNodes", null); __decorate$1([ computed$1, __metadata$1("design:type", Object), __metadata$1("design:paramtypes", []) ], TreeModel.prototype, "activeNodes", null); __decorate$1([ computed$1, __metadata$1("design:type", Object), __metadata$1("design:paramtypes", []) ], TreeModel.prototype, "hiddenNodes", null); __decorate$1([ computed$1, __metadata$1("design:type", Object), __metadata$1("design:paramtypes", []) ], TreeModel.prototype, "selectedLeafNodes", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setData", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "update", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setFocusedNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setFocus", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "doForAll", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "focusNextNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "focusPreviousNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "focusDrillDown", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "focusDrillUp", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setActiveNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setSelectedNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setExpandedNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "expandAll", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "collapseAll", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setIsHidden", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setHiddenNodeIds", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "filterNodes", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", []), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "clearFilter", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "moveNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object, Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "copyNode", null); __decorate$1([ action$1, __metadata$1("design:type", Function), __metadata$1("design:paramtypes", [Object]), __metadata$1("design:returntype", void 0) ], TreeModel.prototype, "setState", null); class TreeDraggedElement { constructor() { this._draggedElement = null; } set(draggedElement) { this._draggedElement = draggedElement; } get() { return this._draggedElement; } isDragging() { return !!this.get(); } } /** @nocollapse */ TreeDraggedElement.ɵprov = ɵɵdefineInjectable({ factory: function TreeDraggedElement_Factory() { return new TreeDraggedElement(); }, token: TreeDraggedElement, providedIn: "root" }); TreeDraggedElement.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; var __decorate$2 = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.len