import { LogCategories } from './../models/constants' ; import { LogService } from 'app/shared/services/log.service' ; import { PortalService } from './portal.service' ; import { Observable } from 'rxjs/Observable' ; import { Injectable } from '@angular/core' ; interface ComponentMap { [ key ] : string ; } @ Injectable ( ) export class TelemetryService { private _featureMap : { [ key ] : ComponentMap ; } = { } ; private _registeredParentFeatures : { [ key ] : string ; } = { } ; private readonly _constructIdFormat = '/feature/{0}/construct' ; private readonly _loadingIdFormat = '/feature/{0}/loading' ; private readonly _debouceTimeMs = 250 ; constructor ( private _portalService , private _logService ) { } public featureConstructComplete ( featureName ) { if ( ! featureName ) { return ; } this . _portalService . sendTimerEvent ( { timerId : this . _constructIdFormat . format ( featureName ) , timerAction : 'stop' , } ) ; } public featureLoading ( isParentComponent , featureName , componentName ) { if ( isParentComponent && this . _featureMap [ featureName ] ) { delete this . _featureMap [ featureName ] ; } if ( ! this . _featureMap [ featureName ] ) { if ( isParentComponent ) { this . _registeredParentFeatures [ featureName ] = featureName ; this . _featureMap [ featureName ] = { } ; this . _logService . verbose ( LogCategories . telemetry , `Feature loading started. feature: ${ featureName }` ) ; this . _portalService . sendTimerEvent ( { timerId : this . _loadingIdFormat . format ( featureName ) , timerAction : 'start' , } ) ; } else if ( ! this . _registeredParentFeatures [ featureName ] ) { const errMesg = `No parentComponent defined for feature: ${ featureName }, component: ${ componentName }.  
Exactly one parent component must be defined for a given feature by setting the isParentComponent property.` ; this . _logService . error ( LogCategories . telemetry , '/no-parent-component-defined' , errMesg ) ; throw Error ( errMesg ) ; } else { this . _logService . verbose ( LogCategories . telemetry , `A child component started after feature load complete.  feature: ${ featureName }, component: ${ componentName }` ) ; return ; } } this . _logService . verbose ( LogCategories . telemetry , `Loading feature: ${ featureName }, component: ${ componentName }` ) ; this . _featureMap [ featureName ] [ componentName ] = componentName ; } public featureLoadingComplete ( featureName , componentName ) { if ( ! this . _featureMap [ featureName ] || ! this . _featureMap [ featureName ] [ componentName ] ) { return ; } delete this . _featureMap [ featureName ] [ componentName ] ; this . _logService . verbose ( LogCategories . telemetry , `Component is done loading.  feature: ${ featureName }, component: ${ componentName }` ) ; if ( Object . keys ( this . _featureMap [ featureName ] ) . length === 0 ) { this . _logService . verbose ( LogCategories . telemetry , `All components should be complete for: ${ featureName }.  Debouncing for ${ this . _debouceTimeMs }ms` ) ; Observable . timer ( this . _debouceTimeMs ) . subscribe ( ( ) => { if ( this . _featureMap [ featureName ] && Object . keys ( this . _featureMap [ featureName ] ) . length === 0 ) { this . _logService . verbose ( LogCategories . telemetry , `Completing load for feature: ${ featureName }` ) ; delete this . _featureMap [ featureName ] ; this . _portalService . sendTimerEvent ( { timerId : this . _loadingIdFormat . format ( featureName ) , timerAction : 'stop' , } ) ; } else { this . _logService . verbose ( LogCategories . telemetry , `New loading signals detected for feature: ${ featureName }` ) ; } } ) ; } } }