@energycap/components 0.26.11-rounded-corners-plus.20220107-1502 → 0.26.11-rounded-corners-plus.20220107-1758

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.
@@ -2908,8 +2908,8 @@
2908
2908
  ComboboxComponent.decorators = [
2909
2909
  { type: i0.Component, args: [{
2910
2910
  selector: 'ec-combobox',
2911
- template: "<div class=\"control control-label-{{labelPosition}}\"\r\n [ngClass]=\"{'open': menuStatus === 'visible',\r\n 'invalid': formModel.touched && formModel.invalid,\r\n 'has-icon': (templateType === 'iconAndLabel' && formModel.value && formModel.value.icon && formModel.value.label === textboxFormModel.value),\r\n 'is-readonly': readonly,\r\n 'is-disabled': formModel.disabled,\r\n 'is-always-open': alwaysOpen}\">\r\n\r\n <label *ngIf=\"label\" ngPreserveWhitespaces>\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\">{{validationErrors}}</span>\r\n </label>\r\n\r\n <ng-container *ngIf=\"alwaysOpen; else popupTarget\">\r\n <div class=\"textbox-group control-input control-group\" [ngClass]=\"textboxElementClasses\">\r\n <ng-container *ngTemplateOutlet=\"textbox\"></ng-container>\r\n </div>\r\n\r\n <ng-container *ngIf=\"filteredOptions.length > 0 || textboxFormModel.value\">\r\n <ng-container *ngTemplateOutlet=\"dropdownmenu\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-template #popupTarget>\r\n <div class=\"textbox-group control-input\" [ngClass]=\"textboxElementClasses\" *ecPopup=\"dropdownmenu\">\r\n <ng-container *ngTemplateOutlet=\"textbox\"></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #textbox>\r\n <i class=\"ec-icon {{formModel.value?.icon}}\"></i>\r\n\r\n <ec-textbox class=\"textbox-group-input mb-0\"\r\n #textbox\r\n [id]=\"id\"\r\n [autofocus]=\"autofocus\"\r\n [formModel]=\"textboxFormModel\"\r\n [maxlength]=\"maxlength\"\r\n [minlength]=\"minlength\"\r\n [placeholder]=\"effectivePlaceholder\"\r\n [required]=\"required\"\r\n [tabindex]=\"tabindex\"\r\n [readonly]=\"readonly\"\r\n (input)=\"textboxValueChanged($event)\"\r\n (keydown)=\"keyNavigate($event)\"\r\n (focusout)=\"onBlur()\"\r\n [upperCase]=\"upperCase\"\r\n [pending]=\"pending && alwaysOpen\"\r\n [autocomplete]=\"'off'\"></ec-textbox>\r\n\r\n <ec-button class=\"textbox-group-btn-right\"\r\n *ngIf=\"!hideToggleButton\"\r\n [id]=\"id + '_button'\"\r\n [disabled]=\"formModel.disabled\"\r\n icon=\"icon-caret-down\"\r\n [tabindex]=\"-1\"\r\n type=\"secondary\"\r\n (click)=\"toggleMenu($event)\"\r\n (keydown)=\"keyNavigate($event)\"></ec-button>\r\n</ng-template>\r\n\r\n<ng-template #dropdownmenu>\r\n <div class=\"popup\"\r\n ecOverlay\r\n [status]=\"pending && !alwaysOpen ? 'pending' : 'hasData'\">\r\n\r\n <button class=\"add-new\"\r\n id=\"{{id}}_addNew\"\r\n #addNewButton\r\n [class.is-selected]=\"addNewSelected\"\r\n *ngIf=\"addNew\"\r\n [hidden]=\"foundMatch || (addNew === 'dynamic' && (!textboxFormModel.value || (formModel.value && textboxFormModel.value === formModel.value.label)))\"\r\n\r\n (click)=\"onAddNew($event)\">\r\n <span class=\"add-new-label ec-util-truncate\">\r\n <span *ngIf=\"addNew === 'static' || addNew === true\" translate>Add new...</span>\r\n <span *ngIf=\"addNew === 'dynamic'\">{{'Add' | translate}} <strong class=\"ec-util-truncate\" [ngClass]=\"{'text-uppercase': upperCase}\">{{textboxFormModel.value}}</strong></span>\r\n </span>\r\n <i class=\"ec-icon icon-add\"></i>\r\n </button>\r\n\r\n <ec-menu id=\"{{id}}_menu\"\r\n [class.border-top-0]=\"!filteredOptions.length && hideNoMatches\"\r\n [ngClass]=\"menuElementClasses\"\r\n [templateType]=\"templateType\"\r\n [customMenuTemplate]=\"customMenuTemplate\"\r\n [showNoItems]=\"!hideNoMatches\"\r\n [noDataText]=\"noMatchesText\"\r\n [items]=\"filteredOptions\"\r\n [selected]=\"selectedItem\"\r\n (selectedChanged)=\"selectedChanged($event)\"></ec-menu>\r\n\r\n <footer *ngIf=\"totalRecords && totalRecords > filteredOptions.length && filteredOptions.length > 0\">\r\n <span>{{filteredOptions.length}} {{'of' | translate}} {{totalRecords}}</span>\r\n </footer>\r\n </div>\r\n</ng-template>\r\n",
2912
- styles: ["@-webkit-keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{color:#1a1a23;display:block;font-family:Roboto,-apple-system,BlinkMacSystemFont,Segoe UI,Oxygen,Ubuntu,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1rem;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{display:flex;flex-direction:column;width:100%}: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-bottom:0;margin-top: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{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;background-clip:border-box;background-color:rgba(26,26,35,.12);background-image:none;border-color:transparent;color:#1a1a23;opacity:1;overflow:hidden;pointer-events:none;user-select:none;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:#fff8cc;background-image:url('data:image/svg+xml;charset=utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"><path fill=\"rgba(26, 26, 35, 0.66)\" d=\"M20.21 20.21h-8.42L10.95 0h10.1l-.84 20.21zm-8.42 3.37h8.42V32h-8.42z\"/></svg>');background-position:.25em;background-repeat:no-repeat;background-size:1em 1em;padding-left:1.5em}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:not(:focus),:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:not(:focus){border-color:#ffe433}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:#fff8cc}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:#ffe433}:host .textbox-group{display:flex;position:relative}:host input:focus,:host select:focus,:host textarea:focus{outline:none}:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-invalid,:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-valid{background-color:#fff8cc;background-image:url('data:image/svg+xml;charset=utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"><path fill=\"rgba(26, 26, 35, 0.66)\" d=\"M20.21 20.21h-8.42L10.95 0h10.1l-.84 20.21zm-8.42 3.37h8.42V32h-8.42z\"/></svg>');background-position:.25em;background-repeat:no-repeat;background-size:1em 1em;padding-left:1.5em}:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-invalid:not(:focus),:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-valid:not(:focus){border-color:#ffe433}:host(.invalid) .control:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:#fff8cc}:host(.invalid) .control:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:#ffe433}.control{position:relative}.control ec-textbox ::ng-deep input.ng-invalid.ng-touched{background-image:none;padding-left:.5rem}.control ec-textbox ::ng-deep input.ng-invalid.ng-touched:not(.is-empty)~.units-left{left:0}.control ec-textbox ::ng-deep input:required:not(:disabled).is-empty{background-color:#fff;background-image:url('data:image/svg+xml;charset=utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"><path fill=\"%23ffe433\" d=\"M31.32 21.69l-.09.18-2.48 4.35c-.36.54-.77.62-1.25.27-.12 0-.2 0-.2-.09L19.53 22v9.37a1.26 1.26 0 0 1-.72.67h-5.26c-.59 0-.83-.3-.83-.89 0-.12.15-.21.15-.27V22l-8 4.71h-.12c-.42.66-.8.21-1.16-.27L1 21.82a.82.82 0 0 1 .35-1.26l.18-.1L9 16 .87 11.47v-.09c0-.36-.39-.74-.09-1.16l2.75-4.35v-.09c0-.42.82-.54 1.29-.36l8 4.62V.89c0-.59.18-.89.77-.89h5c.65 0 .91.3.91.89V10l7.94-4.53c.48-.29.72-.21 1.08.27l2.32 4.35v.09c.66.48.45.89-.08 1.25L23 16l7.91 4.53v.09c-.04.18.53.54.41 1.07z\"/></svg>');background-position:.25em;background-repeat:no-repeat;background-size:1em 1em;border-color:#d2d7d9;padding-left:1.5em}.control ec-textbox ::ng-deep input:required:not(:disabled).is-empty:focus{border-color:#0084a9;box-shadow:0 0 0 1px #0084a9;position:relative;z-index:1}.control .textbox-group .ec-icon{display:none;left:.5rem;position:absolute;top:.5rem;z-index:2}.control.has-icon:not(.invalid) .ec-icon{display:inline-flex}.control.has-icon:not(.invalid) ec-textbox ::ng-deep input{padding-left:1.75em}.control.is-disabled .ec-icon{filter:grayscale(100%);opacity:.65}.control.is-readonly ec-textbox ::ng-deep input{border-bottom-right-radius:var(--ec-border-radius,.25rem);border-right-width:.0625rem;border-top-right-radius:var(--ec-border-radius,.25rem)}.control.is-readonly ec-button{display:none}.control.is-always-open{height:100%}.control.is-always-open .textbox-group,.control.is-always-open label{margin-left:1rem;margin-right:1rem}.control.is-always-open .textbox-group{margin-bottom:1rem}.control.is-always-open .popup{background-color:transparent;border:0;flex:1 1;margin:0;min-height:0;z-index:0}.control.is-always-open ec-menu{border-top:1px solid rgba(26,26,35,.18)}.control.is-always-open ec-menu ::ng-deep ul{max-height:none}label{color:rgba(26,26,35,.66);display:block;font-size:.75rem;line-height:1;margin:.375rem 0}.popup{background-color:#fff;border:.125rem solid #0084a9;margin-bottom:-1px;margin-top:-1px;z-index:50}ec-menu{display:block}ec-menu:not(:first-child){border-top:1px solid rgba(26,26,35,.18)}ec-menu ::ng-deep ul{max-height:30vh}ec-menu ::ng-deep ul li{white-space:nowrap}.add-new{align-items:center;background-color:#fff;border:0;cursor:pointer;display:flex;height:2rem;line-height:1.25;padding:.25rem .5714285714em;width:100%}.add-new.is-highlighted,.add-new.is-selected{background-color:#d9edf2}.add-new:focus{background-color:rgba(26,26,35,.38);outline:none;position:relative;z-index:1}.add-new:active{background-color:#0084a9;color:#fff}.add-new.is-disabled,.add-new:disabled{color:rgba(26,26,35,.66);cursor:default;opacity:.65}.add-new .label{align-items:center;display:flex;flex:auto}.add-new .ec-icon+.label{margin:0 .375rem}.add-new.is-selected,.add-new:hover:not(:active){background-color:#bfe0e9}.add-new:active .ec-icon{color:inherit}.add-new-label{flex:1 1;margin-right:.5rem;text-align:left}.add-new .ec-icon{flex:0 0 auto}footer{border-top:1px solid rgba(26,26,35,.18);color:rgba(26,26,35,.38);font-size:.75rem;line-height:1;padding:.5rem;text-align:right}ec-button ::ng-deep button .ec-icon{background-position:50%;background-size:1em}.open:not(.is-always-open) .textbox-group ec-textbox ::ng-deep input{border-color:#d2d7d9;box-shadow:none}.open:not(.is-always-open) .textbox-group ec-button ::ng-deep button{background-color:#bfe0e9;box-shadow:none}"]
2911
+ template: "<div class=\"control control-label-{{labelPosition}}\"\r\n [ngClass]=\"{'open': menuStatus === 'visible',\r\n 'invalid': formModel.touched && formModel.invalid,\r\n 'has-icon': (templateType === 'iconAndLabel' && formModel.value && formModel.value.icon && formModel.value.label === textboxFormModel.value),\r\n 'is-readonly': readonly,\r\n 'is-disabled': formModel.disabled,\r\n 'is-always-open': alwaysOpen}\">\r\n\r\n <label *ngIf=\"label\" ngPreserveWhitespaces>\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\">{{validationErrors}}</span>\r\n </label>\r\n\r\n <ng-container *ngIf=\"alwaysOpen; else popupTarget\">\r\n <div class=\"textbox-group control-input\" [ngClass]=\"textboxElementClasses\">\r\n <ng-container *ngTemplateOutlet=\"textbox\"></ng-container>\r\n </div>\r\n\r\n <ng-container *ngIf=\"filteredOptions.length > 0 || textboxFormModel.value\">\r\n <ng-container *ngTemplateOutlet=\"dropdownmenu\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</div>\r\n\r\n<ng-template #popupTarget>\r\n <div class=\"textbox-group control-input\" [ngClass]=\"textboxElementClasses\" *ecPopup=\"dropdownmenu\">\r\n <ng-container *ngTemplateOutlet=\"textbox\"></ng-container>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #textbox>\r\n <i class=\"ec-icon {{formModel.value?.icon}}\"></i>\r\n\r\n <ec-textbox class=\"textbox-group-input mb-0\"\r\n #textbox\r\n [id]=\"id\"\r\n [autofocus]=\"autofocus\"\r\n [formModel]=\"textboxFormModel\"\r\n [maxlength]=\"maxlength\"\r\n [minlength]=\"minlength\"\r\n [placeholder]=\"effectivePlaceholder\"\r\n [required]=\"required\"\r\n [tabindex]=\"tabindex\"\r\n [readonly]=\"readonly\"\r\n (input)=\"textboxValueChanged($event)\"\r\n (keydown)=\"keyNavigate($event)\"\r\n (focusout)=\"onBlur()\"\r\n [upperCase]=\"upperCase\"\r\n [pending]=\"pending && alwaysOpen\"\r\n [autocomplete]=\"'off'\"></ec-textbox>\r\n\r\n <ec-button class=\"textbox-group-btn-right\"\r\n *ngIf=\"!hideToggleButton\"\r\n [id]=\"id + '_button'\"\r\n [disabled]=\"formModel.disabled\"\r\n icon=\"icon-caret-down\"\r\n [tabindex]=\"-1\"\r\n type=\"secondary\"\r\n (click)=\"toggleMenu($event)\"\r\n (keydown)=\"keyNavigate($event)\"></ec-button>\r\n</ng-template>\r\n\r\n<ng-template #dropdownmenu>\r\n <div class=\"popup\"\r\n ecOverlay\r\n [status]=\"pending && !alwaysOpen ? 'pending' : 'hasData'\">\r\n\r\n <button class=\"add-new\"\r\n id=\"{{id}}_addNew\"\r\n #addNewButton\r\n [class.is-selected]=\"addNewSelected\"\r\n *ngIf=\"addNew\"\r\n [hidden]=\"foundMatch || (addNew === 'dynamic' && (!textboxFormModel.value || (formModel.value && textboxFormModel.value === formModel.value.label)))\"\r\n\r\n (click)=\"onAddNew($event)\">\r\n <span class=\"add-new-label ec-util-truncate\">\r\n <span *ngIf=\"addNew === 'static' || addNew === true\" translate>Add new...</span>\r\n <span *ngIf=\"addNew === 'dynamic'\">{{'Add' | translate}} <strong class=\"ec-util-truncate\" [ngClass]=\"{'text-uppercase': upperCase}\">{{textboxFormModel.value}}</strong></span>\r\n </span>\r\n <i class=\"ec-icon icon-add\"></i>\r\n </button>\r\n\r\n <ec-menu id=\"{{id}}_menu\"\r\n [class.border-top-0]=\"!filteredOptions.length && hideNoMatches\"\r\n [ngClass]=\"menuElementClasses\"\r\n [templateType]=\"templateType\"\r\n [customMenuTemplate]=\"customMenuTemplate\"\r\n [showNoItems]=\"!hideNoMatches\"\r\n [noDataText]=\"noMatchesText\"\r\n [items]=\"filteredOptions\"\r\n [selected]=\"selectedItem\"\r\n (selectedChanged)=\"selectedChanged($event)\"></ec-menu>\r\n\r\n <footer *ngIf=\"totalRecords && totalRecords > filteredOptions.length && filteredOptions.length > 0\">\r\n <span>{{filteredOptions.length}} {{'of' | translate}} {{totalRecords}}</span>\r\n </footer>\r\n </div>\r\n</ng-template>\r\n",
2912
+ styles: ["@-webkit-keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{color:#1a1a23;display:block;font-family:Roboto,-apple-system,BlinkMacSystemFont,Segoe UI,Oxygen,Ubuntu,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:1rem;margin-bottom:1rem;width:100%}:host :host-context(.form-condensed){margin-bottom:.5rem}:host .control{display:flex;flex-direction:column;width:100%}: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-bottom:0;margin-top: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{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;background-clip:border-box;background-color:rgba(26,26,35,.12);background-image:none;border-color:transparent;color:#1a1a23;opacity:1;overflow:hidden;pointer-events:none;user-select:none;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:#fff8cc;background-image:url('data:image/svg+xml;charset=utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"><path fill=\"rgba(26, 26, 35, 0.66)\" d=\"M20.21 20.21h-8.42L10.95 0h10.1l-.84 20.21zm-8.42 3.37h8.42V32h-8.42z\"/></svg>');background-position:.25em;background-repeat:no-repeat;background-size:1em 1em;padding-left:1.5em}:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-invalid:not(:focus),:host .control.invalid .textbox-group-input ::ng-deep .control input.ng-valid:not(:focus){border-color:#ffe433}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:#fff8cc}:host .control.invalid:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:#ffe433}:host .textbox-group{display:flex;position:relative}:host input:focus,:host select:focus,:host textarea:focus{outline:none}:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-invalid,:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-valid{background-color:#fff8cc;background-image:url('data:image/svg+xml;charset=utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"><path fill=\"rgba(26, 26, 35, 0.66)\" d=\"M20.21 20.21h-8.42L10.95 0h10.1l-.84 20.21zm-8.42 3.37h8.42V32h-8.42z\"/></svg>');background-position:.25em;background-repeat:no-repeat;background-size:1em 1em;padding-left:1.5em}:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-invalid:not(:focus),:host(.invalid) .control .textbox-group-input ::ng-deep .control input.ng-valid:not(:focus){border-color:#ffe433}:host(.invalid) .control:not(.open) .textbox-group-btn-right ::ng-deep button{background-color:#fff8cc}:host(.invalid) .control:not(.open) .textbox-group-btn-right ::ng-deep button:not(:focus){border-color:#ffe433}.control{position:relative}.control ec-textbox ::ng-deep input.ng-invalid.ng-touched{background-image:none;padding-left:.5rem}.control ec-textbox ::ng-deep input.ng-invalid.ng-touched:not(.is-empty)~.units-left{left:0}.control ec-textbox ::ng-deep input:required:not(:disabled).is-empty{background-color:#fff;background-image:url('data:image/svg+xml;charset=utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"><path fill=\"%23ffe433\" d=\"M31.32 21.69l-.09.18-2.48 4.35c-.36.54-.77.62-1.25.27-.12 0-.2 0-.2-.09L19.53 22v9.37a1.26 1.26 0 0 1-.72.67h-5.26c-.59 0-.83-.3-.83-.89 0-.12.15-.21.15-.27V22l-8 4.71h-.12c-.42.66-.8.21-1.16-.27L1 21.82a.82.82 0 0 1 .35-1.26l.18-.1L9 16 .87 11.47v-.09c0-.36-.39-.74-.09-1.16l2.75-4.35v-.09c0-.42.82-.54 1.29-.36l8 4.62V.89c0-.59.18-.89.77-.89h5c.65 0 .91.3.91.89V10l7.94-4.53c.48-.29.72-.21 1.08.27l2.32 4.35v.09c.66.48.45.89-.08 1.25L23 16l7.91 4.53v.09c-.04.18.53.54.41 1.07z\"/></svg>');background-position:.25em;background-repeat:no-repeat;background-size:1em 1em;border-color:#d2d7d9;padding-left:1.5em}.control ec-textbox ::ng-deep input:required:not(:disabled).is-empty:focus{border-color:#0084a9;box-shadow:0 0 0 1px #0084a9;position:relative;z-index:1}.control .textbox-group .ec-icon{display:none;left:.5rem;position:absolute;top:.5rem;z-index:2}.control.has-icon:not(.invalid) .ec-icon{display:inline-flex}.control.has-icon:not(.invalid) ec-textbox ::ng-deep input{padding-left:1.75em}.control.is-disabled .ec-icon{filter:grayscale(100%);opacity:.65}.control.is-readonly ec-textbox ::ng-deep input{border-bottom-right-radius:var(--ec-border-radius,.25rem);border-right-width:.0625rem;border-top-right-radius:var(--ec-border-radius,.25rem)}.control.is-readonly ec-button{display:none}.control.is-always-open{height:100%}.control.is-always-open .textbox-group,.control.is-always-open label{margin-left:1rem;margin-right:1rem}.control.is-always-open .textbox-group{margin-bottom:1rem}.control.is-always-open .popup{background-color:transparent;border:0;box-shadow:none;flex:1 1;margin:0;min-height:0;z-index:0}.control.is-always-open ec-menu{border-top:1px solid rgba(26,26,35,.18)}.control.is-always-open ec-menu ::ng-deep ul{max-height:none}label{color:rgba(26,26,35,.66);display:block;font-size:.75rem;line-height:1;margin:.375rem 0}.popup{background-color:#fff;border-radius:var(--ec-border-radius);box-shadow:var(--ec-box-shadow-overlay);margin-bottom:.25rem;margin-top:.25rem;overflow:hidden;z-index:50}ec-menu{display:block}ec-menu:not(:first-child){border-top:1px solid rgba(26,26,35,.18)}ec-menu ::ng-deep ul{max-height:30vh}ec-menu ::ng-deep ul li{white-space:nowrap}.add-new{align-items:center;background-color:#fff;border:0;cursor:pointer;display:flex;height:2rem;line-height:1.25;padding:.25rem .5714285714em;width:100%}.add-new.is-highlighted,.add-new.is-selected{background-color:#d9edf2}.add-new:focus{background-color:rgba(26,26,35,.38);outline:none;position:relative;z-index:1}.add-new:active{background-color:#0084a9;color:#fff}.add-new.is-disabled,.add-new:disabled{color:rgba(26,26,35,.66);cursor:default;opacity:.65}.add-new .label{align-items:center;display:flex;flex:auto}.add-new .ec-icon+.label{margin:0 .375rem}.add-new.is-selected,.add-new:hover:not(:active){background-color:#bfe0e9}.add-new:active .ec-icon{color:inherit}.add-new-label{flex:1 1;margin-right:.5rem;text-align:left}.add-new .ec-icon{flex:0 0 auto}footer{border-top:1px solid rgba(26,26,35,.18);color:rgba(26,26,35,.38);font-size:.75rem;line-height:1;padding:.5rem;text-align:right}ec-button ::ng-deep button .ec-icon{background-position:50%;background-size:1em}.open:not(.is-always-open) .textbox-group ec-textbox ::ng-deep input{border-color:#d2d7d9;box-shadow:none}.open:not(.is-always-open) .textbox-group ec-button ::ng-deep button{background-color:#bfe0e9;box-shadow:none}"]
2913
2913
  },] }
2914
2914
  ];
