mis-crystal-design-system 18.1.7-signal-16-test-2 → 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.
Files changed (38) hide show
  1. package/async-search-dropdown/async-dropdown.component.d.ts +44 -3
  2. package/daterangepicker_v2/tz-drp-container/tz-drp-container.component.d.ts +9 -2
  3. package/esm2022/async-search-dropdown/async-dropdown.component.mjs +147 -37
  4. package/esm2022/datepicker_v2/tz-dp-container/tz-dp-container.component.mjs +35 -22
  5. package/esm2022/daterangepicker_v2/tz-drp-container/tz-drp-container.component.mjs +270 -187
  6. package/esm2022/dynamic-form/dynamic-form.component.mjs +30 -21
  7. package/esm2022/loader/loader.component.mjs +12 -6
  8. package/esm2022/slider/slider.component.mjs +2 -2
  9. package/esm2022/table/sort-icons.directive.mjs +24 -5
  10. package/esm2022/table/table.component.mjs +200 -93
  11. package/esm2022/table/table.module.mjs +7 -5
  12. package/esm2022/timepicker/timepicker.component.mjs +41 -14
  13. package/esm2022/timerangepicker/timerangepicker.component.mjs +73 -23
  14. package/fesm2022/mis-crystal-design-system-async-search-dropdown.mjs +146 -36
  15. package/fesm2022/mis-crystal-design-system-async-search-dropdown.mjs.map +1 -1
  16. package/fesm2022/mis-crystal-design-system-datepicker_v2.mjs +34 -21
  17. package/fesm2022/mis-crystal-design-system-datepicker_v2.mjs.map +1 -1
  18. package/fesm2022/mis-crystal-design-system-daterangepicker_v2.mjs +269 -186
  19. package/fesm2022/mis-crystal-design-system-daterangepicker_v2.mjs.map +1 -1
  20. package/fesm2022/mis-crystal-design-system-dynamic-form.mjs +29 -20
  21. package/fesm2022/mis-crystal-design-system-dynamic-form.mjs.map +1 -1
  22. package/fesm2022/mis-crystal-design-system-loader.mjs +11 -5
  23. package/fesm2022/mis-crystal-design-system-loader.mjs.map +1 -1
  24. package/fesm2022/mis-crystal-design-system-slider.mjs +2 -2
  25. package/fesm2022/mis-crystal-design-system-slider.mjs.map +1 -1
  26. package/fesm2022/mis-crystal-design-system-table.mjs +227 -99
  27. package/fesm2022/mis-crystal-design-system-table.mjs.map +1 -1
  28. package/fesm2022/mis-crystal-design-system-timepicker.mjs +40 -13
  29. package/fesm2022/mis-crystal-design-system-timepicker.mjs.map +1 -1
  30. package/fesm2022/mis-crystal-design-system-timerangepicker.mjs +72 -22
  31. package/fesm2022/mis-crystal-design-system-timerangepicker.mjs.map +1 -1
  32. package/loader/loader.component.d.ts +7 -1
  33. package/package.json +25 -25
  34. package/styles/mis-old-icon-styles.scss +498 -0
  35. package/table/table.component.d.ts +16 -4
  36. package/table/table.module.d.ts +2 -1
  37. package/timepicker/timepicker.component.d.ts +3 -1
  38. 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, effect, Component, Inject, HostListener, input, output, Injector, Directive, Self, Optional, NgModule } from '@angular/core';
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
- effect(() => {
360
- const localSelectedDates = this.localSelectedDatesSignal();
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 1');
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.currentMonthNumber()));
422
- this.nextMonthSignal.set(getMonth(this.nextMonthNumber()));
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
- parseDateWithMultipleFormats(dateString) {
443
- if (!dateString || dateString === 'Invalid Date' || dateString === 'undefined' || dateString === 'null') {
444
- return dayjs('invalid');
445
- }
446
- const configuredFormat = this.data()?.dpConfig?.format;
447
- if (configuredFormat) {
448
- try {
449
- const parsed = dayjs(dateString, configuredFormat);
450
- if (parsed.isValid()) {
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
- const fallbackFormats = [
459
- 'DD/MMM/YYYY', 'DD/MM/YYYY', 'DD-MMM-YYYY', 'DD-MM-YYYY', 'YYYY-MM-DD'
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
- try {
473
- const parsed = dayjs(dateString);
474
- if (parsed.isValid()) {
475
- return parsed;
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
- const startDateString = (this.localSelectedDatesSignal()?.startDate && typeof this.localSelectedDatesSignal()?.startDate === 'string')
534
- ? this.localSelectedDatesSignal().startDate.split(' ')[0]
535
- : this.localSelectedDatesSignal()?.startDate;
536
- const endDateString = (this.localSelectedDatesSignal()?.endDate && typeof this.localSelectedDatesSignal()?.endDate === 'string')
537
- ? this.localSelectedDatesSignal().endDate.split(' ')[0]
538
- : this.localSelectedDatesSignal()?.endDate;
539
- // Use the custom format for comparison instead of hardcoded DD/MM/YYYY
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, parse dates properly using custom format
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
- // Calculate the day being selected
580
- const dayjsDay = dayjs()
581
- .year(from === "LEFT" ? this.currentYearNumberSignal() : this.nextYearNumberSignal())
582
- .month(from === "LEFT" ? this.currentMonthNumberSignal() : this.nextMonthNumberSignal())
583
- .date(day.date);
584
- let formattedDate = dayjsDay.format(this.data().dpConfig.format);
585
- this.localSelectedDatesSignal.update(current => {
586
- let updatedDates = { ...current };
587
- // Start Date for comparison (using helper for robust check)
588
- const startDate = current.startDate ? this.parseDateWithMultipleFormats(current.startDate) : null;
589
- // FIX 4: Append time if enabled
590
- if (this.data().dpConfig.enableTime === true) {
591
- // The time is set to NOW, as per original non-signal component's logic
592
- formattedDate = this.appendCurrentTime(dayjsDay);
593
- }
594
- if (this.selectionStarted()) {
595
- // If the selected date is the same as the start date (New in your previous signal code, but valid)
596
- if (startDate && dayjsDay.isSame(startDate, "day")) {
597
- this.selectionStartedSignal.set(false);
598
- this.isDatesValidSignal.set(true); // Manually setting validity (can be computed later)
599
- return {
600
- startDate: formattedDate,
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
- else {
626
- // Start selection
627
- this.selectionStartedSignal.set(true);
628
- this.isDatesValidSignal.set(false);
629
- return {
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
- // The date arrays are COMPUTED, so no need for manual set()
637
- this.isDatesValidSignal.set(!!(this.localSelectedDatesSignal().startDate && this.localSelectedDatesSignal().endDate));
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
- // FIX 4: Use robust parsing for minDate/maxDate comparison
671
- const minDate = !!this.data().dpConfig.minDate ? this.parseDateWithMultipleFormats(this.data().dpConfig.minDate) : dayjs('invalid');
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
- // The month/date computed properties (currentMonth, currentMonthDates, etc.)
697
- // update automatically now.
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
- // FIX 4: Use robust parsing/formatting for date part extraction
731
- if (startDateOnly) {
732
- const parsedStart = this.parseDateWithMultipleFormats(startDateOnly);
733
- // This is a complex date format extraction in the original, simplified here
734
- // by taking the date part only (assuming time is always separated by space)
735
- // For true fidelity, the original logic for date part extraction with time must be preserved.
736
- if (parsedStart.isValid()) {
737
- // Preserve original date formatting logic: extract only the date part
738
- // using the configured format elements BEFORE the time components.
739
- const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
740
- if (timeStartMatch) {
741
- const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
742
- const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
743
- startDateOnly = parsedStart.format(dateOnlyFormat);
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
- if (endDateOnly) {
752
- const parsedEnd = this.parseDateWithMultipleFormats(endDateOnly);
753
- if (parsedEnd.isValid()) {
754
- const timeStartMatch = this.data().dpConfig.format.match(/(\s+)(HH|mm|ss|A|a)/);
755
- if (timeStartMatch) {
756
- const timeStartIndex = this.data().dpConfig.format.indexOf(timeStartMatch[0]);
757
- const dateOnlyFormat = this.data().dpConfig.format.substring(0, timeStartIndex);
758
- endDateOnly = parsedEnd.format(dateOnlyFormat);
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
  }