@energycap/components 0.46.13 → 0.46.14-esm-luxon.20260713-1107
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.
|
@@ -16,8 +16,8 @@ import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
|
|
16
16
|
import { ClipboardService } from 'ngx-clipboard';
|
|
17
17
|
import { Subject, of, lastValueFrom, forkJoin, merge, fromEvent, EMPTY, timer, interval, race, ReplaySubject } from 'rxjs';
|
|
18
18
|
import { takeUntil, switchMap, delay, distinctUntilChanged, filter, take, debounceTime, skipUntil, tap, pluck, map, catchError, skipWhile } from 'rxjs/operators';
|
|
19
|
-
import
|
|
20
|
-
import { range, cloneDeep, isEqual, uniqueId, sortBy, orderBy, get, upperFirst } from 'lodash';
|
|
19
|
+
import { DateTime, Info } from 'luxon';
|
|
20
|
+
import { range, cloneDeep, isEqual, uniqueId, sortBy, orderBy, get, upperFirst } from 'lodash-es';
|
|
21
21
|
import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
|
|
22
22
|
import Popper from 'popper.js';
|
|
23
23
|
|
|
@@ -539,7 +539,7 @@ class DateTimeHelper {
|
|
|
539
539
|
/** 3000-01-01 */
|
|
540
540
|
static { this.endOfTime = new Date(3000, 0, 1); }
|
|
541
541
|
/** 3000-01-01 UTC */
|
|
542
|
-
static { this.endOfTimeUTC =
|
|
542
|
+
static { this.endOfTimeUTC = DateTime.fromISO('3000-01-01', { zone: 'utc' }).toJSDate(); }
|
|
543
543
|
/** Default effective date for new AccountMeter relationships: 2010-01-01 */
|
|
544
544
|
static { this.defaultAccountMeterEffectiveDate = new Date(2010, 0, 1); }
|
|
545
545
|
/** The default date that a newly created account becomes effective: 2010-01-01 */
|
|
@@ -581,20 +581,19 @@ class DateTimeHelper {
|
|
|
581
581
|
"yyyyMMdd"
|
|
582
582
|
]; }
|
|
583
583
|
/**
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
'
|
|
591
|
-
'
|
|
592
|
-
'
|
|
593
|
-
'
|
|
594
|
-
'
|
|
595
|
-
'
|
|
596
|
-
'
|
|
597
|
-
'MM-DD-YYYY'
|
|
584
|
+
* Luxon parse formats for the month-first preference. Separator characters
|
|
585
|
+
* in the input are normalized to a hyphen before matching (see {@link parseWithFormats}),
|
|
586
|
+
* so the formats below intentionally use a single separator.
|
|
587
|
+
*/
|
|
588
|
+
static { this.luxonMonthFirstParseFormats = [
|
|
589
|
+
'M-d',
|
|
590
|
+
'MM-dd',
|
|
591
|
+
'M-d-yy',
|
|
592
|
+
'MM-dd-yy',
|
|
593
|
+
'MMddyyyy',
|
|
594
|
+
'yyyyMMdd',
|
|
595
|
+
'yyyy-MM-dd',
|
|
596
|
+
'MM-dd-yyyy'
|
|
598
597
|
]; }
|
|
599
598
|
/**
|
|
600
599
|
* User input formats that we will parse into a date
|
|
@@ -618,44 +617,48 @@ class DateTimeHelper {
|
|
|
618
617
|
"yyyyDDmm"
|
|
619
618
|
]; }
|
|
620
619
|
/**
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
'
|
|
628
|
-
'
|
|
629
|
-
'
|
|
630
|
-
'
|
|
631
|
-
'
|
|
632
|
-
'
|
|
633
|
-
'YYYY-MM-DD',
|
|
634
|
-
'DD-MM-YYYY'
|
|
620
|
+
* Luxon parse formats for the day-first preference. Separator characters
|
|
621
|
+
* in the input are normalized to a hyphen before matching (see {@link parseWithFormats}).
|
|
622
|
+
*/
|
|
623
|
+
static { this.luxonDateFirstParseFormats = [
|
|
624
|
+
'd-M',
|
|
625
|
+
'dd-MM',
|
|
626
|
+
'd-M-yy',
|
|
627
|
+
'dd-MM-yy',
|
|
628
|
+
'ddMMyyyy',
|
|
629
|
+
'yyyyMMdd',
|
|
630
|
+
'yyyy-MM-dd',
|
|
631
|
+
'dd-MM-yyyy'
|
|
635
632
|
]; }
|
|
636
633
|
/**
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
'
|
|
644
|
-
'MMM
|
|
645
|
-
'
|
|
646
|
-
'
|
|
647
|
-
'
|
|
648
|
-
'MMM
|
|
649
|
-
'MMM
|
|
650
|
-
'MMM
|
|
651
|
-
'
|
|
652
|
-
'MMMM
|
|
653
|
-
'
|
|
654
|
-
'MMM
|
|
655
|
-
'
|
|
656
|
-
'MMM,
|
|
657
|
-
'
|
|
658
|
-
'MMMM,
|
|
634
|
+
* Luxon parse formats for medium/long date strings (e.g. "Jan 5, 2024").
|
|
635
|
+
* Shared by date-first and month-first preferences because the month is
|
|
636
|
+
* not numeric, so the order is unambiguous.
|
|
637
|
+
*/
|
|
638
|
+
static { this.luxonMedAndLongDateFormats = [
|
|
639
|
+
// Moment was forgiving with leading zeros (`DD` matched both `9` and `09`);
|
|
640
|
+
// Luxon's `dd` is strict, so single-digit `d` variants are listed explicitly.
|
|
641
|
+
'd MMM',
|
|
642
|
+
'dd MMM',
|
|
643
|
+
'MMM d',
|
|
644
|
+
'MMM dd',
|
|
645
|
+
'd MMM yy',
|
|
646
|
+
'dd MMM yy',
|
|
647
|
+
'd MMM yyyy',
|
|
648
|
+
'dd MMM yyyy',
|
|
649
|
+
'd MMMM yyyy',
|
|
650
|
+
'dd MMMM yyyy',
|
|
651
|
+
'MMM d, yy',
|
|
652
|
+
'MMM d, yyyy',
|
|
653
|
+
'MMM dd, yyyy',
|
|
654
|
+
'MMMM d, yyyy',
|
|
655
|
+
'MMMM dd, yyyy',
|
|
656
|
+
'MMM yy',
|
|
657
|
+
'MMM yyyy',
|
|
658
|
+
'MMMM yyyy',
|
|
659
|
+
'MMM, yy',
|
|
660
|
+
'MMM, yyyy',
|
|
661
|
+
'MMMM, yyyy',
|
|
659
662
|
]; }
|
|
660
663
|
/**
|
|
661
664
|
* Format to display the time portion of a datetime
|
|
@@ -664,6 +667,99 @@ class DateTimeHelper {
|
|
|
664
667
|
///////////////////////////////////////////////////////
|
|
665
668
|
// METHODS
|
|
666
669
|
///////////////////////////////////////////////////////
|
|
670
|
+
/**
|
|
671
|
+
* Convert any date-like value into a Luxon {@link DateTime}. Strings are parsed
|
|
672
|
+
* as ISO 8601; numbers are treated as epoch milliseconds. Returns an invalid
|
|
673
|
+
* DateTime when the input is null/undefined.
|
|
674
|
+
*/
|
|
675
|
+
static toDateTime(value) {
|
|
676
|
+
if (value === null || value === undefined) {
|
|
677
|
+
return DateTime.invalid('null or undefined');
|
|
678
|
+
}
|
|
679
|
+
if (DateTime.isDateTime(value)) {
|
|
680
|
+
return value;
|
|
681
|
+
}
|
|
682
|
+
if (value instanceof Date) {
|
|
683
|
+
return DateTime.fromJSDate(value);
|
|
684
|
+
}
|
|
685
|
+
if (typeof value === 'number') {
|
|
686
|
+
return DateTime.fromMillis(value);
|
|
687
|
+
}
|
|
688
|
+
return DateTime.fromISO(value);
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Translate a moment-style format string (e.g. `MM/DD/YYYY HH:mm:ss A`) into
|
|
692
|
+
* the Luxon equivalent (`MM/dd/yyyy HH:mm:ss a`). Use this when format strings
|
|
693
|
+
* originate from external sources (such as user preferences) that still use
|
|
694
|
+
* moment tokens.
|
|
695
|
+
*
|
|
696
|
+
* Only the tokens currently in use across this library are translated:
|
|
697
|
+
* `Y`→`y`, `D`→`d`, `A`→`a`. `M`, `H`, `h`, `m`, `s` are identical between
|
|
698
|
+
* the two libraries.
|
|
699
|
+
*/
|
|
700
|
+
static momentToLuxonFormat(format) {
|
|
701
|
+
return format
|
|
702
|
+
.replace(/Y/g, 'y')
|
|
703
|
+
.replace(/D/g, 'd')
|
|
704
|
+
.replace(/A/g, 'a');
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Format a date-like value using a moment-style format string. The format
|
|
708
|
+
* string is automatically translated to Luxon tokens, so callers can keep
|
|
709
|
+
* passing the same preference strings (e.g. `MM/DD/YYYY HH:mm:ss`).
|
|
710
|
+
*
|
|
711
|
+
* When `displayInUTC` is true, string inputs without zone info are parsed
|
|
712
|
+
* as UTC (matching `moment.utc(str)`), and all other inputs are shifted to
|
|
713
|
+
* the UTC zone for display. Returns an empty string for invalid input.
|
|
714
|
+
*
|
|
715
|
+
* Moment's lowercase `a` token produces lowercase `am`/`pm`, but Luxon's
|
|
716
|
+
* `a` is locale-aware and emits uppercase `AM`/`PM` in en-US. When the
|
|
717
|
+
* incoming format uses lowercase `a` (and not uppercase `A`), the meridiem
|
|
718
|
+
* in the output is lowercased to preserve the moment contract for user
|
|
719
|
+
* preferences like `h:mm:ss a` that are stored externally.
|
|
720
|
+
*/
|
|
721
|
+
static formatDate(date, momentFormat, displayInUTC = false) {
|
|
722
|
+
let dt;
|
|
723
|
+
if (displayInUTC && typeof date === 'string') {
|
|
724
|
+
dt = DateTime.fromISO(date, { zone: 'utc' });
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
dt = this.toDateTime(date);
|
|
728
|
+
if (displayInUTC) {
|
|
729
|
+
dt = dt.setZone('utc');
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
if (!dt.isValid)
|
|
733
|
+
return '';
|
|
734
|
+
let result = dt.toFormat(this.momentToLuxonFormat(momentFormat));
|
|
735
|
+
if (momentFormat.includes('a') && !momentFormat.includes('A')) {
|
|
736
|
+
result = result.replace(/AM|PM/g, m => m.toLowerCase());
|
|
737
|
+
}
|
|
738
|
+
return result;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Parse a string against a list of format patterns. Returns the first
|
|
742
|
+
* successful parse as a {@link DateTime} (which may be invalid if none match).
|
|
743
|
+
*
|
|
744
|
+
* Format strings may use either Luxon or moment tokens — each pattern is
|
|
745
|
+
* run through {@link momentToLuxonFormat} before matching, so callers can
|
|
746
|
+
* keep passing arrays like `['M/D/YYYY']` from previously moment-based code.
|
|
747
|
+
*
|
|
748
|
+
* Mirrors moment's behavior of ignoring separator characters by normalizing
|
|
749
|
+
* `/`, `.` and `-` in both input and patterns before matching.
|
|
750
|
+
*/
|
|
751
|
+
static parseWithFormats(value, formats) {
|
|
752
|
+
const normalize = (s) => s.replace(/[\/.\-]/g, '-');
|
|
753
|
+
const normalizedValue = normalize(value);
|
|
754
|
+
for (const format of formats) {
|
|
755
|
+
const luxonFormat = this.momentToLuxonFormat(format);
|
|
756
|
+
const dt = DateTime.fromFormat(normalizedValue, normalize(luxonFormat));
|
|
757
|
+
if (dt.isValid) {
|
|
758
|
+
return dt;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return DateTime.invalid('no matching format');
|
|
762
|
+
}
|
|
667
763
|
/**
|
|
668
764
|
* Return true if @see date is equal to the @see endOfTime
|
|
669
765
|
*/
|
|
@@ -675,7 +771,7 @@ class DateTimeHelper {
|
|
|
675
771
|
* Compare two dates and return true if they represent the same year, month, and day (time is ignored).
|
|
676
772
|
*/
|
|
677
773
|
static isSameDay(date1, date2) {
|
|
678
|
-
return
|
|
774
|
+
return this.toDateTime(date1).hasSame(this.toDateTime(date2), 'day');
|
|
679
775
|
}
|
|
680
776
|
/**
|
|
681
777
|
* Get the parse formats based on the given date format. If no date format is
|
|
@@ -694,19 +790,19 @@ class DateTimeHelper {
|
|
|
694
790
|
return dateFormat ? map[dateFormat] : this.monthFirstParseFormats;
|
|
695
791
|
}
|
|
696
792
|
/**
|
|
697
|
-
* Get the
|
|
793
|
+
* Get the Luxon parse formats based on the given date format. If no date format is
|
|
698
794
|
* given, or we don't recognize the format, return the month first parse formats.
|
|
699
795
|
*/
|
|
700
|
-
static
|
|
796
|
+
static getLuxonParseFormats(dateFormat) {
|
|
701
797
|
let map = {
|
|
702
|
-
'MM/DD/YYYY': [...this.
|
|
703
|
-
'MM-DD-YYYY': [...this.
|
|
704
|
-
'DD/MM/YYYY': [...this.
|
|
705
|
-
'DD-MM-YYYY': [...this.
|
|
706
|
-
'YYYY/MM/DD': [...this.
|
|
707
|
-
'YYYY-MM-DD': [...this.
|
|
798
|
+
'MM/DD/YYYY': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
799
|
+
'MM-DD-YYYY': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
800
|
+
'DD/MM/YYYY': [...this.luxonDateFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
801
|
+
'DD-MM-YYYY': [...this.luxonDateFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
802
|
+
'YYYY/MM/DD': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
803
|
+
'YYYY-MM-DD': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats]
|
|
708
804
|
};
|
|
709
|
-
return dateFormat ? map[dateFormat] : this.
|
|
805
|
+
return dateFormat ? map[dateFormat] : this.luxonMonthFirstParseFormats;
|
|
710
806
|
}
|
|
711
807
|
/**
|
|
712
808
|
* Get relationship start date (favoring date in partialFormState if exists)
|
|
@@ -729,28 +825,23 @@ class DateTimeHelper {
|
|
|
729
825
|
return null;
|
|
730
826
|
}
|
|
731
827
|
static isDateBetween(date, startDate, endDate, includeStart, includeEnd) {
|
|
732
|
-
let inclusivity = '()';
|
|
733
|
-
if (includeStart && includeEnd) {
|
|
734
|
-
inclusivity = '[]';
|
|
735
|
-
}
|
|
736
|
-
else if (includeStart) {
|
|
737
|
-
inclusivity = '[)';
|
|
738
|
-
}
|
|
739
|
-
else if (includeEnd) {
|
|
740
|
-
inclusivity = '(]';
|
|
741
|
-
}
|
|
742
828
|
// If a start date is not provide, we'll use our beginning of time instead
|
|
743
829
|
startDate = startDate || this.beginningOfTime;
|
|
744
830
|
// If an end date is not provided, we'll use our end of time instead
|
|
745
831
|
endDate = endDate || this.endOfTime;
|
|
746
|
-
|
|
832
|
+
const d = this.toDateTime(date).startOf('day');
|
|
833
|
+
const s = this.toDateTime(startDate).startOf('day');
|
|
834
|
+
const e = this.toDateTime(endDate).startOf('day');
|
|
835
|
+
const afterStart = includeStart ? d >= s : d > s;
|
|
836
|
+
const beforeEnd = includeEnd ? d <= e : d < e;
|
|
837
|
+
return afterStart && beforeEnd;
|
|
747
838
|
}
|
|
748
839
|
static stringToDate(dateString) {
|
|
749
840
|
if (dateString === null || dateString === undefined) {
|
|
750
841
|
return dateString;
|
|
751
842
|
}
|
|
752
843
|
else {
|
|
753
|
-
return
|
|
844
|
+
return DateTime.fromISO(dateString).toJSDate();
|
|
754
845
|
}
|
|
755
846
|
}
|
|
756
847
|
}
|
|
@@ -764,15 +855,15 @@ class DateInputSelectionStrategyBase {
|
|
|
764
855
|
if (!value) {
|
|
765
856
|
return null;
|
|
766
857
|
}
|
|
767
|
-
|
|
768
|
-
if (date.isValid
|
|
858
|
+
let date = DateTimeHelper.parseWithFormats(value, parseFormats);
|
|
859
|
+
if (date.isValid) {
|
|
769
860
|
// If we're in a temporary state (when the user is typing in a textbox), we need to set the year to the current year if it's before the min year
|
|
770
861
|
// This prevents the calendars from showing unhelpful dates that are in the distant past before the user finishes typing in the date.
|
|
771
862
|
// We don't do this modification when the real selection happens on textbox blur.
|
|
772
|
-
if (opts?.shiftToCurrentYearIfBelow && date.
|
|
773
|
-
date.set(
|
|
863
|
+
if (opts?.shiftToCurrentYearIfBelow && date < DateTime.fromJSDate(opts.shiftToCurrentYearIfBelow)) {
|
|
864
|
+
date = date.set({ year: DateTime.now().year });
|
|
774
865
|
}
|
|
775
|
-
return date.
|
|
866
|
+
return date.toJSDate();
|
|
776
867
|
}
|
|
777
868
|
return null;
|
|
778
869
|
}
|
|
@@ -854,7 +945,7 @@ class DaySelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
854
945
|
getNextSelection(selection) {
|
|
855
946
|
// Add a single day to the selection
|
|
856
947
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
857
|
-
return
|
|
948
|
+
return DateTime.fromJSDate(selection).plus({ days: 1 }).toJSDate();
|
|
858
949
|
}
|
|
859
950
|
// This shouldn't happen based on current date input flows, but if it does just return the selection as-is.
|
|
860
951
|
return selection;
|
|
@@ -862,7 +953,7 @@ class DaySelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
862
953
|
getPreviousSelection(selection) {
|
|
863
954
|
// Subtract a single day from the selection
|
|
864
955
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
865
|
-
return
|
|
956
|
+
return DateTime.fromJSDate(selection).minus({ days: 1 }).toJSDate();
|
|
866
957
|
}
|
|
867
958
|
// This shouldn't happen based on current date input flows, but if it does just return the selection as-is.
|
|
868
959
|
return selection;
|
|
@@ -893,19 +984,19 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
893
984
|
// Update the start and end dates to match a 28-day range, keying off the end date if parseFromEnd is true
|
|
894
985
|
// parseFromEnd is true when a date is being entered from the end date textbox
|
|
895
986
|
if (opts?.parseFromEnd) {
|
|
896
|
-
start =
|
|
987
|
+
start = DateTime.fromJSDate(end).minus({ days: 27 }).toJSDate();
|
|
897
988
|
}
|
|
898
989
|
else {
|
|
899
|
-
end =
|
|
990
|
+
end = DateTime.fromJSDate(start).plus({ days: 27 }).toJSDate();
|
|
900
991
|
}
|
|
901
992
|
}
|
|
902
993
|
// If the start date is not provided, we'll use the end date to calculate the start date
|
|
903
994
|
if (!start && end && !opts?.preventAutoComplete) {
|
|
904
|
-
start =
|
|
995
|
+
start = DateTime.fromJSDate(end).minus({ days: 27 }).toJSDate();
|
|
905
996
|
}
|
|
906
997
|
// If the end date is not provided, we'll use the start date to calculate the end date
|
|
907
998
|
if (!end && start && !opts?.preventAutoComplete) {
|
|
908
|
-
end =
|
|
999
|
+
end = DateTime.fromJSDate(start).plus({ days: 27 }).toJSDate();
|
|
909
1000
|
}
|
|
910
1001
|
if (!start && !end) {
|
|
911
1002
|
return null;
|
|
@@ -916,7 +1007,7 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
916
1007
|
}
|
|
917
1008
|
getSelectionFromDate(date) {
|
|
918
1009
|
return {
|
|
919
|
-
start:
|
|
1010
|
+
start: DateTime.fromJSDate(date).minus({ days: 27 }).toJSDate(),
|
|
920
1011
|
end: date
|
|
921
1012
|
};
|
|
922
1013
|
}
|
|
@@ -926,7 +1017,7 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
926
1017
|
if (!previousSelection.end && previousSelection.start) {
|
|
927
1018
|
return {
|
|
928
1019
|
start: previousSelection.start,
|
|
929
|
-
end:
|
|
1020
|
+
end: DateTime.fromJSDate(previousSelection.start).plus({ days: 27 }).toJSDate()
|
|
930
1021
|
};
|
|
931
1022
|
// If the range only has an end date, make the 28-day range end on that date
|
|
932
1023
|
}
|
|
@@ -943,9 +1034,10 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
943
1034
|
getNextSelection(selection) {
|
|
944
1035
|
// Move the selection to the next 28 days
|
|
945
1036
|
if (DateInput.isSelectionRange(selection) && selection.end) {
|
|
1037
|
+
const end = DateTime.fromJSDate(selection.end);
|
|
946
1038
|
return {
|
|
947
|
-
start:
|
|
948
|
-
end:
|
|
1039
|
+
start: end.plus({ days: 1 }).toJSDate(),
|
|
1040
|
+
end: end.plus({ days: 28 }).toJSDate()
|
|
949
1041
|
};
|
|
950
1042
|
}
|
|
951
1043
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
@@ -955,9 +1047,10 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
955
1047
|
getPreviousSelection(selection) {
|
|
956
1048
|
// Move the selection to the previous 28 days
|
|
957
1049
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1050
|
+
const start = DateTime.fromJSDate(selection.start);
|
|
958
1051
|
return {
|
|
959
|
-
start:
|
|
960
|
-
end:
|
|
1052
|
+
start: start.minus({ days: 28 }).toJSDate(),
|
|
1053
|
+
end: start.minus({ days: 1 }).toJSDate()
|
|
961
1054
|
};
|
|
962
1055
|
}
|
|
963
1056
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
@@ -990,19 +1083,19 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
990
1083
|
// Update the start and end dates to match a 7-day range, keying off the end date if parseFromEnd is true
|
|
991
1084
|
// parseFromEnd is true when a date is being entered from the end date textbox
|
|
992
1085
|
if (opts?.parseFromEnd) {
|
|
993
|
-
start =
|
|
1086
|
+
start = DateTime.fromJSDate(end).minus({ days: 6 }).toJSDate();
|
|
994
1087
|
}
|
|
995
1088
|
else {
|
|
996
|
-
end =
|
|
1089
|
+
end = DateTime.fromJSDate(start).plus({ days: 6 }).toJSDate();
|
|
997
1090
|
}
|
|
998
1091
|
}
|
|
999
1092
|
// If the start date is not provided, we'll use the end date to calculate the start date
|
|
1000
1093
|
if (!start && end && !opts?.preventAutoComplete) {
|
|
1001
|
-
start =
|
|
1094
|
+
start = DateTime.fromJSDate(end).minus({ days: 6 }).toJSDate();
|
|
1002
1095
|
}
|
|
1003
1096
|
// If the end date is not provided, we'll use the start date to calculate the end date
|
|
1004
1097
|
if (!end && start && !opts?.preventAutoComplete) {
|
|
1005
|
-
end =
|
|
1098
|
+
end = DateTime.fromJSDate(start).plus({ days: 6 }).toJSDate();
|
|
1006
1099
|
}
|
|
1007
1100
|
if (!start && !end) {
|
|
1008
1101
|
return null;
|
|
@@ -1014,7 +1107,7 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1014
1107
|
getSelectionFromDate(date) {
|
|
1015
1108
|
// Base the selection on the given date, moving back 6 days
|
|
1016
1109
|
return {
|
|
1017
|
-
start:
|
|
1110
|
+
start: DateTime.fromJSDate(date).minus({ days: 6 }).toJSDate(),
|
|
1018
1111
|
end: date
|
|
1019
1112
|
};
|
|
1020
1113
|
}
|
|
@@ -1024,7 +1117,7 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1024
1117
|
if (!previousSelection.end && previousSelection.start) {
|
|
1025
1118
|
return {
|
|
1026
1119
|
start: previousSelection.start,
|
|
1027
|
-
end:
|
|
1120
|
+
end: DateTime.fromJSDate(previousSelection.start).plus({ days: 6 }).toJSDate()
|
|
1028
1121
|
};
|
|
1029
1122
|
// Otherwise, create the new selection based on the end date backwards
|
|
1030
1123
|
}
|
|
@@ -1041,9 +1134,10 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1041
1134
|
getNextSelection(selection) {
|
|
1042
1135
|
// Shift the range forward by 7 days
|
|
1043
1136
|
if (DateInput.isSelectionRange(selection) && selection.end) {
|
|
1137
|
+
const end = DateTime.fromJSDate(selection.end);
|
|
1044
1138
|
return {
|
|
1045
|
-
start:
|
|
1046
|
-
end:
|
|
1139
|
+
start: end.plus({ days: 1 }).toJSDate(),
|
|
1140
|
+
end: end.plus({ days: 7 }).toJSDate()
|
|
1047
1141
|
};
|
|
1048
1142
|
}
|
|
1049
1143
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
@@ -1053,9 +1147,10 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1053
1147
|
getPreviousSelection(selection) {
|
|
1054
1148
|
// Shift the range back 7 days
|
|
1055
1149
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1150
|
+
const start = DateTime.fromJSDate(selection.start);
|
|
1056
1151
|
return {
|
|
1057
|
-
start:
|
|
1058
|
-
end:
|
|
1152
|
+
start: start.minus({ days: 7 }).toJSDate(),
|
|
1153
|
+
end: start.minus({ days: 1 }).toJSDate()
|
|
1059
1154
|
};
|
|
1060
1155
|
}
|
|
1061
1156
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
@@ -1083,7 +1178,7 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1083
1178
|
// A single date selection shouldn't happen in this mode but it's simple enough to handle
|
|
1084
1179
|
const date = DateInput.isSelectionRange(selection) ? selection.start : selection;
|
|
1085
1180
|
return {
|
|
1086
|
-
textbox:
|
|
1181
|
+
textbox: date ? DateTime.fromJSDate(date).toFormat('MMM, yyyy') : null,
|
|
1087
1182
|
textbox2: null
|
|
1088
1183
|
};
|
|
1089
1184
|
}
|
|
@@ -1096,9 +1191,10 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1096
1191
|
return this.getSelectionFromDate(date);
|
|
1097
1192
|
}
|
|
1098
1193
|
getSelectionFromDate(date) {
|
|
1194
|
+
const dt = DateTime.fromJSDate(date);
|
|
1099
1195
|
return {
|
|
1100
|
-
start:
|
|
1101
|
-
end:
|
|
1196
|
+
start: dt.startOf('month').toJSDate(),
|
|
1197
|
+
end: dt.endOf('month').toJSDate()
|
|
1102
1198
|
};
|
|
1103
1199
|
}
|
|
1104
1200
|
getNewSelectionFromExisting(previousSelection) {
|
|
@@ -1118,8 +1214,8 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1118
1214
|
getNextSelection(selection) {
|
|
1119
1215
|
// Move the selection to the next month
|
|
1120
1216
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1121
|
-
const date =
|
|
1122
|
-
return this.getSelectionFromDate(date.
|
|
1217
|
+
const date = DateTime.fromJSDate(selection.start).plus({ months: 1 });
|
|
1218
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1123
1219
|
}
|
|
1124
1220
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
1125
1221
|
// If it does, just return the selection as-is.
|
|
@@ -1128,8 +1224,8 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1128
1224
|
getPreviousSelection(selection) {
|
|
1129
1225
|
// Move the selection to the previous month
|
|
1130
1226
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1131
|
-
const date =
|
|
1132
|
-
return this.getSelectionFromDate(date.
|
|
1227
|
+
const date = DateTime.fromJSDate(selection.start).minus({ months: 1 });
|
|
1228
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1133
1229
|
}
|
|
1134
1230
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
1135
1231
|
// If it does, just return the selection as-is.
|
|
@@ -1152,9 +1248,9 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1152
1248
|
// Format the the quarter range as "MMM–MMM, YYYY"
|
|
1153
1249
|
// We only have one textbox in this mode
|
|
1154
1250
|
if (DateInput.isSelectionRange(selection)) {
|
|
1155
|
-
const start =
|
|
1156
|
-
const end =
|
|
1157
|
-
const year =
|
|
1251
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start).toFormat('MMM') : '';
|
|
1252
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end).toFormat('MMM') : '';
|
|
1253
|
+
const year = selection.end ? DateTime.fromJSDate(selection.end).toFormat('yyyy') : '';
|
|
1158
1254
|
return {
|
|
1159
1255
|
textbox: `${start}–${end}, ${year}`,
|
|
1160
1256
|
textbox2: null
|
|
@@ -1172,9 +1268,10 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1172
1268
|
return this.getSelectionFromDate(date);
|
|
1173
1269
|
}
|
|
1174
1270
|
getSelectionFromDate(date) {
|
|
1271
|
+
const dt = DateTime.fromJSDate(date);
|
|
1175
1272
|
return {
|
|
1176
|
-
start:
|
|
1177
|
-
end:
|
|
1273
|
+
start: dt.startOf('quarter').toJSDate(),
|
|
1274
|
+
end: dt.endOf('quarter').toJSDate()
|
|
1178
1275
|
};
|
|
1179
1276
|
}
|
|
1180
1277
|
getNewSelectionFromExisting(previousSelection) {
|
|
@@ -1194,8 +1291,8 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1194
1291
|
getNextSelection(selection) {
|
|
1195
1292
|
// Move the selection to the next quarter
|
|
1196
1293
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1197
|
-
const date =
|
|
1198
|
-
return this.getSelectionFromDate(date.
|
|
1294
|
+
const date = DateTime.fromJSDate(selection.start).plus({ quarters: 1 });
|
|
1295
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1199
1296
|
}
|
|
1200
1297
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
1201
1298
|
// If it does, just return the selection as-is.
|
|
@@ -1204,8 +1301,8 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1204
1301
|
getPreviousSelection(selection) {
|
|
1205
1302
|
// Move the selection to the previous quarter
|
|
1206
1303
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1207
|
-
const date =
|
|
1208
|
-
return this.getSelectionFromDate(date.
|
|
1304
|
+
const date = DateTime.fromJSDate(selection.start).minus({ quarters: 1 });
|
|
1305
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1209
1306
|
}
|
|
1210
1307
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
1211
1308
|
// If it does, just return the selection as-is.
|
|
@@ -1228,13 +1325,13 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1228
1325
|
if (!selection) {
|
|
1229
1326
|
return { textbox: null, textbox2: null };
|
|
1230
1327
|
}
|
|
1231
|
-
// We use
|
|
1328
|
+
// We use Luxon's DATE_MED preset here (equivalent to moment's 'll') so the formatted date follows the user's locale
|
|
1232
1329
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
1233
|
-
return { textbox:
|
|
1330
|
+
return { textbox: DateTime.fromJSDate(selection).toLocaleString(DateTime.DATE_MED), textbox2: null };
|
|
1234
1331
|
}
|
|
1235
1332
|
else {
|
|
1236
|
-
const start = selection.start ?
|
|
1237
|
-
const end = selection.end ?
|
|
1333
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start).toLocaleString(DateTime.DATE_MED) : null;
|
|
1334
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end).toLocaleString(DateTime.DATE_MED) : null;
|
|
1238
1335
|
return { textbox: start, textbox2: end };
|
|
1239
1336
|
}
|
|
1240
1337
|
}
|
|
@@ -1245,7 +1342,7 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1245
1342
|
// because we don't have a fixed range to automatically adjust the dates to. If the user is changing the begin date or end date and ends
|
|
1246
1343
|
// up crossing the other date, we should clear out the date that's not being changed so that the user can enter a valid range using the
|
|
1247
1344
|
// begin/end date they just entered.
|
|
1248
|
-
if (start && end &&
|
|
1345
|
+
if (start && end && DateTime.fromJSDate(start) > DateTime.fromJSDate(end)) {
|
|
1249
1346
|
if (opts?.parseFromEnd) {
|
|
1250
1347
|
start = null;
|
|
1251
1348
|
}
|
|
@@ -1263,18 +1360,19 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1263
1360
|
getSelectionFromDate(date, existingSelection) {
|
|
1264
1361
|
if (DateInput.isSelectionRange(existingSelection)) {
|
|
1265
1362
|
const { start, end } = existingSelection;
|
|
1363
|
+
const dDt = DateTime.fromJSDate(date);
|
|
1266
1364
|
if (start && !end) {
|
|
1267
1365
|
// If the selected date is before the existing start date, set it as the new start date and use the existing start date as the end date
|
|
1268
|
-
return
|
|
1366
|
+
return dDt < DateTime.fromJSDate(start) ? { start: date, end: start } : { start, end: date };
|
|
1269
1367
|
}
|
|
1270
1368
|
if (end && !start) {
|
|
1271
1369
|
// If the selected date is after the existing end date, set it as the new end date and use the existing end date as the start date
|
|
1272
|
-
return
|
|
1370
|
+
return dDt < DateTime.fromJSDate(end) ? { start: date, end } : { start: end, end: date };
|
|
1273
1371
|
}
|
|
1274
1372
|
}
|
|
1275
1373
|
else if (DateInput.isSelectionSingleDate(existingSelection)) {
|
|
1276
1374
|
// If the selected date is before the existing date, set it as the new start date and use the existing date as the end date
|
|
1277
|
-
return
|
|
1375
|
+
return DateTime.fromJSDate(date) < DateTime.fromJSDate(existingSelection) ? { start: date, end: existingSelection } : { start: existingSelection, end: date };
|
|
1278
1376
|
}
|
|
1279
1377
|
// If no selection exists or we already have a complete selection, start a new one with the selected date as the start date.
|
|
1280
1378
|
return { start: date, end: null };
|
|
@@ -1295,9 +1393,9 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1295
1393
|
// If we have a valid range, we'll shift the range to the date provided, using it as the end date
|
|
1296
1394
|
// The new selection will have the same length as the previous.
|
|
1297
1395
|
if (DateInput.isSelectionRange(existingSelection) && existingSelection.start && existingSelection.end) {
|
|
1298
|
-
const length =
|
|
1396
|
+
const length = Math.floor(DateTime.fromJSDate(existingSelection.end).diff(DateTime.fromJSDate(existingSelection.start), 'days').days);
|
|
1299
1397
|
return {
|
|
1300
|
-
start:
|
|
1398
|
+
start: DateTime.fromJSDate(date).minus({ days: length }).toJSDate(),
|
|
1301
1399
|
end: date
|
|
1302
1400
|
};
|
|
1303
1401
|
}
|
|
@@ -1309,10 +1407,11 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1309
1407
|
// We can only determine the next selection if we have a valid range
|
|
1310
1408
|
if (DateInput.isSelectionRange(selection) && selection.start && selection.end) {
|
|
1311
1409
|
// Shift the range forward by the number of days between the start and end dates
|
|
1312
|
-
const
|
|
1410
|
+
const end = DateTime.fromJSDate(selection.end);
|
|
1411
|
+
const length = Math.floor(end.diff(DateTime.fromJSDate(selection.start), 'days').days);
|
|
1313
1412
|
return {
|
|
1314
|
-
start:
|
|
1315
|
-
end:
|
|
1413
|
+
start: end.plus({ days: 1 }).toJSDate(),
|
|
1414
|
+
end: end.plus({ days: 1 + length }).toJSDate()
|
|
1316
1415
|
};
|
|
1317
1416
|
}
|
|
1318
1417
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
@@ -1323,10 +1422,11 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1323
1422
|
// We can only determine the previous selection if we have a valid range
|
|
1324
1423
|
if (DateInput.isSelectionRange(selection) && selection.start && selection.end) {
|
|
1325
1424
|
// Shift the range back by the number of days between the start and end dates
|
|
1326
|
-
const
|
|
1425
|
+
const start = DateTime.fromJSDate(selection.start);
|
|
1426
|
+
const length = Math.floor(DateTime.fromJSDate(selection.end).diff(start, 'days').days);
|
|
1327
1427
|
return {
|
|
1328
|
-
start:
|
|
1329
|
-
end:
|
|
1428
|
+
start: start.minus({ days: 1 + length }).toJSDate(),
|
|
1429
|
+
end: start.minus({ days: 1 }).toJSDate()
|
|
1330
1430
|
};
|
|
1331
1431
|
}
|
|
1332
1432
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
@@ -1336,31 +1436,33 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1336
1436
|
getPrimaryCalendarView(selection, minDate, maxDate, currentView) {
|
|
1337
1437
|
let viewDate;
|
|
1338
1438
|
if (DateInput.isSelectionRange(selection)) {
|
|
1339
|
-
|
|
1340
|
-
|
|
1439
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start) : null;
|
|
1440
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end) : null;
|
|
1441
|
+
const minDt = DateTime.fromJSDate(minDate);
|
|
1442
|
+
const maxDt = DateTime.fromJSDate(maxDate);
|
|
1341
1443
|
// Since we're in range mode, the primary calendar is mostly concerned with the start date
|
|
1342
1444
|
if (start) {
|
|
1343
1445
|
// If we have a start date in the selection and it's before the min date, shift the view to the min date.
|
|
1344
|
-
if (start.
|
|
1446
|
+
if (start.startOf('month') < minDt.startOf('month')) {
|
|
1345
1447
|
viewDate = minDate;
|
|
1346
1448
|
// If the start is after the max date, shift the view to the max date.
|
|
1347
1449
|
}
|
|
1348
|
-
else if (start.
|
|
1450
|
+
else if (start.startOf('month') >= maxDt.startOf('month')) {
|
|
1349
1451
|
// the secondary calendar will show the max date month.
|
|
1350
1452
|
// The primary calendar will show the month before the max date.
|
|
1351
|
-
viewDate =
|
|
1453
|
+
viewDate = maxDt.minus({ months: 1 }).toJSDate();
|
|
1352
1454
|
}
|
|
1353
1455
|
else {
|
|
1354
|
-
viewDate = start.
|
|
1456
|
+
viewDate = start.toJSDate();
|
|
1355
1457
|
}
|
|
1356
1458
|
}
|
|
1357
|
-
else if (end && end.
|
|
1459
|
+
else if (end && end.startOf('month') <= minDt.startOf('month')) {
|
|
1358
1460
|
// If we don't have a start date, and the end date is the same month or before the min date, shift the view to the min date.
|
|
1359
1461
|
viewDate = minDate;
|
|
1360
1462
|
}
|
|
1361
|
-
else if (end && end.
|
|
1463
|
+
else if (end && end.startOf('month') <= DateTime.now().startOf('month')) {
|
|
1362
1464
|
// If we don't have a start date, and the end date is the same month or before the current month, shift the view to the month before the end
|
|
1363
|
-
viewDate =
|
|
1465
|
+
viewDate = end.minus({ months: 1 }).toJSDate();
|
|
1364
1466
|
}
|
|
1365
1467
|
else {
|
|
1366
1468
|
// Otherwise, show the current month.
|
|
@@ -1378,32 +1480,34 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1378
1480
|
getSecondaryCalendarView(selection, minDate, maxDate, currentView) {
|
|
1379
1481
|
let viewDate;
|
|
1380
1482
|
if (DateInput.isSelectionRange(selection)) {
|
|
1381
|
-
|
|
1382
|
-
|
|
1483
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start) : null;
|
|
1484
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end) : null;
|
|
1485
|
+
const minDt = DateTime.fromJSDate(minDate);
|
|
1486
|
+
const maxDt = DateTime.fromJSDate(maxDate);
|
|
1383
1487
|
// The secondary calendar is primarily concerned with the end date in the selection.
|
|
1384
1488
|
if (end) {
|
|
1385
|
-
if (end.
|
|
1489
|
+
if (end.startOf('month') > maxDt.startOf('month')) {
|
|
1386
1490
|
// If the end date is after the max date, shift the view to the max date.
|
|
1387
1491
|
viewDate = maxDate;
|
|
1388
1492
|
}
|
|
1389
|
-
else if (end.
|
|
1493
|
+
else if (end.startOf('month') <= minDt.startOf('month')) {
|
|
1390
1494
|
// If the end date is the same month or before the min date, shift the view to show
|
|
1391
1495
|
// the month after the min date. The primary calendar will show the min date month.
|
|
1392
|
-
viewDate =
|
|
1496
|
+
viewDate = minDt.plus({ months: 1 }).toJSDate();
|
|
1393
1497
|
}
|
|
1394
1498
|
else {
|
|
1395
1499
|
// Otherwise, show the end date month.
|
|
1396
|
-
viewDate = end.
|
|
1500
|
+
viewDate = end.toJSDate();
|
|
1397
1501
|
}
|
|
1398
1502
|
}
|
|
1399
|
-
else if (start && start.
|
|
1503
|
+
else if (start && start.startOf('month') >= maxDt.startOf('month')) {
|
|
1400
1504
|
// If we don't have an end date, and the start date is after the max date, show the max date month
|
|
1401
1505
|
viewDate = maxDate;
|
|
1402
1506
|
}
|
|
1403
|
-
else if (start && start.
|
|
1507
|
+
else if (start && start.startOf('month') >= DateTime.now().startOf('month')) {
|
|
1404
1508
|
// If we don't have an end date, and the start date is on or after the current month,
|
|
1405
1509
|
// show the month after the start date.
|
|
1406
|
-
viewDate =
|
|
1510
|
+
viewDate = start.plus({ months: 1 }).toJSDate();
|
|
1407
1511
|
}
|
|
1408
1512
|
else {
|
|
1409
1513
|
// Otherwise, show the current month.
|
|
@@ -1438,12 +1542,12 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1438
1542
|
// Only one date is needed for formatting since the ranges span a single year.
|
|
1439
1543
|
// There shouldn't be any case where there's only a single date but it's covered anyway.
|
|
1440
1544
|
const date = DateInput.isSelectionRange(selection) ? selection.start : selection;
|
|
1441
|
-
return { textbox:
|
|
1545
|
+
return { textbox: date ? DateTime.fromJSDate(date).toFormat('yyyy') : null, textbox2: null };
|
|
1442
1546
|
}
|
|
1443
1547
|
parseString(value, parseFormats, opts) {
|
|
1444
|
-
// Including '
|
|
1548
|
+
// Including 'yy' and 'yyyy' as valid formats for year input. These aren't included in the default parse
|
|
1445
1549
|
// formats because they cause issues with the default date parsing.
|
|
1446
|
-
return super.parseString(value, ['
|
|
1550
|
+
return super.parseString(value, ['yy', 'yyyy', ...parseFormats], opts);
|
|
1447
1551
|
}
|
|
1448
1552
|
parseTextboxValues(value, parseFormats, opts) {
|
|
1449
1553
|
// Only a single textbox is used in year mode
|
|
@@ -1454,9 +1558,10 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1454
1558
|
return this.getSelectionFromDate(date);
|
|
1455
1559
|
}
|
|
1456
1560
|
getSelectionFromDate(date) {
|
|
1561
|
+
const dt = DateTime.fromJSDate(date);
|
|
1457
1562
|
return {
|
|
1458
|
-
start:
|
|
1459
|
-
end:
|
|
1563
|
+
start: dt.startOf('year').toJSDate(),
|
|
1564
|
+
end: dt.endOf('year').toJSDate()
|
|
1460
1565
|
};
|
|
1461
1566
|
}
|
|
1462
1567
|
getNewSelectionFromExisting(previousSelection) {
|
|
@@ -1479,8 +1584,8 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1479
1584
|
getNextSelection(selection) {
|
|
1480
1585
|
// Move the selection to the next year
|
|
1481
1586
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1482
|
-
const date =
|
|
1483
|
-
return this.getSelectionFromDate(date.
|
|
1587
|
+
const date = DateTime.fromJSDate(selection.start).plus({ years: 1 });
|
|
1588
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1484
1589
|
}
|
|
1485
1590
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
1486
1591
|
// If it does, just return the selection as-is.
|
|
@@ -1489,8 +1594,8 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1489
1594
|
getPreviousSelection(selection) {
|
|
1490
1595
|
// Move the selection to the previous year
|
|
1491
1596
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1492
|
-
const date =
|
|
1493
|
-
return this.getSelectionFromDate(date.
|
|
1597
|
+
const date = DateTime.fromJSDate(selection.start).minus({ years: 1 });
|
|
1598
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1494
1599
|
}
|
|
1495
1600
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
1496
1601
|
// If it does, just return the selection as-is.
|
|
@@ -1529,10 +1634,10 @@ class DateDisplayPipe {
|
|
|
1529
1634
|
transform(date, showEndOfTime, showTime, showSeconds) {
|
|
1530
1635
|
let display = '';
|
|
1531
1636
|
let formatString = '';
|
|
1532
|
-
if (date &&
|
|
1637
|
+
if (date != null && DateTimeHelper.toDateTime(date).isValid && (showEndOfTime || !DateTimeHelper.isEndOfTime(date))) {
|
|
1533
1638
|
// use user-preferred formats
|
|
1534
1639
|
this.userPreferenceService.getPreferences().subscribe(result => {
|
|
1535
|
-
//if preferences exist then format date to users preference
|
|
1640
|
+
//if preferences exist then format date to users preference
|
|
1536
1641
|
//otherwise use the last user preference
|
|
1537
1642
|
if (result.preference) {
|
|
1538
1643
|
formatString = result.preference.dateFormat;
|
|
@@ -1546,7 +1651,7 @@ class DateDisplayPipe {
|
|
|
1546
1651
|
this.lastFormatString = formatString;
|
|
1547
1652
|
}
|
|
1548
1653
|
});
|
|
1549
|
-
display =
|
|
1654
|
+
display = DateTimeHelper.formatDate(date, this.lastFormatString);
|
|
1550
1655
|
}
|
|
1551
1656
|
return display;
|
|
1552
1657
|
}
|
|
@@ -1571,6 +1676,32 @@ var DateInput;
|
|
|
1571
1676
|
return !!selection && !isSelectionSingleDate(selection);
|
|
1572
1677
|
}
|
|
1573
1678
|
DateInput.isSelectionRange = isSelectionRange;
|
|
1679
|
+
/**
|
|
1680
|
+
* Coerces a selection into one backed by real {@link Date} objects.
|
|
1681
|
+
*
|
|
1682
|
+
* The form model is typed as `Date | Range`, but hosts commonly bind ISO date strings
|
|
1683
|
+
* (e.g. values straight off an API response). The display path tolerates strings via
|
|
1684
|
+
* Luxon parsing, but the calendar view builders pass the value to `DateTime.fromJSDate`,
|
|
1685
|
+
* which only accepts a `Date` — a string yields an Invalid Date and crashes the calendar
|
|
1686
|
+
* (`RangeError: Invalid time value`). Normalizing at the boundary lets all downstream
|
|
1687
|
+
* calendar/stepper logic rely on actual Dates. Invalid/unparseable values become null.
|
|
1688
|
+
*/
|
|
1689
|
+
function normalizeSelection(selection) {
|
|
1690
|
+
if (selection === null || selection === undefined) {
|
|
1691
|
+
return null;
|
|
1692
|
+
}
|
|
1693
|
+
if (isSelectionSingleDate(selection)) {
|
|
1694
|
+
const dt = DateTimeHelper.toDateTime(selection);
|
|
1695
|
+
return dt.isValid ? dt.toJSDate() : null;
|
|
1696
|
+
}
|
|
1697
|
+
const start = selection.start ? DateTimeHelper.toDateTime(selection.start) : null;
|
|
1698
|
+
const end = selection.end ? DateTimeHelper.toDateTime(selection.end) : null;
|
|
1699
|
+
return {
|
|
1700
|
+
start: start?.isValid ? start.toJSDate() : null,
|
|
1701
|
+
end: end?.isValid ? end.toJSDate() : null
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
DateInput.normalizeSelection = normalizeSelection;
|
|
1574
1705
|
class SelectionStrategies {
|
|
1575
1706
|
constructor(dateDisplayPipe) {
|
|
1576
1707
|
this.dateDisplayPipe = dateDisplayPipe;
|
|
@@ -1613,9 +1744,14 @@ class CalendarItemComponent {
|
|
|
1613
1744
|
this.today = false;
|
|
1614
1745
|
this.outsideActiveMonth = false;
|
|
1615
1746
|
}
|
|
1747
|
+
else if (this.item?.date) {
|
|
1748
|
+
const itemDt = DateTime.fromJSDate(this.item.date);
|
|
1749
|
+
this.today = itemDt.hasSame(DateTime.now(), 'day');
|
|
1750
|
+
this.outsideActiveMonth = !itemDt.hasSame(DateTime.fromJSDate(this.view.date), 'month');
|
|
1751
|
+
}
|
|
1616
1752
|
else {
|
|
1617
|
-
this.today =
|
|
1618
|
-
this.outsideActiveMonth =
|
|
1753
|
+
this.today = false;
|
|
1754
|
+
this.outsideActiveMonth = false;
|
|
1619
1755
|
}
|
|
1620
1756
|
if (this.item?.date) {
|
|
1621
1757
|
this.hidden = this.isHidden(this.item.date, this.minDate, this.maxDate, this.view.mode);
|
|
@@ -1629,24 +1765,30 @@ class CalendarItemComponent {
|
|
|
1629
1765
|
if (!date || !selection) {
|
|
1630
1766
|
return false;
|
|
1631
1767
|
}
|
|
1768
|
+
const unit = view ?? 'day';
|
|
1769
|
+
const dt = DateTime.fromJSDate(date);
|
|
1632
1770
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
1633
|
-
return
|
|
1771
|
+
return dt.hasSame(DateTime.fromJSDate(selection), unit);
|
|
1634
1772
|
}
|
|
1635
1773
|
else {
|
|
1636
1774
|
if (selection.start && !selection.end) {
|
|
1637
|
-
return
|
|
1775
|
+
return dt.hasSame(DateTime.fromJSDate(selection.start), unit);
|
|
1638
1776
|
}
|
|
1639
1777
|
else if (!selection.start && selection.end) {
|
|
1640
|
-
return
|
|
1778
|
+
return dt.hasSame(DateTime.fromJSDate(selection.end), unit);
|
|
1641
1779
|
}
|
|
1642
1780
|
else if (selection.start && selection.end) {
|
|
1643
|
-
|
|
1781
|
+
const d = dt.startOf(unit);
|
|
1782
|
+
const s = DateTime.fromJSDate(selection.start).startOf(unit);
|
|
1783
|
+
const e = DateTime.fromJSDate(selection.end).startOf(unit);
|
|
1784
|
+
return d >= s && d <= e;
|
|
1644
1785
|
}
|
|
1645
1786
|
}
|
|
1646
1787
|
return false;
|
|
1647
1788
|
}
|
|
1648
1789
|
isHidden(date, minDate, maxDate, view) {
|
|
1649
|
-
|
|
1790
|
+
const d = DateTime.fromJSDate(date).startOf(view);
|
|
1791
|
+
return d < DateTime.fromJSDate(minDate).startOf(view) || d > DateTime.fromJSDate(maxDate).startOf(view);
|
|
1650
1792
|
}
|
|
1651
1793
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CalendarItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1652
1794
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.4", type: CalendarItemComponent, isStandalone: false, selector: "button[ec-calendar-item]", inputs: { item: "item", selection: "selection", view: "view", minDate: "minDate", maxDate: "maxDate" }, host: { properties: { "class.is-today": "this.today", "class.is-selected": "this.selected", "class.is-outside-active-month": "this.outsideActiveMonth", "class.is-hidden": "this.hidden", "attr.disabled": "this.disabled" } }, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{font-size:var(--ec-font-size-action);height:2rem;line-height:1.25rem;padding:.3125rem .5rem;border:0;border-radius:var(--ec-border-radius);display:flex;align-items:center;justify-content:center;cursor:pointer}:host .label{display:flex;align-items:center;justify-content:center;white-space:nowrap;flex:auto}:host .ec-icon{flex:none}:host .ec-icon+.label{flex:none;margin-left:.25rem}:host.has-badge{padding-right:.0625rem}:host:focus{outline:none;position:relative;z-index:1}:host:disabled{background-color:var(--ec-background-color-disabled);border:1px solid var(--ec-form-control-border-color-disabled);color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled);cursor:default}:host:disabled .ec-icon{color:var(--ec-color-disabled-dark)}:host{background-color:transparent}:host:disabled{background-color:transparent;border-color:transparent;color:var(--ec-color-hint-dark);--ec-color-icon: var(--ec-color-hint-dark)}:host:hover:not(:disabled){background-color:var(--ec-background-color-hover)}:host:active:not(:disabled){background-color:var(--ec-background-color-selected);font-weight:700}:host:focus:not(:disabled){box-shadow:var(--ec-button-box-shadow-active, 0 0 0 2px var(--ec-border-color-focus))}:host.is-selected{background-color:var(--ec-background-color-selected);font-weight:700}:host{line-height:1.125rem}:host.is-selected,:host.is-selected:disabled{background-color:var(--ec-background-color-selected);font-weight:700}:host.is-today{position:relative}:host.is-today:after{content:\"\";position:absolute;top:50%;left:50%;width:1.75rem;height:1.75rem;transform:translate(-50%,-50%);border:1px solid;border-radius:50%;pointer-events:none}:host.is-outside-active-month{color:var(--ec-color-hint-dark)}:host.is-hidden{opacity:0!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
@@ -1695,8 +1837,12 @@ class CalendarComponent {
|
|
|
1695
1837
|
this.viewChange = new EventEmitter();
|
|
1696
1838
|
/** Array of calendar item rows to display in the calendar. */
|
|
1697
1839
|
this.calendarItems = [];
|
|
1698
|
-
/** Weekday labels to show at the top of the calendar in day view. */
|
|
1699
|
-
this.weekDays =
|
|
1840
|
+
/** Weekday labels to show at the top of the calendar in day view. Starts on Sunday to match the calendar grid layout. */
|
|
1841
|
+
this.weekDays = (() => {
|
|
1842
|
+
// Info.weekdays returns Monday-first; reorder so Sunday is first to match the calendar grid.
|
|
1843
|
+
const mondayFirst = Info.weekdays('short');
|
|
1844
|
+
return [mondayFirst[6], ...mondayFirst.slice(0, 6)].map(d => d.slice(0, 1));
|
|
1845
|
+
})();
|
|
1700
1846
|
this.disablePreviousButton = false;
|
|
1701
1847
|
this.disableNextButton = false;
|
|
1702
1848
|
// Trackby functions for ngFor loops. These reduce the number of DOM elements that need to be updated when the calendar is re-drawn.
|
|
@@ -1720,19 +1866,19 @@ class CalendarComponent {
|
|
|
1720
1866
|
onNextClick() {
|
|
1721
1867
|
// If we're in day view, we're incrementing by month
|
|
1722
1868
|
// In month, quarter, and year views we're incrementing by year\
|
|
1723
|
-
const unit = this.view.mode === 'day' ? '
|
|
1869
|
+
const unit = this.view.mode === 'day' ? 'months' : 'years';
|
|
1724
1870
|
// In year view, we're moving by 16 years at a time. Otherwise we're just moving by 1 month/year.
|
|
1725
1871
|
const count = this.view.mode === 'year' ? 16 : 1;
|
|
1726
|
-
const goToDate =
|
|
1872
|
+
const goToDate = DateTime.fromJSDate(this.view.date).plus({ [unit]: count }).toJSDate();
|
|
1727
1873
|
this.drawCalendar({ mode: this.view.mode, date: goToDate });
|
|
1728
1874
|
}
|
|
1729
1875
|
onPreviousClick() {
|
|
1730
1876
|
// If we're in day view, we're incrementing by month
|
|
1731
1877
|
// In month, quarter, and year views we're incrementing by year
|
|
1732
|
-
const unit = this.view.mode === 'day' ? '
|
|
1878
|
+
const unit = this.view.mode === 'day' ? 'months' : 'years';
|
|
1733
1879
|
// In year view, we're moving by 16 years at a time. Otherwise we're just moving by 1 month/year.
|
|
1734
1880
|
const count = this.view.mode === 'year' ? 16 : 1;
|
|
1735
|
-
const goToDate =
|
|
1881
|
+
const goToDate = DateTime.fromJSDate(this.view.date).minus({ [unit]: count }).toJSDate();
|
|
1736
1882
|
this.drawCalendar({ mode: this.view.mode, date: goToDate });
|
|
1737
1883
|
}
|
|
1738
1884
|
/** Switches the calendar to month view. */
|
|
@@ -1799,13 +1945,14 @@ class CalendarComponent {
|
|
|
1799
1945
|
this.view = view;
|
|
1800
1946
|
this.viewChange.emit(view);
|
|
1801
1947
|
}
|
|
1802
|
-
|
|
1803
|
-
this.
|
|
1948
|
+
const viewDt = DateTime.fromJSDate(this.view.date);
|
|
1949
|
+
this.month = viewDt.toFormat('MMM');
|
|
1950
|
+
this.year = viewDt.toFormat('yyyy');
|
|
1804
1951
|
this.calendarItems = this.getCalendarItems(this.view);
|
|
1805
1952
|
const startYear = this.calendarItems[0][0].date < this.minDate ? this.minDate : this.calendarItems[0][0].date;
|
|
1806
1953
|
const lastItem = this.getLastItem();
|
|
1807
1954
|
const endYear = lastItem.date > this.maxDate ? this.maxDate : lastItem.date;
|
|
1808
|
-
this.yearRange = `${
|
|
1955
|
+
this.yearRange = `${DateTime.fromJSDate(startYear).toFormat('yyyy')}–${DateTime.fromJSDate(endYear).toFormat('yyyy')}`;
|
|
1809
1956
|
this.updateNextPreviousStates();
|
|
1810
1957
|
}
|
|
1811
1958
|
getCalendarItems(view) {
|
|
@@ -1817,53 +1964,58 @@ class CalendarComponent {
|
|
|
1817
1964
|
}
|
|
1818
1965
|
}
|
|
1819
1966
|
getDayViewItems(activeDate) {
|
|
1820
|
-
// 6 rows of 7 days = 42 days
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1967
|
+
// 6 rows of 7 days = 42 days.
|
|
1968
|
+
// Use the start of the week of the first day of the month, anchored to Sunday to match the calendar grid.
|
|
1969
|
+
// Luxon's startOf('week') is Monday-based per ISO, so shift back to Sunday explicitly.
|
|
1970
|
+
const monthStart = DateTime.fromJSDate(activeDate).startOf('month');
|
|
1971
|
+
const sundayStart = monthStart.weekday === 7 ? monthStart : monthStart.startOf('week').minus({ days: 1 });
|
|
1972
|
+
return range(0, 6).map((r) => {
|
|
1973
|
+
return range(0, 7).map((d) => {
|
|
1974
|
+
const date = sundayStart.plus({ days: r * 7 + d });
|
|
1826
1975
|
return {
|
|
1827
|
-
date: date.
|
|
1828
|
-
label: date.
|
|
1976
|
+
date: date.toJSDate(),
|
|
1977
|
+
label: date.toFormat('d')
|
|
1829
1978
|
};
|
|
1830
1979
|
});
|
|
1831
1980
|
});
|
|
1832
1981
|
}
|
|
1833
1982
|
getMonthViewItems(activeDate) {
|
|
1834
1983
|
// 4 rows of 3 months = 12 months
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1984
|
+
const yearStart = DateTime.fromJSDate(activeDate).startOf('year');
|
|
1985
|
+
return range(0, 4).map((r) => {
|
|
1986
|
+
return range(0, 3).map((m) => {
|
|
1987
|
+
const date = yearStart.plus({ months: r * 3 + m });
|
|
1838
1988
|
return {
|
|
1839
|
-
date: date.
|
|
1840
|
-
label: date.
|
|
1989
|
+
date: date.toJSDate(),
|
|
1990
|
+
label: date.toFormat('MMM')
|
|
1841
1991
|
};
|
|
1842
1992
|
});
|
|
1843
1993
|
});
|
|
1844
1994
|
}
|
|
1845
1995
|
getQuarterViewItems(activeDate) {
|
|
1846
1996
|
// 2 rows of 2 quarters = 4 quarters
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
const
|
|
1997
|
+
const yearStart = DateTime.fromJSDate(activeDate).startOf('year');
|
|
1998
|
+
return range(0, 2).map((r) => {
|
|
1999
|
+
return range(0, 2).map((q) => {
|
|
2000
|
+
const date = yearStart.plus({ quarters: r * 2 + q });
|
|
2001
|
+
const endDate = date.endOf('quarter');
|
|
1851
2002
|
return {
|
|
1852
|
-
date: date.
|
|
1853
|
-
label: `${date.
|
|
2003
|
+
date: date.toJSDate(),
|
|
2004
|
+
label: `${date.toFormat('MMM')}–${endDate.toFormat('MMM')}`
|
|
1854
2005
|
};
|
|
1855
2006
|
});
|
|
1856
2007
|
});
|
|
1857
2008
|
}
|
|
1858
2009
|
getYearViewItems(activeDate) {
|
|
1859
2010
|
// 4 rows of 4 years = 16 years
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
2011
|
+
// Subtracting 8 years to put the current active year at the beginning of the 3rd row.
|
|
2012
|
+
const yearStart = DateTime.fromJSDate(activeDate).startOf('year').minus({ years: 8 });
|
|
2013
|
+
return range(0, 4).map((r) => {
|
|
2014
|
+
return range(0, 4).map((y) => {
|
|
2015
|
+
const date = yearStart.plus({ years: r * 4 + y });
|
|
1864
2016
|
return {
|
|
1865
|
-
date: date.
|
|
1866
|
-
label: date.
|
|
2017
|
+
date: date.toJSDate(),
|
|
2018
|
+
label: date.toFormat('yyyy')
|
|
1867
2019
|
};
|
|
1868
2020
|
});
|
|
1869
2021
|
});
|
|
@@ -1873,24 +2025,20 @@ class CalendarComponent {
|
|
|
1873
2025
|
// We don't want to disable the next/previous buttons if the min or max date is within the
|
|
1874
2026
|
// next or previous view
|
|
1875
2027
|
const unit = this.view.mode === 'day' ? 'month' : 'year';
|
|
2028
|
+
const pluralUnit = this.view.mode === 'day' ? 'months' : 'years';
|
|
2029
|
+
const viewDt = DateTime.fromJSDate(this.view.date);
|
|
1876
2030
|
// When in year view, we need to subtract 9 years to determine if we're past the min date.
|
|
1877
2031
|
// The year view is 16 years long, and the current date is the 9th year in the view.
|
|
1878
2032
|
const subCount = this.view.mode === 'year' ? 9 : 1;
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
else {
|
|
1883
|
-
this.disablePreviousButton = false;
|
|
1884
|
-
}
|
|
2033
|
+
const prev = viewDt.minus({ [pluralUnit]: subCount }).startOf(unit);
|
|
2034
|
+
const minDt = DateTime.fromJSDate(this.minDate).startOf(unit);
|
|
2035
|
+
this.disablePreviousButton = prev < minDt;
|
|
1885
2036
|
// When in year view, we need to add 8 years to determine if we're past the max date.
|
|
1886
2037
|
// The year view is 16 years long, and the current date is the 9th year in the view.
|
|
1887
2038
|
const addCount = this.view.mode === 'year' ? 8 : 1;
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
else {
|
|
1892
|
-
this.disableNextButton = false;
|
|
1893
|
-
}
|
|
2039
|
+
const next = viewDt.plus({ [pluralUnit]: addCount }).startOf(unit);
|
|
2040
|
+
const maxDt = DateTime.fromJSDate(this.maxDate).startOf(unit);
|
|
2041
|
+
this.disableNextButton = next > maxDt;
|
|
1894
2042
|
}
|
|
1895
2043
|
getLastItem() {
|
|
1896
2044
|
const lastRow = this.calendarItems[this.calendarItems.length - 1];
|
|
@@ -5268,7 +5416,7 @@ class DateInputComponent extends FormControlBase {
|
|
|
5268
5416
|
* Date parsing formats for user-entered dates. Defaults to month-first formats, but is updated in onInit
|
|
5269
5417
|
* to use the user's preferred date format.
|
|
5270
5418
|
*/
|
|
5271
|
-
this.parseFormats = DateTimeHelper.
|
|
5419
|
+
this.parseFormats = DateTimeHelper.getLuxonParseFormats();
|
|
5272
5420
|
}
|
|
5273
5421
|
ngOnChanges(changes) {
|
|
5274
5422
|
if (changes.selectionMode && !changes.selectionMode.isFirstChange()) {
|
|
@@ -5284,12 +5432,15 @@ class DateInputComponent extends FormControlBase {
|
|
|
5284
5432
|
this.onFormModelStatusChanges();
|
|
5285
5433
|
this.onFormModelValueChanges();
|
|
5286
5434
|
this.onTextboxValueChanges();
|
|
5287
|
-
// Sync the initial disabled status and value of the textbox
|
|
5435
|
+
// Sync the initial disabled status and value of the textbox.
|
|
5436
|
+
// Normalize the form model value so any ISO date strings the host bound to the model
|
|
5437
|
+
// become real Dates before they reach the calendar/stepper logic (see normalizeSelection).
|
|
5288
5438
|
this.syncTextboxControlDisabledStatus(this.formModel.status);
|
|
5289
|
-
const
|
|
5439
|
+
const initialSelection = DateInput.normalizeSelection(this.formModel.value);
|
|
5440
|
+
const initialDisplayValue = this.selectionStrategy.formatSelection(initialSelection);
|
|
5290
5441
|
this.textboxGroup.patchValue(initialDisplayValue, { emitEvent: false });
|
|
5291
5442
|
// Update the calendar selection and view based on the initial form model value
|
|
5292
|
-
this.calendarSelection =
|
|
5443
|
+
this.calendarSelection = initialSelection;
|
|
5293
5444
|
this.updateCalendars(this.calendarSelection);
|
|
5294
5445
|
this.updateSteppers(this.calendarSelection);
|
|
5295
5446
|
}
|
|
@@ -5385,7 +5536,7 @@ class DateInputComponent extends FormControlBase {
|
|
|
5385
5536
|
goToToday() {
|
|
5386
5537
|
// If both calendars are visible, show today in the secondary calendar and the month before in the primary calendar.
|
|
5387
5538
|
if (this.selectionStrategy.showSecondaryCalendar) {
|
|
5388
|
-
this.primaryCalendarView = { mode: 'day', date:
|
|
5539
|
+
this.primaryCalendarView = { mode: 'day', date: DateTime.now().minus({ months: 1 }).toJSDate() };
|
|
5389
5540
|
this.secondaryCalendarView = { mode: 'day', date: new Date() };
|
|
5390
5541
|
// If we're in a single date mode, show today in the primary calendar.
|
|
5391
5542
|
}
|
|
@@ -5434,11 +5585,14 @@ class DateInputComponent extends FormControlBase {
|
|
|
5434
5585
|
// Update the calendar selection textbox value with a formatted date when the form model changes.
|
|
5435
5586
|
// This is triggered by the user selecting a date from the calendar or when the textbox is blurred.
|
|
5436
5587
|
this.formModel.valueChanges.pipe(takeUntil(this.componentDestroyed)).subscribe(value => {
|
|
5437
|
-
|
|
5588
|
+
// Normalize first: the host may set an ISO date string on the model (e.g. an API value),
|
|
5589
|
+
// and the calendar logic requires real Dates to avoid an Invalid Date crash.
|
|
5590
|
+
const selection = DateInput.normalizeSelection(value);
|
|
5591
|
+
const displayValue = this.selectionStrategy.formatSelection(selection);
|
|
5438
5592
|
// Don't emit an event when setting the textbox value to avoid circular updates between the textbox and form model.
|
|
5439
5593
|
this.textboxGroup.patchValue(displayValue, { emitEvent: false });
|
|
5440
|
-
this.updateCalendars(
|
|
5441
|
-
this.updateSteppers(
|
|
5594
|
+
this.updateCalendars(selection);
|
|
5595
|
+
this.updateSteppers(selection);
|
|
5442
5596
|
});
|
|
5443
5597
|
}
|
|
5444
5598
|
onTextboxValueChanges() {
|
|
@@ -5518,7 +5672,7 @@ class DateInputComponent extends FormControlBase {
|
|
|
5518
5672
|
const { preference } = await lastValueFrom(this.userPreferenceService.getPreferences());
|
|
5519
5673
|
const dateFormat = preference?.dateFormat;
|
|
5520
5674
|
this.placeholder = dateFormat ?? this.placeholder;
|
|
5521
|
-
this.parseFormats = DateTimeHelper.
|
|
5675
|
+
this.parseFormats = DateTimeHelper.getLuxonParseFormats(dateFormat);
|
|
5522
5676
|
}
|
|
5523
5677
|
/** Focuses the date input. */
|
|
5524
5678
|
focusInput() {
|
|
@@ -5538,10 +5692,10 @@ class DateInputComponent extends FormControlBase {
|
|
|
5538
5692
|
// This would cause the dates in the other calendar to be unselectable if we were to
|
|
5539
5693
|
// update the min/max dates in these cases.
|
|
5540
5694
|
if (this.primaryCalendarView?.mode === 'day') {
|
|
5541
|
-
this.secondaryCalendarMinDate =
|
|
5695
|
+
this.secondaryCalendarMinDate = DateTime.fromJSDate(this.primaryCalendarView.date).plus({ months: 1 }).startOf('month').toJSDate();
|
|
5542
5696
|
}
|
|
5543
5697
|
if (this.secondaryCalendarView?.mode === 'day') {
|
|
5544
|
-
this.primaryCalendarMaxDate =
|
|
5698
|
+
this.primaryCalendarMaxDate = DateTime.fromJSDate(this.secondaryCalendarView.date).minus({ months: 1 }).endOf('month').toJSDate();
|
|
5545
5699
|
}
|
|
5546
5700
|
}
|
|
5547
5701
|
updateCalendars(selection) {
|
|
@@ -5557,8 +5711,10 @@ class DateInputComponent extends FormControlBase {
|
|
|
5557
5711
|
// However, it's possible that the new date is after the secondary calendar's date. In this case,
|
|
5558
5712
|
// We want to shift the secondary calendar so the calendars stay in order.
|
|
5559
5713
|
if (shiftSecondary && this.secondaryCalendarView) {
|
|
5560
|
-
|
|
5561
|
-
|
|
5714
|
+
const primaryDt = DateTime.fromJSDate(this.primaryCalendarView.date);
|
|
5715
|
+
const secondaryDt = DateTime.fromJSDate(this.secondaryCalendarView.date);
|
|
5716
|
+
if (primaryDt.startOf('month') >= secondaryDt.startOf('month')) {
|
|
5717
|
+
const newSecondaryDate = primaryDt.plus({ months: 1 }).toJSDate();
|
|
5562
5718
|
this.secondaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newSecondaryDate };
|
|
5563
5719
|
}
|
|
5564
5720
|
}
|
|
@@ -5569,8 +5725,10 @@ class DateInputComponent extends FormControlBase {
|
|
|
5569
5725
|
// However, it's possible that the new date is before the primary calendar's date. In this case,
|
|
5570
5726
|
// We want to shift the primary calendar so the calendars stay in order.
|
|
5571
5727
|
if (shiftPrimary && this.primaryCalendarView) {
|
|
5572
|
-
|
|
5573
|
-
|
|
5728
|
+
const primaryDt = DateTime.fromJSDate(this.primaryCalendarView.date);
|
|
5729
|
+
const secondaryDt = DateTime.fromJSDate(this.secondaryCalendarView.date);
|
|
5730
|
+
if (primaryDt.startOf('month') >= secondaryDt.startOf('month')) {
|
|
5731
|
+
const newPrimaryDate = secondaryDt.minus({ months: 1 }).toJSDate();
|
|
5574
5732
|
this.primaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newPrimaryDate };
|
|
5575
5733
|
}
|
|
5576
5734
|
}
|
|
@@ -5620,10 +5778,12 @@ class DateInputComponent extends FormControlBase {
|
|
|
5620
5778
|
// We're using the view mode as the granularity. We don't want to invalidate
|
|
5621
5779
|
// the date in the case where you have a month/quarter/year selected and the min
|
|
5622
5780
|
// or max date is somewhere within that month/quarter/year.
|
|
5623
|
-
|
|
5781
|
+
const unit = this.selectionStrategy.selectionViewMode;
|
|
5782
|
+
const valueDt = DateTime.fromJSDate(value).startOf(unit);
|
|
5783
|
+
if (valueDt < DateTime.fromJSDate(this.minDate).startOf(unit)) {
|
|
5624
5784
|
return { minDate: { minValue: this.minDate } };
|
|
5625
5785
|
}
|
|
5626
|
-
else if (
|
|
5786
|
+
else if (valueDt > DateTime.fromJSDate(this.maxDate).startOf(unit)) {
|
|
5627
5787
|
return { maxDate: { maxValue: this.maxDate } };
|
|
5628
5788
|
}
|
|
5629
5789
|
}
|
|
@@ -11932,7 +12092,9 @@ class DateDisplayPipe2 {
|
|
|
11932
12092
|
}
|
|
11933
12093
|
async transform(date, options) {
|
|
11934
12094
|
const { showEndOfTime, showTime, showSeconds, displayInUTC } = options || {};
|
|
11935
|
-
if (
|
|
12095
|
+
if (date == null)
|
|
12096
|
+
return '';
|
|
12097
|
+
if (!DateTimeHelper.toDateTime(date).isValid || (!showEndOfTime && DateTimeHelper.isEndOfTime(date))) {
|
|
11936
12098
|
return '';
|
|
11937
12099
|
}
|
|
11938
12100
|
const { preference } = await lastValueFrom(this.userPrefs.getPreferences());
|
|
@@ -11944,8 +12106,7 @@ class DateDisplayPipe2 {
|
|
|
11944
12106
|
}
|
|
11945
12107
|
formatString += ` ${timeFormat}`;
|
|
11946
12108
|
}
|
|
11947
|
-
|
|
11948
|
-
return (displayInUTC ? moment.utc(date) : moment(date)).format(formatString);
|
|
12109
|
+
return DateTimeHelper.formatDate(date, formatString, displayInUTC);
|
|
11949
12110
|
}
|
|
11950
12111
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe2, deps: [{ token: UserPreferenceService }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
11951
12112
|
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe2, isStandalone: false, name: "dateDisplay2" }); }
|
|
@@ -11958,6 +12119,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
11958
12119
|
}]
|
|
11959
12120
|
}], ctorParameters: () => [{ type: UserPreferenceService }] });
|
|
11960
12121
|
|
|
12122
|
+
/**
|
|
12123
|
+
* Same behavior as {@link DateDisplayPipe2}, but always appends the short named
|
|
12124
|
+
* timezone abbreviation (e.g. `EST`, `PDT`, `UTC`) to the output. Use this when
|
|
12125
|
+
* downstream consumers need to disambiguate the timezone of a rendered date.
|
|
12126
|
+
*
|
|
12127
|
+
* @example <span>{{ someDate | dateDisplay3 | async }}</span>
|
|
12128
|
+
*/
|
|
12129
|
+
class DateDisplayPipe3 {
|
|
12130
|
+
constructor(userPrefs) {
|
|
12131
|
+
this.userPrefs = userPrefs;
|
|
12132
|
+
}
|
|
12133
|
+
async transform(date, options) {
|
|
12134
|
+
const { showEndOfTime, showTime, showSeconds, displayInUTC } = options || {};
|
|
12135
|
+
if (date == null)
|
|
12136
|
+
return '';
|
|
12137
|
+
if (!DateTimeHelper.toDateTime(date).isValid || (!showEndOfTime && DateTimeHelper.isEndOfTime(date))) {
|
|
12138
|
+
return '';
|
|
12139
|
+
}
|
|
12140
|
+
const { preference } = await lastValueFrom(this.userPrefs.getPreferences());
|
|
12141
|
+
let formatString = preference?.dateFormat || 'MM/DD/YYYY';
|
|
12142
|
+
if (showTime) {
|
|
12143
|
+
let timeFormat = preference.timeFormat;
|
|
12144
|
+
if (!showSeconds) {
|
|
12145
|
+
timeFormat = timeFormat.replace(':ss', '');
|
|
12146
|
+
}
|
|
12147
|
+
formatString += ` ${timeFormat}`;
|
|
12148
|
+
}
|
|
12149
|
+
// Luxon's `ZZZZ` renders the short named offset (e.g. `EST`, `EDT`, `UTC`).
|
|
12150
|
+
// The token passes through `momentToLuxonFormat` unchanged.
|
|
12151
|
+
formatString += ' ZZZZ';
|
|
12152
|
+
return DateTimeHelper.formatDate(date, formatString, !!displayInUTC);
|
|
12153
|
+
}
|
|
12154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe3, deps: [{ token: UserPreferenceService }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
12155
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe3, isStandalone: false, name: "dateDisplay3" }); }
|
|
12156
|
+
}
|
|
12157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe3, decorators: [{
|
|
12158
|
+
type: Pipe,
|
|
12159
|
+
args: [{
|
|
12160
|
+
name: 'dateDisplay3',
|
|
12161
|
+
standalone: false
|
|
12162
|
+
}]
|
|
12163
|
+
}], ctorParameters: () => [{ type: UserPreferenceService }] });
|
|
12164
|
+
|
|
11961
12165
|
/**
|
|
11962
12166
|
* Format a time to the user's preference for display
|
|
11963
12167
|
*/
|
|
@@ -11970,11 +12174,10 @@ class TimeDisplayPipe {
|
|
|
11970
12174
|
* Format a time for display, accounting for user's display preferences.
|
|
11971
12175
|
*/
|
|
11972
12176
|
transform(time, showSeconds) {
|
|
11973
|
-
let display = '';
|
|
11974
12177
|
let formatString = '';
|
|
11975
12178
|
// use user-preferred formats
|
|
11976
12179
|
this.userPreferenceService.getPreferences().subscribe(result => {
|
|
11977
|
-
//if preferences exist then format time to users preference
|
|
12180
|
+
//if preferences exist then format time to users preference
|
|
11978
12181
|
//otherwise use the last user preference
|
|
11979
12182
|
if (result.preference) {
|
|
11980
12183
|
formatString = result.preference.timeFormat;
|
|
@@ -11984,8 +12187,7 @@ class TimeDisplayPipe {
|
|
|
11984
12187
|
this.lastFormatString = formatString;
|
|
11985
12188
|
}
|
|
11986
12189
|
});
|
|
11987
|
-
|
|
11988
|
-
return display;
|
|
12190
|
+
return DateTimeHelper.formatDate(time ?? null, this.lastFormatString);
|
|
11989
12191
|
}
|
|
11990
12192
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimeDisplayPipe, deps: [{ token: UserPreferenceService }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
11991
12193
|
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: TimeDisplayPipe, isStandalone: false, name: "timeDisplay" }); }
|
|
@@ -12013,21 +12215,21 @@ class RelativeDatePipe {
|
|
|
12013
12215
|
* If any of todayLabel, yesterdayLabel is supplied, use the supplied label.
|
|
12014
12216
|
*/
|
|
12015
12217
|
transform(timeSelected, options) {
|
|
12016
|
-
const selected =
|
|
12017
|
-
const today =
|
|
12018
|
-
const yesterday =
|
|
12218
|
+
const selected = DateTime.fromISO(timeSelected);
|
|
12219
|
+
const today = DateTime.now();
|
|
12220
|
+
const yesterday = today.minus({ days: 1 });
|
|
12019
12221
|
const timeDisplay = options?.dateOnly ? `` : ` ${this.timeDisplayPipe.transform(timeSelected)}`;
|
|
12020
12222
|
let displayValue = null;
|
|
12021
12223
|
let prefixValue = '';
|
|
12022
|
-
if (selected.
|
|
12224
|
+
if (selected.hasSame(today, 'day') && !options?.showTimeForToday) {
|
|
12023
12225
|
displayValue = this.translateService.instant(options?.todayLabel ? options?.todayLabel : 'today');
|
|
12024
12226
|
prefixValue = options?.todayPrefix ?? '';
|
|
12025
12227
|
}
|
|
12026
|
-
else if (selected.
|
|
12228
|
+
else if (selected.hasSame(today, 'day') && options?.showTimeForToday && !timeDisplay) {
|
|
12027
12229
|
displayValue = this.timeDisplayPipe.transform(timeSelected);
|
|
12028
12230
|
prefixValue = options?.todayTimePrefix ?? '';
|
|
12029
12231
|
}
|
|
12030
|
-
else if (selected.
|
|
12232
|
+
else if (selected.hasSame(yesterday, 'day')) {
|
|
12031
12233
|
displayValue = this.translateService.instant(options?.yesterdayLabel ? options?.yesterdayLabel : 'yesterday');
|
|
12032
12234
|
prefixValue = options?.yesterdayPrefix ?? '';
|
|
12033
12235
|
}
|
|
@@ -12665,6 +12867,7 @@ class ComponentsModule {
|
|
|
12665
12867
|
DateInputComponent,
|
|
12666
12868
|
KeyboardNavContainerDirective,
|
|
12667
12869
|
DateDisplayPipe2,
|
|
12870
|
+
DateDisplayPipe3,
|
|
12668
12871
|
MultiselectComponent], imports: [CommonModule,
|
|
12669
12872
|
FormsModule,
|
|
12670
12873
|
ReactiveFormsModule,
|
|
@@ -12737,7 +12940,8 @@ class ComponentsModule {
|
|
|
12737
12940
|
CalendarComponent,
|
|
12738
12941
|
DateInputComponent,
|
|
12739
12942
|
KeyboardNavContainerDirective,
|
|
12740
|
-
DateDisplayPipe2
|
|
12943
|
+
DateDisplayPipe2,
|
|
12944
|
+
DateDisplayPipe3] }); }
|
|
12741
12945
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ComponentsModule, providers: [
|
|
12742
12946
|
FormGroupHelper,
|
|
12743
12947
|
DialogService,
|
|
@@ -12747,7 +12951,8 @@ class ComponentsModule {
|
|
|
12747
12951
|
RowCountPipe,
|
|
12748
12952
|
RelativeDatePipe,
|
|
12749
12953
|
HighlightTextPipe,
|
|
12750
|
-
DateDisplayPipe2
|
|
12954
|
+
DateDisplayPipe2,
|
|
12955
|
+
DateDisplayPipe3
|
|
12751
12956
|
], imports: [CommonModule,
|
|
12752
12957
|
FormsModule,
|
|
12753
12958
|
ReactiveFormsModule,
|
|
@@ -12833,6 +13038,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12833
13038
|
DateInputComponent,
|
|
12834
13039
|
KeyboardNavContainerDirective,
|
|
12835
13040
|
DateDisplayPipe2,
|
|
13041
|
+
DateDisplayPipe3,
|
|
12836
13042
|
MultiselectComponent
|
|
12837
13043
|
],
|
|
12838
13044
|
imports: [
|
|
@@ -12854,7 +13060,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12854
13060
|
RowCountPipe,
|
|
12855
13061
|
RelativeDatePipe,
|
|
12856
13062
|
HighlightTextPipe,
|
|
12857
|
-
DateDisplayPipe2
|
|
13063
|
+
DateDisplayPipe2,
|
|
13064
|
+
DateDisplayPipe3
|
|
12858
13065
|
],
|
|
12859
13066
|
exports: [
|
|
12860
13067
|
ButtonComponent,
|
|
@@ -12922,7 +13129,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12922
13129
|
CalendarComponent,
|
|
12923
13130
|
DateInputComponent,
|
|
12924
13131
|
KeyboardNavContainerDirective,
|
|
12925
|
-
DateDisplayPipe2
|
|
13132
|
+
DateDisplayPipe2,
|
|
13133
|
+
DateDisplayPipe3
|
|
12926
13134
|
]
|
|
12927
13135
|
}]
|
|
12928
13136
|
}] });
|
|
@@ -13918,5 +14126,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
13918
14126
|
* Generated bundle index. Do not edit.
|
|
13919
14127
|
*/
|
|
13920
14128
|
|
|
13921
|
-
export { AppBarComponent, AvatarComponent, BannerComponent, ButtonComponent, CacheService, CalendarComponent, CheckboxComponent, ClickAreaForDirective, CollapsibleToggleComponent, ComboboxComponent, ComponentsModule, ConfirmComponent, ConfirmDialogContext, CopyButtonBaseTestInjectorFactory, CopyButtonDirective, CopyTableButtonDirective, CustomValidators, DateDisplayPipe, DateDisplayPipe2, DateInput, DateInputComponent, DateTimeHelper, DialogCloseDuration, DialogCloseEvent, DialogCloseLatestEvent, DialogComponent, DialogEvent, DialogGroupComponent, DialogOpenDuration, DialogOpenEndEvent, DialogOpenStartEvent, DialogResult, DialogService, DropdownComponent, ErrorService, FileTypeExtensions, FileUploadComponent, FormControlBase, FormControlComponent, FormControlLabelComponent, FormGroupComponent, FormGroupHelper, HelpPopoverComponent, HierarchyBase, HierarchyBaseTestInjectorFactory, HierarchyItem, HierarchyMocks, HierarchyTreeComponent, HighlightTextPipe, IfViewportWidthDirective, ItemDisplayComponent, ItemPickerComponent, ItemPickerSelectableContext, JsonDisplayComponent, JsonHelper, KeyboardNavContainerDirective, LinkButtonComponent, MenuComponent, MockActivatedRoute, MockDateDisplayPipe, MockDialog, MockDialogContent, MockTranslateService, MockTranslationHelperService, MultiselectComponent, NavGroup, NavItemActiveDirective, NumericboxComponent, Overlay, PageBaseComponent, PageBaseComponentTestHelper, PageBaseComponentTestInjectorFactory, PageInitResult, PageStatus, PageStatuses, PageTitleComponent, PageViewComponent, PanelCloseDuration, PanelOpenDuration, PopoverComponent, PopupContainerDirective, RadioButtonComponent, RadioButtonOption, RelativeDatePipe, ResizableBase, ResizableColumnComponent, ResizableComponent, RouterHelper, RowCountPipe, ScrollService, SearchableTableComponent, SelectComponent, SpinnerComponent, SplashComponent, SplashService, SpyFactory, TableComponent, TableLockedColumnComponent, TableMasterHeaderRowComponent, TableMasterRowComponent, TablePaginationComponent, TableSelectableRowComponent, TableSelectableRowContext, TabsComponent, Tag, TagsComponent, TelemetryService, TelemetryTrackerService, TextboxComponent, TimeDisplayPipe, ToastComponent, ToastEvent, ToastService, ToasterComponent, TooltipComponent, TooltipDirective, TooltipService, TreeComponent, UnicodeStrings, UserPreferenceService, ValidationMessageService, ViewOverlayComponent, WindowService, WizardBaseComponent, WizardButtonsComponent, WizardProgressComponent, canadianPostalCodeRegex, clickEvent, dateInputFormatRegex, domainPattern, findAllSpacesPattern, forEachFormControl, getApiError, getControlValue, getDecimalPattern, handleKeyNavigate, integerPattern, isApiError, menuAnimationSpeed, mockRouterFactory, mockRouterHelperFactory, numericboxValidation, orderByIgnoreCase, otherZipCodeRegex, phoneNumberValidationPattern, sortByIgnoreCase, textboxValidation, unitedStatesZipCodeRegex, urlValidationPattern, validateFormGroupValuesAreUnique };
|
|
14129
|
+
export { AppBarComponent, AvatarComponent, BannerComponent, ButtonComponent, CacheService, CalendarComponent, CheckboxComponent, ClickAreaForDirective, CollapsibleToggleComponent, ComboboxComponent, ComponentsModule, ConfirmComponent, ConfirmDialogContext, CopyButtonBaseTestInjectorFactory, CopyButtonDirective, CopyTableButtonDirective, CustomValidators, DateDisplayPipe, DateDisplayPipe2, DateDisplayPipe3, DateInput, DateInputComponent, DateTimeHelper, DialogCloseDuration, DialogCloseEvent, DialogCloseLatestEvent, DialogComponent, DialogEvent, DialogGroupComponent, DialogOpenDuration, DialogOpenEndEvent, DialogOpenStartEvent, DialogResult, DialogService, DropdownComponent, ErrorService, FileTypeExtensions, FileUploadComponent, FormControlBase, FormControlComponent, FormControlLabelComponent, FormGroupComponent, FormGroupHelper, HelpPopoverComponent, HierarchyBase, HierarchyBaseTestInjectorFactory, HierarchyItem, HierarchyMocks, HierarchyTreeComponent, HighlightTextPipe, IfViewportWidthDirective, ItemDisplayComponent, ItemPickerComponent, ItemPickerSelectableContext, JsonDisplayComponent, JsonHelper, KeyboardNavContainerDirective, LinkButtonComponent, MenuComponent, MockActivatedRoute, MockDateDisplayPipe, MockDialog, MockDialogContent, MockTranslateService, MockTranslationHelperService, MultiselectComponent, NavGroup, NavItemActiveDirective, NumericboxComponent, Overlay, PageBaseComponent, PageBaseComponentTestHelper, PageBaseComponentTestInjectorFactory, PageInitResult, PageStatus, PageStatuses, PageTitleComponent, PageViewComponent, PanelCloseDuration, PanelOpenDuration, PopoverComponent, PopupContainerDirective, RadioButtonComponent, RadioButtonOption, RelativeDatePipe, ResizableBase, ResizableColumnComponent, ResizableComponent, RouterHelper, RowCountPipe, ScrollService, SearchableTableComponent, SelectComponent, SpinnerComponent, SplashComponent, SplashService, SpyFactory, TableComponent, TableLockedColumnComponent, TableMasterHeaderRowComponent, TableMasterRowComponent, TablePaginationComponent, TableSelectableRowComponent, TableSelectableRowContext, TabsComponent, Tag, TagsComponent, TelemetryService, TelemetryTrackerService, TextboxComponent, TimeDisplayPipe, ToastComponent, ToastEvent, ToastService, ToasterComponent, TooltipComponent, TooltipDirective, TooltipService, TreeComponent, UnicodeStrings, UserPreferenceService, ValidationMessageService, ViewOverlayComponent, WindowService, WizardBaseComponent, WizardButtonsComponent, WizardProgressComponent, canadianPostalCodeRegex, clickEvent, dateInputFormatRegex, domainPattern, findAllSpacesPattern, forEachFormControl, getApiError, getControlValue, getDecimalPattern, handleKeyNavigate, integerPattern, isApiError, menuAnimationSpeed, mockRouterFactory, mockRouterHelperFactory, numericboxValidation, orderByIgnoreCase, otherZipCodeRegex, phoneNumberValidationPattern, sortByIgnoreCase, textboxValidation, unitedStatesZipCodeRegex, urlValidationPattern, validateFormGroupValuesAreUnique };
|
|
13922
14130
|
//# sourceMappingURL=energycap-components.mjs.map
|