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

atinc / ngx-tethys / d9ae709b-3c27-4b69-b125-b8b80b54f90b

pending completion
d9ae709b-3c27-4b69-b125-b8b80b54f90b

Pull #2757

circleci

mengshuicmq
fix: fix code review
Pull Request #2757: feat(color-picker): color-picker support disabled (#INFR-8645)

98 of 6315 branches covered (1.55%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

2392 of 13661 relevant lines covered (17.51%)

83.12 hits per line

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

2.24
/src/tree/tree.service.ts
1
import { coerceArray, isFunction } from 'ngx-tethys/util';
2
import { BehaviorSubject, Subject } from 'rxjs';
3

4
import { Injectable, OnDestroy } from '@angular/core';
5

6
import { ThyTreeNode } from './tree-node.class';
7
import { ThyTreeNodeCheckState } from './tree.class';
×
8

×
9
function checkStateResolve(node: ThyTreeNode) {
×
10
    const checkedNodes = node.children.filter(n => n.isChecked === ThyTreeNodeCheckState.checked);
×
11
    const unCheckedNodes = node.children.filter(n => n.isChecked === ThyTreeNodeCheckState.unchecked);
12
    if (checkedNodes.length === node.children.length) {
×
13
        return ThyTreeNodeCheckState.checked;
×
14
    } else if (unCheckedNodes.length === node.children.length) {
15
        return ThyTreeNodeCheckState.unchecked;
16
    } else {
×
17
        return ThyTreeNodeCheckState.indeterminate;
18
    }
19
}
20

21
type FlattenAllNodesCb = (treeNode: ThyTreeNode) => boolean;
22

1✔
23
/**
24
 * @internal
×
25
 */
×
26
@Injectable()
×
27
export class ThyTreeService implements OnDestroy {
×
28
    selectedNode!: ThyTreeNode;
×
29

30
    flattenNodes$ = new BehaviorSubject<ThyTreeNode[]>([]);
31

×
32
    flattenTreeNodes: ThyTreeNode[] = [];
33

34
    public treeNodes: ThyTreeNode[] = [];
×
35

×
36
    public checkStateResolve: (node: ThyTreeNode) => ThyTreeNodeCheckState = checkStateResolve;
×
37

38
    $statusChange = new Subject<ThyTreeFormatEmitEvent>();
×
39

×
40
    constructor() {}
41

×
42
    public initializeTreeNodes(rootNodes: ThyTreeNode[]) {
×
43
        this.treeNodes = rootNodes;
×
44
    }
×
45

×
46
    public syncFlattenTreeNodes() {
47
        this.flattenTreeNodes = this.getParallelTreeNodes(this.treeNodes, false);
48
        this.flattenNodes$.next(this.flattenTreeNodes);
49
        return this.flattenTreeNodes;
×
50
    }
×
51

52
    private getParallelTreeNodes(rootTrees: ThyTreeNode[] = this.treeNodes, flattenAllNodes: boolean | FlattenAllNodesCb = true) {
×
53
        const flattenTreeData: ThyTreeNode[] = [];
×
54
        function _getParallelTreeNodes(list: ThyTreeNode[]) {
55
            return list.forEach((treeNode, index) => {
56
                flattenTreeData.push(treeNode);
×
57
                const flattenAllNodesFlag = isFunction(flattenAllNodes) ? flattenAllNodes(treeNode) : flattenAllNodes;
×
58
                if (flattenAllNodesFlag || treeNode.isExpanded) {
×
59
                    _getParallelTreeNodes(treeNode.children);
×
60
                }
×
61
            });
62
        }
63
        _getParallelTreeNodes(rootTrees);
64
        return flattenTreeData;
×
65
    }
×
66

67
    setCheckStateResolve(resolve: (node: ThyTreeNode) => ThyTreeNodeCheckState = checkStateResolve) {
68
        this.checkStateResolve = resolve;
×
69
    }
×
70

71
    public resetSortedTreeNodes(treeNodes: ThyTreeNode[], parent?: ThyTreeNode) {
72
        treeNodes.forEach(node => {
×
73
            node.level = node.parentNode ? node.parentNode.level + 1 : 0;
×
74
            node.origin.children = node.children.map(n => n.origin);
75
            node.parentNode = parent;
76
            this.resetSortedTreeNodes(node.children, node);
×
77
        });
×
78
    }
×
79

×
80
    public getTreeNode(key: string | number) {
81
        const allNodes = this.getParallelTreeNodes(this.treeNodes);
×
82
        return allNodes.find(n => n.key === key);
83
    }
×
84

×
85
    public getExpandedNodes(): ThyTreeNode[] {
×
86
        const allNodes = this.getParallelTreeNodes(this.treeNodes);
87
        return allNodes.filter(n => n.isExpanded);
88
    }
×
89

×
90
    public getCheckedNodes(): ThyTreeNode[] {
91
        const allNodes = this.getParallelTreeNodes(this.treeNodes);
92
        return allNodes.filter(n => n.isChecked === ThyTreeNodeCheckState.checked);
×
93
    }
94

95
    public deleteTreeNode(node: ThyTreeNode) {
×
96
        const children = node.parentNode ? node.parentNode.children : this.treeNodes;
97
        const index = children.findIndex(n => n.key === node.key);
98
        if (index > -1) {
×
99
            children.splice(index, 1);
×
100
        }
×
101
        this.syncFlattenTreeNodes();
102
    }
×
103

×
104
    public addTreeNode(node: ThyTreeNode, parent?: ThyTreeNode, index = -1) {
105
        if (parent) {
×
106
            parent.addChildren(node, index);
107
        } else {
108
            if (index > -1) {
×
109
                this.treeNodes.splice(index, 0, node);
110
            } else {
111
                this.treeNodes.push(node);
×
112
            }
×
113
        }
×
114
        this.syncFlattenTreeNodes();
115
    }
×
116

×
117
    public expandTreeNodes(keyOrKeys: string | number | (string | number)[]) {
×
118
        const keys = coerceArray(keyOrKeys);
×
119
        const needExpandNodes = this.getParallelTreeNodes(this.treeNodes).filter(node => {
120
            return keys.indexOf(node.key) > -1;
121
        });
×
122
        needExpandNodes.forEach(node => {
×
123
            node.setExpanded(true);
×
124
        });
×
125
        this.syncFlattenTreeNodes();
×
126
    }
×
127

128
    public statusChanged() {
129
        return this.$statusChange.asObservable();
×
130
    }
×
131

×
132
    // 设置节点选中状态
133
    public setNodeChecked(node: ThyTreeNode, checked: boolean, propagateUp = true, propagateDown = true) {
134
        this._setNodeChecked(node, checked, propagateUp, propagateDown);
135
        this.syncFlattenTreeNodes();
×
136
    }
×
137

138
    private _setNodeChecked(node: ThyTreeNode, checked: boolean, propagateUp = true, propagateDown = true) {
139
        if (propagateDown && node.children) {
×
140
            node.children.forEach(subNode => {
×
141
                this._setNodeChecked(subNode, checked, false, true);
142
            });
143
        }
144
        if (!node.isDisabled) {
×
145
            if (node.children.length) {
×
146
                if (checked) {
147
                    const isAllChildrenChecked = node.children.every(item => item.isChecked === ThyTreeNodeCheckState.checked);
148
                    node.isChecked = isAllChildrenChecked ? ThyTreeNodeCheckState.checked : ThyTreeNodeCheckState.indeterminate;
×
149
                    node.origin.checked = isAllChildrenChecked && checked;
×
150
                } else {
×
151
                    const isAllChildrenUnChecked = node.children.every(item => item.isChecked === ThyTreeNodeCheckState.unchecked);
152
                    node.isChecked = isAllChildrenUnChecked ? ThyTreeNodeCheckState.unchecked : ThyTreeNodeCheckState.indeterminate;
153
                    node.origin.checked = isAllChildrenUnChecked && checked;
154
                }
×
155
            } else {
×
156
                node.isChecked = checked ? ThyTreeNodeCheckState.checked : ThyTreeNodeCheckState.unchecked;
157
                node.origin.checked = checked;
1✔
158
            }
159
        }
1✔
160
        if (propagateUp) {
161
            this._syncNodeCheckState(node.parentNode);
162
        }
163
    }
164

165
    public syncNodeCheckState(node: ThyTreeNode) {
166
        this._syncNodeCheckState(node);
167
        this.syncFlattenTreeNodes();
168
    }
169

170
    private _syncNodeCheckState(node: ThyTreeNode) {
171
        if (node) {
172
            node.isChecked = this.checkStateResolve(node);
173
            this._syncNodeCheckState(node.parentNode);
174
        }
175
    }
176

177
    ngOnDestroy(): void {
178
        this.$statusChange.complete();
179
        this.$statusChange = null;
180
    }
181
}
182

183
export interface ThyTreeFormatEmitEvent {
184
    eventName: string;
185
    node: ThyTreeNode;
186
    event?: MouseEvent | DragEvent;
187
}
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

© 2025 Coveralls, Inc