Skip to content

Commit f639c98

Browse files
feat: remove lodash-es (CirclonGroup#887)
BREAKING CHANGES: getNodeById now uses native javaScript find method instead of lodash find method BEFORE: getNodeById(predicate) - predicate needs to support lodash find method AFTER: getNodeById(predicate) - predicate needs to support javaScript find method
1 parent e77f063 commit f639c98

File tree

11 files changed

+61
-49
lines changed

11 files changed

+61
-49
lines changed

package-lock.json

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
"@angular/cdk": "^10.1.3",
6666
"@angular/forms": "^10.0.0 || ^11.0.0-0",
6767
"@angular/material": "^10.1.3",
68-
"lodash-es": "^4.17.20",
6968
"mobx": "~4.14.1"
7069
},
7170
"devDependencies": {

projects/angular-tree-component/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
"@angular/core": ">=10.0.0 <11.0.0"
4040
},
4141
"dependencies": {
42-
"lodash-es": "^4.17.20",
4342
"mobx": "~4.14.1",
4443
"tslib": "^2.0.0"
4544
},

projects/angular-tree-component/src/lib/components/tree-node-wrapper.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component , Input , ViewEncapsulation , TemplateRef } from '@angular/core';
1+
import { Component , Input , ViewEncapsulation } from '@angular/core';
22
import { TreeNode } from '../models/tree-node.model';
33

