module Sfx { export interface ITelemetryService { isEnabled : boolean ; trackPageView ( ) : void ; trackActionEvent ( name , source , result ) : void ; trackEvent ( message ) : void ; } export class TelemetryService implements ITelemetryService { public static TelemetryEnabledHostsRegex : RegExp = /(^|\.)azure\.com($|:)/i ; private static DelayUpdateTimeInSeconds : number = 10 ; public isEnabled : boolean = false ; private appInsights : any ; private delayedUpdates : { [ key ] : PropertyUpdatePromise ; } ; constructor ( private $window , private $interval , private $location , private $route , private storage ) { this . initialize ( ) ; } public trackPageView ( ) { if ( ! this . isEnabled ) { return ; } this . noThrowWrapper ( ( ) => { let pageView = new PageViewRecord ( this . $location , this . $route . current ) ; if ( pageView . url ) { this . appInsights . trackPageView ( null , pageView . url , pageView . properites ) ; } } ) ; } public trackActionEvent ( name , source , result ) { if ( ! this . isEnabled || ! source || ! name ) { return ; } this . noThrowWrapper ( ( ) => { this . appInsights . trackEvent ( "Action: " + name , { Result : result , Source : source } ) ; } ) ; } public trackEvent ( message ) { if ( ! this . isEnabled || ! message ) { return ; } this . noThrowWrapper ( ( ) => { this . appInsights . trackEvent ( message ) ; } ) ; } private initialize ( ) { this . delayedUpdates = { } ; this . appInsights = this . $window . appInsights ; this . isEnabled = this . shouldEnableTelemetry ( ) ; if ( this . appInsights ) { if ( this . appInsights . config ) { this . appInsights . config . disableTelemetry = ! this . isEnabled ; } if ( this . appInsights . context && this . appInsights . context . application ) { this . appInsights . context . application . ver = VersionInfo . Version ; this . appInsights . context . application . build = VersionInfo . Build ; } } if ( this . isEnabled ) { this . storage . subscribe ( ( key , oldValue , newValue ) => this . storageValueChanged ( key , oldValue , newValue ) ) ; } } private shouldEnableTelemetry ( ) { return this . appInsights && TelemetryService . TelemetryEnabledHostsRegex . test ( this . $location . host ( ) ) ; } private trackPropertyChangedEvent ( key , oldValue , newValue ) { if ( ! this . isEnabled ) { return ; } if ( this . appInsights && key && oldValue !== newValue ) { this . noThrowWrapper ( ( ) => { this . appInsights . trackEvent ( "Property: " + key , { OldValue : oldValue , NewValue : newValue } ) ; } ) ; } delete this . delayedUpdates [ key ] ; } private storageValueChanged ( key , oldValue , newValue ) { if ( ! this . isEnabled ) { return ; } this . noThrowWrapper ( ( ) => { let previousOldValue = oldValue ; let ongoingUpdate = this . delayedUpdates [ key ] ; if ( ongoingUpdate ) { this . $interval . cancel ( ongoingUpdate . promise ) ; previousOldValue = ongoingUpdate . oldValue ; } this . delayedUpdates [ key ] = new PropertyUpdatePromise ( previousOldValue , newValue , this . $interval ( ( ) => this . trackPropertyChangedEvent ( key , previousOldValue , newValue ) , TelemetryService . DelayUpdateTimeInSeconds * 1000 , 1 ) ) ; } ) ; } private noThrowWrapper ( func ) { try { func . apply ( this ) ; } catch ( ex ) { console . error ( ex . toString ( ) ) ; } } } export class PropertyUpdatePromise { constructor ( public oldValue , public newValue , public promise ) { } } export class PageViewProperties { public IsSecure : boolean ; public IsLocal : boolean ; public TabName : string ; } export class PageViewRecord { public url : string ; public properites : PageViewProperties ; constructor ( location , currentRoute ) { if ( ! currentRoute || ! location ) { return ; } this . properites = new PageViewProperties ( ) ; this . url = currentRoute . loadedTemplateUrl ; this . properites . IsSecure = location . protocol ( ) && location . protocol ( ) . toLowerCase ( ) === "https" ; this . properites . IsLocal = location . host ( ) && location . host ( ) . toLowerCase ( ) === "localhost" ; if ( currentRoute . params && currentRoute . params . tabId ) { this . properites . TabName = currentRoute . params . tabId ; } } } ( function ( ) { let module = angular . module ( "telemetryService" , [ "storageService" , "ngRoute" ] ) ; module . factory ( "telemetry" , [ "$window" , "$interval" , "$location" , "$route" , "storage" , ( $window , $interval , $location , $route , storage ) => new TelemetryService ( $window , $interval , $location , $route , storage ) ] ) ; } ) ( ) ; }