| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | ///<reference path="../../headers/common.d.ts" />
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import angular from 'angular'; | 
					
						
							|  |  |  | import _ from 'lodash'; | 
					
						
							|  |  |  | import $ from 'jquery'; | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  | import kbn from 'app/core/utils/kbn'; | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | import coreModule from 'app/core/core_module'; | 
					
						
							|  |  |  | import appEvents from 'app/core/app_events'; | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  | import {IntervalVariable} from './interval_variable'; | 
					
						
							|  |  |  | import {Variable} from './variable'; | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  | export var variableConstructorMap: any = {}; | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | export class VariableSrv { | 
					
						
							|  |  |  |   dashboard: any; | 
					
						
							|  |  |  |   variables: any; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   variableLock: any; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** @ngInject */ | 
					
						
							|  |  |  |   constructor( | 
					
						
							|  |  |  |     private $rootScope, | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |     private $q, | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  |     private $location, | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |     private $injector, | 
					
						
							|  |  |  |     private templateSrv) { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     init(dashboard) { | 
					
						
							|  |  |  |       this.variableLock = {}; | 
					
						
							|  |  |  |       this.dashboard = dashboard; | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  |       this.variables = dashboard.templating.list.map(this.createVariableFromModel.bind(this)); | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       this.templateSrv.init(this.variables); | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  |       var queryParams = this.$location.search(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (let variable of this.variables) { | 
					
						
							|  |  |  |         this.variableLock[variable.name] = this.$q.defer(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this.$q.all(this.variables.map(variable => { | 
					
						
							|  |  |  |         return this.processVariable(variable, queryParams); | 
					
						
							|  |  |  |       })); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     processVariable(variable, queryParams) { | 
					
						
							|  |  |  |       var dependencies = []; | 
					
						
							|  |  |  |       var lock = this.variableLock[variable.name]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (let otherVariable of this.variables) { | 
					
						
							|  |  |  |         if (variable.dependsOn(otherVariable)) { | 
					
						
							|  |  |  |           dependencies.push(this.variableLock[otherVariable.name].promise); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this.$q.all(dependencies).then(() => { | 
					
						
							|  |  |  |         var urlValue = queryParams['var-' + variable.name]; | 
					
						
							|  |  |  |         if (urlValue !== void 0) { | 
					
						
							|  |  |  |           return variable.setValueFromUrl(urlValue).then(lock.resolve); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  |         if (variable.refresh === 1 || variable.refresh === 2) { | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  |           return variable.updateOptions().then(lock.resolve); | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         lock.resolve(); | 
					
						
							|  |  |  |       }).finally(() => { | 
					
						
							|  |  |  |         delete this.variableLock[variable.name]; | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  |     createVariableFromModel(model) { | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       var ctor = variableConstructorMap[model.type]; | 
					
						
							|  |  |  |       if (!ctor) { | 
					
						
							|  |  |  |         throw "Unable to find variable constructor for " + model.type; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       var variable = this.$injector.instantiate(ctor, {model: model}); | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  |       return variable; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  |     addVariable(model) { | 
					
						
							|  |  |  |       var variable = this.createVariableFromModel(model); | 
					
						
							|  |  |  |       this.variables.push(this.createVariableFromModel(variable)); | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       return variable; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 21:27:53 +08:00
										 |  |  |     syncToDashboardModel() { | 
					
						
							|  |  |  |       this.dashboard.templating.list = this.variables.map(variable => { | 
					
						
							|  |  |  |         return variable.model; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |     updateOptions(variable) { | 
					
						
							|  |  |  |       return variable.updateOptions(); | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |     variableUpdated(variable) { | 
					
						
							|  |  |  |       // if there is a variable lock ignore cascading update because we are in a boot up scenario
 | 
					
						
							|  |  |  |       if (this.variableLock[variable.name]) { | 
					
						
							|  |  |  |         return this.$q.when(); | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  |       // cascade updates to variables that use this variable
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       var promises = _.map(this.variables, otherVariable => { | 
					
						
							|  |  |  |         if (otherVariable === variable) { | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  |         if (otherVariable.dependsOn(variable)) { | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  |           return this.updateOptions(otherVariable); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       return this.$q.all(promises); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |     selectOptionsForCurrentValue(variable) { | 
					
						
							|  |  |  |       var i, y, value, option; | 
					
						
							|  |  |  |       var selected: any = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (i = 0; i < variable.options.length; i++) { | 
					
						
							|  |  |  |         option = variable.options[i]; | 
					
						
							|  |  |  |         option.selected = false; | 
					
						
							|  |  |  |         if (_.isArray(variable.current.value)) { | 
					
						
							|  |  |  |           for (y = 0; y < variable.current.value.length; y++) { | 
					
						
							|  |  |  |             value = variable.current.value[y]; | 
					
						
							|  |  |  |             if (option.value === value) { | 
					
						
							|  |  |  |               option.selected = true; | 
					
						
							|  |  |  |               selected.push(option); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else if (option.value === variable.current.value) { | 
					
						
							|  |  |  |           option.selected = true; | 
					
						
							|  |  |  |           selected.push(option); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |       return selected; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     validateVariableSelectionState(variable) { | 
					
						
							|  |  |  |       if (!variable.current) { | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  |         if (!variable.options.length) { return this.$q.when(); } | 
					
						
							| 
									
										
										
										
											2016-09-16 16:48:03 +08:00
										 |  |  |         return variable.setValue(variable.options[0]); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (_.isArray(variable.current.value)) { | 
					
						
							|  |  |  |         var selected = this.selectOptionsForCurrentValue(variable); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if none pick first
 | 
					
						
							|  |  |  |         if (selected.length === 0) { | 
					
						
							|  |  |  |           selected = variable.options[0]; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           selected = { | 
					
						
							|  |  |  |             value: _.map(selected, function(val) {return val.value;}), | 
					
						
							|  |  |  |             text: _.map(selected, function(val) {return val.text;}).join(' + '), | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return variable.setValue(selected); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         var currentOption = _.find(variable.options, {text: variable.current.text}); | 
					
						
							|  |  |  |         if (currentOption) { | 
					
						
							|  |  |  |           return variable.setValue(currentOption); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           if (!variable.options.length) { return Promise.resolve(); } | 
					
						
							|  |  |  |           return variable.setValue(variable.options[0]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-16 22:50:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 17:28:45 +08:00
										 |  |  |     setOptionFromUrl(variable, urlValue) { | 
					
						
							|  |  |  |       var promise = this.$q.when(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (variable.refresh) { | 
					
						
							|  |  |  |         promise = variable.updateOptions(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return promise.then(() => { | 
					
						
							|  |  |  |         var option = _.find(variable.options, op => { | 
					
						
							|  |  |  |           return op.text === urlValue || op.value === urlValue; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         option = option || {text: urlValue, value: urlValue}; | 
					
						
							|  |  |  |         return variable.setValue(option); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setOptionAsCurrent(variable, option) { | 
					
						
							|  |  |  |       variable.current = _.cloneDeep(option); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (_.isArray(variable.current.text)) { | 
					
						
							|  |  |  |         variable.current.text = variable.current.text.join(' + '); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.selectOptionsForCurrentValue(variable); | 
					
						
							|  |  |  |       return this.variableUpdated(variable); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-09-15 20:53:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | coreModule.service('variableSrv', VariableSrv); |