44
@Component({
@@ -43,7 +43,4 @@ export class TreeNodeWrapperComponent {
4343
@Input() index: number;
4444
@Input() templates: any;
4545

46-
constructor() {
47-
}
48-
4946
}

projects/angular-tree-component/src/lib/components/tree-node.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
Component,
33
Input,
44
ViewEncapsulation,
5-
TemplateRef
65
} from '@angular/core';
76
import { TreeNode } from '../models/tree-node.model';
87

projects/angular-tree-component/src/lib/components/tree-viewport.component.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import {
22
Component,
33
ElementRef,
4-
ViewEncapsulation,
54
AfterViewInit,
65
OnInit,
76
OnDestroy,
87
NgZone
98
} from '@angular/core';
109
import { TreeVirtualScroll } from '../models/tree-virtual-scroll.model';
1110
import { TREE_EVENTS } from '../constants/events';
12-
import { throttle } from 'lodash-es';
1311

1412
@Component({
1513
selector: 'tree-viewport',
@@ -24,9 +22,10 @@ import { throttle } from 'lodash-es';
2422
`
2523
})
2624
export class TreeViewportComponent implements AfterViewInit, OnInit, OnDestroy {
27-
setViewport = throttle(() => {
25+
setViewport = this.throttle(() => {
2826
this.virtualScroll.setViewport(this.elementRef.nativeElement);
2927
}, 17);
28+
3029
private readonly scrollEventHandler: ($event: Event) => void;
3130

3231
constructor(
@@ -65,4 +64,15 @@ export class TreeViewportComponent implements AfterViewInit, OnInit, OnDestroy {
6564
'auto'
6665
);
6766
}
67+
68+
private throttle(func, timeFrame) {
69+
let lastTime = 0;
70+
return function () {
71+
let now = Date.now();
72+
if (now - lastTime >= timeFrame) {
73+
func();
74+
lastTime = now;
75+
}
76+
};
77+
}
6878
}

projects/angular-tree-component/src/lib/components/tree.component.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { TreeOptions } from '../models/tree-options.model';
55
import { ITreeOptions } from '../defs/api';
66
import { TreeViewportComponent } from './tree-viewport.component';
77

8-
import { includes, pick } from 'lodash-es';
9-
108
@Component({
119
selector: 'Tree, tree-root',
1210
providers: [TreeModel],
@@ -92,8 +90,7 @@ export class TreeComponent implements OnChanges {
9290
@HostListener('body: keydown', ['$event'])
9391
onKeydown($event) {
9492
if (!this.treeModel.isFocused) return;
95-
if (includes(['input', 'textarea'],
96-
document.activeElement.tagName.toLowerCase())) return;
93+
if (['input', 'textarea'].includes(document.activeElement.tagName.toLowerCase())) return;
9794

9895
const focusedNode = this.treeModel.getFocusedNode();
9996

@@ -116,12 +113,21 @@ export class TreeComponent implements OnChanges {
116113
this.treeModel.setData({
117114
options: changes.options && changes.options.currentValue,
118115
nodes: changes.nodes && changes.nodes.currentValue,
119-
events: pick(this, this.treeModel.eventNames)
116+
events: this.pick(this, this.treeModel.eventNames)
120117
});
121118
}
122119
}
123120

124121
sizeChanged() {
125122
this.viewportComponent.setViewport();
126123
}
124+
125+
private pick(object, keys) {
126+
return keys.reduce((obj, key) => {
127+
if (object && object.hasOwnProperty(key)) {
128+
obj[key] = object[key];
129+
}
130+
return obj;
131+
}, {});
132+
}
127133
}

projects/angular-tree-component/src/lib/defs/api.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ export interface ITreeModel {
524524
getVisibleRoots(): ITreeNode[];
525525
/**
526526
* @param path array of node IDs to be traversed respectively
527-
* @param statrNode optional. Which node to start traversing from
527+
* @param startNode optional. Which node to start traversing from
528528
* @returns The node, if found - null otherwise
529529
*/
530530
getNodeByPath(path: any[], startNode?: ITreeNode): ITreeNode;
@@ -535,8 +535,8 @@ export interface ITreeModel {
535535
getNodeById(id: IDType): ITreeNode;
536536
/**
537537
* @param predicate - either an object or a function, used as a test condition on all nodes.
538-
* Could be every predicate that's supported by lodash's `find` method
539-
* @param statrNode optional. Which node to start traversing from
538+
* Could be every predicate that's supported by javaScripts Array.prototype.find() method
539+
* @param startNode optional. Which node to start traversing from
540540
* @returns First node that matches the predicate, if found - null otherwise
541541
*/
542542
getNodeBy(predicate: any, startNode?: ITreeNode): ITreeNode;

projects/angular-tree-component/src/lib/models/tree-node.model.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { TreeOptions } from './tree-options.model';
44
import { ITreeNode } from '../defs/api';
55
import { TREE_EVENTS } from '../constants/events';
66

7-
import { first, last, some, every } from 'lodash-es';
8-
97
export class TreeNode implements ITreeNode {
108
private handler: IReactionDisposer;
119
@computed get isHidden() { return this.treeModel.isHidden(this); };
@@ -16,14 +14,14 @@ export class TreeNode implements ITreeNode {
1614
if (this.isSelectable()) {
1715
return this.treeModel.isSelected(this);
1816
} else {
19-
return some(this.children, (node: TreeNode) => node.isSelected);
17+
return this.children.some((node: TreeNode) => node.isSelected);
2018
}
2119
};
2220
@computed get isAllSelected() {
2321
if (this.isSelectable()) {
2422
return this.treeModel.isSelected(this);
2523
} else {
26-
return every(this.children, (node: TreeNode) => node.isAllSelected);
24+
return this.children.every((node: TreeNode) => node.isAllSelected);
2725
}
2826
};
2927
@computed get isPartiallySelected() {
@@ -122,13 +120,13 @@ export class TreeNode implements ITreeNode {
122120
getFirstChild(skipHidden = false) {
123121
let children = skipHidden ? this.visibleChildren : this.children;
124122

125-
return first(children || []);
123+
return [].concat(children || []).shift();
126124
}
127125

128126
getLastChild(skipHidden = false) {
129127
let children = skipHidden ? this.visibleChildren : this.children;
130128

131-
return last(children || []);
129+
return [].concat(children || []).pop();
132130
}
133131

134132
findNextNode(goInside = true, skipHidden = false) {

projects/angular-tree-component/src/lib/models/tree-options.model.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import { TreeModel } from './tree.model';
33
import { KEYS } from '../constants/keys';
44
import { ITreeOptions } from '../defs/api';
55

6-
import { defaultsDeep, get, omit, isNumber } from 'lodash-es';
7-
86
export interface IActionHandler {
97
(tree: TreeModel, node: TreeNode, $event: any, ...rest);
108
}
@@ -98,10 +96,17 @@ export class TreeOptions {
9896
actionMapping: IActionMapping;
9997

10098
constructor(private options: ITreeOptions = {}) {
101-
this.actionMapping = defaultsDeep({}, this.options.actionMapping, defaultActionMapping);
99+
console.log('actionMapping', this.options.actionMapping);
100+
console.log('defaultActionMapping', defaultActionMapping);
101+
102+
this.actionMapping = {
103+
...defaultActionMapping,
104+
...this.options.actionMapping,
105+
};
106+
102107
if (options.rtl) {
103-
this.actionMapping.keys[KEYS.RIGHT] = <IActionHandler>get(options, ['actionMapping', 'keys', KEYS.RIGHT]) || TREE_ACTIONS.DRILL_UP;
104-
this.actionMapping.keys[KEYS.LEFT] = <IActionHandler>get(options, ['actionMapping', 'keys', KEYS.LEFT]) || TREE_ACTIONS.DRILL_DOWN;
108+
this.actionMapping.keys[KEYS.RIGHT] = <IActionHandler>options.actionMapping?.keys[KEYS.RIGHT] || TREE_ACTIONS.DRILL_UP;
109+
this.actionMapping.keys[KEYS.LEFT] = <IActionHandler>options.actionMapping?.keys[KEYS.LEFT] || TREE_ACTIONS.DRILL_DOWN;
105110
}
106111
}
107112

@@ -110,7 +115,13 @@ export class TreeOptions {
110115
return this.options.getNodeClone(node);
111116
}
112117

113-
return omit(Object.assign({}, node.data), ['id']);
118+
// remove id from clone
119+
// keeping ie11 compatibility
120+
const nodeClone = Object.assign({}, node.data);
121+
if (nodeClone.id) {
122+
delete nodeClone.id;
123+
}
124+
return nodeClone;
114125
}
115126

116127
allowDrop(element, to, $event?): boolean {
@@ -150,6 +161,6 @@ export class TreeOptions {
150161
}
151162

152163
get dropSlotHeight(): number {
153-
return isNumber(this.options.dropSlotHeight) ? this.options.dropSlotHeight : 2;
164+
return typeof this.options.dropSlotHeight === 'number' ? this.options.dropSlotHeight : 2;
154165
}
155166
}

projects/angular-tree-component/src/lib/models/tree.model.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, EventEmitter, OnDestroy } from '@angular/core';
1+
import { Injectable, OnDestroy } from '@angular/core';
22
import { observable, computed, action, autorun } from 'mobx';
33
import { Subscription } from 'rxjs';
44
import { TreeNode } from './tree-node.model';
@@ -7,8 +7,6 @@ import { TreeVirtualScroll } from './tree-virtual-scroll.model';
77
import { ITreeModel, IDType, IDTypeDictionary } from '../defs/api';
88
import { TREE_EVENTS } from '../constants/events';
99

10-
import { first, last, compact, find, isString, isFunction } from 'lodash-es';
11-
1210
@Injectable()
1311
export class TreeModel implements ITreeModel, OnDestroy {
1412
static focusedTree = null;
@@ -62,11 +60,11 @@ export class TreeModel implements ITreeModel, OnDestroy {
6260
}
6361

6462
getFirstRoot(skipHidden = false) {
65-
return first(skipHidden ? this.getVisibleRoots() : this.roots);
63+
return [].concat(skipHidden ? this.getVisibleRoots() : this.roots).shift();
6664
}
6765

6866
getLastRoot(skipHidden = false) {
69-
return last(skipHidden ? this.getVisibleRoots() : this.roots);
67+
return [].concat(skipHidden ? this.getVisibleRoots() : this.roots).pop();
7068
}
7169

7270
get isFocused() {
@@ -90,31 +88,31 @@ export class TreeModel implements ITreeModel, OnDestroy {
9088
.filter((id) => this.expandedNodeIds[id])
9189
.map((id) => this.getNodeById(id));
9290

93-
return compact(nodes);
91+
return nodes.filter(Boolean);
9492
}
9593

9694
@computed get activeNodes() {
9795
const nodes = Object.keys(this.activeNodeIds)
9896
.filter((id) => this.activeNodeIds[id])
9997
.map((id) => this.getNodeById(id));
10098

101-
return compact(nodes);
99+
return nodes.filter(Boolean);
102100
}
103101

104102
@computed get hiddenNodes() {
105103
const nodes = Object.keys(this.hiddenNodeIds)
106104
.filter((id) => this.hiddenNodeIds[id])
107105
.map((id) => this.getNodeById(id));
108106

109-
return compact(nodes);
107+
return nodes.filter(Boolean);
110108
}
111109

112110
@computed get selectedLeafNodes() {
113111
const nodes = Object.keys(this.selectedLeafNodeIds)
114112
.filter((id) => this.selectedLeafNodeIds[id])
115113
.map((id) => this.getNodeById(id));
116114

117-
return compact(nodes);
115+
return nodes.filter(Boolean);
118116
}
119117

120118
// locating nodes
@@ -127,7 +125,7 @@ export class TreeModel implements ITreeModel, OnDestroy {
127125
if (!startNode.children) return null;
128126

129127
const childId = path.shift();
130-
const childNode = find(startNode.children, { id: childId });
128+
const childNode = startNode.children.find(c => c.id === childId);
131129

132130
if (!childNode) return null;
133131

@@ -145,7 +143,7 @@ export class TreeModel implements ITreeModel, OnDestroy {
145143

146144
if (!startNode.children) return null;
147145

148-
const found = find(startNode.children, predicate);
146+
const found = startNode.children.find(predicate);
149147

150148
if (found) { // found in children
151149
return found;
@@ -349,10 +347,10 @@ export class TreeModel implements ITreeModel, OnDestroy {
349347
}
350348

351349
// support function and string filter
352-
if (isString(filter)) {
350+
if (filter && typeof filter.valueOf() === 'string') {
353351
filterFn = (node) => node.displayField.toLowerCase().indexOf(filter.toLowerCase()) !== -1;
354352
}
355-
else if (isFunction(filter)) {
353+
else if (filter && typeof filter === 'function') {
356354
filterFn = filter;
357355
}
358356
else {

0 commit comments

Comments
 (0)