UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

1,107 lines (1,090 loc) 3.03 MB
import * as i0 from '@angular/core'; import { EventEmitter, Directive, Optional, Host, Output, Input, NgModule, Injectable, HostBinding, Renderer2, ElementRef, HostListener, Pipe, Component, InjectionToken, ViewChild, forwardRef, ContentChildren, Inject, ViewContainerRef, QueryList, SkipSelf, ViewChildren, Self, ChangeDetectorRef, TemplateRef, ContentChild, Injector, NgZone, isDevMode, ErrorHandler } from '@angular/core'; import * as i1 from '@angular/router'; import { NavigationEnd, PRIMARY_OUTLET, RouterModule, NavigationStart } from '@angular/router'; import { ResourceCache } from '@microsoft/windows-admin-center-sdk/core/data/resource-cache'; import { LogLevel } from '@microsoft/windows-admin-center-sdk/core/diagnostics/log-level'; import { Logging } from '@microsoft/windows-admin-center-sdk/core/diagnostics/logging'; import { __decorate, __metadata, __param } from 'tslib'; import { Debounce as Debounce$1 } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators'; import { Dom, ElementPosition } from '@microsoft/windows-admin-center-sdk/core/dom/dom'; import { marked } from 'marked'; import * as i1$1 from '@angular/common'; import { Location, CommonModule, DatePipe } from '@angular/common'; import { GatewayInventoryCache } from '@microsoft/windows-admin-center-sdk/core/shared/gateway-inventory/gateway-inventory-cache'; import { Observable, of, forkJoin, merge, Subject, fromEvent, ReplaySubject, EMPTY, fromEventPattern, zip, from, throwError, interval, timer } from 'rxjs'; import { map, take, catchError, mergeMap, delay, takeLast, shareReplay, tap, filter, takeUntil, takeWhile, first, switchMap, debounceTime } from 'rxjs/operators'; import { AppContext } from '@microsoft/windows-admin-center-sdk/core/data/app-context'; import { PerformanceTracker } from '@microsoft/windows-admin-center-sdk/core/performance/performance-tracker'; import { EnvironmentModule, EnvironmentModuleEntryPointType } from '@microsoft/windows-admin-center-sdk/core/manifest/environment-modules'; import { ActiveConnection } from '@microsoft/windows-admin-center-sdk/core/security/active-connection'; import { ConnectionManager } from '@microsoft/windows-admin-center-sdk/core/security/connection-manager'; import { Rpc } from '@microsoft/windows-admin-center-sdk/core/rpc/rpc'; import { GatewayConnection } from '@microsoft/windows-admin-center-sdk/core/data/gateway-connection'; import { Http } from '@microsoft/windows-admin-center-sdk/core/data/http'; import { AuthorizationManager } from '@microsoft/windows-admin-center-sdk/core/security/authorization-manager'; import { CimConnection } from '@microsoft/windows-admin-center-sdk/core/data/cim-connection'; import { NodeConnection } from '@microsoft/windows-admin-center-sdk/core/data/node-connection'; import { BatchConnection } from '@microsoft/windows-admin-center-sdk/core/data/batch-connection'; import { PowerShellConnection } from '@microsoft/windows-admin-center-sdk/core/data/powershell-connection'; import { TriggerableLifetimeManager } from '@microsoft/windows-admin-center-sdk/core/data/disposable'; import { LifetimeData } from '@microsoft/windows-admin-center-sdk/core/data/lifetime-data'; import { FileTransfer } from '@microsoft/windows-admin-center-sdk/core/data/file-transfer'; import { AzureManager } from '@microsoft/windows-admin-center-sdk/core/azure/azure-manager'; import { CimStream } from '@microsoft/windows-admin-center-sdk/core/data/cim-stream'; import { WebsocketStream } from '@microsoft/windows-admin-center-sdk/core/data/websocket-stream'; import { PowerShellStream } from '@microsoft/windows-admin-center-sdk/core/data/powershell-stream'; import { CredSSPManager } from '@microsoft/windows-admin-center-sdk/core/security/credssp-manager'; import { FrameConnection } from '@microsoft/windows-admin-center-sdk/core/frame/frame-connection'; import { NotificationConnection } from '@microsoft/windows-admin-center-sdk/core/notification/notification-connection'; import { SettingsManager } from '@microsoft/windows-admin-center-sdk/core/data/settings-manager'; import { SshStream } from '@microsoft/windows-admin-center-sdk/core/data/ssh-stream'; import { WorkItemConnection } from '@microsoft/windows-admin-center-sdk/core/notification/work-item-connection'; import { Globalization } from '@microsoft/windows-admin-center-sdk/core/data/globalization'; import { KeyCode } from '@microsoft/windows-admin-center-sdk/core/data/accessibility-manager'; import { Yield as Yield$1 } from '@microsoft/windows-admin-center-sdk/core/base/decorators/yield.decorator'; import { TagManager } from '@microsoft/windows-admin-center-sdk/core/security/tag-manager'; import { ExtensionBroker } from '@microsoft/windows-admin-center-sdk/core/data/extension-broker/extension-broker'; import * as i1$2 from '@angular/forms'; import { NG_VALUE_ACCESSOR, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, ControlContainer, Validators, FormsModule, ReactiveFormsModule, FormGroup, FormControl, FormArray, FormBuilder } from '@angular/forms'; import { Net } from '@microsoft/windows-admin-center-sdk/core/data/net'; import { DateTime } from '@microsoft/windows-admin-center-sdk/core/base/date/date-time'; import { DateType } from '@microsoft/windows-admin-center-sdk/core/base/date/date-type'; import { TimeUnit } from '@microsoft/windows-admin-center-sdk/core/base/date/time-unit'; import { DateRange } from '@microsoft/windows-admin-center-sdk/core/base/date/date-range'; import { CoreEnvironment } from '@microsoft/windows-admin-center-sdk/core/data/core-environment'; import { ActiveDirectory } from '@microsoft/windows-admin-center-sdk/core/data/active-directory/active-directory'; import { SearchType } from '@microsoft/windows-admin-center-sdk/core/data/active-directory/models/search-type'; import { NotificationState } from '@microsoft/windows-admin-center-sdk/core/notification/notification-state'; import { Animator, Duration } from '@microsoft/windows-admin-center-sdk/core/data/animation'; import { TelemetryControlType } from '@microsoft/windows-admin-center-sdk/core/diagnostics/telemetry-control-type'; import { RpcShellNavigateClient } from '@microsoft/windows-admin-center-sdk/core/rpc/shell-navigate/rpc-shell-navigate-client'; import { Chart } from 'chart.js'; import { createUniversalDecorator } from '@microsoft/windows-admin-center-sdk/core/base/decorators/base'; import { RpcAlertSeverity } from '@microsoft/windows-admin-center-sdk/core/rpc/dialog/rpc-dialog-model'; import { RpcOverlayCloseClient } from '@microsoft/windows-admin-center-sdk/core/rpc/overlay/rpc-overlay-close-client'; import { RpcType, RpcOutboundCommands, RpcOpenState, RpcDeactivateState } from '@microsoft/windows-admin-center-sdk/core/rpc/rpc-base'; import { RpcOverlayOpenSubjectServer } from '@microsoft/windows-admin-center-sdk/core/rpc/overlay/rpc-overlay-open-subject-server'; import { RxjsLifetimeManager } from '@microsoft/windows-admin-center-sdk/core/base/rxjs-lifetime-manager'; import { SmeWebTelemetry } from '@microsoft/windows-admin-center-sdk/core/diagnostics/sme-web-telemetry'; import { TelemetryActionTypes } from '@microsoft/windows-admin-center-sdk/core/diagnostics/sme-web-telemetry-models'; import { ColumnPicker } from '@microsoft/windows-admin-center-sdk/core/data/column-picker'; import { Electron } from '@microsoft/windows-admin-center-sdk/core/data/electron'; import { JobsManager } from '@microsoft/windows-admin-center-sdk/core/data/jobs/jobs-manager'; import { NativeQ } from '@microsoft/windows-admin-center-sdk/core/data/native-q'; import { PerformanceProfile } from '@microsoft/windows-admin-center-sdk/core/performance/performance-profile'; import { RpcOverlayCloseKey } from '@microsoft/windows-admin-center-sdk/core/rpc/overlay/rpc-overlay-model'; import { RpcObservablePerformanceConfigServer } from '@microsoft/windows-admin-center-sdk/core/rpc/performance/rpc-observable-performance-config-server'; import { RpcObservableUpdateThemeServer } from '@microsoft/windows-admin-center-sdk/core/rpc/update-theme/rpc-observable-update-theme-server'; import { AzureConstants } from '@microsoft/windows-admin-center-sdk/core/azure/azure-constants'; import { GatewayUrls } from '@microsoft/windows-admin-center-sdk/core/data/gateway-urls'; import { RpcObservableAliveClient } from '@microsoft/windows-admin-center-sdk/core/rpc/alive/rpc-observable-alive-client'; import { ScheduleRebootManager } from '@microsoft/windows-admin-center-sdk/core/data/schedule-reboot'; import { headerConstants } from '@microsoft/windows-admin-center-sdk/core/data/http-constants'; import { RpcObservableExtensionDataClient } from '@microsoft/windows-admin-center-sdk/core/rpc/extension-data/rpc-observable-extension-data-client'; import { SmeExtension } from '@microsoft/windows-admin-center-sdk/core/data/sme-extension'; /** * Directive to provide notification or state changes for angulars @see RouterLink directive. * The design of this directive is identical to @see RouterLinkActive * and as such supports the same @see RouterLinkActiveOptions are supported. */ class SmeRouterLinkDirective { /** * Initializes a new instance of the @see PivotComponent class. * @param link The router link that's defined for the element or child elements * @param linkWithHref The router link with 'a' tags that's defined for the element or child elements * @param router The angular router service */ constructor(link, linkWithHref, router, changeDetectorRef) { this.link = link; this.linkWithHref = linkWithHref; this.router = router; this.changeDetectorRef = changeDetectorRef; /** * The output for when the route is activated */ this.smeRouterLinkActivated = new EventEmitter(); /** * The output for when the route is deactivated */ this.smeRouterLinkDeactivated = new EventEmitter(); /** * Use the same input options as angulars @see RouterLinkActive Directive */ this.routerLinkActiveOptions = { exact: false }; /** * Placeholder for the current activation state */ this.isActive = false; this.subscriptions = []; this.subscriptions.push(this.router.events.subscribe(s => { if (s instanceof NavigationEnd) { this.updateIsActive(); } })); } /** * Angulars AfterContentInit life cycle event */ ngAfterContentInit() { this.updateIsActive(); } /** * Angulars OnChanges life cycle event */ ngDoCheck() { this.updateIsActive(); } ngOnDestroy() { this.subscriptions.forEach(sub => sub.unsubscribe()); } /** * Updates the isActive state and fires appropriate events if that state has changed. */ updateIsActive() { if ((!this.link && !this.linkWithHref) || !this.router.navigated) { return; } const hasActiveLinks = this.hasActiveLinks(); if (this.isActive !== hasActiveLinks) { this.isActive = hasActiveLinks; if (this.isActive) { this.smeRouterLinkActivated.next(); } else { this.smeRouterLinkDeactivated.next(); } this.changeDetectorRef.detectChanges(); } } /** * Indicates if a given link is active * @param link the link to check */ isLinkActive(link) { return this.router.isActive(link.urlTree, this.routerLinkActiveOptions.exact); } /** * Indicates that at leased one link is active */ hasActiveLinks() { return (this.link && this.isLinkActive(this.link)) || (this.linkWithHref && this.isLinkActive(this.linkWithHref)); } } /** @nocollapse */ SmeRouterLinkDirective.ɵfac = function SmeRouterLinkDirective_Factory(t) { return new (t || SmeRouterLinkDirective)(i0.ɵɵdirectiveInject(i1.RouterLink, 9), i0.ɵɵdirectiveInject(i1.RouterLinkWithHref, 9), i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; /** @nocollapse */ SmeRouterLinkDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: SmeRouterLinkDirective, selectors: [["", "routerLink", "", "smeRouterLinkActivated", ""], ["", "routerLink", "", "smeRouterLinkDeactivated", ""]], inputs: { routerLinkActiveOptions: "routerLinkActiveOptions" }, outputs: { smeRouterLinkActivated: "smeRouterLinkActivated", smeRouterLinkDeactivated: "smeRouterLinkDeactivated" } }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SmeRouterLinkDirective, [{ type: Directive, args: [{ selector: '[routerLink][smeRouterLinkActivated],[routerLink][smeRouterLinkDeactivated]' }] }], function () { return [{ type: i1.RouterLink, decorators: [{ type: Optional }, { type: Host }] }, { type: i1.RouterLinkWithHref, decorators: [{ type: Optional }, { type: Host }] }, { type: i1.Router }, { type: i0.ChangeDetectorRef }]; }, { smeRouterLinkActivated: [{ type: Output }], smeRouterLinkDeactivated: [{ type: Output }], routerLinkActiveOptions: [{ type: Input }] }); })(); /** * Module to modify and interact with angulars Router directives */ class SmeRouterModule { } /** @nocollapse */ SmeRouterModule.ɵfac = function SmeRouterModule_Factory(t) { return new (t || SmeRouterModule)(); }; /** @nocollapse */ SmeRouterModule.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: SmeRouterModule }); /** @nocollapse */ SmeRouterModule.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({}); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SmeRouterModule, [{ type: NgModule, args: [{ exports: [ SmeRouterLinkDirective ], declarations: [ SmeRouterLinkDirective ] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(SmeRouterModule, { declarations: [SmeRouterLinkDirective], exports: [SmeRouterLinkDirective] }); })(); /** * Resource service to find a resource data by type and id. */ class ResourceService extends ResourceCache { } /** @nocollapse */ ResourceService.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵResourceService_BaseFactory; return function ResourceService_Factory(t) { return (ɵResourceService_BaseFactory || (ɵResourceService_BaseFactory = i0.ɵɵgetInheritedFactory(ResourceService)))(t || ResourceService); }; }(); /** @nocollapse */ ResourceService.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: ResourceService, factory: ResourceService.ɵfac }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ResourceService, [{ type: Injectable }], null, null); })(); /** * SVG image directive to place SVG image at background-image by CSS style class. */ class SvgDirective { /** * Initializes a new instance of the SvgDirective class. * * @param elementRef the element reference. * @param resourceService the resource service. */ constructor(elementRef, resourceService) { this.elementRef = elementRef; this.resourceService = resourceService; } /** * Set "smeSvg" input as id string of SVG resource. * * @param id The identification of SVG resource. */ set smeSvg(id) { if (id) { id = id.toLowerCase(); const className = this.resourceService.find(ResourceService.svgType, id); if (className) { this.elementRef.nativeElement.classList.add(className); } } } } /** @nocollapse */ SvgDirective.ɵfac = function SvgDirective_Factory(t) { return new (t || SvgDirective)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(ResourceService)); }; /** @nocollapse */ SvgDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: SvgDirective, selectors: [["", "smeSvg", ""]], inputs: { smeSvg: "smeSvg" } }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SvgDirective, [{ type: Directive, args: [{ selector: '[smeSvg]' }] }], function () { return [{ type: i0.ElementRef }, { type: ResourceService }]; }, { smeSvg: [{ type: Input }] }); })(); /** * SVG image directive to place SVG image as inline into the element. */ class SvgInlineDirective { /** * Initializes a new instance of the SvgInlineDirective class. * * @param viewContainer the view container reference. * @param resourceService the resource service. */ constructor(viewContainer, resourceService) { this.viewContainer = viewContainer; this.resourceService = resourceService; } set smeSvgInline(id) { this.viewContainer.clear(); if (id) { id = id.toLowerCase(); const content = this.resourceService.find(ResourceService.svgInlineType, id); if (content) { this.viewContainer.element.nativeElement.innerHTML = content; } } } } /** @nocollapse */ SvgInlineDirective.ɵfac = function SvgInlineDirective_Factory(t) { return new (t || SvgInlineDirective)(i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(ResourceService)); }; /** @nocollapse */ SvgInlineDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: SvgInlineDirective, selectors: [["", "smeSvgInline", ""]], inputs: { smeSvgInline: "smeSvgInline" } }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SvgInlineDirective, [{ type: Directive, args: [{ selector: '[smeSvgInline]' }] }], function () { return [{ type: i0.ViewContainerRef }, { type: ResourceService }]; }, { smeSvgInline: [{ type: Input }] }); })(); /** * SVG resource class for CSS class. */ class SvgResource { /** * Initializes a new instance of the SvgResource class. * * @param svg the svg object generated by gulp-svg-code. */ constructor(svg) { this.svg = svg; this.svgInlineResource = new SvgInlineResource(this.svg); } /** * Build svg resources from SVG object, and register the resource service. * * @param resourceService the resource service. * @param svg the svg object generated by gulp-svg-code. */ static buildRegister(resourceService, svg) { // register SVG resources to resource service. resourceService.register(ResourceService.svgType, new SvgResource(svg)); resourceService.register(ResourceService.svgInlineType, new SvgInlineResource(svg)); } /** * Find SVG string by id. * * @param id the identification of SVG. (id must be lower case) */ find(id) { const result = this.svgInlineResource.findIndex(id); if (!result) { return null; } const segments = result.name.split('/'); return 'svg-' + segments.join('--'); } } /** * SVG inline resource class for ram SVG insertion. */ class SvgInlineResource { /** * Initializes a new instance of the SvgInlineResource class. * * @param svg the svg object generated by gulp-svg-code. */ constructor(svg) { this.svg = svg; this.lowerSvg = this.createLowercaseIndexing(this.svg); } /** * Find SVG string by id. * * @param id the identification of SVG. (id must be lower case) * @return string the Svg resource string. */ find(id) { const result = this.lowerSvg[id]; if (!result) { Logging.log({ level: LogLevel.Warning, message: `Unable to find SVG resource for ${id}`, params: { id: id }, source: 'SvgInlineResource' }); return null; } return result.value; } /** * Find index data. * * @param id the identification of SVG. * @return SvgIndexedData the indexed data. */ findIndex(id) { return this.lowerSvg[id]; } /** * Create lower case property version. * * @param svg the original svg data. * @return any the lower case version of svg. */ createLowercaseIndexing(svg) { const newSvg = {}; let nextCollection = [{ target: svg, path: '' }]; while (nextCollection.length > 0) { const collection = nextCollection; nextCollection = []; for (const current of collection) { MsftSme.forEachKey(current.target, (key, value) => { const path = this.nextPath(current.path, key); if (value && typeof value === 'object') { // add to next level traverse. nextCollection.push({ target: value, path: path }); } else { // register to the collection. const lower = path.toLowerCase(); newSvg[lower] = { name: path, lower: lower, value: value }; } }); } } return newSvg; } nextPath(path, key) { return path === '' ? key : path + '/' + key; } } /** * SVG module class to export SVG directives. */ class SvgModule { } /** @nocollapse */ SvgModule.ɵfac = function SvgModule_Factory(t) { return new (t || SvgModule)(); }; /** @nocollapse */ SvgModule.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: SvgModule }); /** @nocollapse */ SvgModule.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({ providers: [ ResourceService ] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SvgModule, [{ type: NgModule, args: [{ exports: [ SvgDirective, SvgInlineDirective ], declarations: [ SvgDirective, SvgInlineDirective ], providers: [ ResourceService ] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(SvgModule, { declarations: [SvgDirective, SvgInlineDirective], exports: [SvgDirective, SvgInlineDirective] }); })(); /** * Base class for template loaders */ // eslint-disable-next-line @angular-eslint/directive-class-suffix class TemplateLoaderBaseComponent { /** * Instantiates a new instance of TemplateLoaderBaseComponent * @param viewContainer the reference to this elements view container */ constructor(viewContainer) { this.viewContainer = viewContainer; } /** * Implementation of angular OnInit interface */ ngOnInit() { this.view = this.viewContainer.createEmbeddedView(this.template, this.createContext()); } /** * Implementation of angular OnChanges interface * @param changes the changes that occured */ ngOnChanges(changes) { if (!this.view || !this.view.context) { return; } // changes and update the context if those properties exist for (const key in changes) { if (key in this.view.context) { this.view.context[key] = changes[key].currentValue; } } } /** * Implementation of angular OnDestroy interface */ ngOnDestroy() { this.view.destroy(); } } /** @nocollapse */ TemplateLoaderBaseComponent.ɵfac = function TemplateLoaderBaseComponent_Factory(t) { return new (t || TemplateLoaderBaseComponent)(i0.ɵɵdirectiveInject(i0.ViewContainerRef)); }; /** @nocollapse */ TemplateLoaderBaseComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: TemplateLoaderBaseComponent, inputs: { data: "data", template: "template" }, features: [i0.ɵɵNgOnChangesFeature] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TemplateLoaderBaseComponent, [{ type: Directive }], function () { return [{ type: i0.ViewContainerRef }]; }, { data: [{ type: Input }], template: [{ type: Input }] }); })(); class TemplateOutletDirective extends TemplateLoaderBaseComponent { /** * Instantiates a new instance of TooltipTemplateLoaderComponent * @param viewContainer the reference to this elements view container */ constructor(viewContainer) { super(viewContainer); } ngOnChanges(changes) { super.ngOnChanges(changes); if (!this.view || !this.view.context) { return; } if (changes.hostDataName || changes.hostData) { this.applyHostData(this.view.context); } } /** * Creates the context for our embedded view */ createContext() { return this.applyHostData({ $implicit: this.data }); } /** * Applies the hostData property to a given context object. */ applyHostData(context) { const hostDataName = this.hostDataName || 'hostData'; context[hostDataName] = this.hostData; return context; } } /** @nocollapse */ TemplateOutletDirective.ɵfac = function TemplateOutletDirective_Factory(t) { return new (t || TemplateOutletDirective)(i0.ɵɵdirectiveInject(i0.ViewContainerRef)); }; /** @nocollapse */ TemplateOutletDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: TemplateOutletDirective, selectors: [["", "smeTemplateOutlet", ""]], inputs: { hostData: "hostData", hostDataName: "hostDataName" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TemplateOutletDirective, [{ type: Directive, args: [{ selector: '[smeTemplateOutlet]' }] }], function () { return [{ type: i0.ViewContainerRef }]; }, { hostData: [{ type: Input }], hostDataName: [{ type: Input }] }); })(); /** * Module to modify simplify template loading */ class SmeTemplateOutletModule { } /** @nocollapse */ SmeTemplateOutletModule.ɵfac = function SmeTemplateOutletModule_Factory(t) { return new (t || SmeTemplateOutletModule)(); }; /** @nocollapse */ SmeTemplateOutletModule.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: SmeTemplateOutletModule }); /** @nocollapse */ SmeTemplateOutletModule.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({}); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SmeTemplateOutletModule, [{ type: NgModule, args: [{ exports: [ TemplateOutletDirective ], declarations: [ TemplateOutletDirective ] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(SmeTemplateOutletModule, { declarations: [TemplateOutletDirective], exports: [TemplateOutletDirective] }); })(); class DisabledDirective { constructor(host) { this.host = host; } get smeDisabled() { return this.internalDisabled; } set smeDisabled(value) { this.internalDisabled = value; if (value && this.host && document.activeElement === this.host.nativeElement) { this.removeFocus(); } } get attrDisabled() { // angular wont add an attribute if it is null. so return false as null. return this.smeDisabled ? true : null; } removeFocus() { if (this.smeDisabled) { if (document.activeElement === this.host.nativeElement || document.activeElement === document.body) { const next = Dom.getNextFocusableElement(this.host.nativeElement) || Dom.getNextZoneElement(this.host.nativeElement); if (next) { next.focus(); } else { const previous = Dom.getPreviousFocusableElement(this.host.nativeElement) || Dom.getPreviousZoneElement(this.host.nativeElement); if (previous) { previous.focus(); } } } } else if (!this.smeDisabled && document.activeElement === document.body) { this.host.nativeElement.focus(); } } } /** @nocollapse */ DisabledDirective.ɵfac = function DisabledDirective_Factory(t) { return new (t || DisabledDirective)(i0.ɵɵdirectiveInject(i0.ElementRef)); }; /** @nocollapse */ DisabledDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: DisabledDirective, selectors: [["", "smeDisabled", ""]], hostVars: 1, hostBindings: function DisabledDirective_HostBindings(rf, ctx) { if (rf & 2) { i0.ɵɵattribute("disabled", ctx.attrDisabled); } }, inputs: { smeDisabled: "smeDisabled" } }); __decorate([ Debounce$1(0), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], DisabledDirective.prototype, "removeFocus", null); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DisabledDirective, [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: '[smeDisabled]' }] }], function () { return [{ type: i0.ElementRef }]; }, { smeDisabled: [{ type: Input }], attrDisabled: [{ type: HostBinding, args: ['attr.disabled'] }], removeFocus: [] }); })(); class DisabledModule { } /** @nocollapse */ DisabledModule.ɵfac = function DisabledModule_Factory(t) { return new (t || DisabledModule)(); }; /** @nocollapse */ DisabledModule.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: DisabledModule }); /** @nocollapse */ DisabledModule.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({}); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DisabledModule, [{ type: NgModule, args: [{ exports: [ DisabledDirective ], declarations: [ DisabledDirective ] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(DisabledModule, { declarations: [DisabledDirective], exports: [DisabledDirective] }); })(); /** * * @smeDoc {@label Markdown @id sme-markdown-directive} * * @overview * @file {@filepath ./examples/markdown-overview.md} * * @example {@label Basic Usage @id basic-usage} * @file {@filename component.html @filepath ./examples/basic-usage.component.html} * @file {@filename component.ts @filepath ./examples/basic-usage.component.ts} * */ class MarkdownDirective { constructor(host, renderer) { this.host = host; this.renderer = renderer; } get content() { return this.renderedContent; } ngOnInit() { this.renderer.addClass(this.host.nativeElement, 'sme-documentation'); } ngOnChanges(changes) { if (changes.smeMarkdown) { this.render(); } } render() { this.renderedContent = ''; if (marked && !MsftSme.isNullOrWhiteSpace(this.smeMarkdown)) { this.renderedContent = marked.parse(this.smeMarkdown); } } } /** @nocollapse */ MarkdownDirective.ɵfac = function MarkdownDirective_Factory(t) { return new (t || MarkdownDirective)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.Renderer2)); }; /** @nocollapse */ MarkdownDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: MarkdownDirective, selectors: [["", "smeMarkdown", ""]], hostVars: 1, hostBindings: function MarkdownDirective_HostBindings(rf, ctx) { if (rf & 2) { i0.ɵɵhostProperty("innerHtml", ctx.content, i0.ɵɵsanitizeHtml); } }, inputs: { smeMarkdown: "smeMarkdown" }, features: [i0.ɵɵNgOnChangesFeature] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MarkdownDirective, [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: '[smeMarkdown]' }] }], function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, { smeMarkdown: [{ type: Input }], content: [{ type: HostBinding, args: ['innerHtml'] }] }); })(); class MarkdownModule { } /** @nocollapse */ MarkdownModule.ɵfac = function MarkdownModule_Factory(t) { return new (t || MarkdownModule)(); }; /** @nocollapse */ MarkdownModule.ɵmod = /** @pureOrBreakMyCode */ i0.ɵɵdefineNgModule({ type: MarkdownModule }); /** @nocollapse */ MarkdownModule.ɵinj = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjector({}); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MarkdownModule, [{ type: NgModule, args: [{ exports: [ MarkdownDirective ], declarations: [ MarkdownDirective ] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MarkdownModule, { declarations: [MarkdownDirective], exports: [MarkdownDirective] }); })(); const TypeInjectionMap = new Map(); function injectProperties(instance, injector) { if (MsftSme.isNullOrUndefined(injector)) { // eslint-disable-next-line max-len throw new Error(`SmeInjectableBase: No Injector for ${instance.constructor.name}. The angular Injector must be the first argument to the constructor.`); } let prototype = instance.constructor; let proto = Object.getPrototypeOf(instance); let injectionMap = TypeInjectionMap.has(prototype) ? TypeInjectionMap.get(prototype) : {}; while (!MsftSme.isNullOrUndefined(proto)) { prototype = proto.constructor; if (TypeInjectionMap.has(prototype)) { const protoInjection = TypeInjectionMap.get(prototype); injectionMap = Object.assign(Object.assign({}, protoInjection), injectionMap); } // get next prototype proto = Object.getPrototypeOf(proto); } // process any injected properties we found const propertyKeys = Object.keys(injectionMap); if (propertyKeys.length > 0) { // Use the injector to do the heavy lifting and resolve our tokens into properties. propertyKeys.forEach(prop => { const options = injectionMap[prop]; if (options === null || options === void 0 ? void 0 : options.injectOptions.optional) { instance[prop] = injector.get(options.token, null, options.injectOptions); } else { instance[prop] = injector.get(options.token, undefined, { optional: false }); } }); } } /** * As of Angular 9, the SmeInjectable Decorator no longer works. * The new approach is to use an injectable base class that does essentially the same thing. */ class SmeInjectableBase { constructor(injector) { this.injector = injector; injectProperties(this, injector); } } /** @nocollapse */ SmeInjectableBase.ɵfac = function SmeInjectableBase_Factory(t) { return new (t || SmeInjectableBase)(i0.ɵɵinject(i0.Injector)); }; /** @nocollapse */ SmeInjectableBase.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: SmeInjectableBase, factory: SmeInjectableBase.ɵfac }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SmeInjectableBase, [{ type: Injectable }], function () { return [{ type: i0.Injector }]; }, null); })(); /** * Blank implementation of the complete angular component lifecycle. * This enabled our base components to implement the lifecycle even if they dont use all of its functions just yet. * That way if we do decide to use one of these hooks, we dont need to change every derived component as * they should all be calling super() implementation anyway. */ // eslint-disable-next-line @angular-eslint/directive-class-suffix class NgLifecycleBaseComponent extends SmeInjectableBase { /** * Initializes a new instance of the {BaseComponent} class. * @param injector The angular injection service. required by @SmeInjectableBase() decorator */ constructor(injector) { super(injector); this.ngIsInitialized = false; this.ngIsContentInitialized = false; this.ngIsViewInitialized = false; this.ngIsDestroyed = false; } // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method ngOnChanges(changes) { } ngOnInit() { this.ngIsInitialized = true; } // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method ngDoCheck() { } ngOnDestroy() { this.ngIsDestroyed = true; } ngAfterContentInit() { this.ngIsContentInitialized = true; } // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method ngAfterContentChecked() { } ngAfterViewInit() { this.ngIsViewInitialized = true; } // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method ngAfterViewChecked() { } } /** @nocollapse */ NgLifecycleBaseComponent.ɵfac = function NgLifecycleBaseComponent_Factory(t) { return new (t || NgLifecycleBaseComponent)(i0.ɵɵdirectiveInject(i0.Injector)); }; /** @nocollapse */ NgLifecycleBaseComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: NgLifecycleBaseComponent, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NgLifecycleBaseComponent, [{ type: Directive }], function () { return [{ type: i0.Injector }]; }, null); })(); /** * A base class for all components. * - TResourceStrings The typed interface for resource strings. */ // eslint-disable-next-line @angular-eslint/directive-class-suffix class BaseComponent extends NgLifecycleBaseComponent { /** * Initializes a new instance of the {BaseComponent} class. * @param injector The angular injection service. required by @SmeInjectableBase() decorator */ constructor(injector) { super(injector); this.renderer = injector.get(Renderer2); this.hostElement = injector.get(ElementRef); // load the strings for the application this.strings = MsftSme.self().Resources.strings; // initialize subscriptions to empty this.subscriptions = []; // setup component id and idBag this.componentId = `component-${BaseComponent.nextComponentId++}`; this.idBag = this.createIdBag(); MsftSme.forEachKey(this.idBag, (key) => { this.idBag[key] = `${this.componentId}-${key}`; }); // setup initial host classes on this element this.applyInitialHostClasses(); } /** * Implementation of angular OnDestroy interface * derived classes are always expected to call super.ngOnDestroy() when overriding */ ngOnDestroy() { this.subscriptions.forEach((subscription) => { if (subscription && !subscription.closed) { subscription.unsubscribe(); } }); super.ngOnDestroy(); } /** * Creates the idBag used by this component to store unique element ids * Derived classes are always expected to call super.createIdBag() when overriding */ createIdBag() { return {}; } /** * Gets the initial host classes to be applied to this element * Derived classes are always expected to call super.getInitialHostClasses() when overriding */ getInitialHostClasses() { return []; } /** * Shortcut to get an attribute on the host element * @param name The name of the attribute */ getAttribute(name) { return this.hostElement.nativeElement.getAttribute(name); } /** * Shortcut to set an attribute on the host element * @param name The name of the attribute * @param value The value of the attribute */ setAttribute(name, value) { this.renderer.setAttribute(this.hostElement.nativeElement, name, value); } /** * Shortcut to remove an attribute on the host element * @param name The name of the attribute */ removeAttribute(name) { this.renderer.removeAttribute(this.hostElement.nativeElement, name); } /** * Shortcut to add a class on the host element * @param className The name of the attribute */ addClass(className) { this.renderer.addClass(this.hostElement.nativeElement, className); } /** * Shortcut to remove a class on the host element * @param className The name of the class */ removeClass(className) { this.renderer.removeClass(this.hostElement.nativeElement, className); } /** * Shortcut to set a style on the host element * @param style The name of the style * @param value The new value */ setStyle(style, value) { this.renderer.setStyle(this.hostElement.nativeElement, style, value); } /** * Shortcut to remove a style on the host element * @param style The name of the style */ removeStyle(style) { this.renderer.removeStyle(this.hostElement.nativeElement, style); } /** * Shortcut to log a record. The source name is automatically picked up from the class instance * @param message the message of the log record * @param level (optional) the log level (defaults to Debug) * @param params (optional) the parameters to log * @param source (optional) the source of the log message. Defaults to the name of the constructor that instantiated this instance * @return Promise<any> settle to resolve if buffered. */ log(message, level = LogLevel.Debug, params, source = this.logSourceName) { return Logging.log({ level: level, message: message, localParams: params, source: source }); } /** * Applies the initial classes to this components host element. * We preserve any custom classes by removing them, applying the base classes and reapplying the custom classes. */ applyInitialHostClasses() { const customClasses = Dom.getClasses(this.hostElement.nativeElement); customClasses.forEach(c => this.renderer.removeClass(this.hostElement.nativeElement, c)); this.getInitialHostClasses() .concat(customClasses) .forEach(c => this.renderer.addClass(this.hostElement.nativeElement, c)); } } /** * Static constant to provide unique ids for each component * @see {componentId} */ BaseComponent.nextComponentId = 0; /** @nocollapse */ BaseComponent.ɵfac = function BaseComponent_Factory(t) { return new (t || BaseComponent)(i0.ɵɵdirectiveInject(i0.Injector)); }; /** @nocollapse */ BaseComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: BaseComponent, features: [i0.ɵɵInheritDefinitionFeature] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(BaseComponent, [{ type: Directive }], function () { return [{ type: i0.Injector }]; }, null); })(); /** * Internal base component for SME Core controls. It simply removes the need to supply the string type parameter * This class is exported from this file, but not meant to be exported from index.ts bundles. */ class CoreBaseComponent extends BaseComponent { } var Unicode; (function (Unicode) { Unicode["HorizontalEllipsis"] = "\u2026"; })(Unicode || (Unicode = {})); const breakAllClass = 'sme-arrange-word-break-all'; /** * * @smeDoc {@label Clamp @id sme-clamp-directive} * * @overview * @file {@filepath ./examples/clamp-overview.md} * * @example {@label Basic Usage @id basic-usage} * @file {@filename component.html @filepath ./examples/basic-usage.component.html} * @file {@filename component.ts @filepath ./examples/basic-usage.component.ts} * * @example {@label Clamp with auto lines @id auto-lines} * @file {@filename component.html @filepath ./examples/auto-lines-clamp.component.html} * @file {@filename component.ts @filepath ./examples/auto-lines-clamp.component.ts} * */ class ClampDirective extends CoreBaseComponent { /** * Constructs a new instance of the ClampDirective * @param injector The injector for the sme base component */ constructor(injector) { super(injector); /** * Event that outputs a value indicating whether the content is clamped or not */ this.clamped = new EventEmitter(); } /** * The source name to use for logging */ get logSourceName() { return 'ClampDirective'; } /** * The number of lines to clamp to */ get lineCount() { // get the lineCount let lineCount = MsftSme.isNumber(this.smeClampLines) ? this.smeClampLines : 'auto'; // calc line count if it is auto if (lineCount === 'auto') { lineCount = this.hostElement.nativeElement.offsetHeight / this.lineHeight; } // make sure line count is at least 1 line return Math.max(lineCount, 1); } /** * The height that the clamp should be contained within */ get clampHeight() { return this.lineCount * this.lineHeight; } /** * The line height of this element */ get lineHeight() { return parseInt(window.getComputedStyle(this.hostElement.nativeElement).lineHeight, 10); } /** * Indicates that content overflows the desired height of the clamp */ get needsClamping() { return this.hostElement.nativeElement.scrollHeight > this.clampHeight; } get renderedLines() { return this.hostElement.nativeElement.scrollHeight / this.lineHeight; } get breakWords() { return this.hostElement.nativeElement.classList.contains(breakAllClass); } /** * Host listener for page resize event. */ onResize() { // reset initial content state this.resetClampContent(); if (this.needsClamping) { this.clamp(this.hostElement.nativeElement); } } /** * Implementation of angular OnChanges interface * On every input change, we recalculate the clamp. */ ngOnChanges(changes) { super.ngOnChanges(changes); if (changes.smeClamp) { // reset initial content state this.resetClampContent(); } // if the input changes require clamping again, then re-clamp if (this.needsClamping) { this.clamp(this.hostElement.nativeElement); } } setBreakWords() { const element = this.hostElement.nativeElement; if (!element.classList.contains(breakAllClass)) { element.classList.add(breakAllClass); } } removeBreakWords() { const element = this.hostElement.nativeElement; if (element.classList.contains(breakAllClass)) { element.classList.remove(breakAllClass); } } resetClampContent() { // reset initial content state this.removeBreakWords();