Commit e9b1c929 by Torkel Ödegaard

more work on dashboard tags / search (#86)

parent 123f90d2
...@@ -12,10 +12,9 @@ function (angular, _, config, $) { ...@@ -12,10 +12,9 @@ function (angular, _, config, $) {
module.controller('SearchCtrl', function($scope, $rootScope, dashboard, $element, $location) { module.controller('SearchCtrl', function($scope, $rootScope, dashboard, $element, $location) {
$scope.init = function() { $scope.init = function() {
$scope.elasticsearch = $scope.elasticsearch || {};
$scope.giveSearchFocus = 0; $scope.giveSearchFocus = 0;
$scope.selectedIndex = -1; $scope.selectedIndex = -1;
$scope.query = { query: 'title:' };
$rootScope.$on('open-search', $scope.openSearch); $rootScope.$on('open-search', $scope.openSearch);
}; };
...@@ -42,11 +41,20 @@ function (angular, _, config, $) { ...@@ -42,11 +41,20 @@ function (angular, _, config, $) {
$scope.elasticsearch_dashboards = function(query) { $scope.elasticsearch_dashboards = function(query) {
var request = $scope.ejs.Request().indices(config.grafana_index).types('dashboard'); var request = $scope.ejs.Request().indices(config.grafana_index).types('dashboard');
// if elasticsearch has disabled _all field we need
// need to specifiy field here
var q = 'title:' + (query + '*' || '*');
return request.query($scope.ejs.QueryStringQuery(q)).size(50).doSearch() if (query.length === 0) {
query = 'title:';
}
if (query[query.length - 1] !== '*') {
query += '*';
}
return request
.query($scope.ejs.QueryStringQuery(query))
.sort('_uid')
.facet($scope.ejs.TermsFacet("tags").field("tags").order('term').size(50))
.size(50).doSearch()
.then(function(results) { .then(function(results) {
if(_.isUndefined(results.hits)) { if(_.isUndefined(results.hits)) {
...@@ -54,18 +62,36 @@ function (angular, _, config, $) { ...@@ -54,18 +62,36 @@ function (angular, _, config, $) {
return; return;
} }
var hits = _.sortBy(results.hits.hits, '_id'); $scope.search_results = { dashboards: results.hits.hits };
$scope.search_results = { dashboards: hits }; $scope.tags = results.facets.tags.terms;
}); });
}; };
$scope.elasticsearch_dblist = function(queryStr) { $scope.filterByTag = function(tag, evt) {
$scope.query.query = "tags:" + tag + " AND title:";
$scope.search();
$scope.tagsOnly = false;
$scope.giveSearchFocus = $scope.giveSearchFocus + 1;
evt.stopPropagation();
evt.preventDefault();
};
$scope.showTags = function(evt) {
evt.stopPropagation();
$scope.tagsOnly = !$scope.tagsOnly;
$scope.query.query = $scope.tagsOnly ? "tags!" : "";
$scope.giveSearchFocus = $scope.giveSearchFocus + 1;
$scope.selectedIndex = -1;
};
$scope.search = function() {
$scope.showImport = false; $scope.showImport = false;
$scope.selectedIndex = -1; $scope.selectedIndex = -1;
queryStr = queryStr.toLowerCase(); var queryStr = $scope.query.query.toLowerCase();
if (queryStr.indexOf('m:') !== 0) { if (queryStr.indexOf('m:') !== 0) {
queryStr = queryStr.replace(' and ', ' AND ');
$scope.elasticsearch_dashboards(queryStr); $scope.elasticsearch_dashboards(queryStr);
return; return;
} }
...@@ -103,7 +129,8 @@ function (angular, _, config, $) { ...@@ -103,7 +129,8 @@ function (angular, _, config, $) {
} }
$scope.giveSearchFocus = $scope.giveSearchFocus + 1; $scope.giveSearchFocus = $scope.giveSearchFocus + 1;
$scope.elasticsearch_dblist(""); $scope.query.query = 'title:';
$scope.search();
}; };
$scope.addMetricToCurrentDashboard = function (metricId) { $scope.addMetricToCurrentDashboard = function (metricId) {
...@@ -133,8 +160,6 @@ function (angular, _, config, $) { ...@@ -133,8 +160,6 @@ function (angular, _, config, $) {
}); });
module.directive('xngFocus', function() { module.directive('xngFocus', function() {
return function(scope, element, attrs) { return function(scope, element, attrs) {
$(element).click(function(e) { $(element).click(function(e) {
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
class="grafana-target-text-input" class="grafana-target-text-input"
ng-model="target.target" ng-model="target.target"
focus-me="showTextEditor" focus-me="showTextEditor"
spellcheck='false'
ng-model-onblur ng-change="targetTextChanged()" ng-model-onblur ng-change="targetTextChanged()"
ng-show="showTextEditor" /> ng-show="showTextEditor" />
......
...@@ -28,17 +28,35 @@ ...@@ -28,17 +28,35 @@
<i class="icon-th-large"></i> <i class="icon-th-large"></i>
New New
</button> </button>
<span> <span class="position: relative;">
<input type="text" <input type="text"
placeholder="search dashboards, metrics, or graphs" placeholder="search dashboards, metrics, or graphs"
xng-focus="giveSearchFocus" xng-focus="giveSearchFocus"
ng-keydown="keyDown($event)" ng-keydown="keyDown($event)"
ng-model="elasticsearch.query" ng-model="query.query" spellcheck='false'
ng-change="elasticsearch_dblist(elasticsearch.query)" /> ng-change="search()" />
<a class="search-tagview-switch" href="javascript:void(0);"
ng-class="{'active': tagsOnly}"
ng-click="showTags($event)">Tags</a>
</span> </span>
</div> </div>
<h6 ng-hide="search_results.dashboards.length || search_results.metrics.length">No dashboards or metrics matching your query found</h6> <h6 ng-hide="search_results.dashboards.length || search_results.metrics.length">No dashboards or metrics matching your query found</h6>
<table class="table table-condensed table-striped">
<table class="table table-condensed table-striped" ng-if="tagsOnly">
<tr ng-repeat="tag in tags" ng-class="{'selected-tag': $index === selectedIndex }">
<td>
<a ng-click="filterByTag(tag.term, $event)" class="label label-tag">
{{tag.term}}
</a>
</td>
<td style="width:100%;">
{{tag.count}}
</td>
</tr>
</table>
<table class="table table-condensed table-striped" ng-if="!tagsOnly">
<tr bindonce ng-repeat="row in search_results.metrics" <tr bindonce ng-repeat="row in search_results.metrics"
class="grafana-search-metric-result" class="grafana-search-metric-result"
ng-class="{'selected': $index === selectedIndex }"> ng-class="{'selected': $index === selectedIndex }">
...@@ -60,8 +78,10 @@ ...@@ -60,8 +78,10 @@
<td style="width:100%"> <td style="width:100%">
<a href="#/dashboard/elasticsearch/{{row._id}}" bo-text="row._id"></a> <a href="#/dashboard/elasticsearch/{{row._id}}" bo-text="row._id"></a>
</td> </td>
<td style="white-space: nowrap"> <td style="white-space: nowrap; text-align: right;">
<span ng-repeat="tag in row._source.tags" style="margin-right: 5px;" class="label label-tag">{{tag}}</span> <a ng-click="filterByTag(tag, $event)" ng-repeat="tag in row._source.tags" style="margin-right: 5px;" class="label label-tag">
{{tag}}
</a>
</td> </td>
<td><a><i class="icon-share" ng-click="share = dashboard.share_link(row._id,'elasticsearch',row._id)" bs-modal="'app/partials/dashLoaderShare.html'"></i></a></td> <td><a><i class="icon-share" ng-click="share = dashboard.share_link(row._id,'elasticsearch',row._id)" bs-modal="'app/partials/dashLoaderShare.html'"></i></a></td>
</tr> </tr>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
} }
} }
// Search
.grafana-search-panel { .grafana-search-panel {
padding: 6px 10px; padding: 6px 10px;
...@@ -37,6 +39,20 @@ ...@@ -37,6 +39,20 @@
color: white; color: white;
} }
} }
.selected-tag .label-tag {
background-color: @blue;
}
}
.search-tagview-switch {
position: absolute;
top: 15px;
right: 180px;
color: darken(@linkColor, 30%);
&.active {
color: @linkColor;
}
} }
.row-button { .row-button {
...@@ -417,3 +433,5 @@ input[type=text].func-param { ...@@ -417,3 +433,5 @@ input[type=text].func-param {
.sp-palette-container, .sp-picker-container { .sp-palette-container, .sp-picker-container {
border: none; border: none;
} }
...@@ -555,7 +555,12 @@ div.flot-text { ...@@ -555,7 +555,12 @@ div.flot-text {
// Labels & Badges // Labels & Badges
.label-tag, .label-tag:hover { .label-tag {
background-color: @purple; background-color: @purple;
color: @linkColor; color: @linkColor;
} }
.label-tag:hover {
background-color: darken(@purple, 10%);
color: lighten(@linkColor, 5%);
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment