import { Subject } from 'rxjs/Subject' ; import { LogCategories } from './../models/constants' ; import { LogService } from './log.service' ; import { Observable } from 'rxjs/Observable' ; import { BroadcastEvent } from 'app/shared/models/broadcast-event' ; import { ReplaySubject } from 'rxjs/ReplaySubject' ; import { DirtyStateEvent } from './../models/broadcast-event' ; import { Injectable , EventEmitter } from '@angular/core' ; import { Subscription } from 'rxjs/Subscription' ; import { FunctionInfo } from '../models/function-info' ; import { TutorialEvent } from '../models/tutorial' ; import { ErrorEvent } from '../models/error-event' ; import { HttpError } from '../models/http-result' ; import { FunctionMonitorInfo } from '../models/function-monitor' ; interface EventInfo < T > { eventType : BroadcastEvent ; obj : T ; } export interface IBroadcastService { broadcast < T > ( eventType , obj ? ) ; subscribe < T > ( eventType , callback , errorCallback ? , completedCallback ? ) ; broadcastEvent < T > ( eventType , obj ? ) ; getEvents < T > ( eventType ) : Observable < T > ; setDirtyState ( reason ? ) ; clearDirtyState ( reason ? , all ? ) ; getDirtyState ( reason ? ) ; clearAllDirtyStates ( ) ; } @ Injectable ( ) export class BroadcastService implements IBroadcastService { private functionDeletedEvent : EventEmitter < FunctionInfo > ; private functionAddedEvent : EventEmitter < FunctionInfo > ; private functionSelectedEvent : EventEmitter < FunctionInfo > ; private functionUpdatedEvent : EventEmitter < FunctionInfo > ; private integrateChangedEvent : EventEmitter < void > ; private tutorialStepEvent : EventEmitter < TutorialEvent > ; private errorEvent : EventEmitter < ErrorEvent | HttpError > ; private trialExpired : EventEmitter < void > ; private resetKeySelection : EventEmitter < FunctionInfo > ; private clearErrorEvent : EventEmitter < string > ; private refreshMonitorEvent : EventEmitter < FunctionMonitorInfo > ; private dirtyStateMap : { [ key ] : string ; } = { } ; private defaultDirtyReason = 'global' ; private _streamMap : { [ key ] : Subject < EventInfo < any > > ; } = { } ; constructor ( private _logService ) { this . functionDeletedEvent = new EventEmitter < FunctionInfo > ( ) ; this . functionAddedEvent = new EventEmitter < FunctionInfo > ( ) ; this . functionSelectedEvent = new EventEmitter < FunctionInfo > ( ) ; this . functionUpdatedEvent = new EventEmitter < FunctionInfo > ( ) ; this . tutorialStepEvent = new EventEmitter < TutorialEvent > ( ) ; this . integrateChangedEvent = new EventEmitter < void > ( ) ; this . trialExpired = new EventEmitter < void > ( ) ; this . resetKeySelection = new EventEmitter < FunctionInfo > ( ) ; this . clearErrorEvent = new EventEmitter < string > ( ) ; this . refreshMonitorEvent = new EventEmitter < FunctionMonitorInfo > ( ) ; this . errorEvent = new EventEmitter < ErrorEvent > ( ) ; this . _streamMap [ BroadcastEvent . UpdateBusyState ] = new ReplaySubject ( 128 ) ; this . _streamMap [ BroadcastEvent . TreeNavigation ] = new ReplaySubject ( 1 ) ; this . _streamMap [ BroadcastEvent . TreeUpdate ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . OpenTab ] = new ReplaySubject ( 1 ) ; this . _streamMap [ BroadcastEvent . DirtyStateChange ] = new ReplaySubject ( 1 ) ; this . _streamMap [ BroadcastEvent . UpdateAppsList ] = new ReplaySubject ( 1 ) ; this . _streamMap [ BroadcastEvent . IntegrateChanged ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . ReloadDeploymentCenter ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . FunctionEditorEvent ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . RightTabsEvent ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . BottomTabsEvent ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . RefreshMonitoringView ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . FunctionCodeUpdate ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . FunctionRunEvent ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . CloseTab ] = new ReplaySubject ( 1 ) ; this . _streamMap [ BroadcastEvent . PlanUpdated ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . SiteUpdated ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . SlotSwap ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . SlotNew ] = new Subject ( ) ; this . _streamMap [ BroadcastEvent . ByosConfigReceived ] = new Subject ( ) ; } broadcast < T > ( eventType , obj ? ) { const emitter = < EventEmitter < T > > this . _getEventEmitter ( eventType ) ; emitter . emit ( obj ) ; } subscribe < T > ( eventType , callback , errorCallback ? , completedCallback ? ) { const emitter = < EventEmitter < T > > this . _getEventEmitter ( eventType ) ; return emitter . subscribe ( callback , errorCallback , completedCallback ) ; } broadcastEvent < T > ( eventType , obj ? ) { const subject = this . _streamMap [ eventType ] ; if ( ! subject ) { throw Error ( `EventType ${ BroadcastEvent [ eventType ] } not found` ) ; } subject . next ( { eventType : eventType , obj : obj , } ) ; } getEvents < T > ( eventType ) { const subject = this . _streamMap [ eventType ] ; if ( ! subject ) { throw Error ( `EventType ${ BroadcastEvent [ eventType ] } not found` ) ; } return subject . do ( e => { this . _logService . verbose ( LogCategories . broadcastService , BroadcastEvent [ e . eventType ] ) ; } ) . map ( e => < T > e . obj ) ; } setDirtyState ( reason ? ) { this . broadcastEvent < DirtyStateEvent > ( BroadcastEvent . DirtyStateChange , { dirty : true , reason : reason } ) ; reason = reason || this . defaultDirtyReason ; this . dirtyStateMap [ reason ] = reason ; } clearDirtyState ( reason ? , all ? ) { reason = reason || this . defaultDirtyReason ; if ( ! this . dirtyStateMap [ reason ] ) { return ; } this . broadcastEvent < DirtyStateEvent > ( BroadcastEvent . DirtyStateChange , { dirty : false , reason : reason } ) ; delete this . dirtyStateMap [ reason ] ; } getDirtyState ( reason ? ) { if ( reason ) { return this . dirtyStateMap [ reason ] ; } else { return ! this . isEmptyMap ( this . dirtyStateMap ) ; } } clearAllDirtyStates ( ) { this . broadcastEvent < DirtyStateEvent > ( BroadcastEvent . DirtyStateChange , { dirty : false , reason : null } ) ; this . dirtyStateMap = { } ; } private isEmptyMap ( map ) { for ( const key in map ) { if ( map . hasOwnProperty ( key ) ) { return false ; } } return true ; } private _getEventEmitter ( eventType ) { switch ( eventType ) { case BroadcastEvent . FunctionDeleted : return this . functionDeletedEvent ; case BroadcastEvent . FunctionAdded : return this . functionAddedEvent ; case BroadcastEvent . FunctionSelected : return this . functionSelectedEvent ; case BroadcastEvent . FunctionUpdated : return this . functionUpdatedEvent ; case BroadcastEvent . TutorialStep : return this . tutorialStepEvent ; case BroadcastEvent . IntegrateChanged : return this . integrateChangedEvent ; case BroadcastEvent . Error : return this . errorEvent ; case BroadcastEvent . TrialExpired : return this . trialExpired ; case BroadcastEvent . ResetKeySelection : return this . resetKeySelection ; case BroadcastEvent . ClearError : return this . clearErrorEvent ; } } }