• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atinc / ngx-tethys / #55

30 Jul 2025 07:08AM UTC coverage: 9.866% (-80.4%) from 90.297%
#55

push

why520crazy
feat(empty): add setMessage for update display text #TINFR-2616

92 of 6794 branches covered (1.35%)

Branch coverage included in aggregate %.

2014 of 14552 relevant lines covered (13.84%)

6.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

12.37
/src/tree/tree.class.ts
1
import { Signal } from '@angular/core';
2
import { helpers, isArray } from 'ngx-tethys/util';
3
import { BehaviorSubject, Subject } from 'rxjs';
1✔
4

1✔
5
export enum ThyTreeNodeCheckState {
1✔
6
    unchecked = 0,
1✔
7
    checked = 1,
2✔
8
    indeterminate = 2
9
}
1✔
10

1✔
11
export enum ThyTreeDropPosition {
1✔
12
    in = 'in',
1✔
13
    before = 'before',
2✔
14
    after = 'after'
15
}
16

17
export interface ThyTreeNodeData<T = any> {
18
    key?: number | string;
×
19

×
20
    title?: string;
21

×
22
    icon?: string;
×
23

24
    iconStyle?: {
25
        [key: string]: any;
×
26
    };
×
27

×
28
    children?: ThyTreeNodeData<T>[];
×
29

×
30
    origin?: any;
×
31

×
32
    expanded?: boolean;
×
33

×
34
    disabled?: boolean;
×
35

×
36
    checked?: boolean;
×
37

×
38
    data?: T;
×
39

40
    itemClass?: string | string[];
×
41

×
42
    [key: string]: any;
×
43
}
44

45
export interface ThyTreeEmitEvent<T = any> {
×
46
    eventName: string;
×
47

×
48
    node?: ThyTreeNode<T>;
49

50
    event?: Event | any;
51

×
52
    dragNode?: ThyTreeNode<T>;
×
53

54
    targetNode?: ThyTreeNode<T>;
55
}
×
56

×
57
export interface ThyTreeBeforeDragStartContext {
58
    item: ThyTreeNode;
59
}
×
60

61
export interface ThyTreeBeforeDragDropContext {
×
62
    item?: ThyTreeNode;
×
63
    containerItems?: ThyTreeNode[];
×
64
    previousItem?: ThyTreeNode;
×
65
    previousContainerItems?: ThyTreeNode[];
×
66
    position?: ThyTreeDropPosition;
67
}
68

×
69
export interface ThyTreeDragDropEvent<T = any> {
×
70
    dragNode?: ThyTreeNode<T>;
×
71

72
    targetNode?: ThyTreeNode<T>;
73

×
74
    afterNode?: ThyTreeNode<T>;
×
75
}
76

×
77
export class ThyTreeIcons {
×
78
    expand?: string;
79
    collapse?: string;
80
}
×
81

82
export type ThyClickBehavior = 'default' | 'selectCheckbox';
83

×
84
export interface ThyTreeFormatEmitEvent {
85
    eventName: string;
86
    node: ThyTreeNode;
×
87
    event?: MouseEvent | DragEvent;
88
}
×
89

×
90
export interface IThyTreeService {
×
91
    selectedNode: ThyTreeNode;
×
92
    flattenTreeNodes: Signal<ThyTreeNode[]>;
×
93
    treeNodes: ThyTreeNode[];
94
    statusChange$: Subject<ThyTreeFormatEmitEvent>;
95
    initializeTreeNodes: (rootNodes: ThyTreeNodeData[]) => void;
×
96
    syncFlattenTreeNodes: () => void;
97
    setCheckStateResolve: (resolve: (node: ThyTreeNode) => ThyTreeNodeCheckState) => void;
98
    resetSortedTreeNodes: (treeNodes: ThyTreeNode[], parent?: ThyTreeNode) => void;
×
99
    getTreeNode: (key: string | number) => ThyTreeNode;
×
100
    getExpandedNodes: () => ThyTreeNode[];
×
101
    getCheckedNodes: () => ThyTreeNode[];
102
    deleteTreeNode: (node: ThyTreeNode) => void;
103
    addTreeNode: (node: ThyTreeNode, parent?: ThyTreeNode, index?: number) => void;
104
    expandTreeNodes: (keyOrKeys: string | number | (string | number)[] | true) => void;
105
    setNodeChecked: (node: ThyTreeNode, checked: boolean, propagateUp?: boolean, propagateDown?: boolean) => void;
106
    syncNodeCheckState: (node: ThyTreeNode) => void;
107
    checkStateResolve: (node: ThyTreeNode) => ThyTreeNodeCheckState;
108
}
109

