Skip to content

Commit 3049d00

Browse files
feat(datetimepicker): implementa ajustes
implementa ajustes Fixes: DTHFUI-11495
1 parent 7a715f0 commit 3049d00

9 files changed

Lines changed: 149 additions & 113 deletions

projects/ui/src/lib/components/po-calendar/po-calendar.component.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -776,21 +776,21 @@ describe('PoCalendarComponent:', () => {
776776
describe('isToday:', () => {
777777
it('should return true for today', () => {
778778
const today = new Date();
779-
expect(component['isToday'](today)).toBe(true);
779+
expect(component['poCalendarService'].isToday(today)).toBe(true);
780780
});
781781

782782
it('should return false for yesterday', () => {
783783
const yesterday = new Date();
784784
yesterday.setDate(yesterday.getDate() - 1);
785-
expect(component['isToday'](yesterday)).toBe(false);
785+
expect(component['poCalendarService'].isToday(yesterday)).toBe(false);
786786
});
787787

788788
it('should return false for null', () => {
789-
expect(component['isToday'](null)).toBe(false);
789+
expect(component['poCalendarService'].isToday(null)).toBe(false);
790790
});
791791

792792
it('should return false for undefined', () => {
793-
expect(component['isToday'](undefined)).toBe(false);
793+
expect(component['poCalendarService'].isToday(undefined)).toBe(false);
794794
});
795795
});
796796

projects/ui/src/lib/components/po-calendar/po-calendar.component.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import { AbstractControl, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/form
1818

1919
import { isMobile } from '../../utils/util';
2020
import { PoButtonComponent } from '../po-button';
21-
import { PoCalendarLangService } from './services';
2221
import { PoTimerComponent } from '../po-timer/po-timer.component';
22+
import { PoCalendarLangService, PoCalendarService } from './services';
2323
import { PoCalendarBaseComponent } from './po-calendar-base.component';
2424
import { PoDateService } from '../../services/po-date/po-date.service';
2525
import { PoLanguageService } from '../../services/po-language/po-language.service';
@@ -81,6 +81,7 @@ export class PoCalendarComponent extends PoCalendarBaseComponent implements OnIn
8181
@ViewChildren('monthOption') monthOptions: QueryList<PoButtonComponent>;
8282

8383
private readonly changeDetector = inject(ChangeDetectorRef);
84+
private readonly poCalendarService = inject(PoCalendarService);
8485
private readonly poCalendarLangService = inject(PoCalendarLangService);
8586

8687
hoverValue: Date;
@@ -394,7 +395,7 @@ export class PoCalendarComponent extends PoCalendarBaseComponent implements OnIn
394395
this.change.emit(newModel);
395396

396397
// Em modo date-time, se a data selecionada é "hoje", define a hora atual no timer
397-
if (this.isDateTime && this.timerComponent && this.isToday(selectedDate)) {
398+
if (this.isDateTime && this.timerComponent && this.poCalendarService.isToday(selectedDate)) {
398399
const now = new Date();
399400
const hours = ('0' + now.getHours()).slice(-2);
400401
const minutes = ('0' + now.getMinutes()).slice(-2);
@@ -527,18 +528,6 @@ export class PoCalendarComponent extends PoCalendarBaseComponent implements OnIn
527528
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
528529
}
529530

530-
private isToday(date: Date): boolean {
531-
if (!date || !(date instanceof Date)) {
532-
return false;
533-
}
534-
const today = new Date();
535-
return (
536-
date.getDate() === today.getDate() &&
537-
date.getMonth() === today.getMonth() &&
538-
date.getFullYear() === today.getFullYear()
539-
);
540-
}
541-
542531
private enrichPresetsWithDisabledState(
543532
presets: Array<PoCalendarRangePreset>,
544533
minDateInput?: Date,

projects/ui/src/lib/components/po-calendar/services/po-calendar.service.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,30 @@ describe('PoCalendarService:', () => {
8585
it('monthDates: should get month days with year is greater than 101', () => {
8686
expect(service.monthDays(158, 7).length).toBe(5);
8787
});
88+
89+
describe('isToday:', () => {
90+
it('should return true for today', () => {
91+
const today = new Date();
92+
expect(service.isToday(today)).toBe(true);
93+
});
94+
95+
it('should return false for yesterday', () => {
96+
const yesterday = new Date();
97+
yesterday.setDate(yesterday.getDate() - 1);
98+
expect(service.isToday(yesterday)).toBe(false);
99+
});
100+
101+
it('should return false for null', () => {
102+
expect(service.isToday(null)).toBe(false);
103+
});
104+
105+
it('should return false for undefined', () => {
106+
expect(service.isToday(undefined)).toBe(false);
107+
});
108+
109+
it('should return false for non-Date value', () => {
110+
expect(service.isToday('2024-01-01' as any)).toBe(false);
111+
});
112+
});
88113
});
89114
});

projects/ui/src/lib/components/po-calendar/services/po-calendar.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,16 @@ export class PoCalendarService {
100100
}
101101
return startDate;
102102
}
103+
104+
isToday(date: Date): boolean {
105+
if (!date || !(date instanceof Date)) {
106+
return false;
107+
}
108+
const today = new Date();
109+
return (
110+
date.getDate() === today.getDate() &&
111+
date.getMonth() === today.getMonth() &&
112+
date.getFullYear() === today.getFullYear()
113+
);
114+
}
103115
}

projects/ui/src/lib/components/po-field/po-datetimepicker/po-datetimepicker-base.component.spec.ts

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,53 +30,53 @@ describe('PoDatetimepickerBaseComponent:', () => {
3030
spyOn(component, 'refreshValue');
3131
component.writeValue(null);
3232

33-
expect(component.date).toBeUndefined();
34-
expect(component.timeValue).toBe('');
33+
expect(component['date']).toBeUndefined();
34+
expect(component['timeValue']).toBe('');
3535
expect(component.refreshValue).toHaveBeenCalledWith(undefined);
3636
});
3737

3838
it('should clear date and timeValue when value is empty string', () => {
3939
spyOn(component, 'refreshValue');
4040
component.writeValue('');
4141

42-
expect(component.date).toBeUndefined();
43-
expect(component.timeValue).toBe('');
42+
expect(component['date']).toBeUndefined();
43+
expect(component['timeValue']).toBe('');
4444
});
4545

4646
it('should set date and timeValue from Date object', () => {
4747
spyOn(component, 'refreshValue');
4848
const date = new Date(2026, 4, 12, 14, 30, 0);
4949
component.writeValue(date);
5050

51-
expect(component.date.getFullYear()).toBe(2026);
52-
expect(component.date.getMonth()).toBe(4);
53-
expect(component.date.getDate()).toBe(12);
54-
expect(component.timeValue).toBe('14:30');
51+
expect(component['date'].getFullYear()).toBe(2026);
52+
expect(component['date'].getMonth()).toBe(4);
53+
expect(component['date'].getDate()).toBe(12);
54+
expect(component['timeValue']).toBe('14:30');
5555
});
5656

5757
it('should set date and timeValue from ISO string with timezone', () => {
5858
spyOn(component, 'refreshValue');
5959
component.writeValue('2026-05-12T14:30:00-03:00');
6060

61-
expect(component.date).toBeDefined();
62-
expect(component.timeValue).toBeTruthy();
61+
expect(component['date']).toBeDefined();
62+
expect(component['timeValue']).toBeTruthy();
6363
});
6464

6565
it('should set date and timeValue from ISO string without timezone', () => {
6666
spyOn(component, 'refreshValue');
6767
component.writeValue('2026-05-12T14:30:00');
6868

69-
expect(component.date).toBeDefined();
70-
expect(component.timeValue).toContain('14:30');
69+
expect(component['date']).toBeDefined();
70+
expect(component['timeValue']).toContain('14:30');
7171
});
7272

7373
it('should set date with 00:00 time from date-only ISO string', () => {
7474
spyOn(component, 'refreshValue');
7575
component.writeValue('2026-05-12');
7676

77-
expect(component.date).toBeDefined();
78-
expect(component.date.getFullYear()).toBe(2026);
79-
expect(component.timeValue).toBe('00:00');
77+
expect(component['date']).toBeDefined();
78+
expect(component['date'].getFullYear()).toBe(2026);
79+
expect(component['timeValue']).toBe('00:00');
8080
});
8181

8282
it('should call callOnChange with ISO model when date and time are valid', () => {
@@ -165,22 +165,22 @@ describe('PoDatetimepickerBaseComponent:', () => {
165165

166166
describe('getModelValue:', () => {
167167
it('should return empty string when date is undefined', () => {
168-
component.date = undefined;
168+
component['date'] = undefined;
169169
expect(component.getModelValue()).toBe('');
170170
});
171171

172172
it('should return ISO string with timezone when date and time are set', () => {
173-
component.date = new Date(2026, 4, 12);
174-
component.timeValue = '14:30';
173+
component['date'] = new Date(2026, 4, 12);
174+
component['timeValue'] = '14:30';
175175
const result = component.getModelValue();
176176

177177
expect(result).toContain('2026-05-12T14:30');
178178
expect(result).toMatch(/[+-]\d{2}:\d{2}$/);
179179
});
180180

181181
it('should use 00:00 as default time when timeValue is empty', () => {
182-
component.date = new Date(2026, 4, 12);
183-
component.timeValue = '';
182+
component['date'] = new Date(2026, 4, 12);
183+
component['timeValue'] = '';
184184
const result = component.getModelValue();
185185

186186
expect(result).toContain('2026-05-12T00:00');
@@ -243,16 +243,16 @@ describe('PoDatetimepickerBaseComponent:', () => {
243243
describe('controlModel:', () => {
244244
it('should call callOnChange with model value', () => {
245245
spyOn(component, 'callOnChange');
246-
component.date = new Date(2026, 4, 12);
247-
component.timeValue = '14:30';
246+
component['date'] = new Date(2026, 4, 12);
247+
component['timeValue'] = '14:30';
248248
component.controlModel();
249249

250250
expect(component.callOnChange).toHaveBeenCalled();
251251
});
252252

253253
it('should call callOnChange with empty string when no date', () => {
254254
spyOn(component, 'callOnChange');
255-
component.date = undefined;
255+
component['date'] = undefined;
256256
component.controlModel();
257257

258258
expect(component.callOnChange).toHaveBeenCalledWith('');
@@ -271,10 +271,17 @@ describe('PoDatetimepickerBaseComponent:', () => {
271271
});
272272

273273
it('should include seconds when provided in 24h format', () => {
274+
Object.defineProperty(component, 'showSeconds', { value: () => true });
274275
const result = component.formatTimeForDisplay('14:30:45');
275276
expect(result).toBe('14:30:45');
276277
});
277278

279+
it('should truncate seconds when showSeconds is false and time has seconds', () => {
280+
Object.defineProperty(component, 'showSeconds', { value: () => false });
281+
const result = component.formatTimeForDisplay('14:30:45');
282+
expect(result).toBe('14:30');
283+
});
284+
278285
it('should return 12:00 AM when time is empty in 12h format', () => {
279286
Object.defineProperty(component, 'is12HourFormat', { get: () => true });
280287
const result = component.formatTimeForDisplay('');
@@ -312,6 +319,7 @@ describe('PoDatetimepickerBaseComponent:', () => {
312319
});
313320

314321
it('should include seconds in 12h format', () => {
322+
Object.defineProperty(component, 'showSeconds', { value: () => true });
315323
Object.defineProperty(component, 'is12HourFormat', { get: () => true });
316324
const result = component.formatTimeForDisplay('14:30:45');
317325
expect(result).toBe('02:30:45 PM');
@@ -370,14 +378,14 @@ describe('PoDatetimepickerBaseComponent:', () => {
370378

371379
describe('validate - date range and time range:', () => {
372380
it('should return date error when date is out of range', () => {
373-
component.date = new Date(2020, 0, 1);
381+
component['date'] = new Date(2020, 0, 1);
374382
component['_resolvedMinDate'] = new Date(2025, 0, 1);
375383
const control = new FormControl('2020-01-01T10:00-03:00');
376384
expect(component.validate(control)).toEqual({ date: { valid: false } });
377385
});
378386

379387
it('should return time error when time is out of range', () => {
380-
component.date = new Date(2026, 4, 12);
388+
component['date'] = new Date(2026, 4, 12);
381389
component['_timeValue'] = '22:00';
382390
// Set maxTime signal - use internal property since we can't setInput without fixture
383391
component['_resolvedMinDate'] = undefined;
@@ -540,15 +548,15 @@ describe('PoDatetimepickerBaseComponent:', () => {
540548
spyOn(component, 'refreshValue');
541549
component.writeValue('2026-05-12Tinvalid');
542550

543-
expect(component.date).toBeDefined();
551+
expect(component['date']).toBeDefined();
544552
});
545553

546554
it('should parse date-only string and set timeValue to 00:00', () => {
547555
spyOn(component, 'refreshValue');
548556
component['processStringValue']('2026-05-12');
549557

550-
expect(component.date).toBeDefined();
551-
expect(component.timeValue).toBe('00:00');
558+
expect(component['date']).toBeDefined();
559+
expect(component['timeValue']).toBe('00:00');
552560
});
553561
});
554562

@@ -576,6 +584,7 @@ describe('PoDatetimepickerBaseComponent:', () => {
576584

577585
describe('extractTimeFromDate:', () => {
578586
it('should return HH:mm:ss when seconds are not 00', () => {
587+
Object.defineProperty(component, 'showSeconds', { value: () => true });
579588
const date = new Date(2026, 4, 12, 14, 30, 45);
580589
expect(component['extractTimeFromDate'](date)).toBe('14:30:45');
581590
});
@@ -673,13 +682,13 @@ describe('PoDatetimepickerBaseComponent - Effects (with fixture):', () => {
673682
it('should set placeholder when value is string', () => {
674683
fixture.componentRef.setInput('p-placeholder', 'Enter date');
675684
fixture.detectChanges();
676-
expect(component.isPlaceholder).toBe('Enter date');
685+
expect(component.placeholderValue).toBe('Enter date');
677686
});
678687

679688
it('should set empty string when value is not string', () => {
680689
fixture.componentRef.setInput('p-placeholder', undefined);
681690
fixture.detectChanges();
682-
expect(component.isPlaceholder).toBe('');
691+
expect(component.placeholderValue).toBe('');
683692
});
684693
});
685694

0 commit comments

Comments
 (0)