Merge pull request #6543 from bevacqua/bugfix/no-results-timepicker

Fix timepicker button behavior in "No Results" page for timeseries data
This commit is contained in:
Nicolás Bevacqua 2016-06-02 19:22:49 -03:00
commit b6a0b8979d
7 changed files with 160 additions and 52 deletions

View file

@ -0,0 +1,13 @@
import _ from 'lodash';
import $ from 'jquery';
import uiModules from 'ui/modules';
import noResultsTemplate from '../partials/no_results.html';
uiModules
.get('apps/discover')
.directive('discoverNoResults', function () {
return {
restrict: 'E',
template: noResultsTemplate
};
});

View file

@ -56,58 +56,7 @@
<div class="discover-wrapper col-md-10">
<div class="discover-content">
<!-- no results -->
<div ng-show="resultState === 'none'">
<div class="col-md-10 col-md-offset-1">
<h1>No results found <i aria-hidden="true" class="fa fa-meh-o"></i></h1>
<p>
Unfortunately I could not find any results matching your search. I tried really hard. I looked all over the place and frankly, I just couldn't find anything good. Help me, help you. Here are some ideas:
</p>
<div class="shard-failures" ng-show="failures">
<h3>Shard Failures</h3>
<p>The following shard failures ocurred:</p>
<ul>
<li ng-repeat="failure in failures | limitTo: failuresShown"><strong>Index:</strong> {{failure.index}} <strong>Shard:</strong> {{failure.shard}} <strong>Reason:</strong> {{failure.reason}} </li>
</ul>
<a ng-click="showAllFailures()" ng-if="failures.length > failuresShown" title="Show More">Show More</a>
<a ng-click="showLessFailures()" ng-if="failures.length === failuresShown && failures.length > 5" title="Show Less">Show Less</a>
</div>
<div ng-show="opts.timefield">
<p>
<h3>Expand your time range</h3>
<p>I see you are looking at an index with a date field. It is possible your query does not match anything in the current time range, or that there is no data at all in the currently selected time range. Try selecting a wider time range by opening the time picker <i aria-hidden="true" class="fa fa-clock-o"></i> in the top right corner of your screen.
</p>
</div>
<h3>Refine your query</h3>
<p>
The search bar at the top uses Elasticsearch's support for Lucene <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax" target="_blank">Query String syntax</a>. Let's say we're searching web server logs that have been parsed into a few fields.
</p>
<p>
<h4>Examples:</h4>
Find requests that contain the number 200, in any field:
<pre>200</pre>
Or we can search in a specific field. Find 200 in the status field:
<pre>status:200</pre>
Find all status codes between 400-499:
<pre>status:[400 TO 499]</pre>
Find status codes 400-499 with the extension php:
<pre>status:[400 TO 499] AND extension:PHP</pre>
Or HTML
<pre>status:[400 TO 499] AND (extension:php OR extension:html)</pre>
</p>
</div>
</div>
<discover-no-results ng-show="resultState === 'none'"></discover-no-results>
<!-- loading -->
<div ng-show="resultState === 'loading'">

View file

@ -1,4 +1,5 @@
import 'plugins/kibana/discover/saved_searches/saved_searches';
import 'plugins/kibana/discover/directives/no_results';
import 'plugins/kibana/discover/directives/timechart';
import 'ui/navbar_extensions';
import 'ui/collapsible_sidebar';

View file

