diff --git a/.gitignore b/.gitignore index 701b6bbbc11..5ecb68eb64e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ node_modules .aws-config.json dist + +# locally required config files web.config config.js -*.sublime-workspace \ No newline at end of file + +# Editor junk +*.sublime-workspace +*.swp diff --git a/src/app/app.js b/src/app/app.js index c3c46dbdde0..1508f16e013 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -98,7 +98,7 @@ function (angular, $, _, appLevelRequire) { 'pasvaz.bindonce' ]; - _.each('controllers directives factories services filters'.split(' '), + _.each('controllers directives factories services services.dashboard filters'.split(' '), function (type) { var module_name = 'kibana.'+type; // create the module diff --git a/src/app/controllers/dash.js b/src/app/controllers/dash.js index 98f5df2983e..71222c1b7c7 100644 --- a/src/app/controllers/dash.js +++ b/src/app/controllers/dash.js @@ -22,7 +22,8 @@ define([ 'jquery', 'config', 'underscore', - 'services/all' + 'services/all', + 'services/dashboard/all' ], function (angular, $, config, _) { "use strict"; @@ -30,7 +31,7 @@ function (angular, $, config, _) { var module = angular.module('kibana.controllers'); module.controller('DashCtrl', function( - $scope, $rootScope, ejsResource, dashboard, + $scope, $rootScope, $timeout, ejsResource, dashboard, filterSrv, dashboardKeybindings, alertSrv, panelMove, keyboardManager, grafanaVersion) { $scope.requiredElasticSearchVersion = ">=0.90.3"; @@ -56,6 +57,16 @@ function (angular, $, config, _) { $scope.dashboard = dashboard; $scope.dashAlerts = alertSrv; + $scope.filter = filterSrv; + $scope.filter.init( dashboard.current ); + + $scope.$watch('dashboard.current', function(newValue) { + $scope.filter.init( newValue ); + }); + + $scope.$watch('filter.time', function() { + $scope.dashboard.refresh(); + }, true); // Clear existing alerts alertSrv.clearAll(); @@ -66,68 +77,7 @@ function (angular, $, config, _) { $scope.bindKeyboardShortcuts(); }; - $scope.bindKeyboardShortcuts = function() { - $rootScope.$on('panel-fullscreen-enter', function() { - $rootScope.fullscreen = true; - }); - - $rootScope.$on('panel-fullscreen-exit', function() { - $rootScope.fullscreen = false; - }); - - $rootScope.$on('dashboard-saved', function() { - if ($rootScope.fullscreen) { - $rootScope.$emit('panel-fullscreen-exit'); - } - }); - - keyboardManager.bind('ctrl+f', function(evt) { - $rootScope.$emit('open-search', evt); - }, { inputDisabled: true }); - - keyboardManager.bind('ctrl+h', function() { - var current = dashboard.current.hideControls; - dashboard.current.hideControls = !current; - dashboard.current.panel_hints = current; - }, { inputDisabled: true }); - - keyboardManager.bind('ctrl+s', function(evt) { - $rootScope.$emit('save-dashboard', evt); - }, { inputDisabled: true }); - - keyboardManager.bind('ctrl+r', function() { - dashboard.refresh(); - }, { inputDisabled: true }); - - keyboardManager.bind('ctrl+z', function(evt) { - $rootScope.$emit('zoom-out', evt); - }, { inputDisabled: true }); - - keyboardManager.bind('esc', function() { - var popups = $('.popover.in'); - if (popups.length > 0) { - return; - } - $rootScope.$emit('panel-fullscreen-exit'); - }, { inputDisabled: true }); - }; - - $scope.countWatchers = function (scopeStart) { - var q = [scopeStart || $rootScope], watchers = 0, scope; - while (q.length > 0) { - scope = q.pop(); - if (scope.$$watchers) { - watchers += scope.$$watchers.length; - } - if (scope.$$childHead) { - q.push(scope.$$childHead); - } - if (scope.$$nextSibling) { - q.push(scope.$$nextSibling); - } - } - window.console.log(watchers); - }; + $scope.bindKeyboardShortcuts = dashboardKeybindings.shortcuts; $scope.isPanel = function(obj) { if(!_.isNull(obj) && !_.isUndefined(obj) && !_.isUndefined(obj.type)) { @@ -196,4 +146,4 @@ function (angular, $, config, _) { $scope.init(); }); -}); \ No newline at end of file +}); diff --git a/src/app/controllers/dashLoader.js b/src/app/controllers/dashLoader.js index 7f9dc9232dd..fe5ed2a9c66 100644 --- a/src/app/controllers/dashLoader.js +++ b/src/app/controllers/dashLoader.js @@ -8,7 +8,7 @@ function (angular, _, moment) { var module = angular.module('kibana.controllers'); - module.controller('dashLoader', function($scope, $rootScope, $http, dashboard, alertSrv, $location, filterSrv, playlistSrv) { + module.controller('dashLoader', function($scope, $rootScope, $http, dashboard, alertSrv, $location, playlistSrv) { $scope.loader = dashboard.current.loader; $scope.init = function() { @@ -131,7 +131,7 @@ function (angular, _, moment) { // function $scope.zoom // factor :: Zoom factor, so 0.5 = cuts timespan in half, 2 doubles timespan $scope.zoom = function(factor) { - var _range = filterSrv.timeRange(); + var _range = this.filter.timeRange(); var _timespan = (_range.to.valueOf() - _range.from.valueOf()); var _center = _range.to.valueOf() - _timespan/2; @@ -145,7 +145,7 @@ function (angular, _, moment) { _to = Date.now(); } - filterSrv.setTime({ + this.filter.setTime({ from:moment.utc(_from).toDate(), to:moment.utc(_to).toDate(), }); diff --git a/src/app/controllers/graphiteTarget.js b/src/app/controllers/graphiteTarget.js index a7224b2ced6..8e9f9799c94 100644 --- a/src/app/controllers/graphiteTarget.js +++ b/src/app/controllers/graphiteTarget.js @@ -10,7 +10,7 @@ function (angular, _, config, gfunc, Parser) { var module = angular.module('kibana.controllers'); - module.controller('GraphiteTargetCtrl', function($scope, $http, filterSrv) { + module.controller('GraphiteTargetCtrl', function($scope) { $scope.init = function() { parseTarget(); @@ -120,7 +120,7 @@ function (angular, _, config, gfunc, Parser) { } var path = getSegmentPathUpTo(fromIndex + 1); - return $scope.datasource.metricFindQuery(path) + return $scope.datasource.metricFindQuery($scope.filter, path) .then(function(segments) { if (segments.length === 0) { $scope.segments = $scope.segments.splice(0, fromIndex); @@ -157,17 +157,17 @@ function (angular, _, config, gfunc, Parser) { var query = index === 0 ? '*' : getSegmentPathUpTo(index) + '.*'; - return $scope.datasource.metricFindQuery(query) + return $scope.datasource.metricFindQuery($scope.filter, query) .then(function(segments) { _.each(segments, function(segment) { segment.html = segment.val = segment.text; }); - _.each(filterSrv.list, function(filter) { + _.each($scope.filter.templateParameters, function( templateParameter ) { segments.unshift({ type: 'template', - html: '[[' + filter.name + ']]', - val: '[[' + filter.name + ']]', + html: '[[' + templateParameter.name + ']]', + val: '[[' + templateParameter.name + ']]', expandable: true, }); }); diff --git a/src/app/controllers/metricKeys.js b/src/app/controllers/metricKeys.js index e39d2b43c18..fa39bfd4ad3 100644 --- a/src/app/controllers/metricKeys.js +++ b/src/app/controllers/metricKeys.js @@ -52,16 +52,23 @@ function (angular, _, config) { $scope.loadAll = function() { $scope.infoText = "Fetching all metrics from graphite..."; - return $http.get(config.graphiteUrl + "/metrics/index.json") - .then(saveMetricsArray) - .then(function () { + getFromEachGraphite( '/metrics/index.json', saveMetricsArray ) + .then( function() { $scope.infoText = "Indexing complete!"; - }) - .then(null, function(err) { + }).then(null, function(err) { $scope.errorText = err; }); }; + function getFromEachGraphite( request, data_callback, error_callback ) { + return $q.all( _.map( config.datasources, function( datasource ) { + if ( datasource.type = 'graphite' ) { + return $http.get( datasource.url + request ) + .then( data_callback, error_callback ); + } + } ) ); + } + function saveMetricsArray(data, currentIndex) { if (!data && !data.data && data.data.length === 0) { @@ -80,6 +87,7 @@ function (angular, _, config) { }); } + function deleteIndex() { var deferred = $q.defer(); @@ -172,9 +180,9 @@ function (angular, _, config) { function loadMetricsRecursive(metricPath) { - return $http.get(config.graphiteUrl + '/metrics/find/?query=' + metricPath).then(receiveMetric); + return getFromEachGraphite( '/metrics/find/?query=' + metricPath, receiveMetric ); } }); -}); \ No newline at end of file +}); diff --git a/src/app/directives/grafanaGraph.js b/src/app/directives/grafanaGraph.js index d5a44598ad0..798584ca194 100644 --- a/src/app/directives/grafanaGraph.js +++ b/src/app/directives/grafanaGraph.js @@ -10,7 +10,7 @@ function (angular, $, kbn, moment, _) { var module = angular.module('kibana.directives'); - module.directive('grafanaGraph', function(filterSrv, $rootScope, dashboard) { + module.directive('grafanaGraph', function($rootScope, dashboard) { return { restrict: 'A', template: '
', @@ -387,9 +387,11 @@ function (angular, $, kbn, moment, _) { } elem.bind("plotselected", function (event, ranges) { - filterSrv.setTime({ - from : moment.utc(ranges.xaxis.from).toDate(), - to : moment.utc(ranges.xaxis.to).toDate(), + scope.$apply( function() { + scope.filter.setTime({ + from : moment.utc(ranges.xaxis.from).toDate(), + to : moment.utc(ranges.xaxis.to).toDate(), + }); }); }); } diff --git a/src/app/panels/filtering/module.html b/src/app/panels/filtering/module.html index a360161aa83..950390b8107 100644 --- a/src/app/panels/filtering/module.html +++ b/src/app/panels/filtering/module.html @@ -2,7 +2,7 @@
-
+
@@ -47,4 +47,4 @@
-
\ No newline at end of file +
diff --git a/src/app/panels/filtering/module.js b/src/app/panels/filtering/module.js index c7c475fbd60..5a8c49e0cff 100644 --- a/src/app/panels/filtering/module.js +++ b/src/app/panels/filtering/module.js @@ -14,7 +14,7 @@ function (angular, app, _) { var module = angular.module('kibana.panels.filtering', []); app.useModule(module); - module.controller('filtering', function($scope, filterSrv, datasourceSrv, $rootScope, dashboard) { + module.controller('filtering', function($scope, datasourceSrv, $rootScope, $timeout) { $scope.panelMeta = { status : "Stable", @@ -27,33 +27,41 @@ function (angular, app, _) { _.defaults($scope.panel,_d); $scope.init = function() { - $scope.filterSrv = filterSrv; + // empty. Don't know if I need the function then. }; - $scope.remove = function(filter) { - filterSrv.remove(filter); + $scope.remove = function( templateParameter ) { + this.filter.removeTemplateParameter( templateParameter ); + + // TODO hkraemer: check if this makes sense like this + if(!$rootScope.$$phase) { + $rootScope.$apply(); + } + $timeout(function(){ + this.dashboard.refresh(); + },0); }; - $scope.filterOptionSelected = function(filter, option) { - filterSrv.filterOptionSelected(filter, option); - $scope.applyFilterToOtherFilters(filter); + $scope.filterOptionSelected = function( templateParameter, option ) { + this.filter.templateOptionSelected(option); + this.applyFilterToOtherFilters(templateParameter); }; $scope.applyFilterToOtherFilters = function(updatedFilter) { - _.each(filterSrv.list, function(filter) { - if (filter === updatedFilter) { + _.each(this.filter.templateParameters, function( templateParameter ) { + if (templateParameter === updatedFilter) { return; } - if (filter.query.indexOf(updatedFilter.name) !== -1) { - $scope.applyFilter(filter); + if (templateParameter.query.indexOf(updatedFilter.name) !== -1) { + $scope.applyFilter(templateParameter); } }); }; $scope.applyFilter = function(filter) { - var query = filterSrv.applyFilterToTarget(filter.query); + var query = this.filter.applyTemplateToTarget(filter.query); - datasourceSrv.default.metricFindQuery(query) + datasourceSrv.default.metricFindQuery($scope, query) .then(function (results) { filter.editing=undefined; filter.options = _.map(results, function(node) { @@ -69,12 +77,12 @@ function (angular, app, _) { filter.options.unshift({text: 'All', value: allExpr}); } - filterSrv.filterOptionSelected(filter, filter.options[0]); + this.filter.templateOptionSelected(filter, filter.options[0]); }); }; $scope.add = function() { - filterSrv.add({ + this.filter.addTemplateParameter({ type : 'filter', name : 'filter name', editing : true, @@ -83,7 +91,7 @@ function (angular, app, _) { }; $scope.refresh = function() { - dashboard.refresh(); + this.dashboard.refresh(); }; $scope.render = function() { @@ -91,4 +99,4 @@ function (angular, app, _) { }; }); -}); \ No newline at end of file +}); diff --git a/src/app/panels/graphite/module.js b/src/app/panels/graphite/module.js index 9ea1f2d3b47..a47cbbc895a 100644 --- a/src/app/panels/graphite/module.js +++ b/src/app/panels/graphite/module.js @@ -19,7 +19,6 @@ define([ 'kbn', 'moment', './timeSeries', - 'services/filterSrv', 'services/annotationsSrv', 'services/datasourceSrv', 'jquery.flot', @@ -37,7 +36,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) { var module = angular.module('kibana.panels.graphite', []); app.useModule(module); - module.controller('graphite', function($scope, $rootScope, filterSrv, datasourceSrv, $timeout, annotationsSrv) { + module.controller('graphite', function($scope, $rootScope, datasourceSrv, $timeout, annotationsSrv) { $scope.panelMeta = { modals : [], @@ -231,8 +230,8 @@ function (angular, app, $, _, kbn, moment, timeSeries) { }; $scope.updateTimeRange = function () { - $scope.range = filterSrv.timeRange(); - $scope.rangeUnparsed = filterSrv.timeRange(false); + $scope.range = this.filter.timeRange(); + $scope.rangeUnparsed = this.filter.timeRange(false); $scope.resolution = Math.ceil($(window).width() * ($scope.panel.span / 12)); $scope.interval = '10m'; @@ -259,9 +258,9 @@ function (angular, app, $, _, kbn, moment, timeSeries) { datasource: $scope.panel.datasource }; - $scope.annotationsPromise = annotationsSrv.getAnnotations($scope.rangeUnparsed); + $scope.annotationsPromise = annotationsSrv.getAnnotations($scope.filter, $scope.rangeUnparsed); - return $scope.datasource.query(graphiteQuery) + return $scope.datasource.query($scope.filter, graphiteQuery) .then($scope.dataHandler) .then(null, function(err) { $scope.panelMeta.loading = false; diff --git a/src/app/panels/timepicker/module.html b/src/app/panels/timepicker/module.html index f0975d371ae..ea1759d2141 100644 --- a/src/app/panels/timepicker/module.html +++ b/src/app/panels/timepicker/module.html @@ -17,14 +17,14 @@ - + {{time.from.date | date:'MMM d, y HH:mm:ss'}} {{time.from.date | moment:'ago'}} to {{time.to.date | date:'MMM d, y HH:mm:ss'}} {{time.to.date | moment:'ago'}} - Time filter + Time filter refreshed every {{dashboard.current.refresh}} diff --git a/src/app/panels/timepicker/module.js b/src/app/panels/timepicker/module.js index 198239f6a0d..a16ebc132d5 100644 --- a/src/app/panels/timepicker/module.js +++ b/src/app/panels/timepicker/module.js @@ -25,7 +25,7 @@ function (angular, app, _, moment, kbn) { var module = angular.module('kibana.panels.timepicker', []); app.useModule(module); - module.controller('timepicker', function($scope, $modal, $q, filterSrv) { + module.controller('timepicker', function($scope, $modal, $q) { $scope.panelMeta = { status : "Stable", description : "A panel for controlling the time range filters. If you have time based data, "+ @@ -44,8 +44,6 @@ function (angular, app, _, moment, kbn) { _.defaults($scope.panel,_d); - $scope.filterSrv = filterSrv; - // ng-pattern regexs $scope.patterns = { date: /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/, @@ -58,9 +56,9 @@ function (angular, app, _, moment, kbn) { $scope.$on('refresh', function(){$scope.init();}); $scope.init = function() { - var time = filterSrv.timeRange(); + var time = this.filter.timeRange( true ); if(time) { - $scope.panel.now = filterSrv.timeRange(false).to === "now" ? true : false; + $scope.panel.now = this.filter.timeRange(false).to === "now" ? true : false; $scope.time = getScopeTimeObj(time.from,time.to); } }; @@ -135,7 +133,7 @@ function (angular, app, _, moment, kbn) { } // Set the filter - $scope.panel.filter_id = filterSrv.setTime(_filter); + $scope.panel.filter_id = $scope.filter.setTime(_filter); // Update our representation $scope.time = getScopeTimeObj(time.from,time.to); @@ -149,7 +147,7 @@ function (angular, app, _, moment, kbn) { to: "now" }; - filterSrv.setTime(_filter); + this.filter.setTime(_filter); $scope.time = getScopeTimeObj(kbn.parseDate(_filter.from),new Date()); }; diff --git a/src/app/services/annotationsSrv.js b/src/app/services/annotationsSrv.js index dceb28eea10..459b5ff2816 100644 --- a/src/app/services/annotationsSrv.js +++ b/src/app/services/annotationsSrv.js @@ -28,7 +28,7 @@ define([ list = []; }; - this.getAnnotations = function(rangeUnparsed) { + this.getAnnotations = function(filterSrv, rangeUnparsed) { if (!annotationPanel.enable) { return $q.when(null); } @@ -37,7 +37,7 @@ define([ return promiseCached; } - var graphiteMetrics = this.getGraphiteMetrics(rangeUnparsed); + var graphiteMetrics = this.getGraphiteMetrics(filterSrv, rangeUnparsed); var graphiteEvents = this.getGraphiteEvents(rangeUnparsed); promiseCached = $q.all(graphiteMetrics.concat(graphiteEvents)) @@ -81,7 +81,7 @@ define([ }); }; - this.getGraphiteMetrics = function(rangeUnparsed) { + this.getGraphiteMetrics = function(filterSrv, rangeUnparsed) { var annotations = this.getAnnotationsByType('graphite metric'); if (annotations.length === 0) { return []; @@ -97,7 +97,7 @@ define([ var receiveFunc = _.partial(receiveGraphiteMetrics, annotation); - return datasourceSrv.default.query(graphiteQuery) + return datasourceSrv.default.query(filterSrv, graphiteQuery) .then(receiveFunc) .then(null, errorHandler); }); @@ -154,4 +154,4 @@ define([ this.init(); }); -}); \ No newline at end of file +}); diff --git a/src/app/services/dashboard.js b/src/app/services/dashboard.js index 6c4cfd67e34..4f0ca8cee7c 100644 --- a/src/app/services/dashboard.js +++ b/src/app/services/dashboard.js @@ -54,7 +54,6 @@ function (angular, $, kbn, _, config, moment, Modernizr) { // Store a reference to this var self = this; - var filterSrv; this.current = _.clone(_dash); this.last = {}; @@ -157,10 +156,6 @@ function (angular, $, kbn, _, config, moment, Modernizr) { // Set the current dashboard self.current = angular.copy(dashboard); - - filterSrv = $injector.get('filterSrv'); - filterSrv.init(); - if(dashboard.refresh) { self.set_interval(dashboard.refresh); } @@ -467,8 +462,6 @@ function (angular, $, kbn, _, config, moment, Modernizr) { timer.cancel(self.refresh_timer); } }; - - }); }); diff --git a/src/app/services/dashboard/all.js b/src/app/services/dashboard/all.js new file mode 100644 index 00000000000..f861edb5a8d --- /dev/null +++ b/src/app/services/dashboard/all.js @@ -0,0 +1,4 @@ +define([ + './dashboardKeyBindings', +], +function () {}); diff --git a/src/app/services/dashboard/dashboardKeyBindings.js b/src/app/services/dashboard/dashboardKeyBindings.js new file mode 100644 index 00000000000..b399ca5bc5e --- /dev/null +++ b/src/app/services/dashboard/dashboardKeyBindings.js @@ -0,0 +1,58 @@ +define([ + 'angular', + 'jquery', + 'services/all' +], +function( angular, $ ) { + "use strict"; + + var module = angular.module('kibana.services.dashboard'); + + module.service( 'dashboardKeybindings', function($rootScope, keyboardManager, dashboard) { + this.shortcuts = function() { + $rootScope.$on('panel-fullscreen-enter', function() { + $rootScope.fullscreen = true; + }); + + $rootScope.$on('panel-fullscreen-exit', function() { + $rootScope.fullscreen = false; + }); + + $rootScope.$on('dashboard-saved', function() { + if ($rootScope.fullscreen) { + $rootScope.$emit('panel-fullscreen-exit'); + } + }); + + keyboardManager.bind('ctrl+f', function(evt) { + $rootScope.$emit('open-search', evt); + }, { inputDisabled: true }); + + keyboardManager.bind('ctrl+h', function() { + var current = dashboard.current.hideControls; + dashboard.current.hideControls = !current; + dashboard.current.panel_hints = current; + }, { inputDisabled: true }); + + keyboardManager.bind('ctrl+s', function(evt) { + $rootScope.$emit('save-dashboard', evt); + }, { inputDisabled: true }); + + keyboardManager.bind('ctrl+r', function() { + dashboard.refresh(); + }, { inputDisabled: true }); + + keyboardManager.bind('ctrl+z', function(evt) { + $rootScope.$emit('zoom-out', evt); + }, { inputDisabled: true }); + + keyboardManager.bind('esc', function() { + var popups = $('.popover.in'); + if (popups.length > 0) { + return; + } + $rootScope.$emit('panel-fullscreen-exit'); + }, { inputDisabled: true }); + }; + }); +}); diff --git a/src/app/services/datasourceSrv.js b/src/app/services/datasourceSrv.js index 77f0f9f1142..1f6f882ff5a 100644 --- a/src/app/services/datasourceSrv.js +++ b/src/app/services/datasourceSrv.js @@ -10,7 +10,7 @@ function (angular, _, config) { var module = angular.module('kibana.services'); - module.service('datasourceSrv', function($q, filterSrv, $http, GraphiteDatasource, InfluxDatasource) { + module.service('datasourceSrv', function($q, $http, GraphiteDatasource, InfluxDatasource) { this.init = function() { var defaultDatasource = _.findWhere(_.values(config.datasources), { default: true } ); @@ -48,4 +48,4 @@ function (angular, _, config) { this.init(); }); -}); \ No newline at end of file +}); diff --git a/src/app/services/filterSrv.js b/src/app/services/filterSrv.js index 7126a14d5e6..3d882354cbd 100644 --- a/src/app/services/filterSrv.js +++ b/src/app/services/filterSrv.js @@ -8,125 +8,102 @@ define([ var module = angular.module('kibana.services'); - module.service('filterSrv', function(dashboard, $rootScope, $timeout, $routeParams) { + module.factory('filterSrv', function(dashboard, $rootScope, $timeout, $routeParams) { // defaults var _d = { - list: [], + templateParameters: [], time: {} }; - // Save a reference to this - var self = this; + var result = { + _updateTemplateData : function( initial ) { + var _templateData = {}; + _.each(this.templateParameters, function( templateParameter ) { + if (initial) { + var urlValue = $routeParams[ templateParameter.name ]; + if (urlValue) { + templateParameter.current = { text: urlValue, value: urlValue }; + } + } + if (!templateParameter.current || !templateParameter.current.value) { + return; + } - // Call this whenever we need to reload the important stuff - this.init = function() { - dashboard.current.services.filter = dashboard.current.services.filter || {}; + _templateData[ templateParameter.name ] = templateParameter.current.value; + }); + this._templateData = _templateData; + }, - _.defaults(dashboard.current.services.filter, _d); + templateOptionSelected : function(templateParameter, option) { + templateParameter.current = option; + this._updateTemplateData(); + }, - self.list = dashboard.current.services.filter.list; - self.time = dashboard.current.services.filter.time; + addTemplateParameter : function( templateParameter ) { + this.templateParameters.push( templateParameter ); + this._updateTemplateData(); + }, - self.templateSettings = { - interpolate : /\[\[([\s\S]+?)\]\]/g, - }; + applyTemplateToTarget : function(target) { + if (target.indexOf('[[') === -1) { + return target; + } - if (self.list.length) { - this._updateTemplateData(true); - } - }; + return _.template(target, this._templateData, this.templateSettings); + }, - this._updateTemplateData = function(initial) { - self._filterTemplateData = {}; + setTime : function(time) { + _.extend(this.time, time); + // disable refresh if we have an absolute time + if (time.to !== 'now') { + this.old_refresh = this.dashboard.refresh; + dashboard.set_interval(false); + return; + } + + if (this.old_refresh && this.old_refresh !== this.dashboard.refresh) { + dashboard.set_interval(this.old_refresh); + this.old_refresh = null; + } + }, + + timeRange : function(parse) { + var _t = this.time; + if(_.isUndefined(_t) || _.isUndefined(_t.from)) { + return false; + } + if(parse === false) { + return { + from: _t.from, + to: _t.to + }; + } else { + var _from = _t.from; + var _to = _t.to || new Date(); + + return { + from : kbn.parseDate(_from), + to : kbn.parseDate(_to) + }; + } + }, + + removeTemplateParameter : function( templateParameter ) { + this.templateParameters = _.without( this.templateParameters, templateParameter ); + }, + + init : function( dashboard ) { + _.defaults(this, _d); + this.dashboard = dashboard; + this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g }; + if( dashboard && dashboard.services && dashboard.services.filter ) { + // compatiblity hack + this.time = dashboard.services.filter.time; + } - _.each(self.list, function(filter) { - if (initial) { - var urlValue = $routeParams[filter.name]; - if (urlValue) { - filter.current = { text: urlValue, value: urlValue }; - } } - if (!filter.current || !filter.current.value) { - return; - } - - self._filterTemplateData[filter.name] = filter.current.value; - }); - }; - - this.filterOptionSelected = function(filter, option) { - filter.current = option; - this._updateTemplateData(); - dashboard.refresh(); - }; - - this.add = function(filter) { - self.list.push(filter); - }; - - this.applyFilterToTarget = function(target) { - if (target.indexOf('[[') === -1) { - return target; - } - - return _.template(target, self._filterTemplateData, self.templateSettings); - }; - - this.remove = function(filter) { - self.list = dashboard.current.services.filter.list = _.without(self.list, filter); - - if(!$rootScope.$$phase) { - $rootScope.$apply(); - } - - $timeout(function(){ - dashboard.refresh(); - },0); - }; - - this.setTime = function(time) { - _.extend(self.time, time); - - // disable refresh if we have an absolute time - if (time.to !== 'now') { - self.old_refresh = dashboard.current.refresh; - dashboard.set_interval(false); - } - else if (self.old_refresh && self.old_refresh !== dashboard.current.refresh) { - dashboard.set_interval(self.old_refresh); - self.old_refresh = null; - } - - $timeout(function(){ - dashboard.refresh(); - },0); - }; - - this.timeRange = function(parse) { - var _t = self.time; - - if(_.isUndefined(_t)) { - return false; - } - if(parse === false) { - return { - from: _t.from, - to: _t.to - }; - } else { - var - _from = _t.from, - _to = _t.to || new Date(); - - return { - from : kbn.parseDate(_from), - to : kbn.parseDate(_to) - }; - } - }; - - // Now init - self.init(); + }; + return result; }); -}); \ No newline at end of file +}); diff --git a/src/app/services/graphite/graphiteDatasource.js b/src/app/services/graphite/graphiteDatasource.js index d48fdf7dd12..78984a55cf7 100644 --- a/src/app/services/graphite/graphiteDatasource.js +++ b/src/app/services/graphite/graphiteDatasource.js @@ -11,7 +11,7 @@ function (angular, _, $, config, kbn, moment) { var module = angular.module('kibana.services'); - module.factory('GraphiteDatasource', function(dashboard, $q, filterSrv, $http) { + module.factory('GraphiteDatasource', function(dashboard, $q, $http) { function GraphiteDatasource(datasource) { this.type = 'graphite'; @@ -22,7 +22,7 @@ function (angular, _, $, config, kbn, moment) { this.render_method = datasource.render_method || 'POST'; } - GraphiteDatasource.prototype.query = function(options) { + GraphiteDatasource.prototype.query = function(filterSrv, options) { try { var graphOptions = { from: this.translateTime(options.range.from, 'round-down'), @@ -32,7 +32,7 @@ function (angular, _, $, config, kbn, moment) { maxDataPoints: options.maxDataPoints, }; - var params = this.buildGraphiteParams(graphOptions); + var params = this.buildGraphiteParams(filterSrv, graphOptions); if (options.format === 'png') { return $q.when(this.url + '/render' + '?' + params.join('&')); @@ -115,10 +115,10 @@ function (angular, _, $, config, kbn, moment) { return date.format('HH:mm_YYYYMMDD'); }; - GraphiteDatasource.prototype.metricFindQuery = function(query) { + GraphiteDatasource.prototype.metricFindQuery = function(filterSrv, query) { var interpolated; try { - interpolated = filterSrv.applyFilterToTarget(query); + interpolated = filterSrv.applyTemplateToTarget(query); } catch(err) { return $q.reject(err); @@ -158,7 +158,7 @@ function (angular, _, $, config, kbn, moment) { return $http(options); }; - GraphiteDatasource.prototype.buildGraphiteParams = function(options) { + GraphiteDatasource.prototype.buildGraphiteParams = function(filterSrv, options) { var clean_options = []; var graphite_options = ['target', 'targets', 'from', 'until', 'rawData', 'format', 'maxDataPoints']; @@ -174,7 +174,7 @@ function (angular, _, $, config, kbn, moment) { if (key === "targets") { _.each(value, function (value) { if (!value.hide) { - var targetValue = filterSrv.applyFilterToTarget(value.target); + var targetValue = filterSrv.applyTemplateToTarget(value.target); clean_options.push("target=" + encodeURIComponent(targetValue)); } }, this); diff --git a/src/app/services/unsavedChangesSrv.js b/src/app/services/unsavedChangesSrv.js index a0d2a079d34..bdbd024b91d 100644 --- a/src/app/services/unsavedChangesSrv.js +++ b/src/app/services/unsavedChangesSrv.js @@ -56,6 +56,7 @@ function (angular, _, config) { // ignore timespan changes current.services.filter.time = original.services.filter.time = {}; + current.refresh = original.refresh; var currentTimepicker = _.findWhere(current.nav, { type: 'timepicker' }); @@ -99,4 +100,4 @@ function (angular, _, config) { }).run(function(unsavedChangesSrv) { unsavedChangesSrv.init(); }); -}); \ No newline at end of file +}); diff --git a/src/test/specs/filterSrv-specs.js b/src/test/specs/filterSrv-specs.js index 1719827077f..cd5d8434aad 100644 --- a/src/test/specs/filterSrv-specs.js +++ b/src/test/specs/filterSrv-specs.js @@ -19,25 +19,28 @@ define([ _filterSrv = filterSrv; })); + beforeEach(function() { + _filterSrv.init( _dashboard.current ); + }); + describe('init', function() { beforeEach(function() { - _filterSrv.add({ name: 'test', current: { value: 'oogle' } }); - _filterSrv.init(); + _filterSrv.addTemplateParameter({ name: 'test', current: { value: 'oogle' } }); }); it('should initialize template data', function() { - var target = _filterSrv.applyFilterToTarget('this.[[test]].filters'); + var target = _filterSrv.applyTemplateToTarget('this.[[test]].filters'); expect(target).to.be('this.oogle.filters'); }); }); - describe('filterOptionSelected', function() { + describe('templateOptionSelected', function() { beforeEach(function() { - _filterSrv.add({ name: 'test' }); - _filterSrv.filterOptionSelected(_filterSrv.list[0], { value: 'muuuu' }); + _filterSrv.addTemplateParameter({ name: 'test' }); + _filterSrv.templateOptionSelected(_filterSrv.templateParameters[0], { value: 'muuuu' }); }); it('should set current value and update template data', function() { - var target = _filterSrv.applyFilterToTarget('this.[[test]].filters'); + var target = _filterSrv.applyTemplateToTarget('this.[[test]].filters'); expect(target).to.be('this.muuuu.filters'); }); });