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

atinc / ngx-tethys / df6b162a-6409-4216-a048-95638a1cf8c3

11 Apr 2025 10:17AM UTC coverage: 90.237% (+0.001%) from 90.236%
df6b162a-6409-4216-a048-95638a1cf8c3

Pull #3335

circleci

wangyuan-ky
feat(time-picker): enhance time manipulation functions with timezone support
Pull Request #3335: feat(date-picker): add timezone support to date picker components and utilities #TINFR-1734

5610 of 6877 branches covered (81.58%)

Branch coverage included in aggregate %.

45 of 49 new or added lines in 12 files covered. (91.84%)

46 existing lines in 8 files now uncovered.

13365 of 14151 relevant lines covered (94.45%)

992.21 hits per line

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

86.79
/src/date-picker/lib/popups/inner-popup.component.ts
1
import {
2
    ChangeDetectionStrategy,
3
    Component,
4
    EventEmitter,
5
    HostBinding,
6
    Input,
7
    OnChanges,
8
    Output,
9
    Signal,
10
    SimpleChanges,
11
    TemplateRef,
12
    inject
13
} from '@angular/core';
14

15
import { FunctionProp, TinyDate, coerceBooleanProperty } from 'ngx-tethys/util';
16
import { DateHelperService } from '../../date-helper.service';
17
import { RangePartType } from '../../inner-types';
18
import { isAfterMoreThanLessOneYear, isAfterMoreThanOneDecade, isAfterMoreThanOneMonth, isAfterMoreThanOneYear } from '../../picker.util';
19
import { DisabledDateFn, ThyPanelMode } from '../../standard-types';
20
import { DateHeader } from '../date/date-header.component';
21
import { DateTable } from '../date/date-table.component';
1✔
22

23
import { ThyDatePickerLocale, injectLocale } from 'ngx-tethys/i18n';
206✔
24
import { ThyInputDirective } from 'ngx-tethys/input';
206✔
25
import { DecadeHeader } from '../decade/decade-header.component';
206✔
26
import { DecadeTable } from '../decade/decade-table.component';
206✔
27
import { MonthHeader } from '../month/month-header.component';
206✔
28
import { MonthTable } from '../month/month-table.component';
206✔
29
import { QuarterTable } from '../quarter/quarter-table.component';
206✔
30
import { YearHeader } from '../year/year-header.component';
206✔
31
import { YearTable } from '../year/year-table.component';
206✔
32

33
/**
34
 * @private
208✔
35
 */