2915
2915
  ComboboxComponent.ctorParameters = function () { return [
@@ -3524,8 +3524,8 @@
3524
3524
  MenuComponent.decorators = [
3525
3525
  { type: i0.Component, args: [{
3526
3526
  selector: 'ec-menu',
3527
- template: "<nav>\r\n <div class=\"parent\"\r\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\r\n <header id=\"{{id}}_header\"\r\n class=\"item-wrapper text-heading-3\"\r\n [class.is-selected]=\"highlightedItemIndex === -1\"\r\n *ngIf=\"parent\"\r\n (click)=\"back($event)\">\r\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\r\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\r\n </header>\r\n\r\n <ul id=\"{{id}}_list\">\r\n <li *ngFor=\"let item of items; index as i\"\r\n id=\"{{item.id || id + '_item' + i}}\"\r\n class=\"{{item.display || 'item'}} {{item.classList}}\"\r\n [attr.disabled]=\"item.disabled\"\r\n [hidden]=\"item.hidden\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\r\n (routerLinkActivated)=\"selectItem($event, item)\"\r\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': item?.display === 'heading'}\"\r\n (click)=\"selectItem($event, item)\">\r\n\r\n <a *ngIf=\"item.url && !item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n class=\"item-wrapper\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams || null\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <a *ngIf=\"item.url && item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n class=\"item-wrapper\"\r\n href=\"{{item.url}}\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <div *ngIf=\"!item.url\"\r\n class=\"item-wrapper\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\r\n </div>\r\n\r\n <!-- Child menu (Rendered to the right) -->\r\n <ec-menu *ngIf=\"selected?.items\"\r\n id=\"{{id}}_child\"\r\n class=\"child\"\r\n [parent]=\"selected\"\r\n [items]=\"selected?.items\"\r\n [showNoItems]=\"true\"\r\n [templateType]=\"templateType\"\r\n [enableKeyNav]=\"true\"\r\n (selectedChanged)=\"onSelection($event)\"\r\n (menuClosed)=\"toggleChildMenu(false)\">\r\n </ec-menu>\r\n</nav>\r\n\r\n<!-- 'label' Item Template -->\r\n<ng-template #label\r\n let-item>\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\" *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'checkAndLabel' Item Template -->\r\n<ng-template #checkAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon icon-check ec-icon-sm\" *ngIf=\"item.display !== 'heading'\"></i>\r\n\r\n <i class=\"ec-icon {{item.icon}} ml-2\" *ngIf=\"item.icon\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\" *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'iconAndLabel' Item Template -->\r\n<ng-template #iconAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon {{item.icon}}\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\" *ngIf=\"item?.items\"></i>\r\n</ng-template>",
3528
- styles: ["@-webkit-keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{background-color:#fff;display:block;font-size:.875rem;font-weight:400}:host.open>nav>.child,:host.open>nav>.parent{height:100%;left:0;position:absolute;right:0;top:0;transition:transform .25s ease}:host.open>nav>.parent{transform:translateX(0)}:host.open>nav>.child{transform:translateX(100%)}:host.open-active>nav>.parent{transform:translateX(-100%)}:host.open-active>nav>.child{transform:translateX(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{height:100%;overflow:hidden}.parent,nav{display:flex;position:relative}.parent{flex:auto;flex-direction:column;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-highlighted,.parent>header.is-selected{background-color:#d9edf2}.parent>header:hover{background-color:#bfe0e9}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{flex:auto;height:100%;list-style:none;margin:0;overflow-y:auto;padding:0}ul li{cursor:pointer}ul li a{border-bottom:0;color:inherit;text-decoration:none}ul li.is-highlighted,ul li.is-selected{background-color:#d9edf2}ul li:hover .item-wrapper{background-color:#bfe0e9}ul li:focus{background-color:rgba(26,26,35,.38);outline:none;position:relative;z-index:1}ul li.is-disabled{color:rgba(26,26,35,.66);cursor:default;opacity:.65}ul li.is-disabled,ul li.is-readonly{background-color:transparent;color:inherit;cursor:default}ul li.is-checked .icon-check{opacity:1}ul li.heading{background-color:transparent;cursor:default}ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider{border-bottom:1px solid #d2d7d9;margin-bottom:.5rem;padding-bottom:.5rem}.item-wrapper{color:inherit;cursor:inherit;display:flex;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{flex:none;margin-top:.125rem}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:.25rem}.item-wrapper .icon-check{opacity:0}.no-data-message{color:rgba(26,26,35,.38);display:none;font-size:1rem;margin-bottom:0;padding:1rem;text-align:center}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li{white-space:nowrap}:host-context(ec-tree) li.is-highlighted,:host-context(ec-tree) li.is-selected{font-weight:700}:host-context(ec-tree) li.is-highlighted:not(:hover),:host-context(ec-tree) li.is-selected:not(:hover){background-color:transparent}:host-context(.popup) ul{padding-bottom:.5rem;padding-top:.5rem}"]
3527
+ template: "<nav>\r\n <div class=\"parent\"\r\n [class.no-data]=\"showNoItems && (!items || items.length === 0)\">\r\n <header id=\"{{id}}_header\"\r\n class=\"text-heading-3 p-1\"\r\n [class.is-selected]=\"highlightedItemIndex === -1\"\r\n *ngIf=\"parent\"\r\n (click)=\"back($event)\">\r\n <div class=\"item-wrapper\">\r\n <i class=\"ec-icon icon-angle-down rotate-90 flex-shrink\"></i>\r\n <span class=\"label text-truncate flex-grow\">{{parent?.label}}</span>\r\n </div>\r\n </header>\r\n\r\n <ul id=\"{{id}}_list\" class=\"py-1\">\r\n <li *ngFor=\"let item of items; index as i\"\r\n id=\"{{item.id || id + '_item' + i}}\"\r\n class=\"{{item.display || 'item'}} {{item.classList}}\"\r\n [attr.disabled]=\"item.disabled\"\r\n [hidden]=\"item.hidden\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]='item.isActiveExactMatch'\r\n (routerLinkActivated)=\"selectItem($event, item)\"\r\n [ngClass]=\"{'is-highlighted':(selected === item && item?.display !== 'heading') || highlightedItem === item, 'is-link': item.url, 'is-disabled': item.disabled, 'is-readonly': item.readonly, 'is-checked': item.checked, 'text-heading-3': item?.display === 'heading'}\"\r\n (click)=\"selectItem($event, item)\">\r\n\r\n <a *ngIf=\"item.url && !item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n class=\"item-wrapper\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams || null\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <a *ngIf=\"item.url && item.externalLink\"\r\n id=\"{{item.id}}_link\"\r\n class=\"item-wrapper\"\r\n href=\"{{item.url}}\"\r\n target=\"{{item.target || '_self'}}\">\r\n\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </a>\r\n\r\n <div *ngIf=\"!item.url\"\r\n class=\"item-wrapper\">\r\n <ng-container *ngTemplateOutlet=\"internalizedTemplate; context: {$implicit: item}\"></ng-container>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n <p class=\"no-data-message\">{{noDataText | translate}}</p>\r\n </div>\r\n\r\n <!-- Child menu (Rendered to the right) -->\r\n <ec-menu *ngIf=\"selected?.items\"\r\n id=\"{{id}}_child\"\r\n class=\"child\"\r\n [parent]=\"selected\"\r\n [items]=\"selected?.items\"\r\n [showNoItems]=\"true\"\r\n [templateType]=\"templateType\"\r\n [enableKeyNav]=\"true\"\r\n (selectedChanged)=\"onSelection($event)\"\r\n (menuClosed)=\"toggleChildMenu(false)\">\r\n </ec-menu>\r\n</nav>\r\n\r\n<!-- 'label' Item Template -->\r\n<ng-template #label\r\n let-item>\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\" *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'checkAndLabel' Item Template -->\r\n<ng-template #checkAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon icon-check ec-icon-sm\" *ngIf=\"item.display !== 'heading'\"></i>\r\n\r\n <i class=\"ec-icon {{item.icon}} ml-2\" *ngIf=\"item.icon\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\" *ngIf=\"item?.items\"></i>\r\n</ng-template>\r\n\r\n<!-- 'iconAndLabel' Item Template -->\r\n<ng-template #iconAndLabel\r\n let-item>\r\n\r\n <i class=\"ec-icon {{item.icon}}\"></i>\r\n\r\n <span id=\"{{item.id}}_label\"\r\n class=\"label\">{{item.label}}</span>\r\n\r\n <i class=\"ec-icon icon-angle-down rotate-270\" *ngIf=\"item?.items\"></i>\r\n</ng-template>",
3528
+ styles: ["@-webkit-keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{background-color:#fff;display:block;font-size:.875rem;font-weight:400}:host.open>nav>.child,:host.open>nav>.parent{height:100%;left:0;position:absolute;right:0;top:0;transition:transform .25s ease}:host.open>nav>.parent{transform:translateX(0)}:host.open>nav>.child{transform:translateX(100%)}:host.open-active>nav>.parent{transform:translateX(-100%)}:host.open-active>nav>.child{transform:translateX(0)}:host(.bg-transparent){background-color:transparent}:host-context(.is-always-open){height:100%}:host-context(.is-always-open) .item-wrapper{padding-left:1rem;padding-right:1rem}nav{height:100%;overflow:hidden}.parent,nav{display:flex;position:relative}.parent{flex:auto;flex-direction:column;max-width:100%}.parent>header{cursor:pointer}.parent>header.is-highlighted .item-wrapper,.parent>header.is-selected .item-wrapper{background-color:#d9edf2}.parent>header:hover .item-wrapper{background-color:#bfe0e9}.parent.no-data ul{display:none}.parent.no-data .no-data-message{display:block}ul{flex:auto;height:100%;list-style:none;margin:0;overflow-y:auto;padding:0}ul li{cursor:pointer;padding:0 .25rem}ul li a{border-bottom:0;color:inherit;text-decoration:none}ul li.is-highlighted .item-wrapper,ul li.is-selected .item-wrapper{background-color:#d9edf2}ul li:hover .item-wrapper{background-color:#bfe0e9}ul li:focus .item-wrapper{background-color:rgba(26,26,35,.38);outline:none;position:relative;z-index:1}ul li.is-disabled .item-wrapper{color:rgba(26,26,35,.66);opacity:.65}ul li.is-disabled,ul li.is-readonly{cursor:default}ul li.is-disabled .item-wrapper,ul li.is-readonly .item-wrapper{background-color:transparent;color:inherit}ul li.is-checked .icon-check{opacity:1}ul li.heading{cursor:default}ul li.heading .item-wrapper{background-color:transparent}ul li.heading:not(:first-child){margin-top:.5rem}ul li.divider{border-bottom:1px solid #d2d7d9;margin-bottom:.25rem;padding-bottom:.25rem}ul li.indent-1 .item-wrapper{padding-left:1.5rem}ul li.indent-2 .item-wrapper{padding-left:2.5rem}ul li.indent-3 .item-wrapper{padding-left:3.5rem}.item-wrapper{border-radius:var(--ec-border-radius,.25rem);color:inherit;cursor:inherit;display:flex;line-height:1.25rem;min-height:1.75rem;padding:.25rem .5rem}.item-wrapper .label{margin-right:auto}.item-wrapper .label+.ec-icon{margin-left:.5rem}.item-wrapper .ec-icon{flex:none;margin-top:.125rem}.item-wrapper .ec-icon+.label{margin-left:.5rem}.item-wrapper .ec-icon-sm{margin-top:.25rem}.item-wrapper .icon-check{opacity:0}.no-data-message{color:rgba(26,26,35,.38);display:none;font-size:1rem;margin-bottom:0;padding:1rem;text-align:center}:host-context(ec-tree) ul{overflow-x:hidden}:host-context(ec-tree) li{white-space:nowrap}:host-context(ec-tree) li.is-highlighted,:host-context(ec-tree) li.is-selected{font-weight:700}:host-context(ec-tree) li.is-highlighted:not(:hover),:host-context(ec-tree) li.is-selected:not(:hover){background-color:transparent}"]
3529
3529
  },] }
3530
3530
  ];
3531
3531
  MenuComponent.ctorParameters = function () { return [
@@ -8064,6 +8064,256 @@
8064
8064
  { type: UserPreferenceService }
8065
8065
  ]; };
8066
8066
 
8067
+ var HierarchyItem = /** @class */ (function () {
8068
+ function HierarchyItem() {
8069
+ this.id = '';
8070
+ /** Label to display for the item */
8071
+ this.label = '';
8072
+ /** Indicates how many levels deep the item is in the parent structure */
8073
+ this.level = 0;
8074
+ /** Display item as a link or a heading */
8075
+ this.display = 'default';
8076
+ /** Set to hide toggle, even if item has children */
8077
+ this.hideToggle = false;
8078
+ /** Flag to indicate whether the item has children or not, mostly drives
8079
+ * whether you get the expand/collapse button
8080
+ */
8081
+ this.hasChildren = false;
8082
+ /** Array of children if any for the item */
8083
+ this.children = [];
8084
+ /** Flag to indicate if the item has been expanded */
8085
+ this.expanded = false;
8086
+ /** Flag to indicate if the item is selected */
8087
+ this.selected = false;
8088
+ /** Flag to indicate if the item can be selected */
8089
+ this.selectable = false;
8090
+ this.readonly = false;
8091
+ /** Status of each item to indicate whether children lookup is pending or
8092
+ * if an error occurred retrieving data
8093
+ */
8094
+ this.status = "hasData";
8095
+ /** Indicates if the item is a top level entity, e.g. Organization or Cost Center */
8096
+ this.topLevel = false;
8097
+ /**
8098
+ * When checking the url for activeness, the url must match exactly or partially
8099
+ * @see https://angular.io/guide/router#active-router-links
8100
+ */
8101
+ this.isActiveExactMatch = true;
8102
+ }
8103
+ return HierarchyItem;
8104
+ }());
8105
+ var HierarchyBase = /** @class */ (function () {
8106
+ function HierarchyBase(injector) {
8107
+ /** Event emitter to request children for a given item */
8108
+ this.getItemChildren = new i0.EventEmitter();
8109
+ /**
8110
+ * Used to unsubscribe from observables
8111
+ */
8112
+ this._destroyed = new rxjs.Subject();
8113
+ this.telemetryService = injector.get(TelemetryService);
8114
+ }
8115
+ Object.defineProperty(HierarchyBase.prototype, "destroyed", {
8116
+ get: function () {
8117
+ return this._destroyed;
8118
+ },
8119
+ enumerable: false,
8120
+ configurable: true
8121
+ });
8122
+ HierarchyBase.prototype.ngOnChanges = function (changes) {
8123
+ if (changes && changes.rootNode && changes.rootNode.currentValue) {
8124
+ /** If the rootNode has children and we don't know about them yet we must be loading
8125
+ * the view without the new hierarchy api
8126
+ */
8127
+ if (this.rootNode.hasChildren && this.rootNode.children.length === 0) {
8128
+ this.getItemChildren.emit(this.rootNode);
8129
+ }
8130
+ }
8131
+ };
8132
+ /**
8133
+ * Function called when the component is destroyed
8134
+ */
8135
+ HierarchyBase.prototype.ngOnDestroy = function () {
8136
+ this.destroyed.next();
8137
+ this.destroyed.unsubscribe();
8138
+ };
8139
+ /** Handler for the toggle button */
8140
+ HierarchyBase.prototype.toggleItemClicked = function (item, expanded) {
8141
+ item.expanded = expanded;
8142
+ this.telemetryService.trackEvent('toggle-tree-node', {
8143
+ newExpandState: item.expanded ? 'expanded' : 'collapsed',
8144
+ itemDepth: "" + item.level,
8145
+ });
8146
+ if (item.expanded && item.hasChildren && item.children.length === 0) {
8147
+ item.status = "pending";
8148
+ this.getItemChildren.emit(item);
8149
+ }
8150
+ };
8151
+ /** Method exposed to the parent component to set the items children once they are available
8152
+ */
8153
+ HierarchyBase.prototype.setItemChildren = function (parentItem, items) {
8154
+ parentItem.children = items;
8155
+ parentItem.status = "hasData";
8156
+ };
8157
+ /** Method exposed to the parent component to indicate that something happened on the
8158
+ * item that caused an error, could be retrieving children
8159
+ */
8160
+ HierarchyBase.prototype.setItemError = function (parentItem) {
8161
+ parentItem.status = "error";
8162
+ };
8163
+ return HierarchyBase;
8164
+ }());
8165
+ HierarchyBase.decorators = [
8166
+ { type: i0.Directive }
8167
+ ];
8168
+ HierarchyBase.ctorParameters = function () { return [
8169
+ { type: i0.Injector }
8170
+ ]; };
8171
+ HierarchyBase.propDecorators = {
8172
+ rootNode: [{ type: i0.Input }],
8173
+ getItemChildren: [{ type: i0.Output }]
8174
+ };
8175
+
8176
+ var HierarchyTreeComponent = /** @class */ (function (_super) {
8177
+ __extends(HierarchyTreeComponent, _super);
8178
+ function HierarchyTreeComponent(scrollService, injector) {
8179
+ var _this = _super.call(this, injector) || this;
8180
+ _this.scrollService = scrollService;
8181
+ /** The value of the id attribute of the tree's root HTMLUListElement, suffixed with '_root' */
8182
+ _this.id = 'HierarchyTree';
8183
+ /** Emits a HierarchyItem whenever one is selected by clicking */
8184
+ _this.itemSelected = new rxjs.Subject();
8185
+ /** The width of the spacing before a tree node, multipled by a HierarchyItem's level. Value is in pixels */
8186
+ _this.indent = 16;
8187
+ /** The value of the id attribute of the tree's scroll container element, used to scroll a selected item into view. */
8188
+ _this.scrollContainerId = '';
8189
+ return _this;
8190
+ }
8191
+ HierarchyTreeComponent.prototype.ngOnInit = function () {
8192
+ this.scrollContainerId = this.id + "_root";
8193
+ };
8194
+ /**
8195
+ * Scroll to the item currently marked as is-selected. Wait a tick for the
8196
+ * NavItemActiveDirective to update the selected class.
8197
+ */
8198
+ HierarchyTreeComponent.prototype.scrollToSelectedItem = function () {
8199
+ var _this = this;
8200
+ window.setTimeout(function () {
8201
+ var linkSelector = ".item-wrapper.is-selected";
8202
+ _this.scrollService.scrollToItem("#" + _this.scrollContainerId, linkSelector);
8203
+ });
8204
+ };
8205
+ /**
8206
+ * When a HierarchyItem is selected, update the value of the activeUrl property with the value
8207
+ * of that item's url property and emit the item to any subscribers.
8208
+ */
8209
+ HierarchyTreeComponent.prototype.selectItem = function (item) {
8210
+ this.itemSelected.next(item);
8211
+ if (item.display === 'heading' && !item.hideToggle) {
8212
+ this.toggleItemClicked(item, !item.expanded);
8213
+ }
8214
+ };
8215
+ return HierarchyTreeComponent;
8216
+ }(HierarchyBase));
8217
+ HierarchyTreeComponent.decorators = [
8218
+ { type: i0.Component, args: [{
8219
+ selector: 'ec-hierarchy-tree',
8220
+ template: "<ul id=\"{{scrollContainerId}}\"\r\n class=\"flex-grow scroll-y py-1\">\r\n\r\n <li *ngIf=\"!hideRootNode\">\r\n <div class=\"item-wrapper\"\r\n [ngClass]=\"{'is-heading': rootNode?.display === 'heading'}\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveUrl]=\"rootNode?.url\"\r\n [ecNavItemActiveExactMatch]='rootNode?.isActiveExactMatch'>\r\n <a id=\"rootNode_{{rootNode?.id}}_link\"\r\n class=\"item flex-grow d-flex align-items-center\"\r\n routerLink=\"{{rootNode?.url}}\"\r\n [queryParams]=\"rootNode?.queryParams\">\r\n <i class=\"ec-icon {{rootNode.icon}} mx-1 flex-shrink\"\r\n *ngIf=\"rootNode?.icon\"></i>\r\n <span class=\"mx-1\">{{rootNode?.label}}</span>\r\n </a>\r\n </div>\r\n </li>\r\n\r\n <ng-template #hierarchyView\r\n let-items>\r\n <li *ngFor=\"let item of items; index as index; first as isFirst\"\r\n id=\"treeItem_{{item.id}}\">\r\n <div class=\"item-wrapper\"\r\n [ngClass]=\"{'is-heading': item.display === 'heading'}\"\r\n ecNavItemActive=\"is-selected\"\r\n [ecNavItemActiveUrl]=\"item.url\"\r\n [ecNavItemActiveExactMatch]=\"item.isActiveExactMatch\"\r\n [ecNavItemActiveQueryParams]=\"item.queryParams\">\r\n\r\n <!-- This element provides the indentation for each level -->\r\n <span id=\"indent_{{item.id}}\"\r\n class=\"d-block h-100\"\r\n [style.width.px]=\"(indent) * (item.level - 1) + (item.level * 4) + (item.hasChildren ? 0 : indent)\">\r\n </span>\r\n\r\n <!-- Toggle the button icon to be a spinner when item.status is pending -->\r\n <ec-collapsible-toggle id=\"toggle_{{item.id}}\"\r\n class=\"flex-shrink\"\r\n [style.width.px]=\"indent\"\r\n *ngIf=\"item.hasChildren && !item.hideToggle\"\r\n [hidden]=\"item.status === 'pending'\"\r\n [expanded]=\"item.expanded\"\r\n (expandedChange)=\"toggleItemClicked(item, $event)\">\r\n </ec-collapsible-toggle>\r\n\r\n <i class=\"ec-icon icon-loading my-1\"\r\n [hidden]=\"item.status !== 'pending'\"></i>\r\n\r\n <a id=\"treeItem_{{item.id}}_link\"\r\n class=\"item\"\r\n *ngIf=\"item.url\"\r\n (click)=\"selectItem(item)\"\r\n [routerLink]=\"item.url\"\r\n [queryParams]=\"item.queryParams\"\r\n [queryParamsHandling]=\"item.queryParamsHandling || ''\">\r\n <i class=\"ec-icon {{item.icon}} mx-1 flex-shrink\"\r\n *ngIf=\"item.icon\"></i>\r\n <span class=\"mx-1\">{{item.label}}</span>\r\n </a>\r\n <div id=\"treeItem_{{item.id}}_heading\"\r\n class=\"item\"\r\n *ngIf=\"!item.url\"\r\n (click)=\"selectItem(item)\">\r\n <i class=\"ec-icon {{item.icon}} mx-1 flex-shrink\"\r\n *ngIf=\"item.icon\"></i>\r\n <span class=\"mx-1\">{{item.label}}</span>\r\n </div>\r\n </div>\r\n\r\n\r\n <ul *ngIf=\"item.children.length > 0 && item.expanded\">\r\n <ng-container *ngTemplateOutlet=\"hierarchyView; context:{ $implicit: item.children }\"></ng-container>\r\n </ul>\r\n </li>\r\n </ng-template>\r\n\r\n <ng-container *ngTemplateOutlet=\"hierarchyView; context:{ $implicit: rootNode?.children }\"></ng-container>\r\n</ul>\r\n",
8221
+ styles: ["@-webkit-keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(1turn)}}:host{display:block;font-size:.875rem}ul{list-style:none;margin:0;overflow-x:hidden;padding:0}ul li{padding:0 .25rem;white-space:nowrap}ul .item-wrapper{align-items:center;border-radius:var(--ec-border-radius,.25rem);display:flex;height:1.75rem;padding:0 .25rem}ul .item-wrapper.is-heading{color:rgba(26,26,35,.38);cursor:pointer;font-size:.75rem;font-weight:700;text-transform:uppercase}ul .item-wrapper:hover{background-color:#bfe0e9}ul .item-wrapper.is-selected{font-weight:700}ul .item-wrapper a{text-decoration:none}ul .item{align-items:center;color:inherit;display:flex;flex:1 1;min-height:0;min-width:0}"]
8222
+ },] }
8223
+ ];
8224
+ HierarchyTreeComponent.ctorParameters = function () { return [
8225
+ { type: ScrollService },
8226
+ { type: i0.Injector }
8227
+ ]; };
8228
+ HierarchyTreeComponent.propDecorators = {
8229
+ id: [{ type: i0.Input }],
8230
+ hideRootNode: [{ type: i0.Input }],
8231
+ itemSelected: [{ type: i0.Output }]
8232
+ };
8233
+
8234
+ var TreeComponent = /** @class */ (function () {
8235
+ function TreeComponent() {
8236
+ /** The value of the host elements id attribute */
8237
+ this.attrId = '';
8238
+ this._id = '';
8239
+ /** The tree's title displayed in the header */
8240
+ this.treeTitle = '';
8241
+ /** Tree overlay */
8242
+ this.status = new Overlay('hasData');
8243
+ /** Display the tree items with a MenuComponent or a HierarchyTreeComponent */
8244
+ this.type = 'hierarchy';
8245
+ /** Tree dropdown menu overlay */
8246
+ this.menuStatus = new Overlay('hasData');
8247
+ /** The menu item template */
8248
+ this.menuTemplateType = "checkAndLabel";
8249
+ /** Emits the item currently selected item in the tree */
8250
+ this.treeSelection = new i0.EventEmitter();
8251
+ /** Emits when a hierarchy tree item is expanded as a hook to load the item's children */
8252
+ this.getTreeItemChildren = new i0.EventEmitter();
8253
+ this.templateType = 'label';
8254
+ }
8255
+ Object.defineProperty(TreeComponent.prototype, "id", {
8256
+ get: function () {
8257
+ return this._id;
8258
+ },
8259
+ /**
8260
+ * The ID of the component, bound to the host element's id attribute and passed
8261
+ * to child components
8262
+ */
8263
+ set: function (value) {
8264
+ this._id = value;
8265
+ this.attrId = value;
8266
+ },
8267
+ enumerable: false,
8268
+ configurable: true
8269
+ });
8270
+ ;
8271
+ /** Emits when a tree item is selected */
8272
+ TreeComponent.prototype.onItemSelected = function (item) {
8273
+ this.treeSelection.emit(item);
8274
+ };
8275
+ /** Emits when a hierarchy tree item is expanded to load the item's children */
8276
+ TreeComponent.prototype.onHierarchyGetItemChildren = function (item) {
8277
+ this.getTreeItemChildren.emit(item);
8278
+ };
8279
+ /** Scroll to the tree item that is currently selected. */
8280
+ TreeComponent.prototype.scrollToSelectedItem = function () {
8281
+ if (this.menuComponent) {
8282
+ this.menuComponent.scrollToSelectedItem();
8283
+ }
8284
+ if (this.hierarchyTreeComponent) {
8285
+ this.hierarchyTreeComponent.scrollToSelectedItem();
8286
+ }
8287
+ };
8288
+ return TreeComponent;
8289
+ }());
8290
+ TreeComponent.decorators = [
8291
+ { type: i0.Component, args: [{
8292
+ selector: 'ec-tree',
8293
+ template: "<header class=\"flex-shrink d-flex align-items-center border-bottom bg-content\">\r\n <h2 id=\"{{id}}_title\"\r\n class=\"flex-grow m-0 mx-2 text-heading-1\">{{treeTitle | translate}}</h2>\r\n <ec-dropdown *ngIf=\"menuItems?.length\"\r\n id=\"{{id}}_dropdown\"\r\n class=\"flex-shrink fill\"\r\n icon=\"icon-menu\"\r\n [menuTemplateType]=\"menuTemplateType\"\r\n menuPosition=\"left\"\r\n [status]=\"menuStatus\"\r\n [popupFixed]=\"true\"\r\n [showArrow]=\"false\"\r\n [menuMinWidth]=\"240\"\r\n [items]=\"menuItems\">\r\n </ec-dropdown>\r\n</header>\r\n\r\n<div class=\"flex-grow d-flex\"\r\n ecOverlay\r\n [status]=\"status?.status\"\r\n [displayAsMask]=\"true\">\r\n <ng-container *ngIf=\"type === 'menu'\">\r\n <ec-menu [id]=\"id\"\r\n [items]=\"treeItems\"\r\n [templateType]=\"templateType\"\r\n (selectedChanged)=\"onItemSelected($event)\"\r\n class=\"flex-grow\">\r\n </ec-menu>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"type === 'hierarchy'\">\r\n <ec-hierarchy-tree [id]=\"id\"\r\n [rootNode]=\"treeHierarchy\"\r\n [hideRootNode]=\"treeHierarchyHideRootNode\"\r\n (getItemChildren)=\"onHierarchyGetItemChildren($event)\"\r\n (itemSelected)=\"onItemSelected($event)\"\r\n class=\"flex-grow d-flex\">\r\n </ec-hierarchy-tree>\r\n </ng-container>\r\n</div>",
8294
+ styles: [":host{display:flex;flex-direction:column}header{height:3rem}ec-dropdown.fill{height:3rem;width:3rem}"]
8295
+ },] }
8296
+ ];
8297
+ TreeComponent.ctorParameters = function () { return []; };
8298
+ TreeComponent.propDecorators = {
8299
+ attrId: [{ type: i0.HostBinding, args: ['attr.id',] }],
8300
+ id: [{ type: i0.Input }],
8301
+ treeTitle: [{ type: i0.Input }],
8302
+ treeItems: [{ type: i0.Input }],
8303
+ treeHierarchyHideRootNode: [{ type: i0.Input }],
8304
+ treeHierarchy: [{ type: i0.Input }],
8305
+ status: [{ type: i0.Input }],
8306
+ type: [{ type: i0.Input }],
8307
+ menuItems: [{ type: i0.Input }],
8308
+ menuStatus: [{ type: i0.Input }],
8309
+ menuTemplateType: [{ type: i0.Input }],
8310
+ treeSelection: [{ type: i0.Output }],
8311
+ getTreeItemChildren: [{ type: i0.Output }],
8312
+ menuComponent: [{ type: i0.ViewChild, args: [MenuComponent,] }],
8313
+ hierarchyTreeComponent: [{ type: i0.ViewChild, args: [HierarchyTreeComponent,] }],
8314
+ templateType: [{ type: i0.Input }]
8315
+ };
8316
+
8067
8317
  var ComponentsModule = /** @class */ (function () {
8068
8318
  function ComponentsModule() {
8069
8319
  }
@@ -8137,7 +8387,9 @@
8137
8387
  ToastComponent,
8138
8388
  ToasterComponent,
8139
8389
  PageViewComponent,
8140
- PageTitleComponent
8390
+ PageTitleComponent,
8391
+ HierarchyTreeComponent,
8392
+ TreeComponent
8141
8393
  ],
8142
8394
  imports: [
8143
8395
  common.CommonModule,
@@ -8203,7 +8455,9 @@
8203
8455
  ToastComponent,
8204
8456
  ToasterComponent,
8205
8457
  PageViewComponent,
8206
- PageTitleComponent
8458
+ PageTitleComponent,
8459
+ HierarchyTreeComponent,
8460
+ TreeComponent
8207
8461
  ]
8208
8462
  },] }
