@energycap/components 0.46.14 → 0.46.16
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
|
|
|
@@ -368,11 +368,11 @@ class BannerComponent {
|
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BannerComponent, deps: [{ token: CacheService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
371
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: BannerComponent, isStandalone: false, selector: "ec-banner", inputs: { hidden: "hidden", id: "id", type: "type", bannerStyle: "bannerStyle", title: "title", text: "text", list: "list", showCloseBtn: "showCloseBtn", autoHideOnClose: "autoHideOnClose", customIcon: "customIcon", rememberClosed: "rememberClosed" }, outputs: { closed: "closed" }, host: { properties: { "hidden": "this.hidden" } }, usesOnChanges: true, ngImport: i0, template: "<div id=\"banner_{{id}}\" \n class=\"banner {{type}} {{bannerStyle}}\"\n [attr.role]=\"type === 'error' || type === 'warning' ? 'alert' : (type === 'info' || type === 'success' ? 'status' : null)\">\n @if (showCloseBtn) {\n <ec-button id=\"banner{{id}}_close\"\n type=\"icon\"\n icon=\"icon-cancel\"\n ariaLabel=\"Banner_CloseButtonLabel\"\n (clicked)=\"close()\">\n </ec-button>\n }\n <div class=\"banner-content d-flex text-body-1\">\n <i class=\"ec-icon {{icon}}\"></i>\n <div class=\"ml-2\">\n @if (title) {\n <p class=\"title mb-0\">\n {{title}}\n </p>\n }\n @if (text) {\n <p class=\"text mb-0\">{{text}}</p>\n }\n\n @if (list?.length) {\n <ul class=\"list mb-0\">\n @for (item of list; track item) {\n <li>{{item}}</li>\n }\n </ul>\n }\n <ng-content></ng-content>\n </div>\n </div>\n\n</div>\n", styles: [":host{display:flex}:host(.border-bottom-0) .banner{border-bottom:0;border-radius:var(--ec-border-radius-card)}.banner{display:flex;flex-direction:column;flex:1 1;min-height:2.5rem;position:relative;overflow-y:auto;background-color:var(--ec-banner-background-color, var(--ec-background-color-info));border-radius:var(--ec-banner-border-radius, var(--ec-border-radius-card));border:1px solid var(--ec-banner-border-color, var(--ec-color-info))}.banner-content{align-items:var(--ec-banner-align-items-content, normal);padding:.5rem 1rem;flex:none;margin:auto 0;color:var(--ec-banner-color, var(--ec-color-secondary-dark))}.banner-content ::ng-deep p{line-height:inherit}.ec-icon{color:var(--ec-banner-icon-color, var(--ec-color-info));font-size:1.125rem}ec-button{--ec-button-color-icon-hover: var(--ec-color-primary-dark);--ec-background-color-hover: rgba(26, 26, 35, .1);position:absolute;top:.1875rem;right:.25rem}ec-button+.banner-content{padding-right:2.75rem}.title{font-weight:700}.list{margin:0;padding-left:2em}.text+.list{margin-top:1em}.info:not(.toast){--ec-banner-background-color: var(--ec-background-color-info);--ec-banner-border-color: var(--ec-color-info);--ec-banner-icon-color: var(--ec-color-info)}.warning:not(.toast){--ec-banner-background-color: var(--ec-background-color-caution);--ec-banner-border-color: var(--ec-color-caution);--ec-banner-icon-color: var(--ec-color-caution)}.success:not(.toast){--ec-banner-background-color: var(--ec-background-color-success);--ec-banner-border-color: var(--ec-color-success);--ec-banner-icon-color: var(--ec-color-success)}.error:not(.toast){--ec-banner-background-color: var(--ec-background-color-danger);--ec-banner-border-color: var(--ec-color-danger);--ec-banner-icon-color: var(--ec-color-danger)}.pinned{border-radius:0;border-left:0;border-right:0}.promo:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-promo)}.promo:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.instructional:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-instructional)}.instructional:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.toast{--ec-banner-background-color: var(--ec-color-gray-8);--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-primary-light);--ec-color-link: var(--ec-color-link-light);border:0;box-shadow:var(--ec-box-shadow)}.toast ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);top:.25rem;right:.25rem}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }] }); }
|
|
371
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: BannerComponent, isStandalone: false, selector: "ec-banner", inputs: { hidden: "hidden", id: "id", type: "type", bannerStyle: "bannerStyle", title: "title", text: "text", list: "list", showCloseBtn: "showCloseBtn", autoHideOnClose: "autoHideOnClose", customIcon: "customIcon", rememberClosed: "rememberClosed" }, outputs: { closed: "closed" }, host: { properties: { "hidden": "this.hidden" } }, usesOnChanges: true, ngImport: i0, template: "<div id=\"banner_{{id}}\" \n class=\"banner {{type}} {{bannerStyle}}\"\n [attr.role]=\"type === 'error' || type === 'warning' ? 'alert' : (type === 'info' || type === 'success' ? 'status' : null)\">\n @if (showCloseBtn) {\n <ec-button id=\"banner{{id}}_close\"\n type=\"icon\"\n icon=\"icon-cancel\"\n ariaLabel=\"Banner_CloseButtonLabel\"\n (clicked)=\"close()\">\n </ec-button>\n }\n <div class=\"banner-content d-flex text-body-1\">\n <i class=\"ec-icon {{icon}}\" aria-hidden=\"true\"></i>\n <div class=\"ml-2\">\n @if (title) {\n <p class=\"title mb-0\">\n {{title}}\n </p>\n }\n @if (text) {\n <p class=\"text mb-0\">{{text}}</p>\n }\n\n @if (list?.length) {\n <ul class=\"list mb-0\">\n @for (item of list; track item) {\n <li>{{item}}</li>\n }\n </ul>\n }\n <ng-content></ng-content>\n </div>\n </div>\n\n</div>\n", styles: [":host{display:flex}:host(.border-bottom-0) .banner{border-bottom:0;border-radius:var(--ec-border-radius-card)}.banner{display:flex;flex-direction:column;flex:1 1;min-height:2.5rem;position:relative;overflow-y:auto;background-color:var(--ec-banner-background-color, var(--ec-background-color-info));border-radius:var(--ec-banner-border-radius, var(--ec-border-radius-card));border:1px solid var(--ec-banner-border-color, var(--ec-color-info))}.banner-content{align-items:var(--ec-banner-align-items-content, normal);padding:.5rem 1rem;flex:none;margin:auto 0;color:var(--ec-banner-color, var(--ec-color-secondary-dark))}.banner-content ::ng-deep p{line-height:inherit}.ec-icon{color:var(--ec-banner-icon-color, var(--ec-color-info));font-size:1.125rem}ec-button{--ec-button-color-icon-hover: var(--ec-color-primary-dark);--ec-background-color-hover: rgba(26, 26, 35, .1);position:absolute;top:.1875rem;right:.25rem}ec-button+.banner-content{padding-right:2.75rem}.title{font-weight:700}.list{margin:0;padding-left:2em}.text+.list{margin-top:1em}.info:not(.toast){--ec-banner-background-color: var(--ec-background-color-info);--ec-banner-border-color: var(--ec-color-info);--ec-banner-icon-color: var(--ec-color-info)}.warning:not(.toast){--ec-banner-background-color: var(--ec-background-color-caution);--ec-banner-border-color: var(--ec-color-caution);--ec-banner-icon-color: var(--ec-color-caution)}.success:not(.toast){--ec-banner-background-color: var(--ec-background-color-success);--ec-banner-border-color: var(--ec-color-success);--ec-banner-icon-color: var(--ec-color-success)}.error:not(.toast){--ec-banner-background-color: var(--ec-background-color-danger);--ec-banner-border-color: var(--ec-color-danger);--ec-banner-icon-color: var(--ec-color-danger)}.pinned{border-radius:0;border-left:0;border-right:0}.promo:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-promo)}.promo:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.instructional:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-instructional)}.instructional:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.toast{--ec-banner-background-color: var(--ec-color-gray-8);--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-primary-light);--ec-color-link: var(--ec-color-link-light);border:0;box-shadow:var(--ec-box-shadow)}.toast ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);top:.25rem;right:.25rem}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }] }); }
|
|
372
372
|
}
|
|
373
373
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: BannerComponent, decorators: [{
|
|
374
374
|
type: Component,
|
|
375
|
-
args: [{ selector: 'ec-banner', standalone: false, template: "<div id=\"banner_{{id}}\" \n class=\"banner {{type}} {{bannerStyle}}\"\n [attr.role]=\"type === 'error' || type === 'warning' ? 'alert' : (type === 'info' || type === 'success' ? 'status' : null)\">\n @if (showCloseBtn) {\n <ec-button id=\"banner{{id}}_close\"\n type=\"icon\"\n icon=\"icon-cancel\"\n ariaLabel=\"Banner_CloseButtonLabel\"\n (clicked)=\"close()\">\n </ec-button>\n }\n <div class=\"banner-content d-flex text-body-1\">\n <i class=\"ec-icon {{icon}}\"></i>\n <div class=\"ml-2\">\n @if (title) {\n <p class=\"title mb-0\">\n {{title}}\n </p>\n }\n @if (text) {\n <p class=\"text mb-0\">{{text}}</p>\n }\n\n @if (list?.length) {\n <ul class=\"list mb-0\">\n @for (item of list; track item) {\n <li>{{item}}</li>\n }\n </ul>\n }\n <ng-content></ng-content>\n </div>\n </div>\n\n</div>\n", styles: [":host{display:flex}:host(.border-bottom-0) .banner{border-bottom:0;border-radius:var(--ec-border-radius-card)}.banner{display:flex;flex-direction:column;flex:1 1;min-height:2.5rem;position:relative;overflow-y:auto;background-color:var(--ec-banner-background-color, var(--ec-background-color-info));border-radius:var(--ec-banner-border-radius, var(--ec-border-radius-card));border:1px solid var(--ec-banner-border-color, var(--ec-color-info))}.banner-content{align-items:var(--ec-banner-align-items-content, normal);padding:.5rem 1rem;flex:none;margin:auto 0;color:var(--ec-banner-color, var(--ec-color-secondary-dark))}.banner-content ::ng-deep p{line-height:inherit}.ec-icon{color:var(--ec-banner-icon-color, var(--ec-color-info));font-size:1.125rem}ec-button{--ec-button-color-icon-hover: var(--ec-color-primary-dark);--ec-background-color-hover: rgba(26, 26, 35, .1);position:absolute;top:.1875rem;right:.25rem}ec-button+.banner-content{padding-right:2.75rem}.title{font-weight:700}.list{margin:0;padding-left:2em}.text+.list{margin-top:1em}.info:not(.toast){--ec-banner-background-color: var(--ec-background-color-info);--ec-banner-border-color: var(--ec-color-info);--ec-banner-icon-color: var(--ec-color-info)}.warning:not(.toast){--ec-banner-background-color: var(--ec-background-color-caution);--ec-banner-border-color: var(--ec-color-caution);--ec-banner-icon-color: var(--ec-color-caution)}.success:not(.toast){--ec-banner-background-color: var(--ec-background-color-success);--ec-banner-border-color: var(--ec-color-success);--ec-banner-icon-color: var(--ec-color-success)}.error:not(.toast){--ec-banner-background-color: var(--ec-background-color-danger);--ec-banner-border-color: var(--ec-color-danger);--ec-banner-icon-color: var(--ec-color-danger)}.pinned{border-radius:0;border-left:0;border-right:0}.promo:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-promo)}.promo:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.instructional:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-instructional)}.instructional:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.toast{--ec-banner-background-color: var(--ec-color-gray-8);--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-primary-light);--ec-color-link: var(--ec-color-link-light);border:0;box-shadow:var(--ec-box-shadow)}.toast ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);top:.25rem;right:.25rem}\n"] }]
|
|
375
|
+
args: [{ selector: 'ec-banner', standalone: false, template: "<div id=\"banner_{{id}}\" \n class=\"banner {{type}} {{bannerStyle}}\"\n [attr.role]=\"type === 'error' || type === 'warning' ? 'alert' : (type === 'info' || type === 'success' ? 'status' : null)\">\n @if (showCloseBtn) {\n <ec-button id=\"banner{{id}}_close\"\n type=\"icon\"\n icon=\"icon-cancel\"\n ariaLabel=\"Banner_CloseButtonLabel\"\n (clicked)=\"close()\">\n </ec-button>\n }\n <div class=\"banner-content d-flex text-body-1\">\n <i class=\"ec-icon {{icon}}\" aria-hidden=\"true\"></i>\n <div class=\"ml-2\">\n @if (title) {\n <p class=\"title mb-0\">\n {{title}}\n </p>\n }\n @if (text) {\n <p class=\"text mb-0\">{{text}}</p>\n }\n\n @if (list?.length) {\n <ul class=\"list mb-0\">\n @for (item of list; track item) {\n <li>{{item}}</li>\n }\n </ul>\n }\n <ng-content></ng-content>\n </div>\n </div>\n\n</div>\n", styles: [":host{display:flex}:host(.border-bottom-0) .banner{border-bottom:0;border-radius:var(--ec-border-radius-card)}.banner{display:flex;flex-direction:column;flex:1 1;min-height:2.5rem;position:relative;overflow-y:auto;background-color:var(--ec-banner-background-color, var(--ec-background-color-info));border-radius:var(--ec-banner-border-radius, var(--ec-border-radius-card));border:1px solid var(--ec-banner-border-color, var(--ec-color-info))}.banner-content{align-items:var(--ec-banner-align-items-content, normal);padding:.5rem 1rem;flex:none;margin:auto 0;color:var(--ec-banner-color, var(--ec-color-secondary-dark))}.banner-content ::ng-deep p{line-height:inherit}.ec-icon{color:var(--ec-banner-icon-color, var(--ec-color-info));font-size:1.125rem}ec-button{--ec-button-color-icon-hover: var(--ec-color-primary-dark);--ec-background-color-hover: rgba(26, 26, 35, .1);position:absolute;top:.1875rem;right:.25rem}ec-button+.banner-content{padding-right:2.75rem}.title{font-weight:700}.list{margin:0;padding-left:2em}.text+.list{margin-top:1em}.info:not(.toast){--ec-banner-background-color: var(--ec-background-color-info);--ec-banner-border-color: var(--ec-color-info);--ec-banner-icon-color: var(--ec-color-info)}.warning:not(.toast){--ec-banner-background-color: var(--ec-background-color-caution);--ec-banner-border-color: var(--ec-color-caution);--ec-banner-icon-color: var(--ec-color-caution)}.success:not(.toast){--ec-banner-background-color: var(--ec-background-color-success);--ec-banner-border-color: var(--ec-color-success);--ec-banner-icon-color: var(--ec-color-success)}.error:not(.toast){--ec-banner-background-color: var(--ec-background-color-danger);--ec-banner-border-color: var(--ec-color-danger);--ec-banner-icon-color: var(--ec-color-danger)}.pinned{border-radius:0;border-left:0;border-right:0}.promo:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-promo)}.promo:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.instructional:not(.toast){--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-secondary-light);--ec-color-link: var(--ec-color-link-light);border:none;background:var(--ec-background-color-instructional)}.instructional:not(.toast) ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15)}.toast{--ec-banner-background-color: var(--ec-color-gray-8);--ec-banner-color: var(--ec-color-primary-light);--ec-banner-icon-color: var(--ec-color-primary-light);--ec-color-link: var(--ec-color-link-light);border:0;box-shadow:var(--ec-box-shadow)}.toast ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);top:.25rem;right:.25rem}\n"] }]
|
|
376
376
|
}], ctorParameters: () => [{ type: CacheService }], propDecorators: { hidden: [{
|
|
377
377
|
type: HostBinding,
|
|
378
378
|
args: ['hidden']
|
|
@@ -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,22 @@ class DateTimeHelper {
|
|
|
581
581
|
"yyyyMMdd"
|
|
582
582
|
]; }
|
|
583
583
|
/**
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
'
|
|
591
|
-
'
|
|
592
|
-
'
|
|
593
|
-
'
|
|
594
|
-
'
|
|
595
|
-
'
|
|
596
|
-
'
|
|
597
|
-
|
|
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',
|
|
597
|
+
// A lone number is treated as a month; the day defaults to the 1st and the year to the current year
|
|
598
|
+
// (e.g. "11" -> Nov 1 of this year). Listed last so it never shadows the more specific formats above.
|
|
599
|
+
'M'
|
|
598
600
|
]; }
|
|
599
601
|
/**
|
|
600
602
|
* User input formats that we will parse into a date
|
|
@@ -618,44 +620,58 @@ class DateTimeHelper {
|
|
|
618
620
|
"yyyyDDmm"
|
|
619
621
|
]; }
|
|
620
622
|
/**
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
'
|
|
628
|
-
'
|
|
629
|
-
'
|
|
630
|
-
'
|
|
631
|
-
'
|
|
632
|
-
'
|
|
633
|
-
|
|
634
|
-
|
|
623
|
+
* Luxon parse formats for the day-first preference. Separator characters
|
|
624
|
+
* in the input are normalized to a hyphen before matching (see {@link parseWithFormats}).
|
|
625
|
+
*/
|
|
626
|
+
static { this.luxonDateFirstParseFormats = [
|
|
627
|
+
'd-M',
|
|
628
|
+
'dd-MM',
|
|
629
|
+
'd-M-yy',
|
|
630
|
+
'dd-MM-yy',
|
|
631
|
+
'ddMMyyyy',
|
|
632
|
+
'yyyyMMdd',
|
|
633
|
+
'yyyy-MM-dd',
|
|
634
|
+
'dd-MM-yyyy',
|
|
635
|
+
// A lone number is treated as a month; the day defaults to the 1st and the year to the current year
|
|
636
|
+
// (e.g. "11" -> Nov 1 of this year). Listed last so it never shadows the more specific formats above.
|
|
637
|
+
'M'
|
|
635
638
|
]; }
|
|
636
639
|
/**
|
|
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,
|
|
640
|
+
* Luxon parse formats for medium/long date strings (e.g. "Jan 5, 2024").
|
|
641
|
+
* Shared by date-first and month-first preferences because the month is
|
|
642
|
+
* not numeric, so the order is unambiguous.
|
|
643
|
+
*/
|
|
644
|
+
static { this.luxonMedAndLongDateFormats = [
|
|
645
|
+
// Moment was forgiving with leading zeros (`DD` matched both `9` and `09`);
|
|
646
|
+
// Luxon's `dd` is strict, so single-digit `d` variants are listed explicitly.
|
|
647
|
+
'd MMM',
|
|
648
|
+
'dd MMM',
|
|
649
|
+
'MMM d',
|
|
650
|
+
'MMM dd',
|
|
651
|
+
'd MMM yy',
|
|
652
|
+
'dd MMM yy',
|
|
653
|
+
'd MMM yyyy',
|
|
654
|
+
'dd MMM yyyy',
|
|
655
|
+
'd MMMM yyyy',
|
|
656
|
+
'dd MMMM yyyy',
|
|
657
|
+
'MMM d, yy',
|
|
658
|
+
'MMM d, yyyy',
|
|
659
|
+
'MMM dd, yyyy',
|
|
660
|
+
'MMMM d, yyyy',
|
|
661
|
+
'MMMM dd, yyyy',
|
|
662
|
+
// Space-separated month-day-year without a comma (e.g. "Apr 21 1998", "April 21 1998").
|
|
663
|
+
'MMM d yy',
|
|
664
|
+
'MMM dd yy',
|
|
665
|
+
'MMM d yyyy',
|
|
666
|
+
'MMM dd yyyy',
|
|
667
|
+
'MMMM d yyyy',
|
|
668
|
+
'MMMM dd yyyy',
|
|
669
|
+
'MMM yy',
|
|
670
|
+
'MMM yyyy',
|
|
671
|
+
'MMMM yyyy',
|
|
672
|
+
'MMM, yy',
|
|
673
|
+
'MMM, yyyy',
|
|
674
|
+
'MMMM, yyyy',
|
|
659
675
|
]; }
|
|
660
676
|
/**
|
|
661
677
|
* Format to display the time portion of a datetime
|
|
@@ -664,6 +680,103 @@ class DateTimeHelper {
|
|
|
664
680
|
///////////////////////////////////////////////////////
|
|
665
681
|
// METHODS
|
|
666
682
|
///////////////////////////////////////////////////////
|
|
683
|
+
/**
|
|
684
|
+
* Convert any date-like value into a Luxon {@link DateTime}. Strings are parsed
|
|
685
|
+
* as ISO 8601; numbers are treated as epoch milliseconds. Returns an invalid
|
|
686
|
+
* DateTime when the input is null/undefined.
|
|
687
|
+
*/
|
|
688
|
+
static toDateTime(value) {
|
|
689
|
+
if (value === null || value === undefined) {
|
|
690
|
+
return DateTime.invalid('null or undefined');
|
|
691
|
+
}
|
|
692
|
+
if (DateTime.isDateTime(value)) {
|
|
693
|
+
return value;
|
|
694
|
+
}
|
|
695
|
+
if (value instanceof Date) {
|
|
696
|
+
return DateTime.fromJSDate(value);
|
|
697
|
+
}
|
|
698
|
+
if (typeof value === 'number') {
|
|
699
|
+
return DateTime.fromMillis(value);
|
|
700
|
+
}
|
|
701
|
+
return DateTime.fromISO(value);
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Translate a moment-style format string (e.g. `MM/DD/YYYY HH:mm:ss A`) into
|
|
705
|
+
* the Luxon equivalent (`MM/dd/yyyy HH:mm:ss a`). Use this when format strings
|
|
706
|
+
* originate from external sources (such as user preferences) that still use
|
|
707
|
+
* moment tokens.
|
|
708
|
+
*
|
|
709
|
+
* Only the tokens currently in use across this library are translated:
|
|
710
|
+
* `Y`→`y`, `D`→`d`, `A`→`a`. `M`, `H`, `h`, `m`, `s` are identical between
|
|
711
|
+
* the two libraries.
|
|
712
|
+
*/
|
|
713
|
+
static momentToLuxonFormat(format) {
|
|
714
|
+
return format
|
|
715
|
+
.replace(/Y/g, 'y')
|
|
716
|
+
.replace(/D/g, 'd')
|
|
717
|
+
.replace(/A/g, 'a');
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Format a date-like value using a moment-style format string. The format
|
|
721
|
+
* string is automatically translated to Luxon tokens, so callers can keep
|
|
722
|
+
* passing the same preference strings (e.g. `MM/DD/YYYY HH:mm:ss`).
|
|
723
|
+
*
|
|
724
|
+
* When `displayInUTC` is true, string inputs without zone info are parsed
|
|
725
|
+
* as UTC (matching `moment.utc(str)`), and all other inputs are shifted to
|
|
726
|
+
* the UTC zone for display. Returns an empty string for invalid input.
|
|
727
|
+
*
|
|
728
|
+
* Moment's lowercase `a` token produces lowercase `am`/`pm`, but Luxon's
|
|
729
|
+
* `a` is locale-aware and emits uppercase `AM`/`PM` in en-US. When the
|
|
730
|
+
* incoming format uses lowercase `a` (and not uppercase `A`), the meridiem
|
|
731
|
+
* in the output is lowercased to preserve the moment contract for user
|
|
732
|
+
* preferences like `h:mm:ss a` that are stored externally.
|
|
733
|
+
*/
|
|
734
|
+
static formatDate(date, momentFormat, displayInUTC = false) {
|
|
735
|
+
let dt;
|
|
736
|
+
if (displayInUTC && typeof date === 'string') {
|
|
737
|
+
dt = DateTime.fromISO(date, { zone: 'utc' });
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
dt = this.toDateTime(date);
|
|
741
|
+
if (displayInUTC) {
|
|
742
|
+
dt = dt.setZone('utc');
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
if (!dt.isValid)
|
|
746
|
+
return '';
|
|
747
|
+
let result = dt.toFormat(this.momentToLuxonFormat(momentFormat));
|
|
748
|
+
if (momentFormat.includes('a') && !momentFormat.includes('A')) {
|
|
749
|
+
result = result.replace(/AM|PM/g, m => m.toLowerCase());
|
|
750
|
+
}
|
|
751
|
+
return result;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Parse a string against a list of format patterns. Returns the first
|
|
755
|
+
* successful parse as a {@link DateTime} (which may be invalid if none match).
|
|
756
|
+
*
|
|
757
|
+
* Format strings may use either Luxon or moment tokens — each pattern is
|
|
758
|
+
* run through {@link momentToLuxonFormat} before matching, so callers can
|
|
759
|
+
* keep passing arrays like `['M/D/YYYY']` from previously moment-based code.
|
|
760
|
+
*
|
|
761
|
+
* Mirrors moment's behavior of ignoring separator characters by normalizing
|
|
762
|
+
* `/`, `.` and `-` in both input and patterns before matching.
|
|
763
|
+
*/
|
|
764
|
+
static parseWithFormats(value, formats) {
|
|
765
|
+
const normalize = (s) => s.replace(/[\/.\-]/g, '-');
|
|
766
|
+
// Strip surrounding whitespace and separators from the input so a partial entry with a
|
|
767
|
+
// trailing (or leading) separator still matches — e.g. "11/" normalizes to "11", which
|
|
768
|
+
// parses via the month-only format to Nov 1 of the current year. Internal separators are
|
|
769
|
+
// preserved, so full dates like "Apr 21 1998" are unaffected.
|
|
770
|
+
const normalizedValue = normalize(value).replace(/^[\s-]+|[\s-]+$/g, '');
|
|
771
|
+
for (const format of formats) {
|
|
772
|
+
const luxonFormat = this.momentToLuxonFormat(format);
|
|
773
|
+
const dt = DateTime.fromFormat(normalizedValue, normalize(luxonFormat));
|
|
774
|
+
if (dt.isValid) {
|
|
775
|
+
return dt;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return DateTime.invalid('no matching format');
|
|
779
|
+
}
|
|
667
780
|
/**
|
|
668
781
|
* Return true if @see date is equal to the @see endOfTime
|
|
669
782
|
*/
|
|
@@ -675,7 +788,7 @@ class DateTimeHelper {
|
|
|
675
788
|
* Compare two dates and return true if they represent the same year, month, and day (time is ignored).
|
|
676
789
|
*/
|
|
677
790
|
static isSameDay(date1, date2) {
|
|
678
|
-
return
|
|
791
|
+
return this.toDateTime(date1).hasSame(this.toDateTime(date2), 'day');
|
|
679
792
|
}
|
|
680
793
|
/**
|
|
681
794
|
* Get the parse formats based on the given date format. If no date format is
|
|
@@ -694,19 +807,19 @@ class DateTimeHelper {
|
|
|
694
807
|
return dateFormat ? map[dateFormat] : this.monthFirstParseFormats;
|
|
695
808
|
}
|
|
696
809
|
/**
|
|
697
|
-
* Get the
|
|
810
|
+
* Get the Luxon parse formats based on the given date format. If no date format is
|
|
698
811
|
* given, or we don't recognize the format, return the month first parse formats.
|
|
699
812
|
*/
|
|
700
|
-
static
|
|
813
|
+
static getLuxonParseFormats(dateFormat) {
|
|
701
814
|
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.
|
|
815
|
+
'MM/DD/YYYY': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
816
|
+
'MM-DD-YYYY': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
817
|
+
'DD/MM/YYYY': [...this.luxonDateFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
818
|
+
'DD-MM-YYYY': [...this.luxonDateFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
819
|
+
'YYYY/MM/DD': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats],
|
|
820
|
+
'YYYY-MM-DD': [...this.luxonMonthFirstParseFormats, ...this.luxonMedAndLongDateFormats]
|
|
708
821
|
};
|
|
709
|
-
return dateFormat ? map[dateFormat] : this.
|
|
822
|
+
return dateFormat ? map[dateFormat] : this.luxonMonthFirstParseFormats;
|
|
710
823
|
}
|
|
711
824
|
/**
|
|
712
825
|
* Get relationship start date (favoring date in partialFormState if exists)
|
|
@@ -729,28 +842,23 @@ class DateTimeHelper {
|
|
|
729
842
|
return null;
|
|
730
843
|
}
|
|
731
844
|
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
845
|
// If a start date is not provide, we'll use our beginning of time instead
|
|
743
846
|
startDate = startDate || this.beginningOfTime;
|
|
744
847
|
// If an end date is not provided, we'll use our end of time instead
|
|
745
848
|
endDate = endDate || this.endOfTime;
|
|
746
|
-
|
|
849
|
+
const d = this.toDateTime(date).startOf('day');
|
|
850
|
+
const s = this.toDateTime(startDate).startOf('day');
|
|
851
|
+
const e = this.toDateTime(endDate).startOf('day');
|
|
852
|
+
const afterStart = includeStart ? d >= s : d > s;
|
|
853
|
+
const beforeEnd = includeEnd ? d <= e : d < e;
|
|
854
|
+
return afterStart && beforeEnd;
|
|
747
855
|
}
|
|
748
856
|
static stringToDate(dateString) {
|
|
749
857
|
if (dateString === null || dateString === undefined) {
|
|
750
858
|
return dateString;
|
|
751
859
|
}
|
|
752
860
|
else {
|
|
753
|
-
return
|
|
861
|
+
return DateTime.fromISO(dateString).toJSDate();
|
|
754
862
|
}
|
|
755
863
|
}
|
|
756
864
|
}
|
|
@@ -764,15 +872,15 @@ class DateInputSelectionStrategyBase {
|
|
|
764
872
|
if (!value) {
|
|
765
873
|
return null;
|
|
766
874
|
}
|
|
767
|
-
|
|
768
|
-
if (date.isValid
|
|
875
|
+
let date = DateTimeHelper.parseWithFormats(value, parseFormats);
|
|
876
|
+
if (date.isValid) {
|
|
769
877
|
// 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
878
|
// This prevents the calendars from showing unhelpful dates that are in the distant past before the user finishes typing in the date.
|
|
771
879
|
// We don't do this modification when the real selection happens on textbox blur.
|
|
772
|
-
if (opts?.shiftToCurrentYearIfBelow && date.
|
|
773
|
-
date.set(
|
|
880
|
+
if (opts?.shiftToCurrentYearIfBelow && date < DateTime.fromJSDate(opts.shiftToCurrentYearIfBelow)) {
|
|
881
|
+
date = date.set({ year: DateTime.now().year });
|
|
774
882
|
}
|
|
775
|
-
return date.
|
|
883
|
+
return date.toJSDate();
|
|
776
884
|
}
|
|
777
885
|
return null;
|
|
778
886
|
}
|
|
@@ -854,7 +962,7 @@ class DaySelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
854
962
|
getNextSelection(selection) {
|
|
855
963
|
// Add a single day to the selection
|
|
856
964
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
857
|
-
return
|
|
965
|
+
return DateTime.fromJSDate(selection).plus({ days: 1 }).toJSDate();
|
|
858
966
|
}
|
|
859
967
|
// This shouldn't happen based on current date input flows, but if it does just return the selection as-is.
|
|
860
968
|
return selection;
|
|
@@ -862,7 +970,7 @@ class DaySelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
862
970
|
getPreviousSelection(selection) {
|
|
863
971
|
// Subtract a single day from the selection
|
|
864
972
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
865
|
-
return
|
|
973
|
+
return DateTime.fromJSDate(selection).minus({ days: 1 }).toJSDate();
|
|
866
974
|
}
|
|
867
975
|
// This shouldn't happen based on current date input flows, but if it does just return the selection as-is.
|
|
868
976
|
return selection;
|
|
@@ -893,19 +1001,19 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
893
1001
|
// Update the start and end dates to match a 28-day range, keying off the end date if parseFromEnd is true
|
|
894
1002
|
// parseFromEnd is true when a date is being entered from the end date textbox
|
|
895
1003
|
if (opts?.parseFromEnd) {
|
|
896
|
-
start =
|
|
1004
|
+
start = DateTime.fromJSDate(end).minus({ days: 27 }).toJSDate();
|
|
897
1005
|
}
|
|
898
1006
|
else {
|
|
899
|
-
end =
|
|
1007
|
+
end = DateTime.fromJSDate(start).plus({ days: 27 }).toJSDate();
|
|
900
1008
|
}
|
|
901
1009
|
}
|
|
902
1010
|
// If the start date is not provided, we'll use the end date to calculate the start date
|
|
903
1011
|
if (!start && end && !opts?.preventAutoComplete) {
|
|
904
|
-
start =
|
|
1012
|
+
start = DateTime.fromJSDate(end).minus({ days: 27 }).toJSDate();
|
|
905
1013
|
}
|
|
906
1014
|
// If the end date is not provided, we'll use the start date to calculate the end date
|
|
907
1015
|
if (!end && start && !opts?.preventAutoComplete) {
|
|
908
|
-
end =
|
|
1016
|
+
end = DateTime.fromJSDate(start).plus({ days: 27 }).toJSDate();
|
|
909
1017
|
}
|
|
910
1018
|
if (!start && !end) {
|
|
911
1019
|
return null;
|
|
@@ -916,7 +1024,7 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
916
1024
|
}
|
|
917
1025
|
getSelectionFromDate(date) {
|
|
918
1026
|
return {
|
|
919
|
-
start:
|
|
1027
|
+
start: DateTime.fromJSDate(date).minus({ days: 27 }).toJSDate(),
|
|
920
1028
|
end: date
|
|
921
1029
|
};
|
|
922
1030
|
}
|
|
@@ -926,7 +1034,7 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
926
1034
|
if (!previousSelection.end && previousSelection.start) {
|
|
927
1035
|
return {
|
|
928
1036
|
start: previousSelection.start,
|
|
929
|
-
end:
|
|
1037
|
+
end: DateTime.fromJSDate(previousSelection.start).plus({ days: 27 }).toJSDate()
|
|
930
1038
|
};
|
|
931
1039
|
// If the range only has an end date, make the 28-day range end on that date
|
|
932
1040
|
}
|
|
@@ -943,9 +1051,10 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
943
1051
|
getNextSelection(selection) {
|
|
944
1052
|
// Move the selection to the next 28 days
|
|
945
1053
|
if (DateInput.isSelectionRange(selection) && selection.end) {
|
|
1054
|
+
const end = DateTime.fromJSDate(selection.end);
|
|
946
1055
|
return {
|
|
947
|
-
start:
|
|
948
|
-
end:
|
|
1056
|
+
start: end.plus({ days: 1 }).toJSDate(),
|
|
1057
|
+
end: end.plus({ days: 28 }).toJSDate()
|
|
949
1058
|
};
|
|
950
1059
|
}
|
|
951
1060
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
@@ -955,9 +1064,10 @@ class Last28DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
955
1064
|
getPreviousSelection(selection) {
|
|
956
1065
|
// Move the selection to the previous 28 days
|
|
957
1066
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1067
|
+
const start = DateTime.fromJSDate(selection.start);
|
|
958
1068
|
return {
|
|
959
|
-
start:
|
|
960
|
-
end:
|
|
1069
|
+
start: start.minus({ days: 28 }).toJSDate(),
|
|
1070
|
+
end: start.minus({ days: 1 }).toJSDate()
|
|
961
1071
|
};
|
|
962
1072
|
}
|
|
963
1073
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
@@ -990,19 +1100,19 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
990
1100
|
// Update the start and end dates to match a 7-day range, keying off the end date if parseFromEnd is true
|
|
991
1101
|
// parseFromEnd is true when a date is being entered from the end date textbox
|
|
992
1102
|
if (opts?.parseFromEnd) {
|
|
993
|
-
start =
|
|
1103
|
+
start = DateTime.fromJSDate(end).minus({ days: 6 }).toJSDate();
|
|
994
1104
|
}
|
|
995
1105
|
else {
|
|
996
|
-
end =
|
|
1106
|
+
end = DateTime.fromJSDate(start).plus({ days: 6 }).toJSDate();
|
|
997
1107
|
}
|
|
998
1108
|
}
|
|
999
1109
|
// If the start date is not provided, we'll use the end date to calculate the start date
|
|
1000
1110
|
if (!start && end && !opts?.preventAutoComplete) {
|
|
1001
|
-
start =
|
|
1111
|
+
start = DateTime.fromJSDate(end).minus({ days: 6 }).toJSDate();
|
|
1002
1112
|
}
|
|
1003
1113
|
// If the end date is not provided, we'll use the start date to calculate the end date
|
|
1004
1114
|
if (!end && start && !opts?.preventAutoComplete) {
|
|
1005
|
-
end =
|
|
1115
|
+
end = DateTime.fromJSDate(start).plus({ days: 6 }).toJSDate();
|
|
1006
1116
|
}
|
|
1007
1117
|
if (!start && !end) {
|
|
1008
1118
|
return null;
|
|
@@ -1014,7 +1124,7 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1014
1124
|
getSelectionFromDate(date) {
|
|
1015
1125
|
// Base the selection on the given date, moving back 6 days
|
|
1016
1126
|
return {
|
|
1017
|
-
start:
|
|
1127
|
+
start: DateTime.fromJSDate(date).minus({ days: 6 }).toJSDate(),
|
|
1018
1128
|
end: date
|
|
1019
1129
|
};
|
|
1020
1130
|
}
|
|
@@ -1024,7 +1134,7 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1024
1134
|
if (!previousSelection.end && previousSelection.start) {
|
|
1025
1135
|
return {
|
|
1026
1136
|
start: previousSelection.start,
|
|
1027
|
-
end:
|
|
1137
|
+
end: DateTime.fromJSDate(previousSelection.start).plus({ days: 6 }).toJSDate()
|
|
1028
1138
|
};
|
|
1029
1139
|
// Otherwise, create the new selection based on the end date backwards
|
|
1030
1140
|
}
|
|
@@ -1041,9 +1151,10 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1041
1151
|
getNextSelection(selection) {
|
|
1042
1152
|
// Shift the range forward by 7 days
|
|
1043
1153
|
if (DateInput.isSelectionRange(selection) && selection.end) {
|
|
1154
|
+
const end = DateTime.fromJSDate(selection.end);
|
|
1044
1155
|
return {
|
|
1045
|
-
start:
|
|
1046
|
-
end:
|
|
1156
|
+
start: end.plus({ days: 1 }).toJSDate(),
|
|
1157
|
+
end: end.plus({ days: 7 }).toJSDate()
|
|
1047
1158
|
};
|
|
1048
1159
|
}
|
|
1049
1160
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
@@ -1053,9 +1164,10 @@ class Last7DaysSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1053
1164
|
getPreviousSelection(selection) {
|
|
1054
1165
|
// Shift the range back 7 days
|
|
1055
1166
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1167
|
+
const start = DateTime.fromJSDate(selection.start);
|
|
1056
1168
|
return {
|
|
1057
|
-
start:
|
|
1058
|
-
end:
|
|
1169
|
+
start: start.minus({ days: 7 }).toJSDate(),
|
|
1170
|
+
end: start.minus({ days: 1 }).toJSDate()
|
|
1059
1171
|
};
|
|
1060
1172
|
}
|
|
1061
1173
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
@@ -1083,7 +1195,7 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1083
1195
|
// A single date selection shouldn't happen in this mode but it's simple enough to handle
|
|
1084
1196
|
const date = DateInput.isSelectionRange(selection) ? selection.start : selection;
|
|
1085
1197
|
return {
|
|
1086
|
-
textbox:
|
|
1198
|
+
textbox: date ? DateTime.fromJSDate(date).toFormat('MMM, yyyy') : null,
|
|
1087
1199
|
textbox2: null
|
|
1088
1200
|
};
|
|
1089
1201
|
}
|
|
@@ -1096,9 +1208,10 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1096
1208
|
return this.getSelectionFromDate(date);
|
|
1097
1209
|
}
|
|
1098
1210
|
getSelectionFromDate(date) {
|
|
1211
|
+
const dt = DateTime.fromJSDate(date);
|
|
1099
1212
|
return {
|
|
1100
|
-
start:
|
|
1101
|
-
end:
|
|
1213
|
+
start: dt.startOf('month').toJSDate(),
|
|
1214
|
+
end: dt.endOf('month').toJSDate()
|
|
1102
1215
|
};
|
|
1103
1216
|
}
|
|
1104
1217
|
getNewSelectionFromExisting(previousSelection) {
|
|
@@ -1118,8 +1231,8 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1118
1231
|
getNextSelection(selection) {
|
|
1119
1232
|
// Move the selection to the next month
|
|
1120
1233
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1121
|
-
const date =
|
|
1122
|
-
return this.getSelectionFromDate(date.
|
|
1234
|
+
const date = DateTime.fromJSDate(selection.start).plus({ months: 1 });
|
|
1235
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1123
1236
|
}
|
|
1124
1237
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
1125
1238
|
// If it does, just return the selection as-is.
|
|
@@ -1128,8 +1241,8 @@ class MonthSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1128
1241
|
getPreviousSelection(selection) {
|
|
1129
1242
|
// Move the selection to the previous month
|
|
1130
1243
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1131
|
-
const date =
|
|
1132
|
-
return this.getSelectionFromDate(date.
|
|
1244
|
+
const date = DateTime.fromJSDate(selection.start).minus({ months: 1 });
|
|
1245
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1133
1246
|
}
|
|
1134
1247
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
1135
1248
|
// If it does, just return the selection as-is.
|
|
@@ -1147,14 +1260,21 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1147
1260
|
this.validViewModes = ['quarter', 'year'];
|
|
1148
1261
|
this.showSecondaryTextbox = false;
|
|
1149
1262
|
this.showSecondaryCalendar = false;
|
|
1263
|
+
/**
|
|
1264
|
+
* Format of the quarter range shown in the textbox (see {@link formatSelection}), e.g. "Jan–Mar, 2023".
|
|
1265
|
+
* Included in parsing so the displayed value round-trips (Luxon parsing is strict and would otherwise
|
|
1266
|
+
* reject it, clearing the selection when the textbox is blurred). Both month tokens land in the same
|
|
1267
|
+
* quarter, so parsing keys off whichever the parser resolves.
|
|
1268
|
+
*/
|
|
1269
|
+
this.rangeParseFormats = ['MMM–MMM, yyyy', 'MMM–MMM, yy'];
|
|
1150
1270
|
}
|
|
1151
1271
|
formatSelection(selection) {
|
|
1152
1272
|
// Format the the quarter range as "MMM–MMM, YYYY"
|
|
1153
1273
|
// We only have one textbox in this mode
|
|
1154
1274
|
if (DateInput.isSelectionRange(selection)) {
|
|
1155
|
-
const start =
|
|
1156
|
-
const end =
|
|
1157
|
-
const year =
|
|
1275
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start).toFormat('MMM') : '';
|
|
1276
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end).toFormat('MMM') : '';
|
|
1277
|
+
const year = selection.end ? DateTime.fromJSDate(selection.end).toFormat('yyyy') : '';
|
|
1158
1278
|
return {
|
|
1159
1279
|
textbox: `${start}–${end}, ${year}`,
|
|
1160
1280
|
textbox2: null
|
|
@@ -1164,17 +1284,19 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1164
1284
|
return { textbox: null, textbox2: null };
|
|
1165
1285
|
}
|
|
1166
1286
|
parseTextboxValues(value, parseFormats, opts) {
|
|
1167
|
-
// Only one textbox is used in this mode
|
|
1168
|
-
|
|
1287
|
+
// Only one textbox is used in this mode. Try the quarter-range display format first, then fall back
|
|
1288
|
+
// to the standard single-date formats a user might type (e.g. "Feb 2023").
|
|
1289
|
+
const date = this.parseString(value.textbox, [...this.rangeParseFormats, ...parseFormats], opts);
|
|
1169
1290
|
if (!date) {
|
|
1170
1291
|
return null;
|
|
1171
1292
|
}
|
|
1172
1293
|
return this.getSelectionFromDate(date);
|
|
1173
1294
|
}
|
|
1174
1295
|
getSelectionFromDate(date) {
|
|
1296
|
+
const dt = DateTime.fromJSDate(date);
|
|
1175
1297
|
return {
|
|
1176
|
-
start:
|
|
1177
|
-
end:
|
|
1298
|
+
start: dt.startOf('quarter').toJSDate(),
|
|
1299
|
+
end: dt.endOf('quarter').toJSDate()
|
|
1178
1300
|
};
|
|
1179
1301
|
}
|
|
1180
1302
|
getNewSelectionFromExisting(previousSelection) {
|
|
@@ -1194,8 +1316,8 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1194
1316
|
getNextSelection(selection) {
|
|
1195
1317
|
// Move the selection to the next quarter
|
|
1196
1318
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1197
|
-
const date =
|
|
1198
|
-
return this.getSelectionFromDate(date.
|
|
1319
|
+
const date = DateTime.fromJSDate(selection.start).plus({ quarters: 1 });
|
|
1320
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1199
1321
|
}
|
|
1200
1322
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
1201
1323
|
// If it does, just return the selection as-is.
|
|
@@ -1204,8 +1326,8 @@ class QuarterSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1204
1326
|
getPreviousSelection(selection) {
|
|
1205
1327
|
// Move the selection to the previous quarter
|
|
1206
1328
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1207
|
-
const date =
|
|
1208
|
-
return this.getSelectionFromDate(date.
|
|
1329
|
+
const date = DateTime.fromJSDate(selection.start).minus({ quarters: 1 });
|
|
1330
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1209
1331
|
}
|
|
1210
1332
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
1211
1333
|
// If it does, just return the selection as-is.
|
|
@@ -1228,13 +1350,13 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1228
1350
|
if (!selection) {
|
|
1229
1351
|
return { textbox: null, textbox2: null };
|
|
1230
1352
|
}
|
|
1231
|
-
// We use
|
|
1353
|
+
// We use Luxon's DATE_MED preset here (equivalent to moment's 'll') so the formatted date follows the user's locale
|
|
1232
1354
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
1233
|
-
return { textbox:
|
|
1355
|
+
return { textbox: DateTime.fromJSDate(selection).toLocaleString(DateTime.DATE_MED), textbox2: null };
|
|
1234
1356
|
}
|
|
1235
1357
|
else {
|
|
1236
|
-
const start = selection.start ?
|
|
1237
|
-
const end = selection.end ?
|
|
1358
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start).toLocaleString(DateTime.DATE_MED) : null;
|
|
1359
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end).toLocaleString(DateTime.DATE_MED) : null;
|
|
1238
1360
|
return { textbox: start, textbox2: end };
|
|
1239
1361
|
}
|
|
1240
1362
|
}
|
|
@@ -1245,7 +1367,7 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1245
1367
|
// 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
1368
|
// 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
1369
|
// begin/end date they just entered.
|
|
1248
|
-
if (start && end &&
|
|
1370
|
+
if (start && end && DateTime.fromJSDate(start) > DateTime.fromJSDate(end)) {
|
|
1249
1371
|
if (opts?.parseFromEnd) {
|
|
1250
1372
|
start = null;
|
|
1251
1373
|
}
|
|
@@ -1263,18 +1385,19 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1263
1385
|
getSelectionFromDate(date, existingSelection) {
|
|
1264
1386
|
if (DateInput.isSelectionRange(existingSelection)) {
|
|
1265
1387
|
const { start, end } = existingSelection;
|
|
1388
|
+
const dDt = DateTime.fromJSDate(date);
|
|
1266
1389
|
if (start && !end) {
|
|
1267
1390
|
// 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
|
|
1391
|
+
return dDt < DateTime.fromJSDate(start) ? { start: date, end: start } : { start, end: date };
|
|
1269
1392
|
}
|
|
1270
1393
|
if (end && !start) {
|
|
1271
1394
|
// 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
|
|
1395
|
+
return dDt < DateTime.fromJSDate(end) ? { start: date, end } : { start: end, end: date };
|
|
1273
1396
|
}
|
|
1274
1397
|
}
|
|
1275
1398
|
else if (DateInput.isSelectionSingleDate(existingSelection)) {
|
|
1276
1399
|
// 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
|
|
1400
|
+
return DateTime.fromJSDate(date) < DateTime.fromJSDate(existingSelection) ? { start: date, end: existingSelection } : { start: existingSelection, end: date };
|
|
1278
1401
|
}
|
|
1279
1402
|
// If no selection exists or we already have a complete selection, start a new one with the selected date as the start date.
|
|
1280
1403
|
return { start: date, end: null };
|
|
@@ -1295,9 +1418,9 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1295
1418
|
// If we have a valid range, we'll shift the range to the date provided, using it as the end date
|
|
1296
1419
|
// The new selection will have the same length as the previous.
|
|
1297
1420
|
if (DateInput.isSelectionRange(existingSelection) && existingSelection.start && existingSelection.end) {
|
|
1298
|
-
const length =
|
|
1421
|
+
const length = Math.floor(DateTime.fromJSDate(existingSelection.end).diff(DateTime.fromJSDate(existingSelection.start), 'days').days);
|
|
1299
1422
|
return {
|
|
1300
|
-
start:
|
|
1423
|
+
start: DateTime.fromJSDate(date).minus({ days: length }).toJSDate(),
|
|
1301
1424
|
end: date
|
|
1302
1425
|
};
|
|
1303
1426
|
}
|
|
@@ -1309,10 +1432,11 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1309
1432
|
// We can only determine the next selection if we have a valid range
|
|
1310
1433
|
if (DateInput.isSelectionRange(selection) && selection.start && selection.end) {
|
|
1311
1434
|
// Shift the range forward by the number of days between the start and end dates
|
|
1312
|
-
const
|
|
1435
|
+
const end = DateTime.fromJSDate(selection.end);
|
|
1436
|
+
const length = Math.floor(end.diff(DateTime.fromJSDate(selection.start), 'days').days);
|
|
1313
1437
|
return {
|
|
1314
|
-
start:
|
|
1315
|
-
end:
|
|
1438
|
+
start: end.plus({ days: 1 }).toJSDate(),
|
|
1439
|
+
end: end.plus({ days: 1 + length }).toJSDate()
|
|
1316
1440
|
};
|
|
1317
1441
|
}
|
|
1318
1442
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
@@ -1323,10 +1447,11 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1323
1447
|
// We can only determine the previous selection if we have a valid range
|
|
1324
1448
|
if (DateInput.isSelectionRange(selection) && selection.start && selection.end) {
|
|
1325
1449
|
// Shift the range back by the number of days between the start and end dates
|
|
1326
|
-
const
|
|
1450
|
+
const start = DateTime.fromJSDate(selection.start);
|
|
1451
|
+
const length = Math.floor(DateTime.fromJSDate(selection.end).diff(start, 'days').days);
|
|
1327
1452
|
return {
|
|
1328
|
-
start:
|
|
1329
|
-
end:
|
|
1453
|
+
start: start.minus({ days: 1 + length }).toJSDate(),
|
|
1454
|
+
end: start.minus({ days: 1 }).toJSDate()
|
|
1330
1455
|
};
|
|
1331
1456
|
}
|
|
1332
1457
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
@@ -1336,31 +1461,33 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1336
1461
|
getPrimaryCalendarView(selection, minDate, maxDate, currentView) {
|
|
1337
1462
|
let viewDate;
|
|
1338
1463
|
if (DateInput.isSelectionRange(selection)) {
|
|
1339
|
-
|
|
1340
|
-
|
|
1464
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start) : null;
|
|
1465
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end) : null;
|
|
1466
|
+
const minDt = DateTime.fromJSDate(minDate);
|
|
1467
|
+
const maxDt = DateTime.fromJSDate(maxDate);
|
|
1341
1468
|
// Since we're in range mode, the primary calendar is mostly concerned with the start date
|
|
1342
1469
|
if (start) {
|
|
1343
1470
|
// 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.
|
|
1471
|
+
if (start.startOf('month') < minDt.startOf('month')) {
|
|
1345
1472
|
viewDate = minDate;
|
|
1346
1473
|
// If the start is after the max date, shift the view to the max date.
|
|
1347
1474
|
}
|
|
1348
|
-
else if (start.
|
|
1475
|
+
else if (start.startOf('month') >= maxDt.startOf('month')) {
|
|
1349
1476
|
// the secondary calendar will show the max date month.
|
|
1350
1477
|
// The primary calendar will show the month before the max date.
|
|
1351
|
-
viewDate =
|
|
1478
|
+
viewDate = maxDt.minus({ months: 1 }).toJSDate();
|
|
1352
1479
|
}
|
|
1353
1480
|
else {
|
|
1354
|
-
viewDate = start.
|
|
1481
|
+
viewDate = start.toJSDate();
|
|
1355
1482
|
}
|
|
1356
1483
|
}
|
|
1357
|
-
else if (end && end.
|
|
1484
|
+
else if (end && end.startOf('month') <= minDt.startOf('month')) {
|
|
1358
1485
|
// 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
1486
|
viewDate = minDate;
|
|
1360
1487
|
}
|
|
1361
|
-
else if (end && end.
|
|
1488
|
+
else if (end && end.startOf('month') <= DateTime.now().startOf('month')) {
|
|
1362
1489
|
// 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 =
|
|
1490
|
+
viewDate = end.minus({ months: 1 }).toJSDate();
|
|
1364
1491
|
}
|
|
1365
1492
|
else {
|
|
1366
1493
|
// Otherwise, show the current month.
|
|
@@ -1378,32 +1505,34 @@ class RangeSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1378
1505
|
getSecondaryCalendarView(selection, minDate, maxDate, currentView) {
|
|
1379
1506
|
let viewDate;
|
|
1380
1507
|
if (DateInput.isSelectionRange(selection)) {
|
|
1381
|
-
|
|
1382
|
-
|
|
1508
|
+
const start = selection.start ? DateTime.fromJSDate(selection.start) : null;
|
|
1509
|
+
const end = selection.end ? DateTime.fromJSDate(selection.end) : null;
|
|
1510
|
+
const minDt = DateTime.fromJSDate(minDate);
|
|
1511
|
+
const maxDt = DateTime.fromJSDate(maxDate);
|
|
1383
1512
|
// The secondary calendar is primarily concerned with the end date in the selection.
|
|
1384
1513
|
if (end) {
|
|
1385
|
-
if (end.
|
|
1514
|
+
if (end.startOf('month') > maxDt.startOf('month')) {
|
|
1386
1515
|
// If the end date is after the max date, shift the view to the max date.
|
|
1387
1516
|
viewDate = maxDate;
|
|
1388
1517
|
}
|
|
1389
|
-
else if (end.
|
|
1518
|
+
else if (end.startOf('month') <= minDt.startOf('month')) {
|
|
1390
1519
|
// If the end date is the same month or before the min date, shift the view to show
|
|
1391
1520
|
// the month after the min date. The primary calendar will show the min date month.
|
|
1392
|
-
viewDate =
|
|
1521
|
+
viewDate = minDt.plus({ months: 1 }).toJSDate();
|
|
1393
1522
|
}
|
|
1394
1523
|
else {
|
|
1395
1524
|
// Otherwise, show the end date month.
|
|
1396
|
-
viewDate = end.
|
|
1525
|
+
viewDate = end.toJSDate();
|
|
1397
1526
|
}
|
|
1398
1527
|
}
|
|
1399
|
-
else if (start && start.
|
|
1528
|
+
else if (start && start.startOf('month') >= maxDt.startOf('month')) {
|
|
1400
1529
|
// If we don't have an end date, and the start date is after the max date, show the max date month
|
|
1401
1530
|
viewDate = maxDate;
|
|
1402
1531
|
}
|
|
1403
|
-
else if (start && start.
|
|
1532
|
+
else if (start && start.startOf('month') >= DateTime.now().startOf('month')) {
|
|
1404
1533
|
// If we don't have an end date, and the start date is on or after the current month,
|
|
1405
1534
|
// show the month after the start date.
|
|
1406
|
-
viewDate =
|
|
1535
|
+
viewDate = start.plus({ months: 1 }).toJSDate();
|
|
1407
1536
|
}
|
|
1408
1537
|
else {
|
|
1409
1538
|
// Otherwise, show the current month.
|
|
@@ -1438,12 +1567,12 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1438
1567
|
// Only one date is needed for formatting since the ranges span a single year.
|
|
1439
1568
|
// There shouldn't be any case where there's only a single date but it's covered anyway.
|
|
1440
1569
|
const date = DateInput.isSelectionRange(selection) ? selection.start : selection;
|
|
1441
|
-
return { textbox:
|
|
1570
|
+
return { textbox: date ? DateTime.fromJSDate(date).toFormat('yyyy') : null, textbox2: null };
|
|
1442
1571
|
}
|
|
1443
1572
|
parseString(value, parseFormats, opts) {
|
|
1444
|
-
// Including '
|
|
1573
|
+
// Including 'yy' and 'yyyy' as valid formats for year input. These aren't included in the default parse
|
|
1445
1574
|
// formats because they cause issues with the default date parsing.
|
|
1446
|
-
return super.parseString(value, ['
|
|
1575
|
+
return super.parseString(value, ['yy', 'yyyy', ...parseFormats], opts);
|
|
1447
1576
|
}
|
|
1448
1577
|
parseTextboxValues(value, parseFormats, opts) {
|
|
1449
1578
|
// Only a single textbox is used in year mode
|
|
@@ -1454,9 +1583,10 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1454
1583
|
return this.getSelectionFromDate(date);
|
|
1455
1584
|
}
|
|
1456
1585
|
getSelectionFromDate(date) {
|
|
1586
|
+
const dt = DateTime.fromJSDate(date);
|
|
1457
1587
|
return {
|
|
1458
|
-
start:
|
|
1459
|
-
end:
|
|
1588
|
+
start: dt.startOf('year').toJSDate(),
|
|
1589
|
+
end: dt.endOf('year').toJSDate()
|
|
1460
1590
|
};
|
|
1461
1591
|
}
|
|
1462
1592
|
getNewSelectionFromExisting(previousSelection) {
|
|
@@ -1479,8 +1609,8 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1479
1609
|
getNextSelection(selection) {
|
|
1480
1610
|
// Move the selection to the next year
|
|
1481
1611
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1482
|
-
const date =
|
|
1483
|
-
return this.getSelectionFromDate(date.
|
|
1612
|
+
const date = DateTime.fromJSDate(selection.start).plus({ years: 1 });
|
|
1613
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1484
1614
|
}
|
|
1485
1615
|
// This shouldn't happen since the next stepper is disabled if the selection only has one date.
|
|
1486
1616
|
// If it does, just return the selection as-is.
|
|
@@ -1489,8 +1619,8 @@ class YearSelectionStrategy extends DateInputSelectionStrategyBase {
|
|
|
1489
1619
|
getPreviousSelection(selection) {
|
|
1490
1620
|
// Move the selection to the previous year
|
|
1491
1621
|
if (DateInput.isSelectionRange(selection) && selection.start) {
|
|
1492
|
-
const date =
|
|
1493
|
-
return this.getSelectionFromDate(date.
|
|
1622
|
+
const date = DateTime.fromJSDate(selection.start).minus({ years: 1 });
|
|
1623
|
+
return this.getSelectionFromDate(date.toJSDate());
|
|
1494
1624
|
}
|
|
1495
1625
|
// This shouldn't happen since the previous stepper is disabled if the selection only has one date.
|
|
1496
1626
|
// If it does, just return the selection as-is.
|
|
@@ -1529,10 +1659,10 @@ class DateDisplayPipe {
|
|
|
1529
1659
|
transform(date, showEndOfTime, showTime, showSeconds) {
|
|
1530
1660
|
let display = '';
|
|
1531
1661
|
let formatString = '';
|
|
1532
|
-
if (date &&
|
|
1662
|
+
if (date != null && DateTimeHelper.toDateTime(date).isValid && (showEndOfTime || !DateTimeHelper.isEndOfTime(date))) {
|
|
1533
1663
|
// use user-preferred formats
|
|
1534
1664
|
this.userPreferenceService.getPreferences().subscribe(result => {
|
|
1535
|
-
//if preferences exist then format date to users preference
|
|
1665
|
+
//if preferences exist then format date to users preference
|
|
1536
1666
|
//otherwise use the last user preference
|
|
1537
1667
|
if (result.preference) {
|
|
1538
1668
|
formatString = result.preference.dateFormat;
|
|
@@ -1546,7 +1676,7 @@ class DateDisplayPipe {
|
|
|
1546
1676
|
this.lastFormatString = formatString;
|
|
1547
1677
|
}
|
|
1548
1678
|
});
|
|
1549
|
-
display =
|
|
1679
|
+
display = DateTimeHelper.formatDate(date, this.lastFormatString);
|
|
1550
1680
|
}
|
|
1551
1681
|
return display;
|
|
1552
1682
|
}
|
|
@@ -1571,6 +1701,32 @@ var DateInput;
|
|
|
1571
1701
|
return !!selection && !isSelectionSingleDate(selection);
|
|
1572
1702
|
}
|
|
1573
1703
|
DateInput.isSelectionRange = isSelectionRange;
|
|
1704
|
+
/**
|
|
1705
|
+
* Coerces a selection into one backed by real {@link Date} objects.
|
|
1706
|
+
*
|
|
1707
|
+
* The form model is typed as `Date | Range`, but hosts commonly bind ISO date strings
|
|
1708
|
+
* (e.g. values straight off an API response). The display path tolerates strings via
|
|
1709
|
+
* Luxon parsing, but the calendar view builders pass the value to `DateTime.fromJSDate`,
|
|
1710
|
+
* which only accepts a `Date` — a string yields an Invalid Date and crashes the calendar
|
|
1711
|
+
* (`RangeError: Invalid time value`). Normalizing at the boundary lets all downstream
|
|
1712
|
+
* calendar/stepper logic rely on actual Dates. Invalid/unparseable values become null.
|
|
1713
|
+
*/
|
|
1714
|
+
function normalizeSelection(selection) {
|
|
1715
|
+
if (selection === null || selection === undefined) {
|
|
1716
|
+
return null;
|
|
1717
|
+
}
|
|
1718
|
+
if (isSelectionSingleDate(selection)) {
|
|
1719
|
+
const dt = DateTimeHelper.toDateTime(selection);
|
|
1720
|
+
return dt.isValid ? dt.toJSDate() : null;
|
|
1721
|
+
}
|
|
1722
|
+
const start = selection.start ? DateTimeHelper.toDateTime(selection.start) : null;
|
|
1723
|
+
const end = selection.end ? DateTimeHelper.toDateTime(selection.end) : null;
|
|
1724
|
+
return {
|
|
1725
|
+
start: start?.isValid ? start.toJSDate() : null,
|
|
1726
|
+
end: end?.isValid ? end.toJSDate() : null
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
DateInput.normalizeSelection = normalizeSelection;
|
|
1574
1730
|
class SelectionStrategies {
|
|
1575
1731
|
constructor(dateDisplayPipe) {
|
|
1576
1732
|
this.dateDisplayPipe = dateDisplayPipe;
|
|
@@ -1613,9 +1769,14 @@ class CalendarItemComponent {
|
|
|
1613
1769
|
this.today = false;
|
|
1614
1770
|
this.outsideActiveMonth = false;
|
|
1615
1771
|
}
|
|
1772
|
+
else if (this.item?.date) {
|
|
1773
|
+
const itemDt = DateTime.fromJSDate(this.item.date);
|
|
1774
|
+
this.today = itemDt.hasSame(DateTime.now(), 'day');
|
|
1775
|
+
this.outsideActiveMonth = !itemDt.hasSame(DateTime.fromJSDate(this.view.date), 'month');
|
|
1776
|
+
}
|
|
1616
1777
|
else {
|
|
1617
|
-
this.today =
|
|
1618
|
-
this.outsideActiveMonth =
|
|
1778
|
+
this.today = false;
|
|
1779
|
+
this.outsideActiveMonth = false;
|
|
1619
1780
|
}
|
|
1620
1781
|
if (this.item?.date) {
|
|
1621
1782
|
this.hidden = this.isHidden(this.item.date, this.minDate, this.maxDate, this.view.mode);
|
|
@@ -1629,24 +1790,30 @@ class CalendarItemComponent {
|
|
|
1629
1790
|
if (!date || !selection) {
|
|
1630
1791
|
return false;
|
|
1631
1792
|
}
|
|
1793
|
+
const unit = view ?? 'day';
|
|
1794
|
+
const dt = DateTime.fromJSDate(date);
|
|
1632
1795
|
if (DateInput.isSelectionSingleDate(selection)) {
|
|
1633
|
-
return
|
|
1796
|
+
return dt.hasSame(DateTime.fromJSDate(selection), unit);
|
|
1634
1797
|
}
|
|
1635
1798
|
else {
|
|
1636
1799
|
if (selection.start && !selection.end) {
|
|
1637
|
-
return
|
|
1800
|
+
return dt.hasSame(DateTime.fromJSDate(selection.start), unit);
|
|
1638
1801
|
}
|
|
1639
1802
|
else if (!selection.start && selection.end) {
|
|
1640
|
-
return
|
|
1803
|
+
return dt.hasSame(DateTime.fromJSDate(selection.end), unit);
|
|
1641
1804
|
}
|
|
1642
1805
|
else if (selection.start && selection.end) {
|
|
1643
|
-
|
|
1806
|
+
const d = dt.startOf(unit);
|
|
1807
|
+
const s = DateTime.fromJSDate(selection.start).startOf(unit);
|
|
1808
|
+
const e = DateTime.fromJSDate(selection.end).startOf(unit);
|
|
1809
|
+
return d >= s && d <= e;
|
|
1644
1810
|
}
|
|
1645
1811
|
}
|
|
1646
1812
|
return false;
|
|
1647
1813
|
}
|
|
1648
1814
|
isHidden(date, minDate, maxDate, view) {
|
|
1649
|
-
|
|
1815
|
+
const d = DateTime.fromJSDate(date).startOf(view);
|
|
1816
|
+
return d < DateTime.fromJSDate(minDate).startOf(view) || d > DateTime.fromJSDate(maxDate).startOf(view);
|
|
1650
1817
|
}
|
|
1651
1818
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CalendarItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1652
1819
|
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 +1862,12 @@ class CalendarComponent {
|
|
|
1695
1862
|
this.viewChange = new EventEmitter();
|
|
1696
1863
|
/** Array of calendar item rows to display in the calendar. */
|
|
1697
1864
|
this.calendarItems = [];
|
|
1698
|
-
/** Weekday labels to show at the top of the calendar in day view. */
|
|
1699
|
-
this.weekDays =
|
|
1865
|
+
/** Weekday labels to show at the top of the calendar in day view. Starts on Sunday to match the calendar grid layout. */
|
|
1866
|
+
this.weekDays = (() => {
|
|
1867
|
+
// Info.weekdays returns Monday-first; reorder so Sunday is first to match the calendar grid.
|
|
1868
|
+
const mondayFirst = Info.weekdays('short');
|
|
1869
|
+
return [mondayFirst[6], ...mondayFirst.slice(0, 6)].map(d => d.slice(0, 1));
|
|
1870
|
+
})();
|
|
1700
1871
|
this.disablePreviousButton = false;
|
|
1701
1872
|
this.disableNextButton = false;
|
|
1702
1873
|
// 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 +1891,19 @@ class CalendarComponent {
|
|
|
1720
1891
|
onNextClick() {
|
|
1721
1892
|
// If we're in day view, we're incrementing by month
|
|
1722
1893
|
// In month, quarter, and year views we're incrementing by year\
|
|
1723
|
-
const unit = this.view.mode === 'day' ? '
|
|
1894
|
+
const unit = this.view.mode === 'day' ? 'months' : 'years';
|
|
1724
1895
|
// In year view, we're moving by 16 years at a time. Otherwise we're just moving by 1 month/year.
|
|
1725
1896
|
const count = this.view.mode === 'year' ? 16 : 1;
|
|
1726
|
-
const goToDate =
|
|
1897
|
+
const goToDate = DateTime.fromJSDate(this.view.date).plus({ [unit]: count }).toJSDate();
|
|
1727
1898
|
this.drawCalendar({ mode: this.view.mode, date: goToDate });
|
|
1728
1899
|
}
|
|
1729
1900
|
onPreviousClick() {
|
|
1730
1901
|
// If we're in day view, we're incrementing by month
|
|
1731
1902
|
// In month, quarter, and year views we're incrementing by year
|
|
1732
|
-
const unit = this.view.mode === 'day' ? '
|
|
1903
|
+
const unit = this.view.mode === 'day' ? 'months' : 'years';
|
|
1733
1904
|
// In year view, we're moving by 16 years at a time. Otherwise we're just moving by 1 month/year.
|
|
1734
1905
|
const count = this.view.mode === 'year' ? 16 : 1;
|
|
1735
|
-
const goToDate =
|
|
1906
|
+
const goToDate = DateTime.fromJSDate(this.view.date).minus({ [unit]: count }).toJSDate();
|
|
1736
1907
|
this.drawCalendar({ mode: this.view.mode, date: goToDate });
|
|
1737
1908
|
}
|
|
1738
1909
|
/** Switches the calendar to month view. */
|
|
@@ -1799,13 +1970,14 @@ class CalendarComponent {
|
|
|
1799
1970
|
this.view = view;
|
|
1800
1971
|
this.viewChange.emit(view);
|
|
1801
1972
|
}
|
|
1802
|
-
|
|
1803
|
-
this.
|
|
1973
|
+
const viewDt = DateTime.fromJSDate(this.view.date);
|
|
1974
|
+
this.month = viewDt.toFormat('MMM');
|
|
1975
|
+
this.year = viewDt.toFormat('yyyy');
|
|
1804
1976
|
this.calendarItems = this.getCalendarItems(this.view);
|
|
1805
1977
|
const startYear = this.calendarItems[0][0].date < this.minDate ? this.minDate : this.calendarItems[0][0].date;
|
|
1806
1978
|
const lastItem = this.getLastItem();
|
|
1807
1979
|
const endYear = lastItem.date > this.maxDate ? this.maxDate : lastItem.date;
|
|
1808
|
-
this.yearRange = `${
|
|
1980
|
+
this.yearRange = `${DateTime.fromJSDate(startYear).toFormat('yyyy')}–${DateTime.fromJSDate(endYear).toFormat('yyyy')}`;
|
|
1809
1981
|
this.updateNextPreviousStates();
|
|
1810
1982
|
}
|
|
1811
1983
|
getCalendarItems(view) {
|
|
@@ -1817,53 +1989,58 @@ class CalendarComponent {
|
|
|
1817
1989
|
}
|
|
1818
1990
|
}
|
|
1819
1991
|
getDayViewItems(activeDate) {
|
|
1820
|
-
// 6 rows of 7 days = 42 days
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1992
|
+
// 6 rows of 7 days = 42 days.
|
|
1993
|
+
// Use the start of the week of the first day of the month, anchored to Sunday to match the calendar grid.
|
|
1994
|
+
// Luxon's startOf('week') is Monday-based per ISO, so shift back to Sunday explicitly.
|
|
1995
|
+
const monthStart = DateTime.fromJSDate(activeDate).startOf('month');
|
|
1996
|
+
const sundayStart = monthStart.weekday === 7 ? monthStart : monthStart.startOf('week').minus({ days: 1 });
|
|
1997
|
+
return range(0, 6).map((r) => {
|
|
1998
|
+
return range(0, 7).map((d) => {
|
|
1999
|
+
const date = sundayStart.plus({ days: r * 7 + d });
|
|
1826
2000
|
return {
|
|
1827
|
-
date: date.
|
|
1828
|
-
label: date.
|
|
2001
|
+
date: date.toJSDate(),
|
|
2002
|
+
label: date.toFormat('d')
|
|
1829
2003
|
};
|
|
1830
2004
|
});
|
|
1831
2005
|
});
|
|
1832
2006
|
}
|
|
1833
2007
|
getMonthViewItems(activeDate) {
|
|
1834
2008
|
// 4 rows of 3 months = 12 months
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
2009
|
+
const yearStart = DateTime.fromJSDate(activeDate).startOf('year');
|
|
2010
|
+
return range(0, 4).map((r) => {
|
|
2011
|
+
return range(0, 3).map((m) => {
|
|
2012
|
+
const date = yearStart.plus({ months: r * 3 + m });
|
|
1838
2013
|
return {
|
|
1839
|
-
date: date.
|
|
1840
|
-
label: date.
|
|
2014
|
+
date: date.toJSDate(),
|
|
2015
|
+
label: date.toFormat('MMM')
|
|
1841
2016
|
};
|
|
1842
2017
|
});
|
|
1843
2018
|
});
|
|
1844
2019
|
}
|
|
1845
2020
|
getQuarterViewItems(activeDate) {
|
|
1846
2021
|
// 2 rows of 2 quarters = 4 quarters
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
const
|
|
2022
|
+
const yearStart = DateTime.fromJSDate(activeDate).startOf('year');
|
|
2023
|
+
return range(0, 2).map((r) => {
|
|
2024
|
+
return range(0, 2).map((q) => {
|
|
2025
|
+
const date = yearStart.plus({ quarters: r * 2 + q });
|
|
2026
|
+
const endDate = date.endOf('quarter');
|
|
1851
2027
|
return {
|
|
1852
|
-
date: date.
|
|
1853
|
-
label: `${date.
|
|
2028
|
+
date: date.toJSDate(),
|
|
2029
|
+
label: `${date.toFormat('MMM')}–${endDate.toFormat('MMM')}`
|
|
1854
2030
|
};
|
|
1855
2031
|
});
|
|
1856
2032
|
});
|
|
1857
2033
|
}
|
|
1858
2034
|
getYearViewItems(activeDate) {
|
|
1859
2035
|
// 4 rows of 4 years = 16 years
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
2036
|
+
// Subtracting 8 years to put the current active year at the beginning of the 3rd row.
|
|
2037
|
+
const yearStart = DateTime.fromJSDate(activeDate).startOf('year').minus({ years: 8 });
|
|
2038
|
+
return range(0, 4).map((r) => {
|
|
2039
|
+
return range(0, 4).map((y) => {
|
|
2040
|
+
const date = yearStart.plus({ years: r * 4 + y });
|
|
1864
2041
|
return {
|
|
1865
|
-
date: date.
|
|
1866
|
-
label: date.
|
|
2042
|
+
date: date.toJSDate(),
|
|
2043
|
+
label: date.toFormat('yyyy')
|
|
1867
2044
|
};
|
|
1868
2045
|
});
|
|
1869
2046
|
});
|
|
@@ -1873,24 +2050,20 @@ class CalendarComponent {
|
|
|
1873
2050
|
// We don't want to disable the next/previous buttons if the min or max date is within the
|
|
1874
2051
|
// next or previous view
|
|
1875
2052
|
const unit = this.view.mode === 'day' ? 'month' : 'year';
|
|
2053
|
+
const pluralUnit = this.view.mode === 'day' ? 'months' : 'years';
|
|
2054
|
+
const viewDt = DateTime.fromJSDate(this.view.date);
|
|
1876
2055
|
// When in year view, we need to subtract 9 years to determine if we're past the min date.
|
|
1877
2056
|
// The year view is 16 years long, and the current date is the 9th year in the view.
|
|
1878
2057
|
const subCount = this.view.mode === 'year' ? 9 : 1;
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
else {
|
|
1883
|
-
this.disablePreviousButton = false;
|
|
1884
|
-
}
|
|
2058
|
+
const prev = viewDt.minus({ [pluralUnit]: subCount }).startOf(unit);
|
|
2059
|
+
const minDt = DateTime.fromJSDate(this.minDate).startOf(unit);
|
|
2060
|
+
this.disablePreviousButton = prev < minDt;
|
|
1885
2061
|
// When in year view, we need to add 8 years to determine if we're past the max date.
|
|
1886
2062
|
// The year view is 16 years long, and the current date is the 9th year in the view.
|
|
1887
2063
|
const addCount = this.view.mode === 'year' ? 8 : 1;
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
else {
|
|
1892
|
-
this.disableNextButton = false;
|
|
1893
|
-
}
|
|
2064
|
+
const next = viewDt.plus({ [pluralUnit]: addCount }).startOf(unit);
|
|
2065
|
+
const maxDt = DateTime.fromJSDate(this.maxDate).startOf(unit);
|
|
2066
|
+
this.disableNextButton = next > maxDt;
|
|
1894
2067
|
}
|
|
1895
2068
|
getLastItem() {
|
|
1896
2069
|
const lastRow = this.calendarItems[this.calendarItems.length - 1];
|
|
@@ -2325,11 +2498,11 @@ class TooltipComponent {
|
|
|
2325
2498
|
this.overlayRef?.dispose();
|
|
2326
2499
|
}
|
|
2327
2500
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2328
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: TooltipComponent, isStandalone: false, selector: "ec-tooltip", host: { properties: { "style.--ec-tooltip-background-color": "this.backgroundColor", "style.--ec-tooltip-color-title": "this.titleColor" } }, ngImport: i0, template: "<article id=\"{{id}}\" class=\"py-3 position-{{position}}\" [class.show-arrow]=\"!hideArrow\">\n @if (title || subtitle) {\n <header class=\"mb-3\">\n <h1 class=\"text-heading-2 px-3 mb-0\">{{title}}</h1>\n <p class=\"text-caption-1 px-3 mb-0\">{{subtitle}}</p>\n </header>\n }\n\n @if (customContent) {\n <ng-container *ngTemplateOutlet=\"customContent\"></ng-container>\n } @else {\n <div class=\"text-body-1 px-3\" [innerHTML]=\"text\"></div>\n }\n\n\n @if (dismissible) {\n <ec-button id=\"tooltipDismiss\" type=\"icon\" icon=\"icon-cancel\" ariaLabel=\"Tooltip_DismissButton_SC\" (clicked)=\"hide()\"></ec-button>\n }\n</article>\n", styles: [":host{display:block;padding:.75rem}article{background-color:var(--ec-tooltip-background-color, #162F3B);color:var(--ec-tooltip-color, var(--ec-color-primary-light));border-radius:var(--ec-border-radius-card);position:relative;box-shadow:var(--ec-box-shadow-overlay);--ec-color-link: var(--ec-color-link-light)}article.show-arrow:after{content:\"\";height:0;width:0;border:.625rem solid transparent;display:block;position:absolute;pointer-events:none}article.show-arrow.position-top-left:after,article.show-arrow.position-top-center:after,article.show-arrow.position-top-right:after{bottom:-1.25rem;border-top-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-bottom-left:after,article.show-arrow.position-bottom-center:after,article.show-arrow.position-bottom-right:after{top:-1.25rem;border-bottom-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-top-left:after,article.show-arrow.position-bottom-left:after{right:1rem}article.show-arrow.position-top-right:after,article.show-arrow.position-bottom-right:after{left:1rem}article.show-arrow.position-top-center:after,article.show-arrow.position-bottom-center:after{right:50%;transform:translate(50%)}article.show-arrow.position-right-top:after,article.show-arrow.position-right-center:after,article.show-arrow.position-right-bottom:after{left:-1.25rem;border-right-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-left-center:after,article.show-arrow.position-left-bottom:after{right:-1.25rem;border-left-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-right-top:after{top:1rem}article.show-arrow.position-left-bottom:after,article.show-arrow.position-right-bottom:after{bottom:1rem}article.show-arrow.position-left-center:after,article.show-arrow.position-right-center:after{bottom:50%;transform:translateY(50%)}.text-heading-2{color:var(--ec-tooltip-color-title, var(--ec-color-primary-light))}.text-body-1{color:var(--ec-color-primary-light)}.text-body-1 ::ng-deep p:last-child{margin-bottom:0}.text-body-1 ::ng-deep a{font-weight:var(--ec-font-weight-bold)}.text-caption-1{color:var(--ec-color-secondary-light)}ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);position:absolute;top:.25rem;right:.25rem}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }] }); }
|
|
2501
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: TooltipComponent, isStandalone: false, selector: "ec-tooltip", host: { properties: { "style.--ec-tooltip-background-color": "this.backgroundColor", "style.--ec-tooltip-color-title": "this.titleColor" } }, ngImport: i0, template: "<article id=\"{{id}}\" role=\"tooltip\" class=\"py-3 position-{{position}}\" [class.show-arrow]=\"!hideArrow\">\n @if (title || subtitle) {\n <header class=\"mb-3\">\n <h1 class=\"text-heading-2 px-3 mb-0\">{{title}}</h1>\n <p class=\"text-caption-1 px-3 mb-0\">{{subtitle}}</p>\n </header>\n }\n\n @if (customContent) {\n <ng-container *ngTemplateOutlet=\"customContent\"></ng-container>\n } @else {\n <div class=\"text-body-1 px-3\" [innerHTML]=\"text\"></div>\n }\n\n\n @if (dismissible) {\n <ec-button id=\"tooltipDismiss\" type=\"icon\" icon=\"icon-cancel\" ariaLabel=\"Tooltip_DismissButton_SC\" (clicked)=\"hide()\"></ec-button>\n }\n</article>\n", styles: [":host{display:block;padding:.75rem}article{background-color:var(--ec-tooltip-background-color, #162F3B);color:var(--ec-tooltip-color, var(--ec-color-primary-light));border-radius:var(--ec-border-radius-card);position:relative;box-shadow:var(--ec-box-shadow-overlay);--ec-color-link: var(--ec-color-link-light)}article.show-arrow:after{content:\"\";height:0;width:0;border:.625rem solid transparent;display:block;position:absolute;pointer-events:none}article.show-arrow.position-top-left:after,article.show-arrow.position-top-center:after,article.show-arrow.position-top-right:after{bottom:-1.25rem;border-top-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-bottom-left:after,article.show-arrow.position-bottom-center:after,article.show-arrow.position-bottom-right:after{top:-1.25rem;border-bottom-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-top-left:after,article.show-arrow.position-bottom-left:after{right:1rem}article.show-arrow.position-top-right:after,article.show-arrow.position-bottom-right:after{left:1rem}article.show-arrow.position-top-center:after,article.show-arrow.position-bottom-center:after{right:50%;transform:translate(50%)}article.show-arrow.position-right-top:after,article.show-arrow.position-right-center:after,article.show-arrow.position-right-bottom:after{left:-1.25rem;border-right-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-left-center:after,article.show-arrow.position-left-bottom:after{right:-1.25rem;border-left-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-right-top:after{top:1rem}article.show-arrow.position-left-bottom:after,article.show-arrow.position-right-bottom:after{bottom:1rem}article.show-arrow.position-left-center:after,article.show-arrow.position-right-center:after{bottom:50%;transform:translateY(50%)}.text-heading-2{color:var(--ec-tooltip-color-title, var(--ec-color-primary-light))}.text-body-1{color:var(--ec-color-primary-light)}.text-body-1 ::ng-deep p:last-child{margin-bottom:0}.text-body-1 ::ng-deep a{font-weight:var(--ec-font-weight-bold)}.text-caption-1{color:var(--ec-color-secondary-light)}ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);position:absolute;top:.25rem;right:.25rem}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }] }); }
|
|
2329
2502
|
}
|
|
2330
2503
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TooltipComponent, decorators: [{
|
|
2331
2504
|
type: Component,
|
|
2332
|
-
args: [{ selector: 'ec-tooltip', standalone: false, template: "<article id=\"{{id}}\" class=\"py-3 position-{{position}}\" [class.show-arrow]=\"!hideArrow\">\n @if (title || subtitle) {\n <header class=\"mb-3\">\n <h1 class=\"text-heading-2 px-3 mb-0\">{{title}}</h1>\n <p class=\"text-caption-1 px-3 mb-0\">{{subtitle}}</p>\n </header>\n }\n\n @if (customContent) {\n <ng-container *ngTemplateOutlet=\"customContent\"></ng-container>\n } @else {\n <div class=\"text-body-1 px-3\" [innerHTML]=\"text\"></div>\n }\n\n\n @if (dismissible) {\n <ec-button id=\"tooltipDismiss\" type=\"icon\" icon=\"icon-cancel\" ariaLabel=\"Tooltip_DismissButton_SC\" (clicked)=\"hide()\"></ec-button>\n }\n</article>\n", styles: [":host{display:block;padding:.75rem}article{background-color:var(--ec-tooltip-background-color, #162F3B);color:var(--ec-tooltip-color, var(--ec-color-primary-light));border-radius:var(--ec-border-radius-card);position:relative;box-shadow:var(--ec-box-shadow-overlay);--ec-color-link: var(--ec-color-link-light)}article.show-arrow:after{content:\"\";height:0;width:0;border:.625rem solid transparent;display:block;position:absolute;pointer-events:none}article.show-arrow.position-top-left:after,article.show-arrow.position-top-center:after,article.show-arrow.position-top-right:after{bottom:-1.25rem;border-top-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-bottom-left:after,article.show-arrow.position-bottom-center:after,article.show-arrow.position-bottom-right:after{top:-1.25rem;border-bottom-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-top-left:after,article.show-arrow.position-bottom-left:after{right:1rem}article.show-arrow.position-top-right:after,article.show-arrow.position-bottom-right:after{left:1rem}article.show-arrow.position-top-center:after,article.show-arrow.position-bottom-center:after{right:50%;transform:translate(50%)}article.show-arrow.position-right-top:after,article.show-arrow.position-right-center:after,article.show-arrow.position-right-bottom:after{left:-1.25rem;border-right-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-left-center:after,article.show-arrow.position-left-bottom:after{right:-1.25rem;border-left-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-right-top:after{top:1rem}article.show-arrow.position-left-bottom:after,article.show-arrow.position-right-bottom:after{bottom:1rem}article.show-arrow.position-left-center:after,article.show-arrow.position-right-center:after{bottom:50%;transform:translateY(50%)}.text-heading-2{color:var(--ec-tooltip-color-title, var(--ec-color-primary-light))}.text-body-1{color:var(--ec-color-primary-light)}.text-body-1 ::ng-deep p:last-child{margin-bottom:0}.text-body-1 ::ng-deep a{font-weight:var(--ec-font-weight-bold)}.text-caption-1{color:var(--ec-color-secondary-light)}ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);position:absolute;top:.25rem;right:.25rem}\n"] }]
|
|
2505
|
+
args: [{ selector: 'ec-tooltip', standalone: false, template: "<article id=\"{{id}}\" role=\"tooltip\" class=\"py-3 position-{{position}}\" [class.show-arrow]=\"!hideArrow\">\n @if (title || subtitle) {\n <header class=\"mb-3\">\n <h1 class=\"text-heading-2 px-3 mb-0\">{{title}}</h1>\n <p class=\"text-caption-1 px-3 mb-0\">{{subtitle}}</p>\n </header>\n }\n\n @if (customContent) {\n <ng-container *ngTemplateOutlet=\"customContent\"></ng-container>\n } @else {\n <div class=\"text-body-1 px-3\" [innerHTML]=\"text\"></div>\n }\n\n\n @if (dismissible) {\n <ec-button id=\"tooltipDismiss\" type=\"icon\" icon=\"icon-cancel\" ariaLabel=\"Tooltip_DismissButton_SC\" (clicked)=\"hide()\"></ec-button>\n }\n</article>\n", styles: [":host{display:block;padding:.75rem}article{background-color:var(--ec-tooltip-background-color, #162F3B);color:var(--ec-tooltip-color, var(--ec-color-primary-light));border-radius:var(--ec-border-radius-card);position:relative;box-shadow:var(--ec-box-shadow-overlay);--ec-color-link: var(--ec-color-link-light)}article.show-arrow:after{content:\"\";height:0;width:0;border:.625rem solid transparent;display:block;position:absolute;pointer-events:none}article.show-arrow.position-top-left:after,article.show-arrow.position-top-center:after,article.show-arrow.position-top-right:after{bottom:-1.25rem;border-top-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-bottom-left:after,article.show-arrow.position-bottom-center:after,article.show-arrow.position-bottom-right:after{top:-1.25rem;border-bottom-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-top-left:after,article.show-arrow.position-bottom-left:after{right:1rem}article.show-arrow.position-top-right:after,article.show-arrow.position-bottom-right:after{left:1rem}article.show-arrow.position-top-center:after,article.show-arrow.position-bottom-center:after{right:50%;transform:translate(50%)}article.show-arrow.position-right-top:after,article.show-arrow.position-right-center:after,article.show-arrow.position-right-bottom:after{left:-1.25rem;border-right-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-left-center:after,article.show-arrow.position-left-bottom:after{right:-1.25rem;border-left-color:var(--ec-tooltip-background-color, #162F3B)}article.show-arrow.position-left-top:after,article.show-arrow.position-right-top:after{top:1rem}article.show-arrow.position-left-bottom:after,article.show-arrow.position-right-bottom:after{bottom:1rem}article.show-arrow.position-left-center:after,article.show-arrow.position-right-center:after{bottom:50%;transform:translateY(50%)}.text-heading-2{color:var(--ec-tooltip-color-title, var(--ec-color-primary-light))}.text-body-1{color:var(--ec-color-primary-light)}.text-body-1 ::ng-deep p:last-child{margin-bottom:0}.text-body-1 ::ng-deep a{font-weight:var(--ec-font-weight-bold)}.text-caption-1{color:var(--ec-color-secondary-light)}ec-button{--ec-button-color-icon: var(--ec-color-secondary-light);--ec-button-color-icon-hover: var(--ec-color-primary-light);--ec-background-color-hover: rgba(255,255,255,.15);position:absolute;top:.25rem;right:.25rem}\n"] }]
|
|
2333
2506
|
}], propDecorators: { backgroundColor: [{
|
|
2334
2507
|
type: HostBinding,
|
|
2335
2508
|
args: ['style.--ec-tooltip-background-color']
|
|
@@ -4274,11 +4447,11 @@ class ViewOverlayComponent {
|
|
|
4274
4447
|
}
|
|
4275
4448
|
}
|
|
4276
4449
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ViewOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4277
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ViewOverlayComponent, isStandalone: false, selector: "[ecOverlay]", inputs: { status: "status", message: "message", action: "action", noDataTemplate: "noDataTemplate", displayAsMask: "displayAsMask", overlayClassList: "overlayClassList" }, ngImport: i0, template: "<!-- Transcluded Content -->\n@if (displayAsMask || (!displayAsMask && status === 'hasData')) {\n <ng-content></ng-content>\n}\n<!--Used by GI tests to know the overlay status whether we use ngIf or mask version. No visual impact-->\n<span [hidden]=\"true\"\nclass=\"overlay-status-{{status}}\"></span>\n<!-- Overlay goes last so it is rendered on top of preceding content due to source order -->\n@if (status !== 'hasData') {\n <div\n class=\"overlay flex-grow {{overlayClassList}}\"\n\t [ngClass]=\"{'not-mask': !displayAsMask,\n\t\t\t\t'overlay-error': status === 'error',\n\t\t\t\t'overlay-nodata': status === 'noData',\n\t\t\t\t'overlay-pending': status === 'pending'}\">\n <!--Pending Spinner-->\n <ec-spinner [hidden]=\"status !== 'pending'\"></ec-spinner>\n @if (status === 'noData' && noDataTemplate) {\n <ng-container *ngTemplateOutlet=\"noDataTemplate\"></ng-container>\n }\n @if ((status === 'noData' && !noDataTemplate) || status !== 'noData') {\n <!--Status Message-->\n @if (message) {\n <div id=\"statusMessage\"\n class=\"message\"\n [ngClass]=\"{'error': status === 'error', 'mt-1': status === 'pending'}\"\n [innerHtml]=\"message | translate\">\n </div>\n }\n <!-- Action -->\n @if (action?.onClick) {\n <ec-button type=\"common\"\n class=\"mt-3\"\n [icon]=\"action?.icon\"\n (clicked)=\"actionClicked($event)\"\n [label]=\"action?.label\"\n [hidden]=\"status === 'pending'\">\n </ec-button>\n }\n }\n </div>\n}", styles: [":host{position:relative}:host(.bg-body)>.overlay{background-color:var(--ec-background-color-body)}:host(.bg-body).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}:host(.bg-content)>.overlay{background-color:var(--ec-background-color)}:host(.bg-content).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}.overlay{align-items:center;background-color:var(--ec-overlay-background-color, var(--ec-background-color));display:flex;flex-direction:column;justify-content:center;padding:3rem 4rem;z-index:var(--ec-z-index-overlay);position:absolute;inset:0}.overlay.not-mask{position:relative;min-height:100%}.message{color:var(--ec-color-secondary-dark);font-size:var(--ec-font-size-title)}.message.error{color:var(--ec-color-danger);font-size:var(--ec-font-size-title)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: SpinnerComponent, selector: "ec-spinner" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
|
|
4450
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ViewOverlayComponent, isStandalone: false, selector: "[ecOverlay]", inputs: { status: "status", message: "message", action: "action", noDataTemplate: "noDataTemplate", displayAsMask: "displayAsMask", overlayClassList: "overlayClassList" }, ngImport: i0, template: "<!-- Transcluded Content -->\n@if (displayAsMask || (!displayAsMask && status === 'hasData')) {\n <ng-content></ng-content>\n}\n<!--Used by GI tests to know the overlay status whether we use ngIf or mask version. No visual impact-->\n<span [hidden]=\"true\"\nclass=\"overlay-status-{{status}}\"></span>\n<!-- Overlay goes last so it is rendered on top of preceding content due to source order -->\n@if (status !== 'hasData') {\n <div\n class=\"overlay flex-grow {{overlayClassList}}\"\n [attr.role]=\"status === 'error' ? 'alert' : (status === 'pending' ? null : 'status')\"\n [attr.aria-live]=\"status === 'error' ? 'assertive' : (status === 'pending' ? null : 'polite')\"\n [attr.aria-atomic]=\"status === 'pending' ? null : 'true'\"\n\t [ngClass]=\"{'not-mask': !displayAsMask,\n\t\t\t\t'overlay-error': status === 'error',\n\t\t\t\t'overlay-nodata': status === 'noData',\n\t\t\t\t'overlay-pending': status === 'pending'}\">\n <!--Pending Spinner-->\n <ec-spinner [hidden]=\"status !== 'pending'\"></ec-spinner>\n @if (status === 'noData' && noDataTemplate) {\n <ng-container *ngTemplateOutlet=\"noDataTemplate\"></ng-container>\n }\n @if ((status === 'noData' && !noDataTemplate) || status !== 'noData') {\n <!--Status Message-->\n @if (message) {\n <div id=\"statusMessage\"\n class=\"message\"\n [ngClass]=\"{'error': status === 'error', 'mt-1': status === 'pending'}\"\n [innerHtml]=\"message | translate\">\n </div>\n }\n <!-- Action -->\n @if (action?.onClick) {\n <ec-button type=\"common\"\n class=\"mt-3\"\n [icon]=\"action?.icon\"\n (clicked)=\"actionClicked($event)\"\n [label]=\"action?.label\"\n [hidden]=\"status === 'pending'\">\n </ec-button>\n }\n }\n </div>\n}", styles: [":host{position:relative}:host(.bg-body)>.overlay{background-color:var(--ec-background-color-body)}:host(.bg-body).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}:host(.bg-content)>.overlay{background-color:var(--ec-background-color)}:host(.bg-content).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}.overlay{align-items:center;background-color:var(--ec-overlay-background-color, var(--ec-background-color));display:flex;flex-direction:column;justify-content:center;padding:3rem 4rem;z-index:var(--ec-z-index-overlay);position:absolute;inset:0}.overlay.not-mask{position:relative;min-height:100%}.message{color:var(--ec-color-secondary-dark);font-size:var(--ec-font-size-title)}.message.error{color:var(--ec-color-danger);font-size:var(--ec-font-size-title)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: SpinnerComponent, selector: "ec-spinner" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
|
|
4278
4451
|
}
|
|
4279
4452
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ViewOverlayComponent, decorators: [{
|
|
4280
4453
|
type: Component,
|
|
4281
|
-
args: [{ selector: '[ecOverlay]', standalone: false, template: "<!-- Transcluded Content -->\n@if (displayAsMask || (!displayAsMask && status === 'hasData')) {\n <ng-content></ng-content>\n}\n<!--Used by GI tests to know the overlay status whether we use ngIf or mask version. No visual impact-->\n<span [hidden]=\"true\"\nclass=\"overlay-status-{{status}}\"></span>\n<!-- Overlay goes last so it is rendered on top of preceding content due to source order -->\n@if (status !== 'hasData') {\n <div\n class=\"overlay flex-grow {{overlayClassList}}\"\n\t [ngClass]=\"{'not-mask': !displayAsMask,\n\t\t\t\t'overlay-error': status === 'error',\n\t\t\t\t'overlay-nodata': status === 'noData',\n\t\t\t\t'overlay-pending': status === 'pending'}\">\n <!--Pending Spinner-->\n <ec-spinner [hidden]=\"status !== 'pending'\"></ec-spinner>\n @if (status === 'noData' && noDataTemplate) {\n <ng-container *ngTemplateOutlet=\"noDataTemplate\"></ng-container>\n }\n @if ((status === 'noData' && !noDataTemplate) || status !== 'noData') {\n <!--Status Message-->\n @if (message) {\n <div id=\"statusMessage\"\n class=\"message\"\n [ngClass]=\"{'error': status === 'error', 'mt-1': status === 'pending'}\"\n [innerHtml]=\"message | translate\">\n </div>\n }\n <!-- Action -->\n @if (action?.onClick) {\n <ec-button type=\"common\"\n class=\"mt-3\"\n [icon]=\"action?.icon\"\n (clicked)=\"actionClicked($event)\"\n [label]=\"action?.label\"\n [hidden]=\"status === 'pending'\">\n </ec-button>\n }\n }\n </div>\n}", styles: [":host{position:relative}:host(.bg-body)>.overlay{background-color:var(--ec-background-color-body)}:host(.bg-body).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}:host(.bg-content)>.overlay{background-color:var(--ec-background-color)}:host(.bg-content).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}.overlay{align-items:center;background-color:var(--ec-overlay-background-color, var(--ec-background-color));display:flex;flex-direction:column;justify-content:center;padding:3rem 4rem;z-index:var(--ec-z-index-overlay);position:absolute;inset:0}.overlay.not-mask{position:relative;min-height:100%}.message{color:var(--ec-color-secondary-dark);font-size:var(--ec-font-size-title)}.message.error{color:var(--ec-color-danger);font-size:var(--ec-font-size-title)}\n"] }]
|
|
4454
|
+
args: [{ selector: '[ecOverlay]', standalone: false, template: "<!-- Transcluded Content -->\n@if (displayAsMask || (!displayAsMask && status === 'hasData')) {\n <ng-content></ng-content>\n}\n<!--Used by GI tests to know the overlay status whether we use ngIf or mask version. No visual impact-->\n<span [hidden]=\"true\"\nclass=\"overlay-status-{{status}}\"></span>\n<!-- Overlay goes last so it is rendered on top of preceding content due to source order -->\n@if (status !== 'hasData') {\n <div\n class=\"overlay flex-grow {{overlayClassList}}\"\n [attr.role]=\"status === 'error' ? 'alert' : (status === 'pending' ? null : 'status')\"\n [attr.aria-live]=\"status === 'error' ? 'assertive' : (status === 'pending' ? null : 'polite')\"\n [attr.aria-atomic]=\"status === 'pending' ? null : 'true'\"\n\t [ngClass]=\"{'not-mask': !displayAsMask,\n\t\t\t\t'overlay-error': status === 'error',\n\t\t\t\t'overlay-nodata': status === 'noData',\n\t\t\t\t'overlay-pending': status === 'pending'}\">\n <!--Pending Spinner-->\n <ec-spinner [hidden]=\"status !== 'pending'\"></ec-spinner>\n @if (status === 'noData' && noDataTemplate) {\n <ng-container *ngTemplateOutlet=\"noDataTemplate\"></ng-container>\n }\n @if ((status === 'noData' && !noDataTemplate) || status !== 'noData') {\n <!--Status Message-->\n @if (message) {\n <div id=\"statusMessage\"\n class=\"message\"\n [ngClass]=\"{'error': status === 'error', 'mt-1': status === 'pending'}\"\n [innerHtml]=\"message | translate\">\n </div>\n }\n <!-- Action -->\n @if (action?.onClick) {\n <ec-button type=\"common\"\n class=\"mt-3\"\n [icon]=\"action?.icon\"\n (clicked)=\"actionClicked($event)\"\n [label]=\"action?.label\"\n [hidden]=\"status === 'pending'\">\n </ec-button>\n }\n }\n </div>\n}", styles: [":host{position:relative}:host(.bg-body)>.overlay{background-color:var(--ec-background-color-body)}:host(.bg-body).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}:host(.bg-content)>.overlay{background-color:var(--ec-background-color)}:host(.bg-content).is-translucent>.overlay{background-color:var(--ec-background-color-overlay)}.overlay{align-items:center;background-color:var(--ec-overlay-background-color, var(--ec-background-color));display:flex;flex-direction:column;justify-content:center;padding:3rem 4rem;z-index:var(--ec-z-index-overlay);position:absolute;inset:0}.overlay.not-mask{position:relative;min-height:100%}.message{color:var(--ec-color-secondary-dark);font-size:var(--ec-font-size-title)}.message.error{color:var(--ec-color-danger);font-size:var(--ec-font-size-title)}\n"] }]
|
|
4282
4455
|
}], propDecorators: { status: [{
|
|
4283
4456
|
type: Input
|
|
4284
4457
|
}], message: [{
|
|
@@ -5334,7 +5507,7 @@ class DateInputComponent extends FormControlBase {
|
|
|
5334
5507
|
* Date parsing formats for user-entered dates. Defaults to month-first formats, but is updated in onInit
|
|
5335
5508
|
* to use the user's preferred date format.
|
|
5336
5509
|
*/
|
|
5337
|
-
this.parseFormats = DateTimeHelper.
|
|
5510
|
+
this.parseFormats = DateTimeHelper.getLuxonParseFormats();
|
|
5338
5511
|
}
|
|
5339
5512
|
ngOnChanges(changes) {
|
|
5340
5513
|
if (changes.selectionMode && !changes.selectionMode.isFirstChange()) {
|
|
@@ -5350,12 +5523,15 @@ class DateInputComponent extends FormControlBase {
|
|
|
5350
5523
|
this.onFormModelStatusChanges();
|
|
5351
5524
|
this.onFormModelValueChanges();
|
|
5352
5525
|
this.onTextboxValueChanges();
|
|
5353
|
-
// Sync the initial disabled status and value of the textbox
|
|
5526
|
+
// Sync the initial disabled status and value of the textbox.
|
|
5527
|
+
// Normalize the form model value so any ISO date strings the host bound to the model
|
|
5528
|
+
// become real Dates before they reach the calendar/stepper logic (see normalizeSelection).
|
|
5354
5529
|
this.syncTextboxControlDisabledStatus(this.formModel.status);
|
|
5355
|
-
const
|
|
5530
|
+
const initialSelection = DateInput.normalizeSelection(this.formModel.value);
|
|
5531
|
+
const initialDisplayValue = this.selectionStrategy.formatSelection(initialSelection);
|
|
5356
5532
|
this.textboxGroup.patchValue(initialDisplayValue, { emitEvent: false });
|
|
5357
5533
|
// Update the calendar selection and view based on the initial form model value
|
|
5358
|
-
this.calendarSelection =
|
|
5534
|
+
this.calendarSelection = initialSelection;
|
|
5359
5535
|
this.updateCalendars(this.calendarSelection);
|
|
5360
5536
|
this.updateSteppers(this.calendarSelection);
|
|
5361
5537
|
}
|
|
@@ -5451,7 +5627,7 @@ class DateInputComponent extends FormControlBase {
|
|
|
5451
5627
|
goToToday() {
|
|
5452
5628
|
// If both calendars are visible, show today in the secondary calendar and the month before in the primary calendar.
|
|
5453
5629
|
if (this.selectionStrategy.showSecondaryCalendar) {
|
|
5454
|
-
this.primaryCalendarView = { mode: 'day', date:
|
|
5630
|
+
this.primaryCalendarView = { mode: 'day', date: DateTime.now().minus({ months: 1 }).toJSDate() };
|
|
5455
5631
|
this.secondaryCalendarView = { mode: 'day', date: new Date() };
|
|
5456
5632
|
// If we're in a single date mode, show today in the primary calendar.
|
|
5457
5633
|
}
|
|
@@ -5500,11 +5676,14 @@ class DateInputComponent extends FormControlBase {
|
|
|
5500
5676
|
// Update the calendar selection textbox value with a formatted date when the form model changes.
|
|
5501
5677
|
// This is triggered by the user selecting a date from the calendar or when the textbox is blurred.
|
|
5502
5678
|
this.formModel.valueChanges.pipe(takeUntil(this.componentDestroyed)).subscribe(value => {
|
|
5503
|
-
|
|
5679
|
+
// Normalize first: the host may set an ISO date string on the model (e.g. an API value),
|
|
5680
|
+
// and the calendar logic requires real Dates to avoid an Invalid Date crash.
|
|
5681
|
+
const selection = DateInput.normalizeSelection(value);
|
|
5682
|
+
const displayValue = this.selectionStrategy.formatSelection(selection);
|
|
5504
5683
|
// Don't emit an event when setting the textbox value to avoid circular updates between the textbox and form model.
|
|
5505
5684
|
this.textboxGroup.patchValue(displayValue, { emitEvent: false });
|
|
5506
|
-
this.updateCalendars(
|
|
5507
|
-
this.updateSteppers(
|
|
5685
|
+
this.updateCalendars(selection);
|
|
5686
|
+
this.updateSteppers(selection);
|
|
5508
5687
|
});
|
|
5509
5688
|
}
|
|
5510
5689
|
onTextboxValueChanges() {
|
|
@@ -5584,7 +5763,7 @@ class DateInputComponent extends FormControlBase {
|
|
|
5584
5763
|
const { preference } = await lastValueFrom(this.userPreferenceService.getPreferences());
|
|
5585
5764
|
const dateFormat = preference?.dateFormat;
|
|
5586
5765
|
this.placeholder = dateFormat ?? this.placeholder;
|
|
5587
|
-
this.parseFormats = DateTimeHelper.
|
|
5766
|
+
this.parseFormats = DateTimeHelper.getLuxonParseFormats(dateFormat);
|
|
5588
5767
|
}
|
|
5589
5768
|
/** Focuses the date input. */
|
|
5590
5769
|
focusInput() {
|
|
@@ -5604,10 +5783,10 @@ class DateInputComponent extends FormControlBase {
|
|
|
5604
5783
|
// This would cause the dates in the other calendar to be unselectable if we were to
|
|
5605
5784
|
// update the min/max dates in these cases.
|
|
5606
5785
|
if (this.primaryCalendarView?.mode === 'day') {
|
|
5607
|
-
this.secondaryCalendarMinDate =
|
|
5786
|
+
this.secondaryCalendarMinDate = DateTime.fromJSDate(this.primaryCalendarView.date).plus({ months: 1 }).startOf('month').toJSDate();
|
|
5608
5787
|
}
|
|
5609
5788
|
if (this.secondaryCalendarView?.mode === 'day') {
|
|
5610
|
-
this.primaryCalendarMaxDate =
|
|
5789
|
+
this.primaryCalendarMaxDate = DateTime.fromJSDate(this.secondaryCalendarView.date).minus({ months: 1 }).endOf('month').toJSDate();
|
|
5611
5790
|
}
|
|
5612
5791
|
}
|
|
5613
5792
|
updateCalendars(selection) {
|
|
@@ -5623,8 +5802,10 @@ class DateInputComponent extends FormControlBase {
|
|
|
5623
5802
|
// However, it's possible that the new date is after the secondary calendar's date. In this case,
|
|
5624
5803
|
// We want to shift the secondary calendar so the calendars stay in order.
|
|
5625
5804
|
if (shiftSecondary && this.secondaryCalendarView) {
|
|
5626
|
-
|
|
5627
|
-
|
|
5805
|
+
const primaryDt = DateTime.fromJSDate(this.primaryCalendarView.date);
|
|
5806
|
+
const secondaryDt = DateTime.fromJSDate(this.secondaryCalendarView.date);
|
|
5807
|
+
if (primaryDt.startOf('month') >= secondaryDt.startOf('month')) {
|
|
5808
|
+
const newSecondaryDate = primaryDt.plus({ months: 1 }).toJSDate();
|
|
5628
5809
|
this.secondaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newSecondaryDate };
|
|
5629
5810
|
}
|
|
5630
5811
|
}
|
|
@@ -5635,8 +5816,10 @@ class DateInputComponent extends FormControlBase {
|
|
|
5635
5816
|
// However, it's possible that the new date is before the primary calendar's date. In this case,
|
|
5636
5817
|
// We want to shift the primary calendar so the calendars stay in order.
|
|
5637
5818
|
if (shiftPrimary && this.primaryCalendarView) {
|
|
5638
|
-
|
|
5639
|
-
|
|
5819
|
+
const primaryDt = DateTime.fromJSDate(this.primaryCalendarView.date);
|
|
5820
|
+
const secondaryDt = DateTime.fromJSDate(this.secondaryCalendarView.date);
|
|
5821
|
+
if (primaryDt.startOf('month') >= secondaryDt.startOf('month')) {
|
|
5822
|
+
const newPrimaryDate = secondaryDt.minus({ months: 1 }).toJSDate();
|
|
5640
5823
|
this.primaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newPrimaryDate };
|
|
5641
5824
|
}
|
|
5642
5825
|
}
|
|
@@ -5686,10 +5869,12 @@ class DateInputComponent extends FormControlBase {
|
|
|
5686
5869
|
// We're using the view mode as the granularity. We don't want to invalidate
|
|
5687
5870
|
// the date in the case where you have a month/quarter/year selected and the min
|
|
5688
5871
|
// or max date is somewhere within that month/quarter/year.
|
|
5689
|
-
|
|
5872
|
+
const unit = this.selectionStrategy.selectionViewMode;
|
|
5873
|
+
const valueDt = DateTime.fromJSDate(value).startOf(unit);
|
|
5874
|
+
if (valueDt < DateTime.fromJSDate(this.minDate).startOf(unit)) {
|
|
5690
5875
|
return { minDate: { minValue: this.minDate } };
|
|
5691
5876
|
}
|
|
5692
|
-
else if (
|
|
5877
|
+
else if (valueDt > DateTime.fromJSDate(this.maxDate).startOf(unit)) {
|
|
5693
5878
|
return { maxDate: { maxValue: this.maxDate } };
|
|
5694
5879
|
}
|
|
5695
5880
|
}
|
|
@@ -10028,11 +10213,11 @@ class SelectComponent extends FormControlBase {
|
|
|
10028
10213
|
}
|
|
10029
10214
|
}
|
|
10030
10215
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SelectComponent, deps: [{ token: ValidationMessageService }, { token: FormGroupHelper }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10031
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: SelectComponent, isStandalone: false, selector: "ec-select", inputs: { placeholder: "placeholder", options: "options", autoDefault: "autoDefault" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"control\"\n [ngClass]=\"{'is-readonly': readonly, 'is-disabled': formModel.disabled}\">\n\n @if (label) {\n <label\n for=\"{{id}}_select\">\n <span>{{label | translate}}</span>\n @if (helpPopover) {\n <ec-help-popover id=\"{{id}}_helpPopover\"\n class=\"d-inline-block my-n3 mx-n1\"\n text=\"{{helpPopover | translate}}\"\n contentPosition=\"{{helpPopoverPosition}}\">\n </ec-help-popover>\n }\n </label>\n }\n\n <select [attr.id]=\"inputId\"\n tabindex=\"{{tabindex}}\"\n [formControl]=\"formModel\"\n [attr.required]=\"required\"\n [attr.cdkFocusInitial]=\"autofocus || null\">\n @if (!required) {\n <option\n [ngValue]=\"null\">{{placeholder}}</option>\n }\n @for (option of options; track option) {\n <option\n [ngValue]=\"option.value\">{{option.label}}</option>\n }\n </select>\n <i class=\"ec-icon icon-caret-down\"></i>\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:hover:not(:disabled):not(:focus),:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host .control{position:relative}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host select{-webkit-appearance:none;-moz-appearance:none;appearance:none}:host select::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host select::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host select~.icon-required,:host select~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host select:required.is-empty{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host select.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host select.ng-invalid.ng-touched:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.ng-invalid.ng-touched{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.is-pending.ng-valid,:host select.is-pending.ng-invalid,:host select.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select:focus,:host select:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host select:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host select:disabled:required,:host select:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host select:disabled:required+.icon-required,:host select:disabled:required.is-empty+.icon-required{display:none}:host select:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.is-uppercase:not(.is-empty){text-transform:uppercase}:host select{padding-right:1.5rem}:host select:focus{position:static}:host .icon-caret-down{position:absolute;right:.5rem;bottom:.5625rem;z-index:1;pointer-events:none}:host select:disabled~.icon-caret-down{opacity:var(--ec-form-control-opacity-disabled)}:host .is-readonly .icon-caret-down{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
|
|
10216
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: SelectComponent, isStandalone: false, selector: "ec-select", inputs: { placeholder: "placeholder", options: "options", autoDefault: "autoDefault" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"control\"\n [ngClass]=\"{'is-readonly': readonly, 'is-disabled': formModel.disabled}\">\n\n @if (label) {\n <label\n for=\"{{id}}_select\">\n <span>{{label | translate}}</span>\n @if (helpPopover) {\n <ec-help-popover id=\"{{id}}_helpPopover\"\n class=\"d-inline-block my-n3 mx-n1\"\n text=\"{{helpPopover | translate}}\"\n contentPosition=\"{{helpPopoverPosition}}\">\n </ec-help-popover>\n }\n </label>\n }\n\n <select [attr.id]=\"inputId\"\n tabindex=\"{{tabindex}}\"\n [formControl]=\"formModel\"\n [attr.required]=\"required\"\n [attr.cdkFocusInitial]=\"autofocus || null\">\n @if (!required) {\n <option\n [ngValue]=\"null\">{{placeholder}}</option>\n }\n @for (option of options; track option) {\n <option\n [ngValue]=\"option.value\">{{option.label}}</option>\n }\n </select>\n <i class=\"ec-icon icon-caret-down\" aria-hidden=\"true\"></i>\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:hover:not(:disabled):not(:focus),:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host .control{position:relative}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host select{-webkit-appearance:none;-moz-appearance:none;appearance:none}:host select::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host select::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host select~.icon-required,:host select~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host select:required.is-empty{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host select.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host select.ng-invalid.ng-touched:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.ng-invalid.ng-touched{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.is-pending.ng-valid,:host select.is-pending.ng-invalid,:host select.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select:focus,:host select:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host select:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host select:disabled:required,:host select:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host select:disabled:required+.icon-required,:host select:disabled:required.is-empty+.icon-required{display:none}:host select:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.is-uppercase:not(.is-empty){text-transform:uppercase}:host select{padding-right:1.5rem}:host select:focus{position:static}:host .icon-caret-down{position:absolute;right:.5rem;bottom:.5625rem;z-index:1;pointer-events:none}:host select:disabled~.icon-caret-down{opacity:var(--ec-form-control-opacity-disabled)}:host .is-readonly .icon-caret-down{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
|
|
10032
10217
|
}
|
|
10033
10218
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SelectComponent, decorators: [{
|
|
10034
10219
|
type: Component,
|
|
10035
|
-
args: [{ selector: 'ec-select', standalone: false, template: "<div class=\"control\"\n [ngClass]=\"{'is-readonly': readonly, 'is-disabled': formModel.disabled}\">\n\n @if (label) {\n <label\n for=\"{{id}}_select\">\n <span>{{label | translate}}</span>\n @if (helpPopover) {\n <ec-help-popover id=\"{{id}}_helpPopover\"\n class=\"d-inline-block my-n3 mx-n1\"\n text=\"{{helpPopover | translate}}\"\n contentPosition=\"{{helpPopoverPosition}}\">\n </ec-help-popover>\n }\n </label>\n }\n\n <select [attr.id]=\"inputId\"\n tabindex=\"{{tabindex}}\"\n [formControl]=\"formModel\"\n [attr.required]=\"required\"\n [attr.cdkFocusInitial]=\"autofocus || null\">\n @if (!required) {\n <option\n [ngValue]=\"null\">{{placeholder}}</option>\n }\n @for (option of options; track option) {\n <option\n [ngValue]=\"option.value\">{{option.label}}</option>\n }\n </select>\n <i class=\"ec-icon icon-caret-down\"></i>\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:hover:not(:disabled):not(:focus),:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host .control{position:relative}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host select{-webkit-appearance:none;-moz-appearance:none;appearance:none}:host select::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host select::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host select~.icon-required,:host select~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host select:required.is-empty{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host select.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host select.ng-invalid.ng-touched:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.ng-invalid.ng-touched{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.is-pending.ng-valid,:host select.is-pending.ng-invalid,:host select.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select:focus,:host select:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host select:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host select:disabled:required,:host select:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host select:disabled:required+.icon-required,:host select:disabled:required.is-empty+.icon-required{display:none}:host select:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.is-uppercase:not(.is-empty){text-transform:uppercase}:host select{padding-right:1.5rem}:host select:focus{position:static}:host .icon-caret-down{position:absolute;right:.5rem;bottom:.5625rem;z-index:1;pointer-events:none}:host select:disabled~.icon-caret-down{opacity:var(--ec-form-control-opacity-disabled)}:host .is-readonly .icon-caret-down{display:none}\n"] }]
|
|
10220
|
+
args: [{ selector: 'ec-select', standalone: false, template: "<div class=\"control\"\n [ngClass]=\"{'is-readonly': readonly, 'is-disabled': formModel.disabled}\">\n\n @if (label) {\n <label\n for=\"{{id}}_select\">\n <span>{{label | translate}}</span>\n @if (helpPopover) {\n <ec-help-popover id=\"{{id}}_helpPopover\"\n class=\"d-inline-block my-n3 mx-n1\"\n text=\"{{helpPopover | translate}}\"\n contentPosition=\"{{helpPopoverPosition}}\">\n </ec-help-popover>\n }\n </label>\n }\n\n <select [attr.id]=\"inputId\"\n tabindex=\"{{tabindex}}\"\n [formControl]=\"formModel\"\n [attr.required]=\"required\"\n [attr.cdkFocusInitial]=\"autofocus || null\">\n @if (!required) {\n <option\n [ngValue]=\"null\">{{placeholder}}</option>\n }\n @for (option of options; track option) {\n <option\n [ngValue]=\"option.value\">{{option.label}}</option>\n }\n </select>\n <i class=\"ec-icon icon-caret-down\" aria-hidden=\"true\"></i>\n</div>", styles: [":host{color:var(--ec-form-control-color);font-size:var(--ec-form-control-font-size);display:block;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{width:100%;display:flex;flex-direction:column}:host .control.control-label-bottom{flex-direction:column-reverse}:host .control.control-label-left{flex-direction:row}:host .control.control-label-left label{margin-right:.25rem}:host .control.control-label-right{flex-direction:row-reverse}:host .control.control-label-right label{margin-left:.25rem}:host .control.control-label-left,:host .control.control-label-right{align-items:center}:host .control.control-label-left label,:host .control.control-label-right label{flex:1 1;margin-top:0;margin-bottom:0}:host .control.control-label-left .control-input,:host .control.control-label-right .control-input{flex:2 2}:host .control.is-readonly input,:host .control.is-readonly select,:host .control.is-readonly textarea{border-color:var(--ec-form-control-border-color-readonly);background-color:var(--ec-form-control-background-color-readonly);background-clip:border-box;background-image:none;color:var(--ec-form-control-color-readonly);opacity:1;-webkit-user-select:none;user-select:none;pointer-events:none;overflow:hidden;white-space:nowrap}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:focus,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:focus{border-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:hover:not(:disabled):not(:focus),:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid{background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem;background-image:none}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-invalid,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-invalid{display:inline-flex;position:absolute;left:.5rem;top:.5rem;z-index:1}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid~.icon-required,:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid~.icon-required{display:none}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:var(--ec-form-control-border-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:var(--ec-form-control-background-color-invalid)}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host .textbox-group{display:flex;position:relative}:host textarea:focus,:host input:focus,:host select:focus{outline:none}:host .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:host .control{position:relative}:host label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}:host select{-webkit-appearance:none;-moz-appearance:none;appearance:none}:host select::selection{background-color:var(--ec-form-control-background-color-selection);color:var(--ec-form-control-color-selection)}:host select::-webkit-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select::-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select:-ms-input-placeholder{color:var(--ec-form-control-color-placeholder)}:host select:-moz-placeholder{color:var(--ec-form-control-color-placeholder);opacity:1}:host select{background-color:var(--ec-form-control-background-color);border:1px solid var(--ec-form-control-border-color);border-radius:var(--ec-border-radius);background-image:none;background-clip:padding-box;width:100%;line-height:1.25rem;padding:.3125rem .5rem;height:2rem}:host select~.icon-required,:host select~.icon-invalid{color:var(--ec-form-control-border-color-invalid)}:host select:required.is-empty{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.ng-invalid.ng-touched{background-color:var(--ec-form-control-background-color-invalid);border-color:var(--ec-form-control-border-color-invalid)}:host select.ng-invalid.ng-touched:focus{border-color:var(--ec-form-control-background-color-invalid)}:host select.ng-invalid.ng-touched:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.ng-invalid.ng-touched{background-image:none;background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select.is-pending.ng-valid,:host select.is-pending.ng-invalid,:host select.is-pending.ng-pending{background-image:\"\";background-repeat:no-repeat;background-position:.5rem center;background-size:1rem,1rem;padding-left:1.75rem}:host select:focus,:host select:focus.is-empty{border-color:var(--ec-form-control-border-color-focus);box-shadow:var(--ec-form-control-box-shadow-focus);position:relative;z-index:1}:host select:disabled{background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled);color:var(--ec-form-control-color-disabled);opacity:var(--ec-form-control-opacity-disabled)}:host select:disabled:required,:host select:disabled:required.is-empty{background-image:none;padding-left:.5rem;background-color:var(--ec-form-control-background-color-disabled);border-color:var(--ec-form-control-border-color-disabled)}:host select:disabled:required+.icon-required,:host select:disabled:required.is-empty+.icon-required{display:none}:host select:hover:not(:disabled):not(:focus){border-color:var(--ec-form-control-border-color-hover)}:host select.is-uppercase:not(.is-empty){text-transform:uppercase}:host select{padding-right:1.5rem}:host select:focus{position:static}:host .icon-caret-down{position:absolute;right:.5rem;bottom:.5625rem;z-index:1;pointer-events:none}:host select:disabled~.icon-caret-down{opacity:var(--ec-form-control-opacity-disabled)}:host .is-readonly .icon-caret-down{display:none}\n"] }]
|
|
10036
10221
|
}], ctorParameters: () => [{ type: ValidationMessageService }, { type: FormGroupHelper }, { type: i0.ElementRef }], propDecorators: { placeholder: [{
|
|
10037
10222
|
type: Input
|
|
10038
10223
|
}], options: [{
|
|
@@ -10267,6 +10452,8 @@ class ConfirmComponent {
|
|
|
10267
10452
|
this.formGroup = new UntypedFormGroup({});
|
|
10268
10453
|
this.status = new Overlay('hasData');
|
|
10269
10454
|
this.showTextBox = false;
|
|
10455
|
+
/** Result of the inline confirm action, used for the screen-reader status text in the result template */
|
|
10456
|
+
this.inlineResultSuccess = false;
|
|
10270
10457
|
this.destroyed = new Subject();
|
|
10271
10458
|
this.onDialogSave = new EventEmitter();
|
|
10272
10459
|
this.onDialogCancel = new EventEmitter();
|
|
@@ -10345,6 +10532,7 @@ class ConfirmComponent {
|
|
|
10345
10532
|
async doInlineConfirmAction() {
|
|
10346
10533
|
this.status.setStatus('pending', this.context.inlineConfirmPendingMessage);
|
|
10347
10534
|
let result = await this.context.inlineConfirmAction();
|
|
10535
|
+
this.inlineResultSuccess = result.isSuccess;
|
|
10348
10536
|
this.status.setStatus('noData', result.message, {
|
|
10349
10537
|
id: 'inlineConfirmClose',
|
|
10350
10538
|
label: 'Close',
|
|
@@ -10354,11 +10542,11 @@ class ConfirmComponent {
|
|
|
10354
10542
|
});
|
|
10355
10543
|
}
|
|
10356
10544
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
10357
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ConfirmComponent, isStandalone: false, selector: "ec-confirm", inputs: { context: "context" }, outputs: { onDialogSave: "onDialogSave", onDialogCancel: "onDialogCancel" }, ngImport: i0, template: "<section ecOverlay\n [status]=\"status?.status\"\n [message]=\"status?.message\"\n [action]=\"status?.action\"\n [noDataTemplate]=\"inlineConfirmResult\"\n overlayClassList=\"p-0\"\n class=\"bg-body flex-grow d-flex\">\n <form [formGroup]=\"formGroup\" class=\"flex-grow flex-column confirm-content text-body-1\">\n <section class=\"flex-grow\">\n @if (context?.title) {\n <h2 class=\"font-weight-bold mb-3\">{{context?.title}}</h2>\n }\n @if (error) {\n <ec-banner [text]=\"error | translate\" bannerStyle=\"normal\" class=\"mb-3\"></ec-banner>\n }\n @if (context?.message) {\n <div [innerHtml]=\"context?.message | translate\" class=\"mb-3\"></div>\n }\n\n @if (context?.checkConfirm) {\n <ec-checkbox\n [formModel]=\"formGroup.get('checkbox')\"\n name=\"confirmCheckbox\"\n [label]=\"context?.checkboxText\"\n [autofocus]=\"true\"\n ></ec-checkbox>\n }\n @if (showTextBox) {\n <div [innerHtml]=\"context.confirmLabel\" class=\"mb-3\"></div>\n }\n @if ((context?.textboxType && !context?.checkConfirm) || showTextBox) {\n <ec-textbox id=\"confirmTextbox\"\n [autofocus]=\"true\"\n [formModel]=\"formGroup.get('textbox')\"\n [required]=\"context?.textboxRequired\"\n [label]=\"context?.textboxLabel\"\n [type]=\"context?.textboxType\"\n [rows]=\"context?.textareaRows\"\n [placeholder]=\"context?.textboxPlaceholder\"\n [upperCase]=\"context?.textboxUppercase\">\n </ec-textbox>\n }\n </section>\n <footer class=\"mt-auto flex-shrink d-flex py-2 flex-row-reverse\">\n <ec-button id=\"saveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.saveButtonType ? context?.saveButtonType : 'primary'\"\n [label]=\"context?.saveLabel ? context?.saveLabel : 'Save'\"\n [autofocus]=\"!context?.textboxType\"\n [isSubmit]=\"context?.saveOnEnter\"\n (clicked)=\"onSave('primary')\">\n </ec-button>\n @if (context?.alternateSaveLabel) {\n <ec-button id=\"alternateSaveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.alternateSaveButtonType ? context?.alternateSaveButtonType : 'primary'\"\n [label]=\"context?.alternateSaveLabel\"\n (clicked)=\"onSave('alternate')\">\n </ec-button>\n }\n @if (!context?.hideCancel) {\n <ec-button\n id=\"cancelConfirmButton\"\n class=\"ml-auto\"\n type=\"secondary\"\n [label]=\"context?.cancelLabel ? context?.cancelLabel : 'Cancel'\"\n (clicked)=\"onCancel()\">\n </ec-button>\n }\n </footer>\n </form>\n</section>\n\n<ng-template #inlineConfirmResult>\n <section class=\"flex-grow align-self-stretch confirm-content text-body-1\">\n <div class=\"d-flex\">\n <i class=\"ec-icon {{status?.action?.icon}} {{status?.action?.classlist}} inline-confirm-result-icon\"></i>\n <div [innerHTML]=\"status?.message | translate\"></div>\n </div>\n <div class=\"d-flex pt-2 mt-auto\">\n <ec-button id=\"inlineConfirmClose\"\n label=\"Close\"\n type=\"secondary\"\n class=\"ml-auto\"\n (clicked)=\"status?.action?.onClick!()\"\n [autofocus]=\"true\">\n </ec-button>\n </div>\n </section>\n</ng-template>", styles: [":host{width:100%;display:flex}.confirm-content{padding:1.5rem;display:flex;flex-direction:column}.inline-confirm-result-icon{margin:.0625rem .25rem .0625rem 0}\n"], dependencies: [{ kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: TextboxComponent, selector: "ec-textbox", inputs: ["autocomplete", "type", "placeholder", "maxlength", "minlength", "rows", "selectOnAutofocus", "upperCase"] }, { kind: "component", type: ViewOverlayComponent, selector: "[ecOverlay]", inputs: ["status", "message", "action", "noDataTemplate", "displayAsMask", "overlayClassList"] }, { kind: "component", type: BannerComponent, selector: "ec-banner", inputs: ["hidden", "id", "type", "bannerStyle", "title", "text", "list", "showCloseBtn", "autoHideOnClose", "customIcon", "rememberClosed"], outputs: ["closed"] }, { kind: "component", type: CheckboxComponent, selector: "ec-checkbox", inputs: ["name", "icon", "dependentCheckboxesGroup", "ignoreDisabledDependents"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
|
|
10545
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ConfirmComponent, isStandalone: false, selector: "ec-confirm", inputs: { context: "context" }, outputs: { onDialogSave: "onDialogSave", onDialogCancel: "onDialogCancel" }, ngImport: i0, template: "<section ecOverlay\n [status]=\"status?.status\"\n [message]=\"status?.message\"\n [action]=\"status?.action\"\n [noDataTemplate]=\"inlineConfirmResult\"\n overlayClassList=\"p-0\"\n class=\"bg-body flex-grow d-flex\">\n <form [formGroup]=\"formGroup\" class=\"flex-grow flex-column confirm-content text-body-1\">\n <section class=\"flex-grow\">\n @if (context?.title) {\n <h2 class=\"font-weight-bold mb-3\">{{context?.title}}</h2>\n }\n @if (error) {\n <ec-banner [text]=\"error | translate\" bannerStyle=\"normal\" class=\"mb-3\"></ec-banner>\n }\n @if (context?.message) {\n <div [innerHtml]=\"context?.message | translate\" class=\"mb-3\"></div>\n }\n\n @if (context?.checkConfirm) {\n <ec-checkbox\n [formModel]=\"formGroup.get('checkbox')\"\n name=\"confirmCheckbox\"\n [label]=\"context?.checkboxText\"\n [autofocus]=\"true\"\n ></ec-checkbox>\n }\n @if (showTextBox) {\n <div [innerHtml]=\"context.confirmLabel\" class=\"mb-3\"></div>\n }\n @if ((context?.textboxType && !context?.checkConfirm) || showTextBox) {\n <ec-textbox id=\"confirmTextbox\"\n [autofocus]=\"true\"\n [formModel]=\"formGroup.get('textbox')\"\n [required]=\"context?.textboxRequired\"\n [label]=\"context?.textboxLabel\"\n [type]=\"context?.textboxType\"\n [rows]=\"context?.textareaRows\"\n [placeholder]=\"context?.textboxPlaceholder\"\n [upperCase]=\"context?.textboxUppercase\">\n </ec-textbox>\n }\n </section>\n <footer class=\"mt-auto flex-shrink d-flex py-2 flex-row-reverse\">\n <ec-button id=\"saveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.saveButtonType ? context?.saveButtonType : 'primary'\"\n [label]=\"context?.saveLabel ? context?.saveLabel : 'Save'\"\n [autofocus]=\"!context?.textboxType\"\n [isSubmit]=\"context?.saveOnEnter\"\n (clicked)=\"onSave('primary')\">\n </ec-button>\n @if (context?.alternateSaveLabel) {\n <ec-button id=\"alternateSaveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.alternateSaveButtonType ? context?.alternateSaveButtonType : 'primary'\"\n [label]=\"context?.alternateSaveLabel\"\n (clicked)=\"onSave('alternate')\">\n </ec-button>\n }\n @if (!context?.hideCancel) {\n <ec-button\n id=\"cancelConfirmButton\"\n class=\"ml-auto\"\n type=\"secondary\"\n [label]=\"context?.cancelLabel ? context?.cancelLabel : 'Cancel'\"\n (clicked)=\"onCancel()\">\n </ec-button>\n }\n </footer>\n </form>\n</section>\n\n<ng-template #inlineConfirmResult>\n <section class=\"flex-grow align-self-stretch confirm-content text-body-1\">\n <div class=\"d-flex\">\n <i class=\"ec-icon {{status?.action?.icon}} {{status?.action?.classlist}} inline-confirm-result-icon\" aria-hidden=\"true\"></i>\n <span class=\"sr-only\">{{(inlineResultSuccess ? 'Success_TC' : 'Error_TC') | translate}}</span>\n <div [innerHTML]=\"status?.message | translate\"></div>\n </div>\n <div class=\"d-flex pt-2 mt-auto\">\n <ec-button id=\"inlineConfirmClose\"\n label=\"Close\"\n type=\"secondary\"\n class=\"ml-auto\"\n (clicked)=\"status?.action?.onClick!()\"\n [autofocus]=\"true\">\n </ec-button>\n </div>\n </section>\n</ng-template>", styles: [":host{width:100%;display:flex}.confirm-content{padding:1.5rem;display:flex;flex-direction:column}.inline-confirm-result-icon{margin:.0625rem .25rem .0625rem 0}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "lockButton", "icon", "iconColor", "label", "ariaLabel", "ariaExpanded", "ariaHaspopup", "ariaActivedescendant", "ariaControls", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: TextboxComponent, selector: "ec-textbox", inputs: ["autocomplete", "type", "placeholder", "maxlength", "minlength", "rows", "selectOnAutofocus", "upperCase"] }, { kind: "component", type: ViewOverlayComponent, selector: "[ecOverlay]", inputs: ["status", "message", "action", "noDataTemplate", "displayAsMask", "overlayClassList"] }, { kind: "component", type: BannerComponent, selector: "ec-banner", inputs: ["hidden", "id", "type", "bannerStyle", "title", "text", "list", "showCloseBtn", "autoHideOnClose", "customIcon", "rememberClosed"], outputs: ["closed"] }, { kind: "component", type: CheckboxComponent, selector: "ec-checkbox", inputs: ["name", "icon", "dependentCheckboxesGroup", "ignoreDisabledDependents"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] }); }
|
|
10358
10546
|
}
|
|
10359
10547
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ConfirmComponent, decorators: [{
|
|
10360
10548
|
type: Component,
|
|
10361
|
-
args: [{ selector: 'ec-confirm', standalone: false, template: "<section ecOverlay\n [status]=\"status?.status\"\n [message]=\"status?.message\"\n [action]=\"status?.action\"\n [noDataTemplate]=\"inlineConfirmResult\"\n overlayClassList=\"p-0\"\n class=\"bg-body flex-grow d-flex\">\n <form [formGroup]=\"formGroup\" class=\"flex-grow flex-column confirm-content text-body-1\">\n <section class=\"flex-grow\">\n @if (context?.title) {\n <h2 class=\"font-weight-bold mb-3\">{{context?.title}}</h2>\n }\n @if (error) {\n <ec-banner [text]=\"error | translate\" bannerStyle=\"normal\" class=\"mb-3\"></ec-banner>\n }\n @if (context?.message) {\n <div [innerHtml]=\"context?.message | translate\" class=\"mb-3\"></div>\n }\n\n @if (context?.checkConfirm) {\n <ec-checkbox\n [formModel]=\"formGroup.get('checkbox')\"\n name=\"confirmCheckbox\"\n [label]=\"context?.checkboxText\"\n [autofocus]=\"true\"\n ></ec-checkbox>\n }\n @if (showTextBox) {\n <div [innerHtml]=\"context.confirmLabel\" class=\"mb-3\"></div>\n }\n @if ((context?.textboxType && !context?.checkConfirm) || showTextBox) {\n <ec-textbox id=\"confirmTextbox\"\n [autofocus]=\"true\"\n [formModel]=\"formGroup.get('textbox')\"\n [required]=\"context?.textboxRequired\"\n [label]=\"context?.textboxLabel\"\n [type]=\"context?.textboxType\"\n [rows]=\"context?.textareaRows\"\n [placeholder]=\"context?.textboxPlaceholder\"\n [upperCase]=\"context?.textboxUppercase\">\n </ec-textbox>\n }\n </section>\n <footer class=\"mt-auto flex-shrink d-flex py-2 flex-row-reverse\">\n <ec-button id=\"saveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.saveButtonType ? context?.saveButtonType : 'primary'\"\n [label]=\"context?.saveLabel ? context?.saveLabel : 'Save'\"\n [autofocus]=\"!context?.textboxType\"\n [isSubmit]=\"context?.saveOnEnter\"\n (clicked)=\"onSave('primary')\">\n </ec-button>\n @if (context?.alternateSaveLabel) {\n <ec-button id=\"alternateSaveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.alternateSaveButtonType ? context?.alternateSaveButtonType : 'primary'\"\n [label]=\"context?.alternateSaveLabel\"\n (clicked)=\"onSave('alternate')\">\n </ec-button>\n }\n @if (!context?.hideCancel) {\n <ec-button\n id=\"cancelConfirmButton\"\n class=\"ml-auto\"\n type=\"secondary\"\n [label]=\"context?.cancelLabel ? context?.cancelLabel : 'Cancel'\"\n (clicked)=\"onCancel()\">\n </ec-button>\n }\n </footer>\n </form>\n</section>\n\n<ng-template #inlineConfirmResult>\n <section class=\"flex-grow align-self-stretch confirm-content text-body-1\">\n <div class=\"d-flex\">\n <i class=\"ec-icon {{status?.action?.icon}} {{status?.action?.classlist}} inline-confirm-result-icon\"></i>\n <div [innerHTML]=\"status?.message | translate\"></div>\n </div>\n <div class=\"d-flex pt-2 mt-auto\">\n <ec-button id=\"inlineConfirmClose\"\n label=\"Close\"\n type=\"secondary\"\n class=\"ml-auto\"\n (clicked)=\"status?.action?.onClick!()\"\n [autofocus]=\"true\">\n </ec-button>\n </div>\n </section>\n</ng-template>", styles: [":host{width:100%;display:flex}.confirm-content{padding:1.5rem;display:flex;flex-direction:column}.inline-confirm-result-icon{margin:.0625rem .25rem .0625rem 0}\n"] }]
|
|
10549
|
+
args: [{ selector: 'ec-confirm', standalone: false, template: "<section ecOverlay\n [status]=\"status?.status\"\n [message]=\"status?.message\"\n [action]=\"status?.action\"\n [noDataTemplate]=\"inlineConfirmResult\"\n overlayClassList=\"p-0\"\n class=\"bg-body flex-grow d-flex\">\n <form [formGroup]=\"formGroup\" class=\"flex-grow flex-column confirm-content text-body-1\">\n <section class=\"flex-grow\">\n @if (context?.title) {\n <h2 class=\"font-weight-bold mb-3\">{{context?.title}}</h2>\n }\n @if (error) {\n <ec-banner [text]=\"error | translate\" bannerStyle=\"normal\" class=\"mb-3\"></ec-banner>\n }\n @if (context?.message) {\n <div [innerHtml]=\"context?.message | translate\" class=\"mb-3\"></div>\n }\n\n @if (context?.checkConfirm) {\n <ec-checkbox\n [formModel]=\"formGroup.get('checkbox')\"\n name=\"confirmCheckbox\"\n [label]=\"context?.checkboxText\"\n [autofocus]=\"true\"\n ></ec-checkbox>\n }\n @if (showTextBox) {\n <div [innerHtml]=\"context.confirmLabel\" class=\"mb-3\"></div>\n }\n @if ((context?.textboxType && !context?.checkConfirm) || showTextBox) {\n <ec-textbox id=\"confirmTextbox\"\n [autofocus]=\"true\"\n [formModel]=\"formGroup.get('textbox')\"\n [required]=\"context?.textboxRequired\"\n [label]=\"context?.textboxLabel\"\n [type]=\"context?.textboxType\"\n [rows]=\"context?.textareaRows\"\n [placeholder]=\"context?.textboxPlaceholder\"\n [upperCase]=\"context?.textboxUppercase\">\n </ec-textbox>\n }\n </section>\n <footer class=\"mt-auto flex-shrink d-flex py-2 flex-row-reverse\">\n <ec-button id=\"saveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.saveButtonType ? context?.saveButtonType : 'primary'\"\n [label]=\"context?.saveLabel ? context?.saveLabel : 'Save'\"\n [autofocus]=\"!context?.textboxType\"\n [isSubmit]=\"context?.saveOnEnter\"\n (clicked)=\"onSave('primary')\">\n </ec-button>\n @if (context?.alternateSaveLabel) {\n <ec-button id=\"alternateSaveConfirmButton\"\n class=\"ml-2\"\n [type]=\"context?.alternateSaveButtonType ? context?.alternateSaveButtonType : 'primary'\"\n [label]=\"context?.alternateSaveLabel\"\n (clicked)=\"onSave('alternate')\">\n </ec-button>\n }\n @if (!context?.hideCancel) {\n <ec-button\n id=\"cancelConfirmButton\"\n class=\"ml-auto\"\n type=\"secondary\"\n [label]=\"context?.cancelLabel ? context?.cancelLabel : 'Cancel'\"\n (clicked)=\"onCancel()\">\n </ec-button>\n }\n </footer>\n </form>\n</section>\n\n<ng-template #inlineConfirmResult>\n <section class=\"flex-grow align-self-stretch confirm-content text-body-1\">\n <div class=\"d-flex\">\n <i class=\"ec-icon {{status?.action?.icon}} {{status?.action?.classlist}} inline-confirm-result-icon\" aria-hidden=\"true\"></i>\n <span class=\"sr-only\">{{(inlineResultSuccess ? 'Success_TC' : 'Error_TC') | translate}}</span>\n <div [innerHTML]=\"status?.message | translate\"></div>\n </div>\n <div class=\"d-flex pt-2 mt-auto\">\n <ec-button id=\"inlineConfirmClose\"\n label=\"Close\"\n type=\"secondary\"\n class=\"ml-auto\"\n (clicked)=\"status?.action?.onClick!()\"\n [autofocus]=\"true\">\n </ec-button>\n </div>\n </section>\n</ng-template>", styles: [":host{width:100%;display:flex}.confirm-content{padding:1.5rem;display:flex;flex-direction:column}.inline-confirm-result-icon{margin:.0625rem .25rem .0625rem 0}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
10362
10550
|
}], ctorParameters: () => [], propDecorators: { context: [{
|
|
10363
10551
|
type: Input
|
|
10364
10552
|
}], onDialogSave: [{
|
|
@@ -11553,6 +11741,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
11553
11741
|
args: ['timedToast', { static: false, read: ElementRef }]
|
|
11554
11742
|
}] } });
|
|
11555
11743
|
|
|
11744
|
+
/** Module-level counter so each tooltip instance gets a unique DOM id, keeping
|
|
11745
|
+
* aria-describedby unambiguous when more than one tooltip is in the DOM (e.g. during
|
|
11746
|
+
* the hide delay or across multiple anchors). */
|
|
11747
|
+
let uniqueTooltipId = 0;
|
|
11556
11748
|
class TooltipDirective {
|
|
11557
11749
|
constructor(tooltipService, element, renderer2) {
|
|
11558
11750
|
this.tooltipService = tooltipService;
|
|
@@ -11581,6 +11773,10 @@ class TooltipDirective {
|
|
|
11581
11773
|
* if we never showed the tooltip this will remain null and we won't have an event to unsubscribe to
|
|
11582
11774
|
*/
|
|
11583
11775
|
this.mouseMoveUnsubscribe = null;
|
|
11776
|
+
/**Set when we show a tooltip so Escape can dismiss it without moving the pointer (WCAG 1.4.13).
|
|
11777
|
+
* Unsubscribed when hide fires, like mouseMoveUnsubscribe.
|
|
11778
|
+
*/
|
|
11779
|
+
this.keydownUnsubscribe = null;
|
|
11584
11780
|
}
|
|
11585
11781
|
ngOnInit() {
|
|
11586
11782
|
//checkInputsValue(): if there is an error it will prevent to execute
|
|
@@ -11607,6 +11803,10 @@ class TooltipDirective {
|
|
|
11607
11803
|
onMouseMove(event) {
|
|
11608
11804
|
let callCallback = false;
|
|
11609
11805
|
if (this.contentRect) {
|
|
11806
|
+
//Keep the tooltip visible while the pointer is over the tooltip content itself (WCAG 1.4.13)
|
|
11807
|
+
if (this.isPointerOverTooltip(event)) {
|
|
11808
|
+
return;
|
|
11809
|
+
}
|
|
11610
11810
|
callCallback = this.tooltipService.onMove(event, this.contentRect);
|
|
11611
11811
|
if (callCallback) {
|
|
11612
11812
|
//trigger on hide process
|
|
@@ -11622,9 +11822,39 @@ class TooltipDirective {
|
|
|
11622
11822
|
}
|
|
11623
11823
|
//Trigger the process to hide and later the process
|
|
11624
11824
|
//to mark as complete the cycle of show and hide the tooltip
|
|
11625
|
-
onLeave() {
|
|
11825
|
+
onLeave(event) {
|
|
11826
|
+
//Moving from the anchor onto the tooltip content should not hide it (WCAG 1.4.13).
|
|
11827
|
+
//The document mousemove backstop hides it once the pointer leaves both.
|
|
11828
|
+
const overlayElement = this.tooltip?.overlayRef?.overlayElement;
|
|
11829
|
+
if (overlayElement && event?.relatedTarget && overlayElement.contains(event.relatedTarget)) {
|
|
11830
|
+
return;
|
|
11831
|
+
}
|
|
11626
11832
|
this.interrupt.next();
|
|
11627
11833
|
}
|
|
11834
|
+
//Show the tooltip for keyboard users when the anchor receives focus (WCAG 2.1.1)
|
|
11835
|
+
onFocusIn() {
|
|
11836
|
+
this.mouseOver.next();
|
|
11837
|
+
}
|
|
11838
|
+
//Hide the tooltip when keyboard focus leaves the anchor
|
|
11839
|
+
onFocusOut() {
|
|
11840
|
+
this.interrupt.next();
|
|
11841
|
+
}
|
|
11842
|
+
//Dismiss the tooltip on Escape without moving pointer or focus (WCAG 1.4.13)
|
|
11843
|
+
onKeydown(event) {
|
|
11844
|
+
if (event.key === 'Escape') {
|
|
11845
|
+
this.interrupt.next();
|
|
11846
|
+
}
|
|
11847
|
+
}
|
|
11848
|
+
//True when the pointer coordinates are within the tooltip overlay element
|
|
11849
|
+
isPointerOverTooltip(event) {
|
|
11850
|
+
const overlayElement = this.tooltip?.overlayRef?.overlayElement;
|
|
11851
|
+
if (!overlayElement) {
|
|
11852
|
+
return false;
|
|
11853
|
+
}
|
|
11854
|
+
const rect = overlayElement.getBoundingClientRect();
|
|
11855
|
+
return event.clientX >= rect.left && event.clientX <= rect.right
|
|
11856
|
+
&& event.clientY >= rect.top && event.clientY <= rect.bottom;
|
|
11857
|
+
}
|
|
11628
11858
|
checkInputsValue() {
|
|
11629
11859
|
let parametersWithValue = 0;
|
|
11630
11860
|
if (this.tooltipText) {
|
|
@@ -11651,7 +11881,7 @@ class TooltipDirective {
|
|
|
11651
11881
|
*/
|
|
11652
11882
|
createTooltipOptions() {
|
|
11653
11883
|
this.tooltipOptions = {
|
|
11654
|
-
id: `tooltip_${this.tooltipConfig?.id ? this.tooltipConfig
|
|
11884
|
+
id: `tooltip_${this.tooltipConfig?.id ? this.tooltipConfig.id : ++uniqueTooltipId}`,
|
|
11655
11885
|
text: this.tooltipConfig?.text || this.tooltipText,
|
|
11656
11886
|
title: this.tooltipConfig?.title,
|
|
11657
11887
|
subtitle: this.tooltipConfig?.subtitle,
|
|
@@ -11672,6 +11902,11 @@ class TooltipDirective {
|
|
|
11672
11902
|
if (!this.tooltip) {
|
|
11673
11903
|
this.tooltip = this.tooltipService.show(element, this.tooltipPosition, this.tooltipOptions);
|
|
11674
11904
|
this.mouseMoveUnsubscribe = this.renderer2.listen(document, 'mousemove', this.onMouseMove.bind(this));
|
|
11905
|
+
this.keydownUnsubscribe = this.renderer2.listen(document, 'keydown', this.onKeydown.bind(this));
|
|
11906
|
+
//Associate the tooltip content with its anchor so screen readers announce it (WCAG 4.1.2)
|
|
11907
|
+
if (this.tooltipOptions?.id) {
|
|
11908
|
+
this.renderer2.setAttribute(element, 'aria-describedby', this.tooltipOptions.id);
|
|
11909
|
+
}
|
|
11675
11910
|
}
|
|
11676
11911
|
}
|
|
11677
11912
|
hide() {
|
|
@@ -11685,6 +11920,11 @@ class TooltipDirective {
|
|
|
11685
11920
|
if (this.mouseMoveUnsubscribe) {
|
|
11686
11921
|
this.mouseMoveUnsubscribe();
|
|
11687
11922
|
}
|
|
11923
|
+
if (this.keydownUnsubscribe) {
|
|
11924
|
+
this.keydownUnsubscribe();
|
|
11925
|
+
this.keydownUnsubscribe = null;
|
|
11926
|
+
}
|
|
11927
|
+
this.renderer2.removeAttribute(this.element.nativeElement, 'aria-describedby');
|
|
11688
11928
|
}
|
|
11689
11929
|
//Interrupt the flow of mouseover with a delay and triggers the
|
|
11690
11930
|
//flow to hide the tooltip with a delay
|
|
@@ -11698,7 +11938,7 @@ class TooltipDirective {
|
|
|
11698
11938
|
this.interrupt.next();
|
|
11699
11939
|
}
|
|
11700
11940
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TooltipDirective, deps: [{ token: TooltipService }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
11701
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: TooltipDirective, isStandalone: false, selector: "[ecTooltip]", inputs: { tooltipConfig: "tooltipConfig", tooltipText: "tooltipText", tooltipCustomContent: "tooltipCustomContent", tooltipPosition: "tooltipPosition" }, host: { listeners: { "mouseover": "onMouseOver()", "mouseleave": "onLeave()" } }, ngImport: i0 }); }
|
|
11941
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: TooltipDirective, isStandalone: false, selector: "[ecTooltip]", inputs: { tooltipConfig: "tooltipConfig", tooltipText: "tooltipText", tooltipCustomContent: "tooltipCustomContent", tooltipPosition: "tooltipPosition" }, host: { listeners: { "mouseover": "onMouseOver()", "mouseleave": "onLeave($event)", "focusin": "onFocusIn()", "focusout": "onFocusOut()" } }, ngImport: i0 }); }
|
|
11702
11942
|
}
|
|
11703
11943
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TooltipDirective, decorators: [{
|
|
11704
11944
|
type: Directive,
|
|
@@ -11719,7 +11959,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
11719
11959
|
args: ['mouseover']
|
|
11720
11960
|
}], onLeave: [{
|
|
11721
11961
|
type: HostListener,
|
|
11722
|
-
args: ['mouseleave']
|
|
11962
|
+
args: ['mouseleave', ['$event']]
|
|
11963
|
+
}], onFocusIn: [{
|
|
11964
|
+
type: HostListener,
|
|
11965
|
+
args: ['focusin']
|
|
11966
|
+
}], onFocusOut: [{
|
|
11967
|
+
type: HostListener,
|
|
11968
|
+
args: ['focusout']
|
|
11723
11969
|
}] } });
|
|
11724
11970
|
|
|
11725
11971
|
class TreeComponent {
|
|
@@ -11998,7 +12244,9 @@ class DateDisplayPipe2 {
|
|
|
11998
12244
|
}
|
|
11999
12245
|
async transform(date, options) {
|
|
12000
12246
|
const { showEndOfTime, showTime, showSeconds, displayInUTC } = options || {};
|
|
12001
|
-
if (
|
|
12247
|
+
if (date == null)
|
|
12248
|
+
return '';
|
|
12249
|
+
if (!DateTimeHelper.toDateTime(date).isValid || (!showEndOfTime && DateTimeHelper.isEndOfTime(date))) {
|
|
12002
12250
|
return '';
|
|
12003
12251
|
}
|
|
12004
12252
|
const { preference } = await lastValueFrom(this.userPrefs.getPreferences());
|
|
@@ -12010,8 +12258,7 @@ class DateDisplayPipe2 {
|
|
|
12010
12258
|
}
|
|
12011
12259
|
formatString += ` ${timeFormat}`;
|
|
12012
12260
|
}
|
|
12013
|
-
|
|
12014
|
-
return (displayInUTC ? moment.utc(date) : moment(date)).format(formatString);
|
|
12261
|
+
return DateTimeHelper.formatDate(date, formatString, displayInUTC);
|
|
12015
12262
|
}
|
|
12016
12263
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe2, deps: [{ token: UserPreferenceService }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
12017
12264
|
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe2, isStandalone: false, name: "dateDisplay2" }); }
|
|
@@ -12024,6 +12271,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12024
12271
|
}]
|
|
12025
12272
|
}], ctorParameters: () => [{ type: UserPreferenceService }] });
|
|
12026
12273
|
|
|
12274
|
+
/**
|
|
12275
|
+
* Same behavior as {@link DateDisplayPipe2}, but always appends the short named
|
|
12276
|
+
* timezone abbreviation (e.g. `EST`, `PDT`, `UTC`) to the output. Use this when
|
|
12277
|
+
* downstream consumers need to disambiguate the timezone of a rendered date.
|
|
12278
|
+
*
|
|
12279
|
+
* @example <span>{{ someDate | dateDisplay3 | async }}</span>
|
|
12280
|
+
*/
|
|
12281
|
+
class DateDisplayPipe3 {
|
|
12282
|
+
constructor(userPrefs) {
|
|
12283
|
+
this.userPrefs = userPrefs;
|
|
12284
|
+
}
|
|
12285
|
+
async transform(date, options) {
|
|
12286
|
+
const { showEndOfTime, showTime, showSeconds, displayInUTC } = options || {};
|
|
12287
|
+
if (date == null)
|
|
12288
|
+
return '';
|
|
12289
|
+
if (!DateTimeHelper.toDateTime(date).isValid || (!showEndOfTime && DateTimeHelper.isEndOfTime(date))) {
|
|
12290
|
+
return '';
|
|
12291
|
+
}
|
|
12292
|
+
const { preference } = await lastValueFrom(this.userPrefs.getPreferences());
|
|
12293
|
+
let formatString = preference?.dateFormat || 'MM/DD/YYYY';
|
|
12294
|
+
if (showTime) {
|
|
12295
|
+
let timeFormat = preference.timeFormat;
|
|
12296
|
+
if (!showSeconds) {
|
|
12297
|
+
timeFormat = timeFormat.replace(':ss', '');
|
|
12298
|
+
}
|
|
12299
|
+
formatString += ` ${timeFormat}`;
|
|
12300
|
+
}
|
|
12301
|
+
// Luxon's `ZZZZ` renders the short named offset (e.g. `EST`, `EDT`, `UTC`).
|
|
12302
|
+
// The token passes through `momentToLuxonFormat` unchanged.
|
|
12303
|
+
formatString += ' ZZZZ';
|
|
12304
|
+
return DateTimeHelper.formatDate(date, formatString, !!displayInUTC);
|
|
12305
|
+
}
|
|
12306
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe3, deps: [{ token: UserPreferenceService }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
12307
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe3, isStandalone: false, name: "dateDisplay3" }); }
|
|
12308
|
+
}
|
|
12309
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DateDisplayPipe3, decorators: [{
|
|
12310
|
+
type: Pipe,
|
|
12311
|
+
args: [{
|
|
12312
|
+
name: 'dateDisplay3',
|
|
12313
|
+
standalone: false
|
|
12314
|
+
}]
|
|
12315
|
+
}], ctorParameters: () => [{ type: UserPreferenceService }] });
|
|
12316
|
+
|
|
12027
12317
|
/**
|
|
12028
12318
|
* Format a time to the user's preference for display
|
|
12029
12319
|
*/
|
|
@@ -12036,11 +12326,10 @@ class TimeDisplayPipe {
|
|
|
12036
12326
|
* Format a time for display, accounting for user's display preferences.
|
|
12037
12327
|
*/
|
|
12038
12328
|
transform(time, showSeconds) {
|
|
12039
|
-
let display = '';
|
|
12040
12329
|
let formatString = '';
|
|
12041
12330
|
// use user-preferred formats
|
|
12042
12331
|
this.userPreferenceService.getPreferences().subscribe(result => {
|
|
12043
|
-
//if preferences exist then format time to users preference
|
|
12332
|
+
//if preferences exist then format time to users preference
|
|
12044
12333
|
//otherwise use the last user preference
|
|
12045
12334
|
if (result.preference) {
|
|
12046
12335
|
formatString = result.preference.timeFormat;
|
|
@@ -12050,8 +12339,7 @@ class TimeDisplayPipe {
|
|
|
12050
12339
|
this.lastFormatString = formatString;
|
|
12051
12340
|
}
|
|
12052
12341
|
});
|
|
12053
|
-
|
|
12054
|
-
return display;
|
|
12342
|
+
return DateTimeHelper.formatDate(time ?? null, this.lastFormatString);
|
|
12055
12343
|
}
|
|
12056
12344
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimeDisplayPipe, deps: [{ token: UserPreferenceService }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
12057
12345
|
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.4", ngImport: i0, type: TimeDisplayPipe, isStandalone: false, name: "timeDisplay" }); }
|
|
@@ -12079,21 +12367,21 @@ class RelativeDatePipe {
|
|
|
12079
12367
|
* If any of todayLabel, yesterdayLabel is supplied, use the supplied label.
|
|
12080
12368
|
*/
|
|
12081
12369
|
transform(timeSelected, options) {
|
|
12082
|
-
const selected =
|
|
12083
|
-
const today =
|
|
12084
|
-
const yesterday =
|
|
12370
|
+
const selected = DateTime.fromISO(timeSelected);
|
|
12371
|
+
const today = DateTime.now();
|
|
12372
|
+
const yesterday = today.minus({ days: 1 });
|
|
12085
12373
|
const timeDisplay = options?.dateOnly ? `` : ` ${this.timeDisplayPipe.transform(timeSelected)}`;
|
|
12086
12374
|
let displayValue = null;
|
|
12087
12375
|
let prefixValue = '';
|
|
12088
|
-
if (selected.
|
|
12376
|
+
if (selected.hasSame(today, 'day') && !options?.showTimeForToday) {
|
|
12089
12377
|
displayValue = this.translateService.instant(options?.todayLabel ? options?.todayLabel : 'today');
|
|
12090
12378
|
prefixValue = options?.todayPrefix ?? '';
|
|
12091
12379
|
}
|
|
12092
|
-
else if (selected.
|
|
12380
|
+
else if (selected.hasSame(today, 'day') && options?.showTimeForToday && !timeDisplay) {
|
|
12093
12381
|
displayValue = this.timeDisplayPipe.transform(timeSelected);
|
|
12094
12382
|
prefixValue = options?.todayTimePrefix ?? '';
|
|
12095
12383
|
}
|
|
12096
|
-
else if (selected.
|
|
12384
|
+
else if (selected.hasSame(yesterday, 'day')) {
|
|
12097
12385
|
displayValue = this.translateService.instant(options?.yesterdayLabel ? options?.yesterdayLabel : 'yesterday');
|
|
12098
12386
|
prefixValue = options?.yesterdayPrefix ?? '';
|
|
12099
12387
|
}
|
|
@@ -12123,13 +12411,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12123
12411
|
|
|
12124
12412
|
class PageTitleComponent {
|
|
12125
12413
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PageTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
12126
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: PageTitleComponent, isStandalone: false, selector: "app-page-title", inputs: { title: "title", titleIcon: "titleIcon", subTitle: "subTitle", subTitleUrl: "subTitleUrl" }, host: { classAttribute: "d-flex" }, ngImport: i0, template: "@if (titleIcon) {\n <i\n
|
|
12414
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: PageTitleComponent, isStandalone: false, selector: "app-page-title", inputs: { title: "title", titleIcon: "titleIcon", subTitle: "subTitle", subTitleUrl: "subTitleUrl" }, host: { classAttribute: "d-flex" }, ngImport: i0, template: "@if (titleIcon) {\n <i\n class=\"flex-shrink mr-1 my-1 ec-icon ec-icon-md {{titleIcon}}\"\n aria-hidden=\"true\"></i>\n}\n<div class=\"text-truncate\">\n @if (title) {\n <h1\n class=\"text-title-1 mb-0 py-1 text-truncate\"\n title=\"{{title}}\">{{title}}</h1>\n }\n @if (subTitle && !subTitleUrl) {\n <p\n class=\"text-caption-1 mb-0 mt-n1 text-truncate\">{{subTitle}}</p>\n }\n @if (subTitle && subTitleUrl) {\n <a\n id=\"subTitle_link\"\n class=\"d-block text-truncate mb-0 mt-n1 font-size-small\"\n routerLink=\"{{subTitleUrl}}\"\n target=\"_self\">\n {{subTitle}}\n </a>\n }\n</div>", dependencies: [{ kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] }); }
|
|
12127
12415
|
}
|
|
12128
12416
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PageTitleComponent, decorators: [{
|
|
12129
12417
|
type: Component,
|
|
12130
12418
|
args: [{ selector: 'app-page-title', host: {
|
|
12131
12419
|
class: 'd-flex'
|
|
12132
|
-
}, standalone: false, template: "@if (titleIcon) {\n <i\n
|
|
12420
|
+
}, standalone: false, template: "@if (titleIcon) {\n <i\n class=\"flex-shrink mr-1 my-1 ec-icon ec-icon-md {{titleIcon}}\"\n aria-hidden=\"true\"></i>\n}\n<div class=\"text-truncate\">\n @if (title) {\n <h1\n class=\"text-title-1 mb-0 py-1 text-truncate\"\n title=\"{{title}}\">{{title}}</h1>\n }\n @if (subTitle && !subTitleUrl) {\n <p\n class=\"text-caption-1 mb-0 mt-n1 text-truncate\">{{subTitle}}</p>\n }\n @if (subTitle && subTitleUrl) {\n <a\n id=\"subTitle_link\"\n class=\"d-block text-truncate mb-0 mt-n1 font-size-small\"\n routerLink=\"{{subTitleUrl}}\"\n target=\"_self\">\n {{subTitle}}\n </a>\n }\n</div>" }]
|
|
12133
12421
|
}], propDecorators: { title: [{
|
|
12134
12422
|
type: Input
|
|
12135
12423
|
}], titleIcon: [{
|
|
@@ -12731,6 +13019,7 @@ class ComponentsModule {
|
|
|
12731
13019
|
DateInputComponent,
|
|
12732
13020
|
KeyboardNavContainerDirective,
|
|
12733
13021
|
DateDisplayPipe2,
|
|
13022
|
+
DateDisplayPipe3,
|
|
12734
13023
|
MultiselectComponent], imports: [CommonModule,
|
|
12735
13024
|
FormsModule,
|
|
12736
13025
|
ReactiveFormsModule,
|
|
@@ -12803,7 +13092,8 @@ class ComponentsModule {
|
|
|
12803
13092
|
CalendarComponent,
|
|
12804
13093
|
DateInputComponent,
|
|
12805
13094
|
KeyboardNavContainerDirective,
|
|
12806
|
-
DateDisplayPipe2
|
|
13095
|
+
DateDisplayPipe2,
|
|
13096
|
+
DateDisplayPipe3] }); }
|
|
12807
13097
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ComponentsModule, providers: [
|
|
12808
13098
|
FormGroupHelper,
|
|
12809
13099
|
DialogService,
|
|
@@ -12813,7 +13103,8 @@ class ComponentsModule {
|
|
|
12813
13103
|
RowCountPipe,
|
|
12814
13104
|
RelativeDatePipe,
|
|
12815
13105
|
HighlightTextPipe,
|
|
12816
|
-
DateDisplayPipe2
|
|
13106
|
+
DateDisplayPipe2,
|
|
13107
|
+
DateDisplayPipe3
|
|
12817
13108
|
], imports: [CommonModule,
|
|
12818
13109
|
FormsModule,
|
|
12819
13110
|
ReactiveFormsModule,
|
|
@@ -12899,6 +13190,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12899
13190
|
DateInputComponent,
|
|
12900
13191
|
KeyboardNavContainerDirective,
|
|
12901
13192
|
DateDisplayPipe2,
|
|
13193
|
+
DateDisplayPipe3,
|
|
12902
13194
|
MultiselectComponent
|
|
12903
13195
|
],
|
|
12904
13196
|
imports: [
|
|
@@ -12920,7 +13212,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12920
13212
|
RowCountPipe,
|
|
12921
13213
|
RelativeDatePipe,
|
|
12922
13214
|
HighlightTextPipe,
|
|
12923
|
-
DateDisplayPipe2
|
|
13215
|
+
DateDisplayPipe2,
|
|
13216
|
+
DateDisplayPipe3
|
|
12924
13217
|
],
|
|
12925
13218
|
exports: [
|
|
12926
13219
|
ButtonComponent,
|
|
@@ -12988,7 +13281,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
12988
13281
|
CalendarComponent,
|
|
12989
13282
|
DateInputComponent,
|
|
12990
13283
|
KeyboardNavContainerDirective,
|
|
12991
|
-
DateDisplayPipe2
|
|
13284
|
+
DateDisplayPipe2,
|
|
13285
|
+
DateDisplayPipe3
|
|
12992
13286
|
]
|
|
12993
13287
|
}]
|
|
12994
13288
|
}] });
|
|
@@ -13984,5 +14278,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
13984
14278
|
* Generated bundle index. Do not edit.
|
|
13985
14279
|
*/
|
|
13986
14280
|
|
|
13987
|
-
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 };
|
|
14281
|
+
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 };
|
|
13988
14282
|
//# sourceMappingURL=energycap-components.mjs.map
|