@ -0,0 +1,51 @@
<div>
<div class="col-md-10 col-md-offset-1" data-test-subj="discoverNoResults">
<h1>No results found <i aria-hidden="true" class="fa fa-meh-o"></i></h1>
<p>
Unfortunately I could not find any results matching your search. I tried really hard. I looked all over the place and frankly, I just couldn't find anything good. Help me, help you. Here are some ideas:
</p>
<div class="shard-failures" ng-show="failures">
<h3>Shard Failures</h3>
<p>The following shard failures ocurred:</p>
<ul>
<li ng-repeat="failure in failures | limitTo: failuresShown"><strong>Index:</strong> {{failure.index}} <strong>Shard:</strong> {{failure.shard}} <strong>Reason:</strong> {{failure.reason}} </li>
</ul>
<a ng-click="showAllFailures()" ng-if="failures.length > failuresShown" title="Show More">Show More</a>
<a ng-click="showLessFailures()" ng-if="failures.length === failuresShown && failures.length > 5" title="Show Less">Show Less</a>
</div>
<div ng-show="opts.timefield">
<p>
<h3>Expand your time range</h3>
<p>I see you are looking at an index with a date field. It is possible your query does not match anything in the current time range, or that there is no data at all in the currently selected time range. Click the button below to open the time picker. For future reference you can open the time picker by clicking on the <a class="btn btn-xs navbtn" ng-click="kbnTopNav.toggle('filter')" aria-expanded="kbnTopNav.is('filter')" aria-label="time picker" data-test-subj="discoverNoResultsTimefilter"><i aria-hidden="true" class="fa fa-clock-o"></i> time picker</a> button in the top right corner of your screen.
</p>
</div>
<h3>Refine your query</h3>
<p>
The search bar at the top uses Elasticsearch's support for Lucene <a href="http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax" target="_blank">Query String syntax</a>. Let's say we're searching web server logs that have been parsed into a few fields.
</p>
<p>
<h4>Examples:</h4>
Find requests that contain the number 200, in any field:
<pre>200</pre>
Or we can search in a specific field. Find 200 in the status field:
<pre>status:200</pre>
Find all status codes between 400-499:
<pre>status:[400 TO 499]</pre>
Find status codes 400-499 with the extension php:
<pre>status:[400 TO 499] AND extension:PHP</pre>
Or HTML
<pre>status:[400 TO 499] AND (extension:php OR extension:html)</pre>
</p>
</div>
</div>

View file

@ -261,6 +261,12 @@ import {
.catch(common.handleError(this));
});
bdd.it('should not show "no results"', () => {
return discoverPage.hasNoResults().then(visible => {
expect(visible).to.be(false);
})
.catch(common.handleError(this));
});
function verifyChartData(expectedBarChartData) {
return common.try(function tryingForTime() {
@ -290,6 +296,69 @@ import {
}
});
bdd.describe('query #2, which has an empty time range', function () {
var fromTime = '1999-06-11 09:22:11.000';
var toTime = '1999-06-12 11:21:04.000';
bdd.before(() => {
common.debug('setAbsoluteRangeForAnotherQuery');
return headerPage
.setAbsoluteRange(fromTime, toTime)
.catch(common.handleError(this));
});
bdd.it('should show "no results"', () => {
return discoverPage.hasNoResults().then(visible => {
expect(visible).to.be(true);
})
.catch(common.handleError(this));
});
bdd.it('should suggest a new time range is picked', () => {
return discoverPage.hasNoResultsTimepicker().then(visible => {
expect(visible).to.be(true);
})
.catch(common.handleError(this));
});
bdd.it('should open and close the time picker', () => {
let i = 0;
return closeTimepicker() // close
.then(() => isTimepickerOpen(false)
.then(el => el.click()) // open
.then(() => isTimepickerOpen(true))
.then(el => el.click()) // close
.then(() => isTimepickerOpen(false))
.catch(common.handleError(this))
);
function closeTimepicker() {
return headerPage.isTimepickerOpen().then(shown => {
if (!shown) {
return;
}
return discoverPage
.getNoResultsTimepicker()
.click(); // close
});
}
function isTimepickerOpen(expected) {
return headerPage.isTimepickerOpen().then(shown => {
common.debug(`expect (#${++i}) timepicker to be ${peek(expected)} (is ${peek(shown)}).`);
expect(shown).to.be(expected);
return discoverPage.getNoResultsTimepicker();
function peek(state) {
return state ? 'open' : 'closed';
}
});
}
});
});
});
}());
}());

View file

@ -225,6 +225,24 @@ export default (function () {
return thisTime
.findByClassName('sidebar-list')
.getProperty('clientWidth');
},
hasNoResults: function hasNoResults() {
return common
.findTestSubject('discoverNoResults')
.then(() => true)
.catch(() => false);
},
getNoResultsTimepicker: function getNoResultsTimepicker() {
return common.findTestSubject('discoverNoResultsTimefilter');
},
hasNoResultsTimepicker: function hasNoResultsTimepicker() {
return this
.getNoResultsTimepicker()
.then(() => true)
.catch(() => false);
}
};

View file

@ -48,6 +48,13 @@ export default (function () {
.findDisplayedByClassName('navbar-timepicker-time-desc').click();
},
isTimepickerOpen: function isTimepickerOpen() {
return this.remote.setFindTimeout(defaultFindTimeout)
.findDisplayedByCssSelector('.kbn-timepicker')
.then(() => true)
.catch(() => false);
},
clickAbsoluteButton: function clickAbsoluteButton() {
return this.remote.setFindTimeout(defaultFindTimeout)
.findByLinkText('Absolute').click();