36
@Component({
37
    changeDetection: ChangeDetectionStrategy.OnPush,
488✔
38
    // eslint-disable-next-line @angular-eslint/component-selector
39
    selector: 'inner-popup',
40
    exportAs: 'innerPopup',
488✔
41
    templateUrl: 'inner-popup.component.html',
70✔
42
    imports: [
43
        ThyInputDirective,
488!
44
        DecadeHeader,
×
45
        DecadeTable,
46
        YearHeader,
47
        YearTable,
48
        MonthHeader,
8✔
49
        MonthTable,
50
        QuarterTable,
51
        DateHeader,
28!
52
        DateTable
28✔
53
    ]
54
})
55
export class InnerPopup implements OnChanges {
3✔
56
    private dateHelper = inject(DateHelperService);
3✔
57
    locale: Signal<ThyDatePickerLocale> = injectLocale('datePicker');
2✔
58

2✔
59
    @HostBinding('class.thy-calendar-picker-inner-popup') className = true;
60
    @HostBinding('class.thy-calendar-picker-inner-popup-with-range-input') _showDateRangeInput = false;
61

1✔
62
    @Input() showWeek: boolean;
1✔
63
    @Input() isRange: boolean;
64
    @Input() activeDate: TinyDate;
65
    @Input() rangeActiveDate: TinyDate[]; // Range ONLY
66
    @Input() enablePrev: boolean;
4✔
67
    @Input() enableNext: boolean;
4!
68
    @Input() disabledDate: DisabledDateFn;
4✔
69
    @Input() dateRender: FunctionProp<TemplateRef<Date> | string>;
4✔
70
    @Input() selectedValue: TinyDate[]; // Range ONLY
71
    @Input() hoverValue: TinyDate[]; // Range ONLY
72

×
73
    @Input() panelMode: ThyPanelMode;
×
74
    @Input() timeZone: string;
75

76
    @Input({ transform: coerceBooleanProperty })
77
    set showDateRangeInput(value: boolean) {
5✔
78
        this._showDateRangeInput = value;
5✔
79
    }
4✔
80

4✔
81
    get showDateRangeInput() {
82
        return this._showDateRangeInput;
83
    }
1✔
84

1✔
85
    @Input() partType: RangePartType;
86

87
    @Input() endPanelMode: ThyPanelMode;
UNCOV
88

×
89
    @Output() readonly panelModeChange = new EventEmitter<ThyPanelMode>();
×
90

×
91
    @Input() value: TinyDate;
×
92

93
    @Output() readonly headerChange = new EventEmitter<TinyDate>();
UNCOV
94
    @Output() readonly selectDate = new EventEmitter<TinyDate>();
×
95
    @Output() readonly dayHover = new EventEmitter<TinyDate>();
×
96

97
    prefixCls = 'thy-calendar';
98

99
    ngOnChanges(changes: SimpleChanges): void {
740✔
100
        if (changes.activeDate && !changes.activeDate.currentValue) {
456✔
101
            this.activeDate = new TinyDate(undefined, this.timeZone);
200✔
102
        }
200✔
103
        if (changes.panelMode && changes.panelMode.currentValue === 'time') {
104
            this.panelMode = 'date';
105
        }
256✔
106
    }
107

108
    getReadableValue(value: TinyDate) {
109
        return value ? this.dateHelper.format(value.nativeDate, 'yyyy-MM-dd') : '';
284✔
110
    }
111

112
    onSelectDate(date: TinyDate): void {
113
        const value = date instanceof TinyDate ? date : new TinyDate(date, this.timeZone);
976✔
114

558✔
115
        this.selectDate.emit(value);
251✔
116
    }
251✔
117

200✔
118
    onChooseMonth(value: TinyDate): void {
119
        this.activeDate = this.activeDate.setMonth(value.getMonth());
51✔
120
        if (this.endPanelMode === 'month') {
34✔
121
            this.value = value;
122
            this.selectDate.emit(value);
17✔
123
        } else {
13✔
124
            this.headerChange.emit(value);
125
            this.panelModeChange.emit(this.endPanelMode);
126
        }
127
    }
307✔
128

129
    onChooseQuarter(value: TinyDate): void {
130
        this.activeDate = this.activeDate.setQuarter(value.getQuarter());
131
        if (this.endPanelMode === 'quarter') {
418✔
132
            this.value = value;
133
            this.selectDate.emit(value);
134
        } else {
1✔
135
            this.headerChange.emit(value);
136
            this.panelModeChange.emit(this.endPanelMode);
137
        }
138
    }
139

140
    onChooseYear(value: TinyDate): void {
141
        this.activeDate = this.activeDate.setYear(value.getYear());
142
        if (this.endPanelMode === 'year') {
143
            this.value = value;
144
            this.selectDate.emit(value);
145
        } else {
146
            this.headerChange.emit(value);
147
            this.panelModeChange.emit(this.endPanelMode);
148
        }
149
    }
150

151
    onChooseDecade(value: TinyDate): void {
152
        this.activeDate = this.activeDate.setYear(value.getYear());
153
        if (this.endPanelMode === 'decade') {
154
            this.value = value;
155
            this.selectDate.emit(value);
156
        } else {
157
            this.headerChange.emit(value);
158
            this.panelModeChange.emit('year');
159
        }
1✔
160
    }
161

162
    enablePrevNext(direction: 'prev' | 'next', mode: ThyPanelMode): boolean {
163
        if (this.isRange) {
164
            if ((this.partType === 'left' && direction === 'next') || (this.partType === 'right' && direction === 'prev')) {
165
                const [headerLeftDate, headerRightDate] = this.rangeActiveDate;
166
                return isAfterMoreThanOneMonth(headerRightDate, headerLeftDate);
167
            } else {
168
                return true;
169
            }
170
        } else {
171
            return true;
172
        }
173
    }
174

175
    enableSuperPrevNext(direction: 'prev' | 'next', panelMode: ThyPanelMode) {
176
        if (this.isRange) {
177
            if ((this.partType === 'left' && direction === 'next') || (this.partType === 'right' && direction === 'prev')) {
178
                const [headerLeftDate, headerRightDate] = this.rangeActiveDate;
179
                if (panelMode === 'date') {
180
                    return isAfterMoreThanLessOneYear(headerRightDate, headerLeftDate);
181
                } else if (panelMode === 'month' || panelMode === 'quarter') {
182
                    return isAfterMoreThanOneYear(headerRightDate, headerLeftDate);
183
                } else if (panelMode === 'year') {
184
                    return isAfterMoreThanOneDecade(headerRightDate, headerLeftDate);
185
                }
186
            } else {
187
                return true;
188
            }
189
        } else {
190
            return true;
191
        }
192
    }
193
}
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