8209
8463
  ];
@@ -8800,6 +9054,84 @@
8800
9054
  }
8801
9055
  ];
8802
9056
 
9057
+ (function (HierarchyMocks) {
9058
+ HierarchyMocks.mockRoot = function () { return ({
9059
+ id: "1",
9060
+ level: 0,
9061
+ hasChildren: true,
9062
+ children: [],
9063
+ label: ''
9064
+ }); };
9065
+ HierarchyMocks.bldgWithChildren = function () {
9066
+ return {
9067
+ placeId: 3, parentId: 0, placeTypeId: 2, placeCode: 'HASCHILDREN_BLDG', placeInfo: 'A Cool Bldg Has Children',
9068
+ hasChildren: true, placeChildren: [], meterChildren: [], hasActiveChildren: true
9069
+ };
9070
+ };
9071
+ HierarchyMocks.bldgWithChildrenHierarchyItem = function () { return ({
9072
+ id: HierarchyMocks.bldgWithChildren().placeId.toString(),
9073
+ icon: 'icon-building',
9074
+ label: HierarchyMocks.bldgWithChildren().placeInfo + " [" + HierarchyMocks.bldgWithChildren().placeCode + "]",
9075
+ children: [], hasChildren: true, level: 1, selectable: true, topLevel: false
9076
+ }); };
9077
+ HierarchyMocks.orgWithChildren = function () {
9078
+ return {
9079
+ placeId: 1, parentId: 0, placeTypeId: 1, placeCode: 'HASCHILDREN_ORG', placeInfo: 'A Org Has Children',
9080
+ hasChildren: true, placeChildren: [], meterChildren: [], hasActiveChildren: true
9081
+ };
9082
+ };
9083
+ HierarchyMocks.orgWithChildrenHierarchyItem = function () { return ({
9084
+ id: HierarchyMocks.orgWithChildren().placeId.toString(),
9085
+ icon: 'icon-organization',
9086
+ label: HierarchyMocks.orgWithChildren().placeInfo + " [" + HierarchyMocks.orgWithChildren().placeCode + "]",
9087
+ children: [], hasChildren: true, level: 1, selectable: true, topLevel: true
9088
+ }); };
9089
+ HierarchyMocks.orgWithoutChildren = function () {
9090
+ return {
9091
+ placeId: 2, parentId: 0, placeTypeId: 1, placeCode: 'NOCHILDREN_ORG', placeInfo: 'No Children Org',
9092
+ hasChildren: false, placeChildren: [], meterChildren: [], hasActiveChildren: false
9093
+ };
9094
+ };
9095
+ HierarchyMocks.orgWithoutChildrenHierarchyItem = function () { return ({
9096
+ id: HierarchyMocks.orgWithoutChildren().placeId.toString(),
9097
+ icon: 'icon-organization',
9098
+ label: HierarchyMocks.orgWithoutChildren().placeInfo + " [" + HierarchyMocks.orgWithoutChildren().placeCode + "]",
9099
+ children: [], hasChildren: false, level: 1, selectable: true, topLevel: true
9100
+ }); };
9101
+ HierarchyMocks.bldgWithoutChildren = function () {
9102
+ return {
9103
+ placeId: 4, parentId: 0, placeTypeId: 2, placeCode: 'NOCHILDREN_BLDG', placeInfo: 'Zzz No Children Bldg',
9104
+ hasChildren: false, placeChildren: [], meterChildren: [], hasActiveChildren: false
9105
+ };
9106
+ };
9107
+ HierarchyMocks.bldgWithoutChildrenHierarchyItem = function () { return ({
9108
+ id: HierarchyMocks.bldgWithoutChildren().placeId.toString(),
9109
+ icon: 'icon-building',
9110
+ label: HierarchyMocks.bldgWithoutChildren().placeInfo + " [" + HierarchyMocks.bldgWithoutChildren().placeCode + "]",
9111
+ children: [], hasChildren: false, level: 1, selectable: true, topLevel: false
9112
+ }); };
9113
+ HierarchyMocks.sortedHierarchyPlaces = function () { return [
9114
+ HierarchyMocks.bldgWithChildrenHierarchyItem(), HierarchyMocks.orgWithChildrenHierarchyItem(), HierarchyMocks.orgWithoutChildrenHierarchyItem(), HierarchyMocks.bldgWithoutChildrenHierarchyItem()
9115
+ ]; };
9116
+ })(exports.HierarchyMocks || (exports.HierarchyMocks = {}));
9117
+
9118
+ var HierarchyBaseTestInjectorFactory = /** @class */ (function () {
9119
+ function HierarchyBaseTestInjectorFactory() {
9120
+ }
9121
+ HierarchyBaseTestInjectorFactory.getComponentInjector = function () {
9122
+ return i0.Injector.create({
9123
+ providers: [
9124
+ {
9125
+ provide: TelemetryService,
9126
+ useFactory: function () { return SpyFactory.createSpy(TelemetryService); },
9127
+ deps: []
9128
+ }
9129
+ ]
9130
+ });
9131
+ };
9132
+ return HierarchyBaseTestInjectorFactory;
9133
+ }());
9134
+
8803
9135
  /*
8804
9136
  * Public API Surface of @energycap/components
8805
9137
  */
