diff --git a/package.json b/package.json index edf5a1930b1f..9227ccf9378f 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "grunt-cli": "0.1.13", "grunt-contrib-clean": "0.6.0", "grunt-contrib-copy": "0.8.1", - "grunt-esvm": "3.0.4", + "grunt-esvm": "3.1.1", "grunt-karma": "0.12.0", "grunt-run": "0.5.0", "grunt-s3": "0.2.0-alpha.3", diff --git a/src/fixtures/logstash_fields.js b/src/fixtures/logstash_fields.js index 92b57c27b965..c23cfafbbcaf 100644 --- a/src/fixtures/logstash_fields.js +++ b/src/fixtures/logstash_fields.js @@ -16,7 +16,7 @@ function stubbedLogstashFields() { { name: 'extension', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true }, { name: 'machine.os', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true }, { name: 'geo.src', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true }, - { name: '_type', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true }, + { name: '_type', type: 'string', indexed: false, analyzed: true, sortable: true, filterable: true }, { name: '_id', type: 'string', indexed: false, analyzed: false, sortable: false, filterable: true}, { name: '_source', type: 'string', indexed: false, analyzed: false, sortable: false, filterable: false}, { name: 'custom_user_field', type: 'conflict', indexed: false, analyzed: false, sortable: false, filterable: true }, diff --git a/src/plugins/kbn_vislib_vis_types/public/tile_map.js b/src/plugins/kbn_vislib_vis_types/public/tile_map.js index 788b50e832e8..acc7e4591848 100644 --- a/src/plugins/kbn_vislib_vis_types/public/tile_map.js +++ b/src/plugins/kbn_vislib_vis_types/public/tile_map.js @@ -5,6 +5,7 @@ import VisSchemasProvider from 'ui/vis/schemas'; import AggResponseGeoJsonGeoJsonProvider from 'ui/agg_response/geo_json/geo_json'; import FilterBarPushFilterProvider from 'ui/filter_bar/push_filter'; import tileMapTemplate from 'plugins/kbn_vislib_vis_types/editors/tile_map.html'; + export default function TileMapVisType(Private, getAppState, courier, config) { const VislibVisType = Private(VislibVisTypeVislibVisTypeProvider); const Schemas = Private(VisSchemasProvider); @@ -120,6 +121,8 @@ export default function TileMapVisType(Private, getAppState, courier, config) { group: 'buckets', name: 'split', title: 'Split Chart', + deprecate: true, + deprecateMessage: 'The Split Chart feature for Tile Maps has been deprecated.', min: 0, max: 1 } diff --git a/src/plugins/kibana/public/dashboard/index.html b/src/plugins/kibana/public/dashboard/index.html index 89b92ea703a5..8b4021ab8053 100644 --- a/src/plugins/kibana/public/dashboard/index.html +++ b/src/plugins/kibana/public/dashboard/index.html @@ -1,5 +1,5 @@
- +
@@ -51,8 +51,9 @@ ng-click="configTemplate.toggle('options');"> Options -
+ +
diff --git a/src/plugins/kibana/public/discover/controllers/discover.js b/src/plugins/kibana/public/discover/controllers/discover.js index 9790b05e60f3..e8c3c4ad1233 100644 --- a/src/plugins/kibana/public/discover/controllers/discover.js +++ b/src/plugins/kibana/public/discover/controllers/discover.js @@ -481,8 +481,7 @@ app.controller('discover', function ($scope, config, courier, $route, $window, N schema: 'segment', params: { field: $scope.opts.timefield, - interval: $state.interval, - min_doc_count: 0 + interval: $state.interval } } ]; diff --git a/src/plugins/kibana/public/discover/index.html b/src/plugins/kibana/public/discover/index.html index 5cb958aeb030..7989535a6ed2 100644 --- a/src/plugins/kibana/public/discover/index.html +++ b/src/plugins/kibana/public/discover/index.html @@ -1,5 +1,5 @@
- +
@@ -39,8 +39,9 @@ ng-click="configTemplate.toggle('share');"> Share -
+ +
Select {{ groupName }} type
  • @@ -18,10 +19,10 @@ class="vis-editor-agg-wide-btn">
    -
    +
    Add {{ groupName }}
    -
    +
    Add sub-{{ groupName }}
    diff --git a/src/plugins/kibana/public/visualize/editor/agg_group.js b/src/plugins/kibana/public/visualize/editor/agg_group.js index 52efea728f25..1718d80c1b58 100644 --- a/src/plugins/kibana/public/visualize/editor/agg_group.js +++ b/src/plugins/kibana/public/visualize/editor/agg_group.js @@ -33,6 +33,7 @@ uiModules $scope.schemas.forEach(function (schema) { stats.min += schema.min; stats.max += schema.max; + stats.deprecate = schema.deprecate; }); $scope.availableSchema = $scope.schemas.filter(function (schema) { diff --git a/src/plugins/kibana/public/visualize/editor/agg_params.html b/src/plugins/kibana/public/visualize/editor/agg_params.html index e4473e73a8b2..5f822ada4f0e 100644 --- a/src/plugins/kibana/public/visualize/editor/agg_params.html +++ b/src/plugins/kibana/public/visualize/editor/agg_params.html @@ -10,4 +10,13 @@ style="display: none;">
    - \ No newline at end of file +
    +

    + {{ agg.schema.deprecateMessage }} +

    +

    + "{{ agg.schema.title }}" has been deprecated. +

    +
    + + diff --git a/src/plugins/kibana/public/visualize/editor/editor.html b/src/plugins/kibana/public/visualize/editor/editor.html index 9bbd9cd84c8e..755a702d1804 100644 --- a/src/plugins/kibana/public/visualize/editor/editor.html +++ b/src/plugins/kibana/public/visualize/editor/editor.html @@ -1,5 +1,5 @@
    - +
    @@ -46,8 +46,9 @@ aria-label="Refresh"> Refresh -
    + +
    this.destroy()); + } + } + + jqOn(el, ...args) { + const $el = $(el); + $el.on(...args); + this.disposal.push(() => $el.off(...args)); + } + + fakeD3Bind(el, event, handler) { + this.jqOn(el, event, (e) => { + // mimick https://github.com/mbostock/d3/blob/3abb00113662463e5c19eb87cd33f6d0ddc23bc0/src/selection/on.js#L87-L94 + const o = d3.event; // Events can be reentrant (e.g., focus). + d3.event = e; + try { + handler.apply(this, [this.__data__]); + } finally { + d3.event = o; + } + }); } } - -Binder.prototype._bind = function (on, off, emitter, args) { - on.apply(emitter, args); - this.disposal.push(function () { - off.apply(emitter, args); - }); -}; - -Binder.prototype.on = function (emitter/*, ...args */) { - this._bind(emitter.on, emitter.off || emitter.removeListener, emitter, rest(arguments)); -}; - -Binder.prototype.jqOn = function (el/*, ...args */) { - var $el = $(el); - this._bind($el.on, $el.off, $el, rest(arguments)); -}; - -Binder.prototype.fakeD3Bind = function (el, event, handler) { - this.jqOn(el, event, function (e) { - // mimick https://github.com/mbostock/d3/blob/3abb00113662463e5c19eb87cd33f6d0ddc23bc0/src/selection/on.js#L87-L94 - var o = d3.event; // Events can be reentrant (e.g., focus). - d3.event = e; - try { - handler.apply(this, [this.__data__]); - } finally { - d3.event = o; - } - }); -}; - -Binder.prototype.destroy = function () { - var destroyers = this.disposal; - this.disposal = []; - callEach(destroyers); -}; - -module.exports = Binder; diff --git a/src/ui/public/courier/fetch/call_client.js b/src/ui/public/courier/fetch/call_client.js index 2157e4420d95..5f3aa747aef5 100644 --- a/src/ui/public/courier/fetch/call_client.js +++ b/src/ui/public/courier/fetch/call_client.js @@ -20,6 +20,8 @@ export default function CourierFetchCallClient(Private, Promise, es, esShardTime const executable = statuses.filter(isRequest); let execCount = executable.length; + if (!execCount) return Promise.resolve([]); + // resolved by respond() let esPromise; const defer = Promise.defer(); diff --git a/src/ui/public/courier/fetch/fetch_these.js b/src/ui/public/courier/fetch/fetch_these.js index 78affdf29ac5..27b0c3cc1e36 100644 --- a/src/ui/public/courier/fetch/fetch_these.js +++ b/src/ui/public/courier/fetch/fetch_these.js @@ -29,22 +29,26 @@ export default function FetchTheseProvider(Private, Promise) { } function fetchWithStrategy(strategy, requests) { + function replaceAbortedRequests() { + requests = requests.map(r => r.aborted ? ABORTED : r); + } - requests = requests.map(function (req) { - return req.aborted ? ABORTED : req; - }); - + replaceAbortedRequests(); return startRequests(requests) .then(function () { + replaceAbortedRequests(); return callClient(strategy, requests); }) .then(function (responses) { + replaceAbortedRequests(); return callResponseHandlers(requests, responses); }) .then(function (responses) { + replaceAbortedRequests(); return continueIncomplete(strategy, requests, responses, fetchWithStrategy); }) .then(function (responses) { + replaceAbortedRequests(); return responses.map(function (resp) { switch (resp) { case ABORTED: diff --git a/src/ui/public/courier/fetch/request/__tests__/segmented.js b/src/ui/public/courier/fetch/request/__tests__/segmented.js index 4ccb32e0c38b..a30f3da68747 100644 --- a/src/ui/public/courier/fetch/request/__tests__/segmented.js +++ b/src/ui/public/courier/fetch/request/__tests__/segmented.js @@ -32,9 +32,7 @@ describe('ui/courier/fetch/request/segmented', () => { expect(returned.then).to.be.Function; }); - it('does not call super.start() until promise is resolved', () => { - expect(searchReqStart.called).to.be(false); - $rootScope.$apply(); + it('calls super.start() synchronously', () => { expect(searchReqStart.called).to.be(true); }); }); diff --git a/src/ui/public/courier/fetch/request/segmented.js b/src/ui/public/courier/fetch/request/segmented.js index 71ae5e2fa8b8..7ea9c1893a97 100644 --- a/src/ui/public/courier/fetch/request/segmented.js +++ b/src/ui/public/courier/fetch/request/segmented.js @@ -42,6 +42,8 @@ export default function SegmentedReqProvider(es, Private, Promise, timefilter, c *********/ start() { + super.start(); + this._complete = []; this._active = null; this._segments = []; @@ -61,12 +63,12 @@ export default function SegmentedReqProvider(es, Private, Promise, timefilter, c // parameters via the handle if (_.isFunction(this._initFn)) this._initFn(this._handle); return this._createQueue().then((queue) => { + if (this.stopped) return; + this._all = queue.slice(0); // Send the initial fetch status this._reportStatus(); - - return super.start(); }); } diff --git a/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js b/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js new file mode 100644 index 000000000000..23b80580c516 --- /dev/null +++ b/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js @@ -0,0 +1,61 @@ +import ngMock from 'ng_mock'; +import expect from 'expect.js'; + +import MockState from 'fixtures/mock_state'; +import notify from 'ui/notify'; +import AggConfigResult from 'ui/vis/agg_config_result'; + +import VisProvider from 'ui/vis'; +import StubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; +import FilterBarClickHandlerProvider from 'ui/filter_bar/filter_bar_click_handler'; + +describe('filterBarClickHandler', function () { + let setup = null; + + beforeEach(ngMock.module('kibana')); + beforeEach(ngMock.inject(function (Private) { + setup = function () { + const Vis = Private(VisProvider); + const createClickHandler = Private(FilterBarClickHandlerProvider); + const indexPattern = Private(StubbedLogstashIndexPatternProvider); + + const vis = new Vis(indexPattern, { + type: 'histogram', + aggs: [ + { type: 'count', schema: 'metric' }, + { + type: 'terms', + schema: 'segment', + params: { field: '_type' } + } + ] + }); + const aggConfigResult = new AggConfigResult(vis.aggs[1], void 0, 'apache', 'apache'); + + const $state = new MockState({ filters: [] }); + const clickHandler = createClickHandler($state); + + return { clickHandler, $state, aggConfigResult }; + }; + })); + + afterEach(function () { + notify._notifs.splice(0); + }); + + context('on non-filterable fields', function () { + it('warns about trying to filter on a non-filterable field', function () { + const { clickHandler, aggConfigResult } = setup(); + expect(notify._notifs).to.have.length(0); + clickHandler({ point: { aggConfigResult }}); + expect(notify._notifs).to.have.length(1); + }); + + it('does not warn if the event is click is being simulated', function () { + const { clickHandler, aggConfigResult } = setup(); + expect(notify._notifs).to.have.length(0); + clickHandler({ point: { aggConfigResult }}, true); + expect(notify._notifs).to.have.length(0); + }); + }); +}); diff --git a/src/ui/public/filter_bar/filter_bar_click_handler.js b/src/ui/public/filter_bar/filter_bar_click_handler.js index cb7eafc8ff60..d5396b593e21 100644 --- a/src/ui/public/filter_bar/filter_bar_click_handler.js +++ b/src/ui/public/filter_bar/filter_bar_click_handler.js @@ -39,7 +39,9 @@ export default function (Notifier) { try { return result.createFilter(); } catch (e) { - notify.warning(e.message); + if (!simulate) { + notify.warning(e.message); + } } }) .filter(Boolean) diff --git a/src/ui/public/styles/variables/bootstrap-mods.less b/src/ui/public/styles/variables/bootstrap-mods.less index f341e7825ca3..cf89cce9fda7 100644 --- a/src/ui/public/styles/variables/bootstrap-mods.less +++ b/src/ui/public/styles/variables/bootstrap-mods.less @@ -46,7 +46,7 @@ //** By default, this inherits from the ``. @headings-font-family: @font-family-base; @headings-font-weight: 400; -@headings-line-height: 1.1; +@headings-line-height: 1.3; //** By default, this inherits from the ``. @headings-color: inherit; diff --git a/src/ui/public/timepicker/timepicker.html b/src/ui/public/timepicker/timepicker.html index f1af4b4fbe6f..62d7ae367fd8 100644 --- a/src/ui/public/timepicker/timepicker.html +++ b/src/ui/public/timepicker/timepicker.html @@ -69,6 +69,7 @@ ng-model="relative.count" ng-change="formatRelative()" greater-than="-1" + min="0" type="number" class="form-control">
    diff --git a/src/ui/public/vis/schemas.js b/src/ui/public/vis/schemas.js index 37fed2929194..3eeea29d6be7 100644 --- a/src/ui/public/vis/schemas.js +++ b/src/ui/public/vis/schemas.js @@ -30,7 +30,8 @@ export default function VisTypeSchemasFactory(Private) { title: schema.name, aggFilter: '*', editor: false, - params: [] + params: [], + deprecate: false }); // convert the params into a params registry diff --git a/src/utils/binder.js b/src/utils/binder.js new file mode 100644 index 000000000000..92d132bf17b9 --- /dev/null +++ b/src/utils/binder.js @@ -0,0 +1,19 @@ +export default class Binder { + constructor() { + this.disposal = []; + } + + on(emitter, ...args) { + const on = emitter.on || emitter.addListener; + const off = emitter.off || emitter.removeListener; + + on.apply(emitter, args); + this.disposal.push(() => off.apply(emitter, args)); + } + + destroy() { + const destroyers = this.disposal; + this.disposal = []; + destroyers.forEach(fn => fn()); + } +} diff --git a/tasks/config/esvm.js b/tasks/config/esvm.js index 478df34b2429..91ebfb7b40b0 100644 --- a/tasks/config/esvm.js +++ b/tasks/config/esvm.js @@ -9,9 +9,6 @@ module.exports = function (grunt) { branch: 'master', fresh: !grunt.option('esvm-no-fresh'), config: { - network: { - host: '127.0.0.1' - }, http: { port: 9200 } diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 86271155f8cc..9cec39dc31ca 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -108,12 +108,11 @@ define(function (require) { }); bdd.it('should show the correct bar chart', function () { - var expectedBarChartData = [ '0', '0', '0', '0', '0', '0', '3.237', + var expectedBarChartData = [ '3.237', '17.674', '64.75', '125.737', '119.962', '65.712', '16.449', '2.712', '3.675', '17.674', '59.762', '119.087', '123.812', '61.862', '15.487', '2.362', '2.800', '15.312', '61.862', '123.2', - '118.562', '63.524', '17.587', '2.537', '0', '0', '0', '0', '0', - '0', '0' + '118.562', '63.524', '17.587', '2.537' ]; return common.sleep(4000) .then(function () { @@ -142,8 +141,7 @@ define(function (require) { bdd.it('should show correct data for chart interval Hourly', function () { var chartInterval = 'Hourly'; - var expectedBarChartData = [ '0', '0', '0', '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1.527', '2.290', + var expectedBarChartData = [ '1.527', '2.290', '5.599', '7.890', '13.236', '30.290', '46.072', '55.490', '86.8', '112', '122.181', '131.6', '132.872', '113.527', '102.581', '81.709', '65.672', '43.781', '24.181', '14', '9.672', '6.109', @@ -154,8 +152,7 @@ define(function (require) { '2.036', '1.781', '4.327', '8.654', '9.418', '26.472', '38.945', '61.345', '79.672', '102.836', '125.236', '130.327', '128.036', '120.4', '96.472', '74.581', '70.509', '39.709', '25.199', '13.490', - '12.472', '4.072', '2.290', '1.018', '0', '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' + '12.472', '4.072', '2.290', '1.018' ]; return discoverPage.setChartInterval(chartInterval) .then(function () { @@ -170,7 +167,7 @@ define(function (require) { bdd.it('should show correct data for chart interval Daily', function () { var chartInterval = 'Daily'; var expectedBarChartData = [ - '0', '133.196', '129.192', '129.724', '0' + '133.196', '129.192', '129.724' ]; return discoverPage.setChartInterval(chartInterval) .then(function () { @@ -223,12 +220,11 @@ define(function (require) { bdd.it('should show correct data for chart interval Auto', function () { var chartInterval = 'Auto'; - var expectedBarChartData = [ '0', '0', '0', '0', '0', '0', '3.237', + var expectedBarChartData = [ '3.237', '17.674', '64.75', '125.737', '119.962', '65.712', '16.449', '2.712', '3.675', '17.674', '59.762', '119.087', '123.812', '61.862', '15.487', '2.362', '2.800', '15.312', '61.862', '123.2', - '118.562', '63.524', '17.587', '2.537', '0', '0', '0', '0', '0', - '0', '0' + '118.562', '63.524', '17.587', '2.537' ]; return discoverPage.setChartInterval(chartInterval) .then(function () { diff --git a/test/support/pages/discover_page.js b/test/support/pages/discover_page.js index b5638a18882b..62604fe27178 100644 --- a/test/support/pages/discover_page.js +++ b/test/support/pages/discover_page.js @@ -28,7 +28,7 @@ define(function (require) { getTimespanText: function getTimespanText() { return thisTime - .findByCssSelector('.kibana-nav-actions .navbar-timepicker-time-desc pretty-duration') + .findByCssSelector('.kibana-nav-options .navbar-timepicker-time-desc pretty-duration') .getVisibleText(); },