diff --git a/package.json b/package.json
index c49c26137d685..bd040ddc458cc 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"dashboarding"
],
"private": false,
- "version": "5.0.0-reskin-snapshot",
+ "version": "5.0.0-snapshot",
"build": {
"number": 8467,
"sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9"
@@ -81,10 +81,10 @@
"ansicolors": "0.3.2",
"autoprefixer": "5.1.1",
"autoprefixer-loader": "2.0.0",
- "babel": "5.8.23",
- "babel-core": "5.8.23",
+ "babel": "5.8.38",
+ "babel-core": "5.8.38",
"babel-loader": "5.3.2",
- "babel-runtime": "5.8.20",
+ "babel-runtime": "5.8.38",
"bluebird": "2.9.34",
"boom": "2.8.0",
"bootstrap": "3.3.6",
diff --git a/src/plugins/kibana/public/visualize/styles/main.less b/src/plugins/kibana/public/visualize/styles/main.less
index b0b18de2a573d..cfbd3addd324b 100644
--- a/src/plugins/kibana/public/visualize/styles/main.less
+++ b/src/plugins/kibana/public/visualize/styles/main.less
@@ -13,6 +13,14 @@
padding: 0;
display: flex;
+ div.wizard-small {
+ flex: 2;
+ }
+
+ div.wizard-large {
+ flex: 3;
+ }
+
.wizard-column {
flex: 1;
display: flex;
@@ -45,11 +53,6 @@
.list-group {
margin-bottom: 0;
-
- .list-group-item {
- border-radius: 0;
- border: none;
- }
}
.striped {
diff --git a/src/plugins/kibana/public/visualize/wizard/step_2.html b/src/plugins/kibana/public/visualize/wizard/step_2.html
index e8cf5964b655d..bc49fab790d95 100644
--- a/src/plugins/kibana/public/visualize/wizard/step_2.html
+++ b/src/plugins/kibana/public/visualize/wizard/step_2.html
@@ -1,20 +1,15 @@
-
-
From a New Search
-
-
+
+
From a New Search, Select Index
+
+
-
+
Or, From a Saved Search
{
- expect(res.payload).not.to.contain('Invalid cookie header');
- done();
+ describe('cookie validation', function () {
+ it('allows non-strict cookies', function (done) {
+ const options = {
+ method: 'GET',
+ url: '/',
+ headers: {
+ cookie: 'test:80=value;test_80=value'
+ }
+ };
+ kbnTestServer.makeRequest(kbnServer, options, (res) => {
+ expect(res.payload).not.to.contain('Invalid cookie header');
+ done();
+ });
+ });
+
+ it('returns an error if the cookie can\'t be parsed', function (done) {
+ const options = {
+ method: 'GET',
+ url: '/',
+ headers: {
+ cookie: 'a'
+ }
+ };
+ kbnTestServer.makeRequest(kbnServer, options, (res) => {
+ expect(res.payload).to.contain('Invalid cookie header');
+ done();
+ });
});
});
- it('returns an error if the cookie can\'t be parsed', function (done) {
- const options = {
- method: 'GET',
- url: '/',
- headers: {
- cookie: 'a'
+ describe('url shortener', () => {
+ const shortenOptions = {
+ method: 'POST',
+ url: '/shorten',
+ payload: {
+ url: '/app/kibana#/visualize/create'
}
};
- kbnTestServer.makeRequest(kbnServer, options, (res) => {
- expect(res.payload).to.contain('Invalid cookie header');
- done();
+
+ it('generates shortened urls', (done) => {
+ kbnTestServer.makeRequest(kbnServer, shortenOptions, (res) => {
+ expect(typeof res.payload).to.be('string');
+ expect(res.payload.length > 0).to.be(true);
+ done();
+ });
+ });
+
+ it('redirects shortened urls', (done) => {
+ kbnTestServer.makeRequest(kbnServer, shortenOptions, (res) => {
+ const gotoOptions = {
+ method: 'GET',
+ url: '/goto/' + res.payload
+ };
+ kbnTestServer.makeRequest(kbnServer, gotoOptions, (res) => {
+ expect(res.statusCode).to.be(302);
+ expect(res.headers.location).to.be(shortenOptions.payload.url);
+ done();
+ });
+ });
});
+
});
+
});
diff --git a/src/server/kbn_server.js b/src/server/kbn_server.js
index d42554026b21f..5eb51ff77a9eb 100644
--- a/src/server/kbn_server.js
+++ b/src/server/kbn_server.js
@@ -20,6 +20,9 @@ module.exports = class KbnServer {
require('./logging'),
require('./status'),
+ // writes pid file
+ require('./pid'),
+
// find plugins and set this.plugins
require('./plugins/scan'),
@@ -74,9 +77,8 @@ module.exports = class KbnServer {
await this.ready();
await fromNode(cb => server.start(cb));
- await require('./pid')(this, server, config);
- server.log(['listening', 'info'], 'Server running at ' + server.info.uri);
+ server.log(['listening', 'info'], `Server running at ${server.info.uri}`);
return server;
}
diff --git a/src/server/plugins/plugin.js b/src/server/plugins/plugin.js
index 18c7786c15720..dfccce43c8331 100644
--- a/src/server/plugins/plugin.js
+++ b/src/server/plugins/plugin.js
@@ -1,4 +1,5 @@
import _ from 'lodash';
+import toPath from 'lodash/internal/toPath';
import Joi from 'joi';
import Bluebird, { attempt, fromNode } from 'bluebird';
import { basename, resolve } from 'path';
@@ -37,6 +38,8 @@ const defaultConfigSchema = Joi.object({
* @param {String} [opts.version=pkg.version] - the version of this plugin
* @param {Function} [opts.init] - A function that will be called to initialize
* this plugin at the appropriate time.
+ * @param {Function} [opts.configPrefix=this.id] - The prefix to use for configuration
+ * values in the main configuration service
* @param {Function} [opts.config] - A function that produces a configuration
* schema using Joi, which is passed as its
* first argument.
@@ -57,6 +60,7 @@ module.exports = class Plugin {
this.requiredIds = opts.require || [];
this.version = opts.version || pkg.version;
this.externalInit = opts.init || _.noop;
+ this.configPrefix = opts.configPrefix || this.id;
this.getConfigSchema = opts.config || _.noop;
this.init = _.once(this.init);
this[extendInitFns] = [];
@@ -86,18 +90,18 @@ module.exports = class Plugin {
async readConfig() {
let schema = await this.getConfigSchema(Joi);
let { config } = this.kbnServer;
- config.extendSchema(this.id, schema || defaultConfigSchema);
+ config.extendSchema(this.configPrefix, schema || defaultConfigSchema);
- if (config.get([this.id, 'enabled'])) {
+ if (config.get([...toPath(this.configPrefix), 'enabled'])) {
return true;
} else {
- config.removeSchema(this.id);
+ config.removeSchema(this.configPrefix);
return false;
}
}
async init() {
- let { id, version, kbnServer } = this;
+ let { id, version, kbnServer, configPrefix } = this;
let { config } = kbnServer;
// setup the hapi register function and get on with it
@@ -132,7 +136,7 @@ module.exports = class Plugin {
await fromNode(cb => {
kbnServer.server.register({
register: register,
- options: config.has(id) ? config.get(id) : null
+ options: config.has(configPrefix) ? config.get(configPrefix) : null
}, cb);
});
diff --git a/src/ui/public/directives/__tests__/paginated_selectable_list.js b/src/ui/public/directives/__tests__/paginated_selectable_list.js
new file mode 100644
index 0000000000000..3d74e9923c5dd
--- /dev/null
+++ b/src/ui/public/directives/__tests__/paginated_selectable_list.js
@@ -0,0 +1,165 @@
+import angular from 'angular';
+import expect from 'expect.js';
+import ngMock from 'ng_mock';
+import _ from 'lodash';
+
+var objectList = [
+ { title: 'apple' },
+ { title: 'orange' },
+ { title: 'coconut' },
+ { title: 'banana' },
+ { title: 'grapes' }
+];
+
+var stringList = [
+ 'apple',
+ 'orange',
+ 'coconut',
+ 'banana',
+ 'grapes'
+];
+
+var lists = [objectList, stringList, []];
+
+var $scope;
+var $element;
+var $isolatedScope;
+
+lists.forEach(function (list) {
+ var isArrayOfObjects = list.every((item) => {
+ return _.isPlainObject(item);
+ });
+
+ var init = function (arr) {
+ // Load the application
+ ngMock.module('kibana');
+
+ // Create the scope
+ ngMock.inject(function ($rootScope, $compile) {
+ $scope = $rootScope.$new();
+ $scope.perPage = 5;
+ $scope.list = list;
+ $scope.listProperty = isArrayOfObjects ? 'title' : undefined;
+ $scope.test = function (val) {
+ return val;
+ };
+
+ // Create the element
+ $element = angular.element('');
+
+ // And compile it
+ $compile($element)($scope);
+
+ // Fire a digest cycle
+ $element.scope().$digest();
+
+ // Grab the isolate scope so we can test it
+ $isolatedScope = $element.isolateScope();
+ });
+ };
+
+ describe('paginatedSelectableList', function () {
+
+ describe('$scope.hits', function () {
+ beforeEach(function () {
+ init(list);
+ });
+
+ it('should initially sort an array of objects in ascending order', function () {
+ var property = $isolatedScope.listProperty;
+ var sortedList = property ? _.sortBy(list, property) : _.sortBy(list);
+
+ expect($isolatedScope.hits).to.be.an('array');
+
+ $isolatedScope.hits.forEach(function (hit, index) {
+ if (property) {
+ expect(hit[property]).to.equal(sortedList[index][property]);
+ } else {
+ expect(hit).to.equal(sortedList[index]);
+ }
+ });
+ });
+ });
+
+ describe('$scope.sortHits', function () {
+ beforeEach(function () {
+ init(list);
+ });
+
+ it('should sort an array of objects in ascending order', function () {
+ var property = $isolatedScope.listProperty;
+ var sortedList = property ? _.sortBy(list, property) : _.sortBy(list);
+
+ $isolatedScope.isAscending = false;
+ $isolatedScope.sortHits(list);
+
+ expect($isolatedScope.isAscending).to.be(true);
+
+ $isolatedScope.hits.forEach(function (hit, index) {
+ if (property) {
+ expect(hit[property]).to.equal(sortedList[index][property]);
+ } else {
+ expect(hit).to.equal(sortedList[index]);
+ }
+ });
+ });
+
+ it('should sort an array of objects in descending order', function () {
+ var property = $isolatedScope.listProperty;
+ var reversedList = property ? _.sortBy(list, property).reverse() : _.sortBy(list).reverse();
+
+ $isolatedScope.isAscending = true;
+ $isolatedScope.sortHits(list);
+
+ expect($isolatedScope.isAscending).to.be(false);
+
+ $isolatedScope.hits.forEach(function (hit, index) {
+ if (property) {
+ expect(hit[property]).to.equal(reversedList[index][property]);
+ } else {
+ expect(hit).to.equal(reversedList[index]);
+ }
+ });
+ });
+ });
+
+ describe('$scope.makeUrl', function () {
+ beforeEach(function () {
+ init(list);
+ });
+
+ it('should return the result of the function its passed', function () {
+ var property = $isolatedScope.listProperty;
+ var sortedList = property ? _.sortBy(list, property) : _.sortBy(list);
+
+ $isolatedScope.hits.forEach(function (hit, index) {
+ if (property) {
+ expect($isolatedScope.makeUrl(hit)[property]).to.equal(sortedList[index][property]);
+ } else {
+ expect($isolatedScope.makeUrl(hit)).to.equal(sortedList[index]);
+ }
+ });
+ });
+ });
+
+ describe('$scope.onSelect', function () {
+ beforeEach(function () {
+ init(list);
+ });
+
+ it('should return the result of the function its passed', function () {
+ var property = $isolatedScope.listProperty;
+ var sortedList = property ? _.sortBy(list, property) : _.sortBy(list);
+
+ $isolatedScope.hits.forEach(function (hit, index) {
+ if (property) {
+ expect($isolatedScope.onSelect(hit)[property]).to.equal(sortedList[index][property]);
+ } else {
+ expect($isolatedScope.onSelect(hit)).to.equal(sortedList[index]);
+ }
+ });
+ });
+ });
+ });
+});
diff --git a/src/ui/public/directives/paginate.js b/src/ui/public/directives/paginate.js
index 08a9934753d38..2bcc0a57d075a 100644
--- a/src/ui/public/directives/paginate.js
+++ b/src/ui/public/directives/paginate.js
@@ -194,5 +194,3 @@ uiModules.get('kibana')
template: paginateControlsTemplate
};
});
-
-
diff --git a/src/ui/public/directives/paginated_selectable_list.js b/src/ui/public/directives/paginated_selectable_list.js
new file mode 100644
index 0000000000000..7a63cca6fc9c5
--- /dev/null
+++ b/src/ui/public/directives/paginated_selectable_list.js
@@ -0,0 +1,61 @@
+import _ from 'lodash';
+import uiModules from 'ui/modules';
+import paginatedSelectableListTemplate from 'ui/partials/paginated_selectable_list.html';
+
+const module = uiModules.get('kibana');
+
+module.directive('paginatedSelectableList', function (kbnUrl) {
+
+ return {
+ restrict: 'E',
+ scope: {
+ perPage: '=?',
+ list: '=',
+ listProperty: '=',
+ userMakeUrl: '=?',
+ userOnSelect: '=?'
+ },
+ template: paginatedSelectableListTemplate,
+ controller: function ($scope, $element, $filter) {
+ $scope.perPage = $scope.perPage || 10;
+ $scope.hits = $scope.list = _.sortBy($scope.list, accessor);
+ $scope.hitCount = $scope.hits.length;
+
+ /**
+ * Boolean that keeps track of whether hits are sorted ascending (true)
+ * or descending (false)
+ * * @type {Boolean}
+ */
+ $scope.isAscending = true;
+
+ /**
+ * Sorts saved object finder hits either ascending or descending
+ * @param {Array} hits Array of saved finder object hits
+ * @return {Array} Array sorted either ascending or descending
+ */
+ $scope.sortHits = function (hits) {
+ const sortedList = _.sortBy(hits, accessor);
+
+ $scope.isAscending = !$scope.isAscending;
+ $scope.hits = $scope.isAscending ? sortedList : sortedList.reverse();
+ };
+
+ $scope.makeUrl = function (hit) {
+ if ($scope.userMakeUrl) {
+ return $scope.userMakeUrl(hit);
+ }
+ };
+
+ $scope.onSelect = function (hit, $event) {
+ if ($scope.userOnSelect) {
+ return $scope.userOnSelect(hit, $event);
+ }
+ };
+
+ function accessor(val) {
+ const prop = $scope.listProperty;
+ return prop ? val[prop] : val;
+ }
+ }
+ };
+});
diff --git a/src/ui/public/partials/paginated_selectable_list.html b/src/ui/public/partials/paginated_selectable_list.html
new file mode 100644
index 0000000000000..8b9874bf4f322
--- /dev/null
+++ b/src/ui/public/partials/paginated_selectable_list.html
@@ -0,0 +1,43 @@
+
+
+
+
diff --git a/src/ui/public/partials/saved_object_finder.html b/src/ui/public/partials/saved_object_finder.html
index e5eda0c18cdf8..11990711f3501 100644
--- a/src/ui/public/partials/saved_object_finder.html
+++ b/src/ui/public/partials/saved_object_finder.html
@@ -8,7 +8,7 @@
{{finder.hitCount}} of {{finder.hitCount}}
diff --git a/src/ui/public/share/__tests__/url_shortener.js b/src/ui/public/share/__tests__/url_shortener.js
new file mode 100644
index 0000000000000..fd21cdd965044
--- /dev/null
+++ b/src/ui/public/share/__tests__/url_shortener.js
@@ -0,0 +1,124 @@
+import _ from 'lodash';
+import sinon from 'sinon';
+import expect from 'expect.js';
+import ngMock from 'ng_mock';
+import chrome from 'ui/chrome';
+import LibUrlShortenerProvider from 'ui/share/lib/url_shortener';
+
+describe('Url shortener', () => {
+ let $rootScope;
+ let $location;
+ let $http;
+ let urlShortener;
+ let $httpBackend;
+ const shareId = 'id123';
+
+ beforeEach(ngMock.module('kibana'));
+ beforeEach(ngMock.inject(function (_$rootScope_, _$location_, _$httpBackend_, Private) {
+ $location = _$location_;
+ $rootScope = _$rootScope_;
+ $httpBackend = _$httpBackend_;
+ urlShortener = Private(LibUrlShortenerProvider);
+ }));
+
+ describe('Shorten without base path', () => {
+ it('should shorten urls with a port', function (done) {
+ $httpBackend.when('POST', '/shorten').respond(function (type, route, data) {
+ expect(JSON.parse(data).url).to.be('/app/kibana#123');
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl('http://localhost:5601/app/kibana#123').then(function (url) {
+ expect(url).to.be(`http://localhost:5601/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+
+ it('should shorten urls without a port', function (done) {
+ $httpBackend.when('POST', '/shorten').respond(function (type, route, data) {
+ expect(JSON.parse(data).url).to.be('/app/kibana#123');
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl('http://localhost/app/kibana#123').then(function (url) {
+ expect(url).to.be(`http://localhost/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+ });
+
+ describe('Shorten with base path', () => {
+ const basePath = '/foo';
+
+ let getBasePath;
+ beforeEach(ngMock.inject((Private) => {
+ getBasePath = sinon.stub(chrome, 'getBasePath', () => basePath);
+ urlShortener = Private(LibUrlShortenerProvider);
+ }));
+
+ it('should shorten urls with a port', (done) => {
+ $httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
+ expect(JSON.parse(data).url).to.be('/app/kibana#123');
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl(`http://localhost:5601${basePath}/app/kibana#123`).then((url) => {
+ expect(url).to.be(`http://localhost:5601${basePath}/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+
+ it('should shorten urls without a port', (done) => {
+ $httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
+ expect(JSON.parse(data).url).to.be('/app/kibana#123');
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl(`http://localhost${basePath}/app/kibana#123`).then((url) => {
+ expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+
+ it('should shorten urls with a query string', (done) => {
+ $httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
+ expect(JSON.parse(data).url).to.be('/app/kibana?foo#123');
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl(`http://localhost${basePath}/app/kibana?foo#123`).then((url) => {
+ expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+
+ it('should shorten urls without a hash', (done) => {
+ $httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
+ expect(JSON.parse(data).url).to.be('/app/kibana');
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl(`http://localhost${basePath}/app/kibana`).then((url) => {
+ expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+
+ it('should shorten urls with a query string in the hash', (done) => {
+ const relativeUrl = "/app/kibana#/discover?_g=(refreshInterval:(display:Off,pause:!f,value:0),time:(from:now-15m,mode:quick,to:now))&_a=(columns:!(_source),index:%27logstash-*%27,interval:auto,query:(query_string:(analyze_wildcard:!t,query:%27*%27)),sort:!(%27@timestamp%27,desc))"; //eslint-disable-line max-len, quotes
+ $httpBackend.when('POST', `${basePath}/shorten`).respond((type, route, data) => {
+ expect(JSON.parse(data).url).to.be(relativeUrl);
+ return [200, shareId];
+ });
+ urlShortener.shortenUrl(`http://localhost${basePath}${relativeUrl}`).then((url) => {
+ expect(url).to.be(`http://localhost${basePath}/goto/${shareId}`);
+ done();
+ });
+ $httpBackend.flush();
+ });
+
+ afterEach(() => {
+ getBasePath.restore();
+ });
+ });
+});
diff --git a/src/ui/public/share/lib/url_shortener.js b/src/ui/public/share/lib/url_shortener.js
index d20afb2a9af9e..76b755771fc15 100644
--- a/src/ui/public/share/lib/url_shortener.js
+++ b/src/ui/public/share/lib/url_shortener.js
@@ -1,24 +1,30 @@
import chrome from 'ui/chrome';
+import url from 'url';
export default function createUrlShortener(Notifier, $http, $location) {
const notify = new Notifier({
location: 'Url Shortener'
});
- const basePath = chrome.getBasePath();
- const baseUrl = `${$location.protocol()}://${$location.host()}:${$location.port()}${basePath}`;
- async function shortenUrl(url) {
- const relativeUrl = url.replace(baseUrl, '');
- const formData = { url: relativeUrl };
+ function shortenUrl(absoluteUrl) {
+ const basePath = chrome.getBasePath();
+
+ const parsedUrl = url.parse(absoluteUrl);
+ const path = parsedUrl.path.replace(basePath, '');
+ const hash = parsedUrl.hash ? parsedUrl.hash : '';
+ const relativeUrl = path + hash;
- try {
- const result = await $http.post(`${basePath}/shorten`, formData);
+ const formData = { url: relativeUrl };
- return `${baseUrl}/goto/${result.data}`;
- } catch (err) {
- notify.error(err);
- throw err;
- }
+ return $http.post(`${basePath}/shorten`, formData).then((result) => {
+ return url.format({
+ protocol: parsedUrl.protocol,
+ host: parsedUrl.host,
+ pathname: `${basePath}/goto/${result.data}`
+ });
+ }).catch((response) => {
+ notify.error(response);
+ });
}
return {
diff --git a/src/ui/public/styles/base.less b/src/ui/public/styles/base.less
index 62899e437691e..4a97d0d8d407e 100644
--- a/src/ui/public/styles/base.less
+++ b/src/ui/public/styles/base.less
@@ -320,7 +320,8 @@ bread-crumbs {
}
//== SavedObjectFinder
-saved-object-finder {
+saved-object-finder,
+paginated-selectable-list {
.row {
background-color: @kibanaGray6;
padding: 10px;
@@ -328,6 +329,27 @@ saved-object-finder {
flex-direction: row;
}
+ .finder-hit-count,
+ .finder-manage-object {
+ min-width: 80px;
+ padding: 5px;
+ text-align: center;
+ }
+
+ .finder-hit-count {
+ flex: 1;
+
+ span {
+ color: @kibanaGray3;
+ }
+ }
+
+ .finder-manage-object {
+ flex: 3;
+ text-align: left;
+ text-transform: capitalize;
+ }
+
.form-group {
margin-bottom: 0;
float: left;
@@ -337,7 +359,6 @@ saved-object-finder {
border: none;
padding: 5px 0px;
border-radius: @border-radius-base;
- text-transform: capitalize;
}
span {
@@ -350,30 +371,6 @@ saved-object-finder {
width: 15px;
}
}
-
- .finder-hit-count, .finder-manage-object {
- min-width: 80px;
- padding: 5px;
- }
-
- .finder-hit-count {
- flex: 1;
- text-align: center;
-
- span {
- color: @kibanaGray3;
- }
- }
-
- .finder-manage-object {
- flex: 3;
- text-align: left;
- text-transform: capitalize;
- }
- }
-
- .list-group-item-menu:hover {
- background-color: transparent;
}
ul.li-striped {
@@ -413,6 +410,7 @@ saved-object-finder {
margin-right: 10px;
}
+ display: block;
color: @saved-object-finder-link-color !important;
}
@@ -464,6 +462,12 @@ saved-object-finder {
}
}
}
+
+ paginate {
+ paginate-controls {
+ margin: 20px;
+ }
+ }
}
// when rendered within a config dropdown, don't use a bottom margin
diff --git a/src/ui/public/styles/dark-variables.less b/src/ui/public/styles/dark-variables.less
index 3b07e8f8bf7b0..e61a7c7a8898e 100644
--- a/src/ui/public/styles/dark-variables.less
+++ b/src/ui/public/styles/dark-variables.less
@@ -156,4 +156,3 @@
@sidebar-bg: @btn-default-bg;
@sidebar-hover-bg: darken(@btn-default-bg, 5%);
@sidebar-hover-color: @text-color;
-
diff --git a/src/ui/public/styles/variables/for-theme.less b/src/ui/public/styles/variables/for-theme.less
index 6aab3d69c557b..ab9933ecdbc4e 100644
--- a/src/ui/public/styles/variables/for-theme.less
+++ b/src/ui/public/styles/variables/for-theme.less
@@ -172,7 +172,7 @@
@list-group-menu-item-color: @link-color;
@list-group-menu-item-select-color: @link-color;
@list-group-menu-item-active-bg: @well-bg;
-@list-group-menu-item-hover-bg: @well-bg;
+@list-group-menu-item-hover-bg: @kibanaGray5;
// Hint Box ====================================================================