diff --git a/src/core_plugins/kibana/public/dashboard/dashboard_context.js b/src/core_plugins/kibana/public/dashboard/dashboard_context.js index 1824ba3f21bd0..3bac2e4de87f1 100644 --- a/src/core_plugins/kibana/public/dashboard/dashboard_context.js +++ b/src/core_plugins/kibana/public/dashboard/dashboard_context.js @@ -6,10 +6,12 @@ import { luceneStringToDsl } from '../../../../ui/public/courier/data_source/bui export function dashboardContextProvider(Private, getAppState) { return () => { + const appState = getAppState(); const queryFilter = Private(FilterBarQueryFilterProvider); const bool = { must: [], must_not: [] }; + if (!appState) return { bool: bool }; const filterBarFilters = queryFilter.getFilters(); - const queryBarQuery = getAppState().query; + const queryBarQuery = appState.query; if (queryBarQuery.language === 'lucene') { // Add the query bar filter, its handled differently. diff --git a/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js b/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js index 98825fd0f2a6b..19246e78a19f1 100644 --- a/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js +++ b/src/core_plugins/metrics/public/kbn_vis_types/request_handler.js @@ -12,16 +12,17 @@ const MetricsRequestHandlerProvider = function (Private, Notifier, config, timef const timezone = Private(timezoneProvider)(); return new Promise((resolve) => { const panel = vis.params; + const timeRange = vis.params.timeRange || timefilter.getBounds(); if (panel && panel.id) { const params = { - timerange: { timezone, ...timefilter.getBounds() }, + timerange: { timezone, ...timeRange }, filters: [dashboardContext()], panels: [panel] }; try { const maxBuckets = config.get('metrics:max_buckets'); - validateInterval(timefilter, panel, maxBuckets); + validateInterval(timeRange, panel, maxBuckets); const httpResult = $http.post('../api/metrics/vis/data', params) .then(resp => resp.data) .catch(resp => { throw resp.data; }); diff --git a/src/core_plugins/metrics/public/lib/validate_interval.js b/src/core_plugins/metrics/public/lib/validate_interval.js index 6a342a8bace19..4ad3fa4a4dd33 100644 --- a/src/core_plugins/metrics/public/lib/validate_interval.js +++ b/src/core_plugins/metrics/public/lib/validate_interval.js @@ -1,8 +1,8 @@ import { parseInterval } from 'ui/utils/parse_interval'; import { GTE_INTERVAL_RE } from '../../common/interval_regexp'; -export function validateInterval(timefilter, panel, maxBuckets) { +export function validateInterval(bounds, panel, maxBuckets) { const { interval } = panel; - const { min, max } = timefilter.getBounds(); + const { min, max } = bounds; // No need to check auto it will return around 100 if (!interval) return; if (interval === 'auto') return; diff --git a/src/core_plugins/timelion/public/vis/timelion_request_handler.js b/src/core_plugins/timelion/public/vis/timelion_request_handler.js index 49e289a608eb9..c5af2965a05bc 100644 --- a/src/core_plugins/timelion/public/vis/timelion_request_handler.js +++ b/src/core_plugins/timelion/public/vis/timelion_request_handler.js @@ -20,6 +20,14 @@ const TimelionRequestHandlerProvider = function (Private, Notifier, $http, $root const expression = vis.params.expression; if (!expression) return; + let timeFilter = timefilter.time; + if (vis.params.timeRange) { + timeFilter = { + mode: 'absolute', + from: vis.params.timeRange.min.toJSON(), + to: vis.params.timeRange.max.toJSON() + }; + } const httpResult = $http.post('../api/timelion/run', { sheet: [expression], extended: { @@ -27,7 +35,7 @@ const TimelionRequestHandlerProvider = function (Private, Notifier, $http, $root filter: dashboardContext() } }, - time: _.extend(timefilter.time, { + time: _.extend(timeFilter, { interval: vis.params.interval, timezone: timezone }), diff --git a/src/ui/public/courier/data_source/search_source.js b/src/ui/public/courier/data_source/search_source.js index 29fce52bc0aa3..12cbc261db702 100644 --- a/src/ui/public/courier/data_source/search_source.js +++ b/src/ui/public/courier/data_source/search_source.js @@ -154,7 +154,7 @@ export function SearchSourceProvider(Promise, Private, config) { const self = this; if (self._parent === false) return; if (self._parent) return self._parent; - return onlyHardLinked ? undefined : Private(RootSearchSourceProvider).get(); + return onlyHardLinked || this.skipTimeRangeFilter ? undefined : Private(RootSearchSourceProvider).get(); }; /** diff --git a/src/ui/public/timefilter/timefilter.js b/src/ui/public/timefilter/timefilter.js index 00518c9d9165e..8a92a03f5aa59 100644 --- a/src/ui/public/timefilter/timefilter.js +++ b/src/ui/public/timefilter/timefilter.js @@ -77,7 +77,7 @@ uiModules $rootScope.$apply(); }; - Timefilter.prototype.get = function (indexPattern) { + Timefilter.prototype.get = function (indexPattern, range) { if (!indexPattern) { //in CI, we sometimes seem to fail here. @@ -91,8 +91,8 @@ uiModules const bounds = this.getBounds(); filter = { range : {} }; filter.range[timefield.name] = { - gte: bounds.min.valueOf(), - lte: bounds.max.valueOf(), + gte: range ? range.min.valueOf() : bounds.min.valueOf(), + lte: range ? range.max.valueOf() : bounds.max.valueOf(), format: 'epoch_millis' }; } diff --git a/src/ui/public/visualize/loader.js b/src/ui/public/visualize/loader.js new file mode 100644 index 0000000000000..7aa6aca28d0a4 --- /dev/null +++ b/src/ui/public/visualize/loader.js @@ -0,0 +1,36 @@ +import $ from 'jquery'; + +export function VisualizeLoaderProvider($compile, $rootScope, savedVisualizations) { + const renderVis = (el, savedObj, params) => { + const scope = $rootScope.$new(); + scope.savedObj = savedObj; + scope.appState = params.appState; + scope.uiState = params.uiState; + scope.timeRange = params.timeRange; + scope.showSpyPanel = params.showSpyPanel; + scope.editorMode = params.editorMode; + + const container = el instanceof $ ? el : $(el); + + container.html(''); + const visEl = $(''); + const visHtml = $compile(visEl)(scope); + container.html(visHtml); + return visEl; + }; + + return { + embedVisualizationWithId: async (el, savedVisualizationId, params) => { + return new Promise((resolve) => { + savedVisualizations.get(savedVisualizationId).then(savedObj => { + const element = renderVis(el, savedObj, params); + resolve(element); + }); + }); + }, + embedVisualizationWithSavedObject: (el, savedObj, params) => { + return renderVis(el, savedObj, params); + } + }; +} diff --git a/src/ui/public/visualize/visualize.html b/src/ui/public/visualize/visualize.html index f8bda15cf3fab..411a328d1b3b1 100644 --- a/src/ui/public/visualize/visualize.html +++ b/src/ui/public/visualize/visualize.html @@ -1,6 +1,6 @@ directive`); - $scope.savedObj = await savedVisualizations.get($scope.savedId); - } + if (!$scope.savedObj) throw(`saved object was not provided to directive`); if (!$scope.appState) $scope.appState = getAppState(); if (!$scope.uiState) $scope.uiState = new PersistedState({}); $scope.vis = $scope.savedObj.vis; - $scope.editorMode = $scope.editorMode || false; - $scope.vis.editorMode = $scope.editorMode; $scope.vis.visualizeScope = true; if ($scope.timeRange) { + $scope.vis.params.timeRange = { + min: dateMath.parse($scope.timeRange.min), + max: dateMath.parse($scope.timeRange.max) + }; + $scope.vis.aggs.forEach(agg => { if (agg.type.name !== 'date_histogram') return; - agg.setTimeRange({ - min: new Date($scope.timeRange.min), - max: new Date($scope.timeRange.max) - }); + agg.setTimeRange($scope.vis.params.timeRange); }); + + const searchSource = $scope.savedObj.searchSource; + const filter = timefilter.get(searchSource.index(), $scope.vis.params.timeRange); + const searchSourceFilters = searchSource.get('filter'); + if (searchSourceFilters instanceof Array) { + searchSourceFilters.push(filter); + searchSource.skipTimeRangeFilter = true; + } } + $scope.editorMode = $scope.editorMode || false; + $scope.vis.editorMode = $scope.editorMode; + // spy panel is supported only with courier request handler $scope.shouldShowSpyPanel = () => { if ($scope.vis.type.requestHandler !== 'courier') return false; return $scope.vis.type.requiresSearch && $scope.showSpyPanel; }; - if (!$scope.appState) $scope.appState = getAppState(); - const requestHandler = getHandler(requestHandlers, $scope.vis.type.requestHandler); const responseHandler = getHandler(responseHandlers, $scope.vis.type.responseHandler);