@@ -8843,6 +9175,10 @@
8843
9175
  exports.FormControlComponent = FormControlComponent;
8844
9176
  exports.FormGroupComponent = FormGroupComponent;
8845
9177
  exports.FormGroupHelper = FormGroupHelper;
9178
+ exports.HierarchyBase = HierarchyBase;
9179
+ exports.HierarchyBaseTestInjectorFactory = HierarchyBaseTestInjectorFactory;
9180
+ exports.HierarchyItem = HierarchyItem;
9181
+ exports.HierarchyTreeComponent = HierarchyTreeComponent;
8846
9182
  exports.IfViewportWidthDirective = IfViewportWidthDirective;
8847
9183
  exports.ItemDisplayComponent = ItemDisplayComponent;
8848
9184
  exports.JsonDisplayComponent = JsonDisplayComponent;
@@ -8896,6 +9232,7 @@
8896
9232
  exports.ToastEvent = ToastEvent;
8897
9233
  exports.ToastService = ToastService;
8898
9234
  exports.ToasterComponent = ToasterComponent;
9235
+ exports.TreeComponent = TreeComponent;
8899
9236
  exports.UnicodeStrings = UnicodeStrings;
8900
9237
  exports.UserPreferenceService = UserPreferenceService;
8901
9238
  exports.ValidationMessageService = ValidationMessageService;