diff --git a/js/filters.js b/js/filters.js index b17e7098d2e..0b6c4580bfb 100644 --- a/js/filters.js +++ b/js/filters.js @@ -4,7 +4,20 @@ angular.module('kibana.filters', []) .filter('stringSort', function() { - return function(input) { - return input.sort(); - }; - }); \ No newline at end of file + return function(input) { + return input.sort(); + }; +}).filter('pinnedQuery', function(querySrv) { + return function( items, pinned) { + var ret = _.filter(querySrv.ids,function(id){ + var v = querySrv.list[id]; + if(!_.isUndefined(v.pin) && v.pin === true && pinned === true) { + return true; + } + if((_.isUndefined(v.pin) || v.pin === false) && pinned === false) { + return true; + } + }); + return ret; + }; +}); \ No newline at end of file diff --git a/js/services.js b/js/services.js index ed4a6794138..f6cd7495092 100644 --- a/js/services.js +++ b/js/services.js @@ -193,7 +193,7 @@ angular.module('kibana.services', []) }; }) -.service('query', function(dashboard) { +.service('querySrv', function(dashboard, ejsResource) { // Create an object to hold our service state on the dashboard dashboard.current.services.query = dashboard.current.services.query || {}; _.defaults(dashboard.current.services.query,{ @@ -203,7 +203,9 @@ angular.module('kibana.services', []) }); // For convenience + var ejs = ejsResource(config.elasticsearch); var _q = dashboard.current.services.query; + this.colors = [ "#7EB26D","#EAB839","#6ED0E0","#EF843C","#E24D42","#1F78C1","#BA43A9","#705DA0", //1 "#508642","#CCA300","#447EBC","#C15C17","#890F02","#0A437C","#6D1F62","#584477", //2 @@ -243,6 +245,7 @@ angular.module('kibana.services', []) query: '*', alias: '', color: colorAt(_id), + pin: false, id: _id, type: 'lucene' }; @@ -268,6 +271,20 @@ angular.module('kibana.services', []) } }; + this.getEjsObj = function(id) { + return self.toEjsObj(self.list[id]); + }; + + this.toEjsObj = function (q) { + switch(q.type) + { + case 'lucene': + return ejs.QueryStringQuery(q.query || '*'); + default: + return _.isUndefined(q.query) ? false : ejs.QueryStringQuery(q.query || '*'); + } + }; + this.findQuery = function(queryString) { return _.findWhere(self.list,{query:queryString}); }; @@ -485,7 +502,7 @@ angular.module('kibana.services', []) // Store a reference to this var self = this; - var filterSrv,query; + var filterSrv,querySrv; this.current = {}; this.last = {}; @@ -574,11 +591,11 @@ angular.module('kibana.services', []) self.current = _.clone(dashboard); // Ok, now that we've setup the current dashboard, we can inject our services - query = $injector.get('query'); + querySrv = $injector.get('querySrv'); filterSrv = $injector.get('filterSrv'); // Make sure these re-init - query.init(); + querySrv.init(); filterSrv.init(); if(dashboard.index.interval !== 'none' && filterSrv.idsByType('time').length === 0) { diff --git a/panels/bettermap/module.js b/panels/bettermap/module.js index f7775583c9c..9e7020e3b97 100644 --- a/panels/bettermap/module.js +++ b/panels/bettermap/module.js @@ -20,7 +20,7 @@ 'use strict'; angular.module('kibana.bettermap', []) -.controller('bettermap', function($scope, query, dashboard, filterSrv) { +.controller('bettermap', function($scope, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { @@ -67,8 +67,8 @@ angular.module('kibana.bettermap', []) var _segment = _.isUndefined(segment) ? 0 : segment; var boolQuery = $scope.ejs.BoolQuery(); - _.each(query.list,function(q) { - boolQuery = boolQuery.should($scope.ejs.QueryStringQuery((q.query || '*'))); + _.each(querySrv.list,function(q) { + boolQuery = boolQuery.should(querySrv.toEjsObj(q)); }); var request = $scope.ejs.Request().indices(dashboard.indices[_segment]) diff --git a/panels/fields/module.js b/panels/fields/module.js index 35ae3193213..a7748c7895f 100644 --- a/panels/fields/module.js +++ b/panels/fields/module.js @@ -24,7 +24,7 @@ 'use strict'; angular.module('kibana.fields', []) -.controller('fields', function($scope, eventBus, $timeout, dashboard, query, filterSrv) { +.controller('fields', function($scope, eventBus, $timeout, dashboard, filterSrv) { // Set and populate defaults var _d = { diff --git a/panels/histogram/module.js b/panels/histogram/module.js index 22a72439144..ade19af47e8 100644 --- a/panels/histogram/module.js +++ b/panels/histogram/module.js @@ -41,15 +41,15 @@ 'use strict'; angular.module('kibana.histogram', []) -.controller('histogram', function($scope, eventBus, query, dashboard, filterSrv) { +.controller('histogram', function($scope, eventBus, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { status : "Stable", group : "default", - query : [ {query: "*", label:"Query"} ], mode : 'count', time_field : '@timestamp', + queries : [], value_field : null, auto_int : true, resolution : 100, @@ -73,7 +73,7 @@ angular.module('kibana.histogram', []) $scope.init = function() { - $scope.queries = query; + $scope.querySrv = querySrv; $scope.$on('refresh',function(){ $scope.get_data(); @@ -103,9 +103,9 @@ angular.module('kibana.histogram', []) var request = $scope.ejs.Request().indices(dashboard.indices[_segment]); // Build the query - _.each($scope.queries.ids, function(id) { + _.each(querySrv.ids, function(id) { var query = $scope.ejs.FilteredQuery( - $scope.ejs.QueryStringQuery($scope.queries.list[id].query || '*'), + querySrv.getEjsObj(id), filterSrv.getBoolFilter(filterSrv.ids) ); @@ -151,13 +151,13 @@ angular.module('kibana.histogram', []) // Make sure we're still on the same query/queries if($scope.query_id === query_id && - _.intersection(facetIds,query.ids).length === query.ids.length + _.intersection(facetIds,querySrv.ids).length === querySrv.ids.length ) { var i = 0; var data, hits; - _.each(query.ids, function(id) { + _.each(querySrv.ids, function(id) { var v = results.facets[id]; // Null values at each end of the time range ensure we see entire range @@ -184,7 +184,7 @@ angular.module('kibana.histogram', []) // Create the flot series object var series = { data: { - info: $scope.queries.list[id], + info: querySrv.list[id], data: data, hits: hits }, diff --git a/panels/hits/module.js b/panels/hits/module.js index dcff20324c7..51f78cfa135 100644 --- a/panels/hits/module.js +++ b/panels/hits/module.js @@ -22,7 +22,7 @@ 'use strict'; angular.module('kibana.hits', []) -.controller('hits', function($scope, query, dashboard, filterSrv) { +.controller('hits', function($scope, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { @@ -62,9 +62,9 @@ angular.module('kibana.hits', []) var request = $scope.ejs.Request().indices(dashboard.indices[_segment]); // Build the question part of the query - _.each(query.ids, function(id) { + _.each(querySrv.ids, function(id) { var _q = $scope.ejs.FilteredQuery( - $scope.ejs.QueryStringQuery(query.list[id].query || '*'), + querySrv.getEjsObj(id), filterSrv.getBoolFilter(filterSrv.ids)); request = request @@ -99,10 +99,10 @@ angular.module('kibana.hits', []) // Make sure we're still on the same query/queries if($scope.query_id === query_id && - _.intersection(facetIds,query.ids).length === query.ids.length + _.intersection(facetIds,querySrv.ids).length === querySrv.ids.length ) { var i = 0; - _.each(query.ids, function(id) { + _.each(querySrv.ids, function(id) { var v = results.facets[id]; var hits = _.isUndefined($scope.data[i]) || _segment === 0 ? v.count : $scope.data[i].hits+v.count; @@ -110,7 +110,7 @@ angular.module('kibana.hits', []) // Create series $scope.data[i] = { - info: query.list[id], + info: querySrv.list[id], id: id, hits: hits, data: [[i,hits]] @@ -144,7 +144,7 @@ angular.module('kibana.hits', []) $scope.get_data(); } -}).directive('hitsChart', function(query) { +}).directive('hitsChart', function(querySrv) { return { restrict: 'A', link: function(scope, elem, attrs, ctrl) { @@ -195,7 +195,7 @@ angular.module('kibana.hits', []) color: "#eee", hoverable: true, }, - colors: query.colors + colors: querySrv.colors }); } if(scope.panel.chart === 'pie') { @@ -227,7 +227,7 @@ angular.module('kibana.hits', []) }, //grid: { hoverable: true, clickable: true }, grid: { hoverable: true, clickable: true }, - colors: query.colors + colors: querySrv.colors }); } diff --git a/panels/map/module.js b/panels/map/module.js index 1c7e698c21a..777b71d71ff 100644 --- a/panels/map/module.js +++ b/panels/map/module.js @@ -28,7 +28,7 @@ 'use strict'; angular.module('kibana.map', []) -.controller('map', function($scope, $rootScope, query, dashboard, filterSrv) { +.controller('map', function($scope, $rootScope, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { @@ -62,7 +62,7 @@ angular.module('kibana.map', []) request = $scope.ejs.Request().indices(dashboard.indices); var boolQuery = $scope.ejs.BoolQuery(); - _.each(query.list,function(q) { + _.each(querySrv.list,function(q) { boolQuery = boolQuery.should($scope.ejs.QueryStringQuery(q.query || '*')); }); diff --git a/panels/pie/module.js b/panels/pie/module.js index 56413c9e800..640356464ef 100644 --- a/panels/pie/module.js +++ b/panels/pie/module.js @@ -29,7 +29,7 @@ 'use strict'; angular.module('kibana.pie', []) -.controller('pie', function($scope, $rootScope, query, dashboard, filterSrv) { +.controller('pie', function($scope, $rootScope, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { @@ -89,8 +89,8 @@ angular.module('kibana.pie', []) // This could probably be changed to a BoolFilter var boolQuery = $scope.ejs.BoolQuery(); - _.each(query.list,function(q) { - boolQuery = boolQuery.should($scope.ejs.QueryStringQuery(q.query || '*')); + _.each(querySrv.list,function(q) { + boolQuery = boolQuery.should(querySrv.toEjsObj(q)); }); var results; @@ -162,7 +162,7 @@ angular.module('kibana.pie', []) }; }) -.directive('pie', function(query, filterSrv, dashboard) { +.directive('pie', function(querySrv, filterSrv, dashboard) { return { restrict: 'A', link: function(scope, elem, attrs) { @@ -239,7 +239,7 @@ angular.module('kibana.pie', []) clickable: true }, legend: { show: false }, - colors: query.colors + colors: querySrv.colors }; // Populate element @@ -248,6 +248,7 @@ angular.module('kibana.pie', []) scope.plot = $.plot(elem, scope.data, pie); }); } + } function tt(x, y, contents) { diff --git a/panels/query/meta.html b/panels/query/meta.html index b807e5e99a7..7c8b9b62049 100644 --- a/panels/query/meta.html +++ b/panels/query/meta.html @@ -1,15 +1,20 @@ -
+
+ × -
Query Alias
+ + Query Alias
- +
- +
\ No newline at end of file diff --git a/panels/query/module.html b/panels/query/module.html index b92480c47a2..ae71080abd5 100644 --- a/panels/query/module.html +++ b/panels/query/module.html @@ -1,12 +1,12 @@ - + -
- +
+ Pinned + + {{querySrv.list[id].alias || querySrv.list[id].query}} + +
\ No newline at end of file diff --git a/panels/query/module.js b/panels/query/module.js index d7227f123ae..493ea16073a 100644 --- a/panels/query/module.js +++ b/panels/query/module.js @@ -16,26 +16,27 @@ 'use strict'; angular.module('kibana.query', []) -.controller('query', function($scope, query, $rootScope) { +.controller('query', function($scope, querySrv, $rootScope) { // Set and populate defaults var _d = { status : "Experimental", label : "Search", query : "*", + pinned : true, group : "default", history : [], remember: 10 // max: 100, angular strap can't take a variable for items param }; _.defaults($scope.panel,_d); - $scope.queries = query; + $scope.querySrv = querySrv; $scope.init = function() { }; $scope.refresh = function(query) { - update_history(_.pluck($scope.queries.list,'query')); + update_history(_.pluck($scope.querySrv.list,'query')); $rootScope.$broadcast('refresh'); }; @@ -43,6 +44,10 @@ angular.module('kibana.query', []) $rootScope.$broadcast('render'); }; + $scope.toggle_pin = function(id) { + querySrv.list[id].pin = querySrv.list[id].pin ? false : true; + }; + var update_history = function(query) { if($scope.panel.remember > 0) { $scope.panel.history = _.union(query.reverse(),$scope.panel.history); diff --git a/panels/table/module.js b/panels/table/module.js index 7878f913a82..0f9acefeeb0 100644 --- a/panels/table/module.js +++ b/panels/table/module.js @@ -30,7 +30,7 @@ 'use strict'; angular.module('kibana.table', []) -.controller('table', function($rootScope, $scope, eventBus, fields, query, dashboard, filterSrv) { +.controller('table', function($rootScope, $scope, eventBus, fields, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { @@ -69,7 +69,7 @@ angular.module('kibana.table', []) $scope.panel.fields = _.clone(fields); }); eventBus.register($scope,'table_documents', function(event, docs) { - query.list[query.ids[0]].query = docs.query; + querySrv.list[querySrv.ids[0]].query = docs.query; $scope.data = docs.docs; }); }; @@ -139,8 +139,8 @@ angular.module('kibana.table', []) var request = $scope.ejs.Request().indices(dashboard.indices[_segment]); var boolQuery = $scope.ejs.BoolQuery(); - _.each(query.list,function(q) { - boolQuery = boolQuery.should($scope.ejs.QueryStringQuery(q.query || '*')); + _.each(querySrv.list,function(q) { + boolQuery = boolQuery.should(querySrv.toEjsObj(q)); }); request = request.query( @@ -250,7 +250,7 @@ angular.module('kibana.table', []) }); eventBus.broadcast($scope.$id,$scope.panel.group,"table_documents", { - query: query.list[query.ids[0]].query, + query: querySrv.list[querySrv.ids[0]].query, docs : _.pluck($scope.data,'_source'), index: $scope.index }); diff --git a/panels/trends/module.html b/panels/trends/module.html index db75e6ba0fd..8720a73d3f7 100644 --- a/panels/trends/module.html +++ b/panels/trends/module.html @@ -2,10 +2,10 @@
- + {{query.percent}}% - ({{query.info.alias}}) + ({{query.info.alias}})
\ No newline at end of file diff --git a/panels/trends/module.js b/panels/trends/module.js index 65a9fa42eef..7d524bf93c7 100644 --- a/panels/trends/module.js +++ b/panels/trends/module.js @@ -22,7 +22,7 @@ 'use strict'; angular.module('kibana.trends', []) -.controller('trends', function($scope, kbnIndex, query, dashboard, filterSrv) { +.controller('trends', function($scope, kbnIndex, querySrv, dashboard, filterSrv) { // Set and populate defaults var _d = { @@ -78,9 +78,9 @@ angular.module('kibana.trends', []) // Build the question part of the query - _.each(query.ids, function(id) { + _.each(querySrv.ids, function(id) { var q = $scope.ejs.FilteredQuery( - $scope.ejs.QueryStringQuery(query.list[id].query || '*'), + querySrv.getEjsObj(id), filterSrv.getBoolFilter(_ids_without_time).must( $scope.ejs.RangeFilter(timeField) .from($scope.time.from) @@ -93,10 +93,11 @@ angular.module('kibana.trends', []) ).size(0); }); + // And again for the old time period - _.each(query.ids, function(id) { + _.each(querySrv.ids, function(id) { var q = $scope.ejs.FilteredQuery( - $scope.ejs.QueryStringQuery(query.list[id].query || '*'), + querySrv.getEjsObj(id), filterSrv.getBoolFilter(_ids_without_time).must( $scope.ejs.RangeFilter(timeField) .from($scope.old_time.from) @@ -108,6 +109,7 @@ angular.module('kibana.trends', []) ).size(0); }); + // TODO: Spy for trend panel //$scope.populate_modal(request); @@ -121,8 +123,7 @@ angular.module('kibana.trends', []) ).then(function (p) { $scope.index = _.union(p,$scope.index); request = request.indices($scope.index[_segment]); - process_results(request.doSearch()); - + process_results(request.doSearch(),_segment,query_id); }); } else { process_results(request.indices($scope.index[_segment]).doSearch(),_segment,query_id); @@ -133,7 +134,6 @@ angular.module('kibana.trends', []) // Populate scope when we have results var process_results = function(results,_segment,query_id) { results.then(function(results) { - $scope.panel.loading = false; if(_segment === 0) { $scope.hits = {}; @@ -152,10 +152,10 @@ angular.module('kibana.trends', []) // Make sure we're still on the same query/queries if($scope.query_id === query_id && - _.intersection(facetIds,query.ids).length === query.ids.length + _.intersection(facetIds,querySrv.ids).length === querySrv.ids.length ) { var i = 0; - _.each(query.ids, function(id) { + _.each(querySrv.ids, function(id) { var v = results.facets[id]; var n = results.facets[id].count; var o = results.facets['old_'+id].count; @@ -172,7 +172,7 @@ angular.module('kibana.trends', []) '?' : Math.round(percentage(hits.old,hits.new)*100)/100; // Create series $scope.data[i] = { - info: query.list[id], + info: querySrv.list[id], hits: { new : hits.new, old : hits.old