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

atinc / ngx-tethys / e62d3b10-1466-49c3-aabd-707148681fc8

14 Jun 2024 08:24AM UTC coverage: 90.422%. Remained the same
e62d3b10-1466-49c3-aabd-707148681fc8

push

circleci

minlovehua
feat: use the ngx-tethys/util's coerceBooleanProperty instead of booleanAttribute #INFR-12648

5467 of 6692 branches covered (81.69%)

Branch coverage included in aggregate %.

117 of 120 new or added lines in 66 files covered. (97.5%)

183 existing lines in 46 files now uncovered.

13216 of 13970 relevant lines covered (94.6%)

985.91 hits per line

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

93.94
/src/property-operation/property-operation.component.ts
1
import {
2
    AfterContentInit,
3
    Component,
4
    ContentChild,
5
    ElementRef,
6
    EventEmitter,
7
    HostBinding,
8
    Input,
9
    OnInit,
10
    Output,
11
    TemplateRef,
12
    ViewChild,
13
    OnDestroy,
14
    NgZone
15
} from '@angular/core';
16
import { useHostRenderer } from '@tethys/cdk/dom';
17
import { ThyTranslate } from 'ngx-tethys/core';
18
import { coerceBooleanProperty, htmlElementIsEmpty } from 'ngx-tethys/util';
1✔
19
import { fromEvent, Subject } from 'rxjs';
20
import { takeUntil } from 'rxjs/operators';
38✔
21
import { ThyIcon } from 'ngx-tethys/icon';
22
import { ThyFlexibleText } from 'ngx-tethys/flexible-text';
23
import { ThyButtonIcon } from 'ngx-tethys/button';
11✔
24
import { NgTemplateOutlet, NgIf, NgClass } from '@angular/common';
11✔
25

26
type ThyPropertyOperationTypes = 'primary' | 'success' | 'warning' | 'danger';
UNCOV
27

×
28
/**
29
 * 属性操作组件
30
 * @name thy-property-operation
25✔
31
 * @order 10
32
 */