110
export class ThyTreeNode<T = any> {
111
    key?: number | string;
112

113
    title?: string;
114

115
    children: ThyTreeNode[];
116

117
    parentNode: ThyTreeNode;
118

119
    level = 0;
120

121
    origin: ThyTreeNodeData<T>;
122

123
    isExpanded: boolean;
124

125
    isChecked: ThyTreeNodeCheckState;
126

127
    isLoading: boolean;
128

129
    isDisabled: boolean;
130

131
    itemClass?: string[];
132

133
    private readonly service: IThyTreeService;
134

135
    get treeService(): IThyTreeService {
136
        if (this.service) {
137
            return this.service;
138
        } else if (this.parentNode) {
139
            return this.parentNode.treeService;
140
        }
141
    }
142

143
    constructor(node: ThyTreeNodeData, parent: ThyTreeNode = null, service?: IThyTreeService) {
144
        this.title = node.title;
145
        this.key = node.key;
146
        this.children = [];
147
        this.parentNode = parent;
148
        this.level = parent ? parent.level + 1 : this.level;
149
        this.origin = node;
150
        this.isDisabled = node.disabled || false;
151
        this.isExpanded = node.expanded || false;
152
        this.isChecked = node.checked ? ThyTreeNodeCheckState.checked : ThyTreeNodeCheckState.unchecked;
153
        this.isLoading = false;
154
        if (node.itemClass) {
155
            this.itemClass = isArray(node.itemClass) ? node.itemClass : [node.itemClass];
156
        }
157
        if (node.children) {
158
            node.children.forEach(childNode => {
159
                this.children.push(new ThyTreeNode(childNode, this, service));
160
            });
161
        }
162
        this.service = service;
163
        if (node.children && node.children.length && service) {
164
            this.isChecked = service.checkStateResolve(this);
165
        }
166
    }
167

168
    public setKey(key: string) {
169
        this.origin.key = key;
170
        this.key = key;
171
    }
172

173
    public setTitle(title: string) {
174
        this.origin.title = title;
175
        this.title = title;
176
    }
177

178
    public setLevel(level: number) {
179
        this.level = level;
180
    }
181

182
    private _setExpanded(expanded: boolean, propagate = false) {
183
        this.origin.expanded = expanded;
184
        this.isExpanded = expanded;
185
        if (propagate && this.children) {
186
            this.children.forEach(n => n._setExpanded(expanded, propagate));
187
        }
188
    }
189

190
    public setExpanded(expanded: boolean, propagate = false) {
191
        this._setExpanded(expanded, propagate);
192
        this.treeService.syncFlattenTreeNodes();
193
    }
194

195
    public setLoading(loading: boolean): void {
196
        this.isLoading = loading;
197
        this.treeService.syncFlattenTreeNodes();
198
    }
199

200
    public setChecked(checked: boolean, propagateUp = true, propagateDown = true) {
201
        this.treeService.setNodeChecked(this, checked, propagateUp, propagateDown);
202
    }
203

204
    public syncNodeCheckState() {
205
        this.treeService.syncNodeCheckState(this);
206
    }
207

208
    public getParentNode(): ThyTreeNode {
209
        return this.parentNode;
210
    }
211

212
    public getChildren(): ThyTreeNode[] {
213
        return this.children;
214
    }
215

216
    public addChildren(children: ThyTreeNodeData | ThyTreeNodeData[], index: number = -1): void {
217
        children = helpers.coerceArray(children);
218
        ((children as ThyTreeNodeData[]) || []).forEach((childNode: ThyTreeNodeData, i: number) => {
219
            if (index === -1) {
220
                this.children.push(new ThyTreeNode(childNode, this));
221
            } else {
222
                this.children.splice(index + i, 0, new ThyTreeNode(childNode, this, this.treeService));
223
            }
224
        });
225

226
        this.origin.children = this.getChildren().map(n => n.origin);
227
        this.setLoading(false);
228
        this.treeService.statusChange$.next({
229
            eventName: 'addChildren',
230
            node: this
231
        });
232
    }
233
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc