mis-crystal-design-system 18.1.7-signal-16-test → 18.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/async-search-dropdown/async-dropdown.component.d.ts +44 -3
- package/daterangepicker_v2/tz-drp-container/tz-drp-container.component.d.ts +9 -2
- package/esm2022/async-search-dropdown/async-dropdown.component.mjs +147 -37
- package/esm2022/datepicker_v2/tz-dp-container/tz-dp-container.component.mjs +35 -22
- package/esm2022/daterangepicker_v2/tz-daterangepicker.directive.mjs +6 -3
- package/esm2022/daterangepicker_v2/tz-drp-container/tz-drp-container.component.mjs +270 -187
- package/esm2022/dynamic-form/dynamic-form.component.mjs +30 -21
- package/esm2022/loader/loader.component.mjs +12 -6
- package/esm2022/slider/slider.component.mjs +2 -2
- package/esm2022/table/sort-icons.directive.mjs +24 -5
- package/esm2022/table/table.component.mjs +200 -93
- package/esm2022/table/table.module.mjs +7 -5
- package/esm2022/timepicker/timepicker.component.mjs +41 -14
- package/esm2022/timerangepicker/timerangepicker.component.mjs +73 -23
- package/fesm2022/mis-crystal-design-system-async-search-dropdown.mjs +146 -36
- package/fesm2022/mis-crystal-design-system-async-search-dropdown.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-datepicker_v2.mjs +34 -21
- package/fesm2022/mis-crystal-design-system-datepicker_v2.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-daterangepicker_v2.mjs +274 -188
- package/fesm2022/mis-crystal-design-system-daterangepicker_v2.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-dynamic-form.mjs +29 -20
- package/fesm2022/mis-crystal-design-system-dynamic-form.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-loader.mjs +11 -5
- package/fesm2022/mis-crystal-design-system-loader.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-slider.mjs +2 -2
- package/fesm2022/mis-crystal-design-system-slider.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-table.mjs +227 -99
- package/fesm2022/mis-crystal-design-system-table.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-timepicker.mjs +40 -13
- package/fesm2022/mis-crystal-design-system-timepicker.mjs.map +1 -1
- package/fesm2022/mis-crystal-design-system-timerangepicker.mjs +72 -22
- package/fesm2022/mis-crystal-design-system-timerangepicker.mjs.map +1 -1
- package/loader/loader.component.d.ts +7 -1
- package/package.json +18 -18
- package/table/table.component.d.ts +16 -4
- package/table/table.module.d.ts +2 -1
- package/timepicker/timepicker.component.d.ts +3 -1
- package/timerangepicker/timerangepicker.component.d.ts +5 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal, computed,
|
|
2
|
+
import { InjectionToken, signal, computed, Component, Inject, HostListener, input, output, Injector, Directive, Self, Optional, NgModule } from '@angular/core';
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import timezone from 'dayjs/plugin/timezone';
|
|
5
5
|
import utc from 'dayjs/plugin/utc';
|
|
@@ -252,6 +252,57 @@ dayjs.extend(customParseFormat);
|
|
|
252
252
|
dayjs.extend(isSameOrAfter);
|
|
253
253
|
dayjs.extend(isSameOrBefore);
|
|
254
254
|
class TzDrpContainerComponent {
|
|
255
|
+
/**
|
|
256
|
+
* Parse date string using configured format with fallback
|
|
257
|
+
*/
|
|
258
|
+
parseDateWithMultipleFormats(dateString) {
|
|
259
|
+
if (!dateString || dateString === 'Invalid Date' || dateString === 'undefined' || dateString === 'null') {
|
|
260
|
+
return dayjs('invalid');
|
|
261
|
+
}
|
|
262
|
+
// First try the configured format
|
|
263
|
+
const configuredFormat = this.data().dpConfig?.format;
|
|
264
|
+
if (configuredFormat) {
|
|
265
|
+
try {
|
|
266
|
+
const parsed = dayjs(dateString, configuredFormat);
|
|
267
|
+
if (parsed.isValid()) {
|
|
268
|
+
return parsed;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
// Continue to fallback formats
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Fallback to common formats if configured format fails
|
|
276
|
+
const fallbackFormats = [
|
|
277
|
+
'DD/MMM/YYYY',
|
|
278
|
+
'DD/MM/YYYY',
|
|
279
|
+
'DD-MMM-YYYY',
|
|
280
|
+
'DD-MM-YYYY',
|
|
281
|
+
'YYYY-MM-DD'
|
|
282
|
+
];
|
|
283
|
+
for (const format of fallbackFormats) {
|
|
284
|
+
try {
|
|
285
|
+
const parsed = dayjs(dateString, format);
|
|
286
|
+
if (parsed.isValid()) {
|
|
287
|
+
return parsed;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
// Continue to next format
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// If all formats fail, try parsing without format (let dayjs guess)
|
|
295
|
+
try {
|
|
296
|
+
const parsed = dayjs(dateString);
|
|
297
|
+
if (parsed.isValid()) {
|
|
298
|
+
return parsed;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
console.warn('Failed to parse date with any format:', dateString, error);
|
|
303
|
+
}
|
|
304
|
+
return dayjs('invalid');
|
|
305
|
+
}
|
|
255
306
|
constructor(injectedData, toast) {
|
|
256
307
|
this.injectedData = injectedData;
|
|
257
308
|
this.toast = toast;
|
|
@@ -356,35 +407,10 @@ class TzDrpContainerComponent {
|
|
|
356
407
|
format: DATE_FORMAT
|
|
357
408
|
};
|
|
358
409
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
let selectedStartDate;
|
|
362
|
-
if (localSelectedDates?.startDate) {
|
|
363
|
-
// Use the robust helper for parsing
|
|
364
|
-
selectedStartDate = this.parseDateWithMultipleFormats(localSelectedDates.startDate);
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
selectedStartDate = dayjs('invalid');
|
|
368
|
-
}
|
|
369
|
-
if (selectedStartDate.isValid()) {
|
|
370
|
-
this.currentYearNumberSignal.set(selectedStartDate.year());
|
|
371
|
-
this.nextYearNumberSignal.set(selectedStartDate.add(1, "month").year());
|
|
372
|
-
this.currentMonthNumberSignal.set(selectedStartDate.get("month"));
|
|
373
|
-
this.nextMonthNumberSignal.set(selectedStartDate.add(1, "month").month());
|
|
374
|
-
const selectedEndDate = localSelectedDates?.endDate ? this.parseDateWithMultipleFormats(localSelectedDates.endDate) : null;
|
|
375
|
-
// Logic for next month being set by end date
|
|
376
|
-
if (selectedEndDate && selectedEndDate.isValid() && selectedEndDate.isAfter(selectedStartDate, 'month')) {
|
|
377
|
-
this.nextMonthNumberSignal.set(selectedEndDate.month());
|
|
378
|
-
this.nextYearNumberSignal.set(selectedEndDate.year());
|
|
379
|
-
}
|
|
380
|
-
// Update calendar dates to reflect the selected dates
|
|
381
|
-
this.currentMonthDatesSignal.set(this.generateDates(this.currentMonthNumberSignal(), this.currentYearNumberSignal()));
|
|
382
|
-
this.nextMonthDatesSignal.set(this.generateDates(this.nextMonthNumberSignal(), this.nextYearNumberSignal()));
|
|
383
|
-
}
|
|
384
|
-
}, { allowSignalWrites: true });
|
|
410
|
+
// Update calendar from initial selected dates
|
|
411
|
+
this.updateCalendarFromSelectedDates();
|
|
385
412
|
}
|
|
386
413
|
ngOnInit() {
|
|
387
|
-
console.log('ngOnInit');
|
|
388
414
|
this.calculateMinMaxDays();
|
|
389
415
|
this.initializeTimeValues();
|
|
390
416
|
if (this.data()?.showPrevMonth && !this.isPreviousMonthDisabled) {
|
|
@@ -418,8 +444,8 @@ class TzDrpContainerComponent {
|
|
|
418
444
|
}
|
|
419
445
|
this.currentMonthNumberSignal.set(thisMonth.month());
|
|
420
446
|
this.nextMonthNumberSignal.set(thisMonth.clone().add(1, "month").month());
|
|
421
|
-
this.currentMonthSignal.set(getMonth(this.
|
|
422
|
-
this.nextMonthSignal.set(getMonth(this.
|
|
447
|
+
this.currentMonthSignal.set(getMonth(this.currentMonthNumberSignal()));
|
|
448
|
+
this.nextMonthSignal.set(getMonth(this.nextMonthNumberSignal()));
|
|
423
449
|
if (this.nextMonthNumberSignal() === 0 && direction === "PREVIOUS") {
|
|
424
450
|
this.currentYearNumberSignal.set(this.currentYearNumberSignal() - 1);
|
|
425
451
|
}
|
|
@@ -439,46 +465,36 @@ class TzDrpContainerComponent {
|
|
|
439
465
|
this.nextMonthDatesSignal.set(this.generateDates(this.nextMonthNumber(), this.nextYearNumber()));
|
|
440
466
|
this.calculateMinMaxDays();
|
|
441
467
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
return parsed;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
catch (error) {
|
|
455
|
-
// Continue to fallback formats
|
|
456
|
-
}
|
|
468
|
+
/**
|
|
469
|
+
* Update calendar month/year based on selected dates
|
|
470
|
+
* This method is called whenever localSelectedDatesSignal changes to keep calendar in sync
|
|
471
|
+
*/
|
|
472
|
+
updateCalendarFromSelectedDates() {
|
|
473
|
+
const localSelectedDates = this.localSelectedDatesSignal();
|
|
474
|
+
let selectedStartDate;
|
|
475
|
+
if (localSelectedDates?.startDate) {
|
|
476
|
+
selectedStartDate = this.parseDateWithMultipleFormats(localSelectedDates.startDate);
|
|
457
477
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
];
|
|
461
|
-
for (const format of fallbackFormats) {
|
|
462
|
-
try {
|
|
463
|
-
const parsed = dayjs(dateString, format);
|
|
464
|
-
if (parsed.isValid()) {
|
|
465
|
-
return parsed;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
catch (error) {
|
|
469
|
-
// Continue to next format
|
|
470
|
-
}
|
|
478
|
+
else {
|
|
479
|
+
selectedStartDate = dayjs('invalid');
|
|
471
480
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
481
|
+
if (selectedStartDate.isValid()) {
|
|
482
|
+
this.currentYearNumberSignal.set(selectedStartDate.year());
|
|
483
|
+
this.nextYearNumberSignal.set(selectedStartDate.add(1, "month").year());
|
|
484
|
+
this.currentMonthNumberSignal.set(selectedStartDate.get("month"));
|
|
485
|
+
this.nextMonthNumberSignal.set(selectedStartDate.add(1, "month").month());
|
|
486
|
+
const selectedEndDate = localSelectedDates?.endDate ? this.parseDateWithMultipleFormats(localSelectedDates.endDate) : null;
|
|
487
|
+
if (selectedEndDate && selectedEndDate.isValid() && selectedEndDate.isAfter(selectedStartDate, 'month')) {
|
|
488
|
+
this.nextMonthNumberSignal.set(selectedEndDate.month());
|
|
489
|
+
this.nextYearNumberSignal.set(selectedEndDate.year());
|
|
476
490
|
}
|
|
491
|
+
// Update month labels
|
|
492
|
+
this.currentMonthSignal.set(getMonth(this.currentMonthNumberSignal()));
|
|
493
|
+
this.nextMonthSignal.set(getMonth(this.nextMonthNumberSignal()));
|
|
494
|
+
// Update calendar dates to reflect the selected dates
|
|
495
|
+
this.currentMonthDatesSignal.set(this.generateDates(this.currentMonthNumberSignal(), this.currentYearNumberSignal()));
|
|
496
|
+
this.nextMonthDatesSignal.set(this.generateDates(this.nextMonthNumberSignal(), this.nextYearNumberSignal()));
|
|
477
497
|
}
|
|
478
|
-
catch (error) {
|
|
479
|
-
console.warn('Failed to parse date with any format:', dateString, error);
|
|
480
|
-
}
|
|
481
|
-
return dayjs('invalid');
|
|
482
498
|
}
|
|
483
499
|
generateDates(month, currentYearNumber) {
|
|
484
500
|
let dates = [];
|
|
@@ -530,13 +546,38 @@ class TzDrpContainerComponent {
|
|
|
530
546
|
const isCurrentDay = this.dayjsInstance().year(currentYearNumber).month(month).date(currentDate).format(this.data().dpConfig.format) ===
|
|
531
547
|
this.dayjsInstance().format(this.data().dpConfig.format);
|
|
532
548
|
// Extract date part for comparison (handle both date-only and datetime formats)
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
549
|
+
let startDateString = this.localSelectedDatesSignal()?.startDate;
|
|
550
|
+
let endDateString = this.localSelectedDatesSignal()?.endDate;
|
|
551
|
+
// Only extract date part if the format contains time components
|
|
552
|
+
if (this.data().dpConfig.format.includes('HH') || this.data().dpConfig.format.includes('mm') || this.data().dpConfig.format.includes('A')) {
|
|
553
|
+
// For datetime formats, we need to extract just the date part
|
|
554
|
+
// Try to parse the full string and then format it as date-only for comparison
|
|
555
|
+
if (startDateString) {
|
|
556
|
+
const parsedStart = this.parseDateWithMultipleFormats(startDateString);
|
|
557
|
+
if (parsedStart.isValid()) {
|
|
558
|
+
// Extract date part by finding the time boundary - handle spaces in date part
|
|
559
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
560
|
+
if (timeStartMatch) {
|
|
561
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
562
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
563
|
+
startDateString = parsedStart.format(dateOnlyFormat);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (endDateString) {
|
|
568
|
+
const parsedEnd = this.parseDateWithMultipleFormats(endDateString);
|
|
569
|
+
if (parsedEnd.isValid()) {
|
|
570
|
+
// Extract date part by finding the time boundary - handle spaces in date part
|
|
571
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
572
|
+
if (timeStartMatch) {
|
|
573
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
574
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
575
|
+
endDateString = parsedEnd.format(dateOnlyFormat);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
// Parse the selected dates to get proper dayjs instances for comparison
|
|
540
581
|
const startDateParsed = startDateString ? this.parseDateWithMultipleFormats(startDateString) : null;
|
|
541
582
|
const endDateParsed = endDateString ? this.parseDateWithMultipleFormats(endDateString) : null;
|
|
542
583
|
const isSelectedStartDay = !isDisabledDay &&
|
|
@@ -547,7 +588,7 @@ class TzDrpContainerComponent {
|
|
|
547
588
|
endDateParsed &&
|
|
548
589
|
endDateParsed.isValid() &&
|
|
549
590
|
date.isSame(endDateParsed, 'day');
|
|
550
|
-
// For range calculation,
|
|
591
|
+
// For range calculation, use the already parsed dates
|
|
551
592
|
const isAfterSelectedStartDate = startDateParsed ? this.dayjsInstance(date).isAfter(startDateParsed, "day") : false;
|
|
552
593
|
const isBeforeSelectedEndDate = endDateParsed ? this.dayjsInstance(date).isBefore(endDateParsed, "day") : false;
|
|
553
594
|
const inRangeDay = startDateParsed && endDateParsed &&
|
|
@@ -571,93 +612,143 @@ class TzDrpContainerComponent {
|
|
|
571
612
|
return dates;
|
|
572
613
|
}
|
|
573
614
|
selectDay(from, day) {
|
|
574
|
-
if (day.date <= 0)
|
|
615
|
+
if (day.date <= 0)
|
|
575
616
|
return;
|
|
576
|
-
}
|
|
577
617
|
if (!day.isDisabledDay) {
|
|
578
618
|
this.selectedItemLabelSignal.set(this.CUSTOM_RANGE_LABEL);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
endDate: formattedDate,
|
|
602
|
-
selectedRangeLabel: this.CUSTOM_RANGE_LABEL
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
// If the selected date is before the start date, make it the new start date
|
|
606
|
-
if (startDate && dayjsDay.isBefore(startDate, "day")) {
|
|
607
|
-
// Start selection over
|
|
608
|
-
this.selectionStartedSignal.set(true);
|
|
609
|
-
this.isDatesValidSignal.set(false);
|
|
610
|
-
return {
|
|
611
|
-
startDate: formattedDate,
|
|
612
|
-
endDate: null,
|
|
613
|
-
selectedRangeLabel: this.CUSTOM_RANGE_LABEL
|
|
614
|
-
};
|
|
619
|
+
if (this.selectionStartedSignal()) {
|
|
620
|
+
const dayjsDay = dayjs()
|
|
621
|
+
.year(from === "LEFT" ? this.currentYearNumberSignal() : this.nextYearNumberSignal())
|
|
622
|
+
.month(from === "LEFT" ? this.currentMonthNumberSignal() : this.nextMonthNumberSignal())
|
|
623
|
+
.date(day.date);
|
|
624
|
+
// Extract date part from existing start date for comparison
|
|
625
|
+
let startDateString = this.localSelectedDatesSignal().startDate;
|
|
626
|
+
// Only extract date part if the format contains time components
|
|
627
|
+
if (this.data().dpConfig.format.includes('HH') || this.data().dpConfig.format.includes('mm') || this.data().dpConfig.format.includes('A')) {
|
|
628
|
+
// For datetime formats, we need to extract just the date part
|
|
629
|
+
// Try to parse the full string and then format it as date-only for comparison
|
|
630
|
+
if (startDateString) {
|
|
631
|
+
const parsedStart = this.parseDateWithMultipleFormats(startDateString);
|
|
632
|
+
if (parsedStart.isValid()) {
|
|
633
|
+
// Extract date part by finding the time boundary - handle spaces in date part
|
|
634
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
635
|
+
if (timeStartMatch) {
|
|
636
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
637
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
638
|
+
startDateString = parsedStart.format(dateOnlyFormat);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
615
641
|
}
|
|
616
|
-
// End selection
|
|
617
|
-
this.selectionStartedSignal.set(false);
|
|
618
|
-
this.isDatesValidSignal.set(true);
|
|
619
|
-
return {
|
|
620
|
-
...current,
|
|
621
|
-
endDate: formattedDate,
|
|
622
|
-
selectedRangeLabel: this.CUSTOM_RANGE_LABEL
|
|
623
|
-
};
|
|
624
642
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
this.
|
|
629
|
-
|
|
643
|
+
const startDate = startDateString ? this.parseDateWithMultipleFormats(startDateString) : null;
|
|
644
|
+
// If the selected date is before the start date, make it the new start date
|
|
645
|
+
if (startDate && dayjsDay.isBefore(startDate, "day")) {
|
|
646
|
+
let formattedDate = dayjsDay.format(this.data().dpConfig.format);
|
|
647
|
+
// If time is enabled, append current time to the date
|
|
648
|
+
if (this.data().dpConfig.enableTime === true) {
|
|
649
|
+
const now = dayjs();
|
|
650
|
+
// Extract date part from the configured format - handle spaces in date part
|
|
651
|
+
// Look for the pattern where time starts (HH, mm, ss, A, a)
|
|
652
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
653
|
+
if (timeStartMatch) {
|
|
654
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
655
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
656
|
+
const timeOnlyFormat = this.data().dpConfig.format.substring(timeStartIndex + timeStartMatch[1].length);
|
|
657
|
+
const dateString = dayjsDay.format(dateOnlyFormat);
|
|
658
|
+
const timeString = now.format(timeOnlyFormat);
|
|
659
|
+
formattedDate = dateString + timeStartMatch[1] + timeString;
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
// Fallback if no time pattern found
|
|
663
|
+
formattedDate = dayjsDay.format(this.data().dpConfig.format);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
this.localSelectedDatesSignal.set({
|
|
630
667
|
startDate: formattedDate,
|
|
631
668
|
endDate: null,
|
|
632
669
|
selectedRangeLabel: this.CUSTOM_RANGE_LABEL
|
|
633
|
-
};
|
|
670
|
+
});
|
|
671
|
+
this.updateCalendarFromSelectedDates();
|
|
672
|
+
return;
|
|
634
673
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
674
|
+
this.selectionStartedSignal.set(false);
|
|
675
|
+
let formattedEndDate = dayjsDay.format(this.data().dpConfig.format);
|
|
676
|
+
// If time is enabled, append current time to the date
|
|
677
|
+
if (this.data().dpConfig.enableTime === true) {
|
|
678
|
+
const now = dayjs();
|
|
679
|
+
// Extract date part from the configured format - handle spaces in date part
|
|
680
|
+
// Look for the pattern where time starts (HH, mm, ss, A, a)
|
|
681
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
682
|
+
if (timeStartMatch) {
|
|
683
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
684
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
685
|
+
const timeOnlyFormat = this.data().dpConfig.format.substring(timeStartIndex + timeStartMatch[1].length);
|
|
686
|
+
const dateString = dayjsDay.format(dateOnlyFormat);
|
|
687
|
+
const timeString = now.format(timeOnlyFormat);
|
|
688
|
+
formattedEndDate = dateString + timeStartMatch[1] + timeString;
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
// Fallback if no time pattern found
|
|
692
|
+
formattedEndDate = dayjsDay.format(this.data().dpConfig.format);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
this.localSelectedDatesSignal.set({
|
|
696
|
+
...this.localSelectedDatesSignal(),
|
|
697
|
+
endDate: formattedEndDate,
|
|
698
|
+
selectedRangeLabel: this.CUSTOM_RANGE_LABEL
|
|
699
|
+
});
|
|
700
|
+
this.updateCalendarFromSelectedDates();
|
|
701
|
+
}
|
|
702
|
+
else {
|
|
703
|
+
this.selectionStartedSignal.set(true);
|
|
704
|
+
let formattedStartDate = dayjs()
|
|
705
|
+
.year(from === "LEFT" ? this.currentYearNumberSignal() : this.nextYearNumberSignal())
|
|
706
|
+
.month(from === "LEFT" ? this.currentMonthNumberSignal() : this.nextMonthNumberSignal())
|
|
707
|
+
.date(day.date)
|
|
708
|
+
.format(this.data().dpConfig.format);
|
|
709
|
+
// If time is enabled, append current time to the date
|
|
710
|
+
if (this.data().dpConfig.enableTime === true) {
|
|
711
|
+
const now = dayjs();
|
|
712
|
+
// Extract date part from the configured format - handle spaces in date part
|
|
713
|
+
// Look for the pattern where time starts (HH, mm, ss, A, a)
|
|
714
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
715
|
+
if (timeStartMatch) {
|
|
716
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
717
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
718
|
+
const timeOnlyFormat = this.data().dpConfig.format.substring(timeStartIndex + timeStartMatch[1].length);
|
|
719
|
+
const dateString = dayjs()
|
|
720
|
+
.year(from === "LEFT" ? this.currentYearNumberSignal() : this.nextYearNumberSignal())
|
|
721
|
+
.month(from === "LEFT" ? this.currentMonthNumberSignal() : this.nextMonthNumberSignal())
|
|
722
|
+
.date(day.date)
|
|
723
|
+
.format(dateOnlyFormat);
|
|
724
|
+
const timeString = now.format(timeOnlyFormat);
|
|
725
|
+
formattedStartDate = dateString + timeStartMatch[1] + timeString;
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
// Fallback if no time pattern found
|
|
729
|
+
formattedStartDate = dayjs()
|
|
730
|
+
.year(from === "LEFT" ? this.currentYearNumberSignal() : this.nextYearNumberSignal())
|
|
731
|
+
.month(from === "LEFT" ? this.currentMonthNumberSignal() : this.nextMonthNumberSignal())
|
|
732
|
+
.date(day.date)
|
|
733
|
+
.format(this.data().dpConfig.format);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
this.localSelectedDatesSignal.set({
|
|
737
|
+
startDate: formattedStartDate,
|
|
738
|
+
endDate: null,
|
|
739
|
+
selectedRangeLabel: this.CUSTOM_RANGE_LABEL
|
|
740
|
+
});
|
|
741
|
+
this.updateCalendarFromSelectedDates();
|
|
742
|
+
}
|
|
743
|
+
this.isDatesValidSignal.set(false);
|
|
744
|
+
if (this.localSelectedDatesSignal().startDate && this.localSelectedDatesSignal().endDate) {
|
|
745
|
+
this.isDatesValidSignal.set(true);
|
|
746
|
+
}
|
|
638
747
|
}
|
|
639
748
|
if (day.toastMessage) {
|
|
640
749
|
this.toast.displayMsg(day.toastMessage, 4000);
|
|
641
750
|
}
|
|
642
751
|
}
|
|
643
|
-
// Helper method to append current time (replicates original selectDay complex formatting logic)
|
|
644
|
-
appendCurrentTime(date) {
|
|
645
|
-
if (!this.data().dpConfig.enableTime)
|
|
646
|
-
return date.format(this.data().dpConfig.format);
|
|
647
|
-
// This complex formatting logic must be replicated exactly for backward compatibility
|
|
648
|
-
const now = dayjs();
|
|
649
|
-
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
650
|
-
if (timeStartMatch) {
|
|
651
|
-
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
652
|
-
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
653
|
-
const timeOnlyFormat = this.data().dpConfig.format.substring(timeStartIndex + timeStartMatch[1].length);
|
|
654
|
-
const dateString = date.format(dateOnlyFormat);
|
|
655
|
-
const timeString = now.format(timeOnlyFormat);
|
|
656
|
-
return dateString + timeStartMatch[1] + timeString;
|
|
657
|
-
}
|
|
658
|
-
// Fallback if no time pattern found
|
|
659
|
-
return date.format(this.data().dpConfig.format);
|
|
660
|
-
}
|
|
661
752
|
selectRange(item) {
|
|
662
753
|
if (!item)
|
|
663
754
|
return;
|
|
@@ -665,11 +756,9 @@ class TzDrpContainerComponent {
|
|
|
665
756
|
let endDate = this.dayjsInstance(item.value[1]);
|
|
666
757
|
const startDateStr = startDate.format(this.data().dpConfig.format);
|
|
667
758
|
const endDateStr = endDate.format(this.data().dpConfig.format);
|
|
668
|
-
// Note: The original datesDisabled check uses the custom dayjsInstance, which is good.
|
|
669
759
|
const isAnyDateDisabled = this.data().datesDisabled.some((date) => this.dayjsInstance(date, this.data().dpConfig.format).isBetween(startDateStr, endDateStr, null, '[]'));
|
|
670
|
-
|
|
671
|
-
const
|
|
672
|
-
const maxDate = !!this.data().dpConfig.maxDate ? this.parseDateWithMultipleFormats(this.data().dpConfig.maxDate) : dayjs('invalid');
|
|
760
|
+
const minDate = !!this.data().dpConfig.minDate ? this.dayjsInstance(this.data().dpConfig.minDate, this.data().dpConfig.format) : dayjs('invalid');
|
|
761
|
+
const maxDate = !!this.data().dpConfig.maxDate ? this.dayjsInstance(this.data().dpConfig.maxDate, this.data().dpConfig.format) : dayjs('invalid');
|
|
673
762
|
const isWithinLimits = (!minDate.isValid() || !startDate.isBefore(minDate, "day")) &&
|
|
674
763
|
(!maxDate.isValid() || !endDate.isAfter(maxDate, "day"));
|
|
675
764
|
if (!isWithinLimits || isAnyDateDisabled) {
|
|
@@ -679,7 +768,6 @@ class TzDrpContainerComponent {
|
|
|
679
768
|
this.selectedItemLabelSignal.set(item.label);
|
|
680
769
|
this.currentMonthNumberSignal.set(startDate.month());
|
|
681
770
|
this.currentYearNumberSignal.set(startDate.year());
|
|
682
|
-
// Month/Year rollover logic is kept as is to match original functionality
|
|
683
771
|
if (this.currentMonthNumberSignal() === 11) {
|
|
684
772
|
this.nextMonthNumberSignal.set(0);
|
|
685
773
|
this.nextYearNumberSignal.set(this.currentYearNumberSignal() + 1);
|
|
@@ -693,8 +781,10 @@ class TzDrpContainerComponent {
|
|
|
693
781
|
endDate: endDateStr,
|
|
694
782
|
selectedRangeLabel: item.label
|
|
695
783
|
});
|
|
696
|
-
|
|
697
|
-
|
|
784
|
+
this.currentMonthSignal.set(getMonth(this.currentMonthNumberSignal()));
|
|
785
|
+
this.nextMonthSignal.set(getMonth(this.nextMonthNumberSignal()));
|
|
786
|
+
this.currentMonthDatesSignal.set(this.generateDates(this.currentMonthNumberSignal(), this.currentYearNumberSignal()));
|
|
787
|
+
this.nextMonthDatesSignal.set(this.generateDates(this.nextMonthNumberSignal(), this.nextYearNumberSignal()));
|
|
698
788
|
this.isDatesValidSignal.set(!!(this.localSelectedDatesSignal().startDate && this.localSelectedDatesSignal().endDate));
|
|
699
789
|
}
|
|
700
790
|
resetRange() {
|
|
@@ -709,13 +799,11 @@ class TzDrpContainerComponent {
|
|
|
709
799
|
this.currentMonthDatesSignal.set(this.generateDates(this.currentMonthNumber(), this.currentYearNumber()));
|
|
710
800
|
this.nextMonthDatesSignal.set(this.generateDates(this.nextMonthNumber(), this.nextYearNumber()));
|
|
711
801
|
}
|
|
712
|
-
// TzDrpContainerComponent (Signal-Migrated)
|
|
713
802
|
applyDates() {
|
|
714
803
|
// If time is enabled, append time to the dates before applying
|
|
715
804
|
if (this.data().dpConfig.enableTime === true) {
|
|
716
805
|
let startTime;
|
|
717
806
|
let endTime;
|
|
718
|
-
// Use signal accessors
|
|
719
807
|
if (this.is12HourFormat()) {
|
|
720
808
|
startTime = this.formatTime(this.startHour(), this.startMinute(), this.startAmPm());
|
|
721
809
|
endTime = this.formatTime(this.endHour(), this.endMinute(), this.endAmPm());
|
|
@@ -724,41 +812,36 @@ class TzDrpContainerComponent {
|
|
|
724
812
|
startTime = this.formatTime(this.startHour24(), this.startMinute(), '');
|
|
725
813
|
endTime = this.formatTime(this.endHour24(), this.endMinute(), '');
|
|
726
814
|
}
|
|
815
|
+
// Extract only the date part (before any existing time) and append the selected time
|
|
727
816
|
const localDates = this.localSelectedDatesSignal();
|
|
728
817
|
let startDateOnly = localDates.startDate;
|
|
729
818
|
let endDateOnly = localDates.endDate;
|
|
730
|
-
//
|
|
731
|
-
if (
|
|
732
|
-
|
|
733
|
-
//
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
}
|
|
745
|
-
else {
|
|
746
|
-
// Fallback to splitting if format is date-only
|
|
747
|
-
startDateOnly = (typeof startDateOnly === 'string') ? startDateOnly.split(' ')[0] : startDateOnly;
|
|
819
|
+
// Only extract date part if the format contains time components
|
|
820
|
+
if (this.data().dpConfig.format.includes('HH') || this.data().dpConfig.format.includes('mm') || this.data().dpConfig.format.includes('A')) {
|
|
821
|
+
// For datetime formats, we need to extract just the date part
|
|
822
|
+
// Try to parse the full string and then format it as date-only for comparison
|
|
823
|
+
if (startDateOnly) {
|
|
824
|
+
const parsedStart = this.parseDateWithMultipleFormats(startDateOnly);
|
|
825
|
+
if (parsedStart.isValid()) {
|
|
826
|
+
// Extract date part by finding the time boundary - handle spaces in date part
|
|
827
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
828
|
+
if (timeStartMatch) {
|
|
829
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
830
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
831
|
+
startDateOnly = parsedStart.format(dateOnlyFormat);
|
|
832
|
+
}
|
|
748
833
|
}
|
|
749
834
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
else {
|
|
761
|
-
endDateOnly = (typeof endDateOnly === 'string') ? endDateOnly.split(' ')[0] : endDateOnly;
|
|
835
|
+
if (endDateOnly) {
|
|
836
|
+
const parsedEnd = this.parseDateWithMultipleFormats(endDateOnly);
|
|
837
|
+
if (parsedEnd.isValid()) {
|
|
838
|
+
// Extract date part by finding the time boundary - handle spaces in date part
|
|
839
|
+
const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
|
|
840
|
+
if (timeStartMatch) {
|
|
841
|
+
const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
|
|
842
|
+
const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
|
|
843
|
+
endDateOnly = parsedEnd.format(dateOnlyFormat);
|
|
844
|
+
}
|
|
762
845
|
}
|
|
763
846
|
}
|
|
764
847
|
}
|
|
@@ -1198,16 +1281,19 @@ class TzDaterangepickerDirective {
|
|
|
1198
1281
|
backdropClass: "cdk-overlay-transparent-backdrop"
|
|
1199
1282
|
});
|
|
1200
1283
|
this.overlayRef = this.overlay.create(config);
|
|
1284
|
+
// Get current values at the time of opening
|
|
1285
|
+
const currentSelectedDates = this.selectedDates();
|
|
1286
|
+
const currentSelectedRangeLabel = this.selectedRangeLabel();
|
|
1201
1287
|
const tempRef = new ComponentPortal(TzDrpContainerComponent, this.viewContainerRef, Injector.create({
|
|
1202
1288
|
providers: [
|
|
1203
1289
|
{
|
|
1204
1290
|
provide: CONTAINER_DATA,
|
|
1205
1291
|
useValue: {
|
|
1206
1292
|
messages: this.dateMessages(),
|
|
1207
|
-
dates:
|
|
1293
|
+
dates: currentSelectedDates,
|
|
1208
1294
|
dpConfig: this.dpConfig(),
|
|
1209
1295
|
datesDisabled: this.datesDisabled(),
|
|
1210
|
-
selectedRangeLabel:
|
|
1296
|
+
selectedRangeLabel: currentSelectedRangeLabel,
|
|
1211
1297
|
dateChange: this.applyDate.bind(this),
|
|
1212
1298
|
close: this.close.bind(this)
|
|
1213
1299
|
}
|