33
@Component({
11✔
34
    selector: 'thy-property-operation',
35
    templateUrl: './property-operation.component.html',
36
    standalone: true,
11✔
37
    imports: [NgTemplateOutlet, NgIf, NgClass, ThyButtonIcon, ThyFlexibleText, ThyIcon]
38
})
UNCOV
39
export class ThyPropertyOperation implements OnInit, AfterContentInit, OnDestroy {
×
40
    private initialized = false;
41

42
    private hostRenderer = useHostRenderer();
11✔
43

11✔
44
    labelText: string;
45

11✔
46
    onlyHasTips = false;
48✔
47

11✔
48
    showClose = false;
49

37✔
50
    type: ThyPropertyOperationTypes;
51

11✔
52
    icon: string;
48✔
53

11✔
54
    value: string;
55

37✔
56
    labelHideWhenHasValue = false;
11✔
57

58
    /**
26!
59
     * 点击移除图标时的事件回调,此函数只有在thyShowClose为true时才会发生
26✔
60
     */
61
    @Output() thyOnRemove = new EventEmitter();
UNCOV
62

×
63
    /**
64
     * 点击事件回调
65
     */
66
    @Output() thyClick = new EventEmitter<Event>();
38✔
67

38✔
68
    @HostBinding('class.thy-property-operation') _isPropertyOperation = true;
38✔
69

38✔
70
    @ContentChild('operationIcon') operationIcon: TemplateRef<any>;
38✔
71

38✔
72
    @ViewChild('contentElement', { static: true }) contentElement: ElementRef;
38✔
73

38✔
74
    /**
38✔
75
     * 属性的 Label 文本
38✔
76
     */
38✔
77
    @Input()
38✔
78
    set thyLabelText(value: string) {
79
        this.labelText = value;
80
    }
37✔
81

37✔
82
    /**
83
     * 属性的值
84
     */
31✔
85
    @Input()
29✔
86
    set thyValue(value: string) {
87
        this.value = value;
2✔
88
        this.setOnlyHasTips();
89
    }
90

91
    /**
37✔
92
     * 属性的 Label Translate Key
37✔
93
     */
94
    @Input()
95
    set thyLabelTextTranslateKey(value: string) {
38✔
96
        this.labelText = this.thyTranslate.instant(value);
97
    }
98

1✔
99
    /**
1✔
100
     * 图标
101
     */
1✔
102
    @Input()
103
    set thyIcon(value: string) {
104
        this.icon = value;
105
    }
106

1✔
107
    /**
108
     * 当有属性值时是否展示移除图标
109
     * @default false
110
     */
111
    @Input({ transform: coerceBooleanProperty })
112
    set thyShowClose(value: boolean) {
113
        this.showClose = value;
114
    }
115

116
    // 支持有值时,label不显示
117
    @Input({ transform: coerceBooleanProperty })
118
    set thyLabelHasValue(value: boolean) {
119
        this.labelHideWhenHasValue = !value;
120
    }
121

122
    /**
123
     * 有值时隐藏 label
124
     * @default false
1✔
125
     */
126
    @Input({ transform: coerceBooleanProperty })
127
    set thyLabelHideWhenHasValue(value: boolean) {
128
        this.labelHideWhenHasValue = value;
129
    }
130

131
    /**
132
     * 属性类型
133
     * @type  danger | primary | success | warning | null
134
     * @default null
135
     */
136
    @Input()
137
    set thyType(value: ThyPropertyOperationTypes) {
138
        this.type = value;
139
        this.setHostClass();
140
    }
141

142
    /**
143
     * 激活状态
144
     * @default false
145
     */
146
    @HostBinding('class.active')
147
    @Input({ alias: 'thyActive', transform: coerceBooleanProperty })
148
    active: boolean;
149

150
    /**
151
     * 禁用操作,添加后property operation中thyClick和thyOnRemove事件将会被禁用
152
     * @default false
153
     */
154
    @HostBinding('class.thy-property-operation-disabled')
155
    @Input({ alias: 'thyDisabled', transform: coerceBooleanProperty })
156
    disabled: boolean;
157

158
    private destroy$ = new Subject<void>();
159

160
    private setHostClass(first = false) {
161
        if (!this.initialized && !first) {
162
            return;
163
        }
164
        this.hostRenderer.updateClass(this.type ? [`thy-property-operation-${this.type}`] : []);
165
    }
166

167
    private setOnlyHasTips(first = false) {
168
        if (!this.initialized && !first) {
169
            return;
170
        }
171
        if (this.value) {
172
            this.onlyHasTips = false;
173
        } else if (htmlElementIsEmpty(this.contentElement.nativeElement)) {
174
            this.onlyHasTips = true;
175
        } else {
176
            this.onlyHasTips = false;
177
        }
178
    }
179

180
    constructor(private thyTranslate: ThyTranslate, private elementRef: ElementRef<HTMLElement>, private ngZone: NgZone) {}
181

182
    ngOnInit() {
183
        this.setHostClass(true);
184

185
        this.ngZone.runOutsideAngular(() =>
186
            fromEvent<Event>(this.elementRef.nativeElement, 'click')
187
                .pipe(takeUntil(this.destroy$))
188
                .subscribe(event => {
189
                    if (this.disabled || this.thyClick.observers.length === 0) {
190
                        return;
191
                    }
192

193
                    this.ngZone.run(() => this.thyClick.emit(event));
194
                })
195
        );
196
    }
197

198
    ngAfterContentInit() {
199
        this.setOnlyHasTips(true);
200
        this.initialized = true;
201
    }
202

203
    ngOnDestroy(): void {
204
        this.destroy$.next();
205
    }
206

207
    remove($event: Event) {
208
        $event.stopPropagation();
209
        this.thyOnRemove.emit($event);
210
    }
211
}
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