• 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

9.09
/src/date-range/date-range.component.ts
1
import { Component, forwardRef, OnInit, Input, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';
2
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
3
import { DateRangeItemInfo } from './date-range.class';
4
import { ThyPopover } from 'ngx-tethys/popover';
5
import { OptionalDateRangesComponent } from './optional-dates/optional-dates.component';
6

7
import {
8
    getUnixTime,
9
    startOfISOWeek,
10
    endOfISOWeek,
11
    endOfMonth,
12
    startOfMonth,
13
    addDays,
1✔
14
    addMonths,
1✔
15
    addYears,
16
    isSameDay,
×
17
    endOfDay,
18
    startOfDay
19
} from 'date-fns';
20
import { ThyDatePickerFormatPipe } from 'ngx-tethys/date-picker';
21
import { ThyIconComponent } from 'ngx-tethys/icon';
22
import { ThyActionComponent } from 'ngx-tethys/action';
23
import { NgIf, NgClass } from '@angular/common';
24
import { InputBoolean } from 'ngx-tethys/core';
1✔
25

26
const allDayTimestamp = 24 * 60 * 60;
×
27

28
const INPUT_CONTROL_VALUE_ACCESSOR: any = {
29
    provide: NG_VALUE_ACCESSOR,
×
30
    useExisting: forwardRef(() => ThyDateRangeComponent),
×
31
    multi: true
×
32
};
×
33

×
34
/**
×
35
 * 预设时间段及自定义时间段选择组件
×
36
 * @name thy-date-range
×
37
 * @order 10
38
 */
39
@Component({
40
    selector: 'thy-date-range',
41
    templateUrl: './date-range.component.html',
42
    providers: [INPUT_CONTROL_VALUE_ACCESSOR],
43
    standalone: true,
44
    imports: [NgIf, ThyActionComponent, ThyIconComponent, NgClass, ThyDatePickerFormatPipe]
45
})
46
export class ThyDateRangeComponent implements OnInit, ControlValueAccessor {
47
    /**
48
     * 自定义可选值列表项
49
     * @type DateRangeItemInfo[]
50
     */
51
    @Input()
52
    set thyOptionalDateRanges(value: DateRangeItemInfo[]) {
53
        this.optionalDateRanges = value.length > 0 ? value : this.optionalDateRanges;
54
    }
55

56
    /**
57
     * 隐藏下拉选择时间段
58
     * @default false
×
59
     */
×
60
    @Input() @InputBoolean() thyHiddenMenu = false;
61

62
    /**
×
63
     * 禁用左右切换时间段
×
64
     * @default false
65
     */
×
66
    @Input() @InputBoolean() thyDisabledSwitch = false;
×
67

×
68
    /**
69
     * 自定义日期选择的展示文字
×
70
     */
×
71
    @Input() thyCustomTextValue = '自定义';
72

73
    /**
×
74
     * 自定义日期选择中可选择的最小时间
75
     * @type Date | number
76
     */
×
77
    @Input() thyMinDate: Date | number;
78

79
    /**
80
     * 自定义日期选择中可选择的最大时间
×
81
     * @type Date | number
82
     */
83
    @Input() thyMaxDate: Date | number;
84

85
    /**
86
     * 选中的时间段的展示形式,
×
87
     * <br/> `custom`形式:`2023-07-01 ~ 2023-07-31`;
×
88
     * <br/> `exception`形式:`2023-07-01`,具体展示还与`thyPickerFormat`有关。
×
89
     */
×
90
    @Input() thyCustomKey: 'custom' | 'exception' = 'custom';
×
91

×
92
    /**
×
93
     * 自定义日期展示格式,比如`yyyy年MM月`,只有当`thyCustomKey`值设为`exception`时才会生效
94
     */
95
    @Input() thyPickerFormat: string;
96

97
    /**
98
     * 自定义日期禁用日期
99
     */
×
100
    @Input() thyDisabledDate: (d: Date) => boolean;
101

102
    /**
103
     * 自定义日期选择日期回调
104
     * @type EventEmitter<Date[]>
105
     */
106
    @Output() readonly thyOnCalendarChange = new EventEmitter<Date[]>();
×
107

×
108
    public selectedDate?: DateRangeItemInfo;
×
109

110
    public optionalDateRanges: DateRangeItemInfo[] = [
111
        {
112
            key: 'week',
113
            text: '本周',
114
            begin: getUnixTime(startOfISOWeek(new Date())),
115
            end: getUnixTime(endOfISOWeek(new Date())),
×
116
            timestamp: {
×
117
                interval: 7,
118
                unit: 'day'
×
119
            }
120
        },
121
        {
122
            key: 'month',
123
            text: '本月',
124
            begin: getUnixTime(startOfMonth(new Date())),
125
            end: getUnixTime(endOfMonth(new Date())),
×
126
            timestamp: {
×
127
                interval: 1,
×
128
                unit: 'month'
129
            }
130
        }
131
    ];
132

133
    public selectedDateRange: {
134
        begin: number;
×
135
        end: number;
136
    };
137

138
    public onModelChange: Function = () => {};
139

140
    public onModelTouched: Function = () => {};
141

142
    constructor(private thyPopover: ThyPopover, private cdr: ChangeDetectorRef) {}
143

×
144
    writeValue(value: any): void {
×
145
        if (value) {
×
146
            this.selectedDate = value;
147
        } else if (this.optionalDateRanges.length > 0) {
148
            this.selectedDate = this.optionalDateRanges[0];
149
            this.onModelChange(this.selectedDate);
150
        }
151
        this._setSelectedDateRange();
152
        this.cdr.detectChanges();
×
153
    }
154

155
    registerOnChange(fn: any): void {
156
        this.onModelChange = fn;
157
    }
158

159
    registerOnTouched(fn: any): void {
160
        this.onModelTouched = fn;
161
    }
×
162

×
163
    ngOnInit() {}
×
164

165
    private _setSelectedDateRange() {
166
        this.selectedDateRange = {
×
167
            begin: this.selectedDate.begin,
168
            end: this.selectedDate.end
169
        };
×
170
    }
171

172
    private _calculateNewTime(type: string) {
×
173
        if (this.selectedDate.timestamp) {
×
174
            const beginDate = new Date(this.selectedDate.begin * 1000);
175
            const endDate = new Date(this.selectedDate.end * 1000);
×
176
            const interval = this.selectedDate.timestamp.interval;
177

178
            if (this.selectedDate.timestamp.unit === 'day') {
179
                if (type === 'previous') {
180
                    return {
181
                        begin: getUnixTime(addDays(beginDate, -1 * interval)),
182
                        end: getUnixTime(addDays(endDate, -1 * interval)),
183
                        key: this.thyCustomKey
184
                    };
185
                } else {
186
                    return {
187
                        begin: getUnixTime(addDays(beginDate, 1 * interval)),
188
                        end: getUnixTime(addDays(endDate, 1 * interval)),
189
                        key: this.thyCustomKey
190
                    };
191
                }
192
            } else if (this.selectedDate.timestamp.unit === 'month') {
×
193
                if (type === 'previous') {
×
194
                    return {
195
                        begin: getUnixTime(addMonths(beginDate, -1 * interval)),
196
                        end: getUnixTime(endOfDay(addDays(beginDate, -1))),
×
197
                        key: this.thyCustomKey
198
                    };
199
                } else {
200
                    const endIsEndDayOfMonth = isSameDay(endDate, endOfMonth(endDate));
201
                    return {
1✔
202
                        begin: getUnixTime(startOfDay(addDays(endDate, 1))),
203
                        end: endIsEndDayOfMonth
204
                            ? getUnixTime(endOfMonth(addMonths(endDate, 1 * interval)))
205
                            : getUnixTime(addMonths(endDate, 1 * interval)),
1✔
206
                        key: this.thyCustomKey
207
                    };
208
                }
209
            } else if (this.selectedDate.timestamp.unit === 'year') {
210
                if (type === 'previous') {
211
                    return {
212
                        begin: getUnixTime(addYears(beginDate, -1 * interval)),
213
                        end: getUnixTime(addYears(endDate, -1 * interval)),
214
                        key: this.thyCustomKey
215
                    };
216
                } else {
217
                    return {
218
                        begin: getUnixTime(addYears(beginDate, 1 * interval)),
1✔
219
                        end: getUnixTime(addYears(endDate, 1 * interval)),
220
                        key: this.thyCustomKey
221
                    };
222
                }
1✔
223
            }
224
        } else {
225
            const interval: number = this.selectedDate.end - this.selectedDate.begin + allDayTimestamp;
226
            if (type === 'previous') {
1✔
227
                return {
228
                    begin: this.selectedDate.begin - interval,
229
                    end: this.selectedDate.end - interval,
230
                    key: this.thyCustomKey
231
                };
232
            } else {
233
                return {
234
                    begin: this.selectedDate.begin + interval,
235
                    end: this.selectedDate.end + interval,
236
                    key: this.thyCustomKey
237
                };
238
            }
239
        }
240
    }
241

242
    private _setPreviousOrNextDate(type: string) {
243
        this.selectedDate = Object.assign({}, this.selectedDate, this._calculateNewTime(type));
244
        this._setSelectedDateRange();
245
        this.onModelChange(this.selectedDate);
246
    }
247

248
    public previous() {
249
        this._setPreviousOrNextDate('previous');
250
    }
251

252
    public next() {
253
        this._setPreviousOrNextDate('next');
254
    }
255

256
    public openOptionalDateRangesMenu(event: Event) {
257
        if (this.thyHiddenMenu) {
258
            return;
259
        }
260
        this.thyPopover.open(OptionalDateRangesComponent, {
261
            origin: event.currentTarget as HTMLElement,
262
            hasBackdrop: true,
263
            backdropClass: 'thy-overlay-transparent-backdrop',
264
            offset: 0,
265
            manualClosure: true,
266
            originActiveClass: 'thy-date-range-text-active',
267
            initialState: {
268
                hiddenMenu: this.thyHiddenMenu,
269
                optionalDateRanges: this.optionalDateRanges,
270
                selectedDate: this.selectedDate,
271
                minDate: this.thyMinDate,
272
                maxDate: this.thyMaxDate,
273
                customValue: this.thyCustomTextValue,
274
                customKey: this.thyCustomKey,
275
                disabledDate: this.thyDisabledDate,
276
                selectedDateRange: (dateRange: DateRangeItemInfo) => {
277
                    this.onModelChange(dateRange);
278
                    this.selectedDate = dateRange;
279
                },
280
                calendarChange: (date: Date[]) => {
281
                    this.thyOnCalendarChange.emit(date);
282
                }
283
            }
284
        });
285
    }
286
}
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