Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; });
Expand Down
4 changes: 2 additions & 2 deletions src/core_plugins/metrics/public/lib/validate_interval.js
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@ 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: {
es: {
filter: dashboardContext()
}
},
time: _.extend(timefilter.time, {
time: _.extend(timeFilter, {
interval: vis.params.interval,
timezone: timezone
}),
Expand Down
2 changes: 1 addition & 1 deletion src/ui/public/courier/data_source/search_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
};

/**
Expand Down
6 changes: 3 additions & 3 deletions src/ui/public/timefilter/timefilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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'
};
}
Expand Down
36 changes: 36 additions & 0 deletions src/ui/public/visualize/loader.js
Original file line number Diff line number Diff line change
@@ -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 = $('<visualize saved-obj="savedObj" app-state="appState" ui-state="uiState" ' +
'time-range="timeRange" editor-mode="editorMode" show-spy-panel="showSpyPanel"></visualize>');
const visHtml = $compile(visEl)(scope);
container.html(visHtml);
return visEl;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we return undefined instead. What's the use-case of having client have access to the element?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to be able to listen to renderComplete event

};

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);
}
};
}
4 changes: 2 additions & 2 deletions src/ui/public/visualize/visualize.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<visualization-editor
ng-if="editorMode==true"
ng-if="editorMode===true"
vis="vis"
vis-data="visData"
ui-state="uiState"
Expand All @@ -9,7 +9,7 @@
show-spy-panel="shouldShowSpyPanel()"
/>
<visualization
ng-if="editorMode==false"
ng-if="editorMode!==true"
class={{vis.type.name}}
vis="vis"
vis-data="visData"
Expand Down
35 changes: 21 additions & 14 deletions src/ui/public/visualize/visualize.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from 'lodash';
import dateMath from '@elastic/datemath';
import { uiModules } from 'ui/modules';
import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory';
import visualizeTemplate from 'ui/visualize/visualize.html';
Expand All @@ -18,7 +19,7 @@ import {

uiModules
.get('kibana/directive', ['ngSanitize'])
.directive('visualize', function (Notifier, Private, timefilter, getAppState, Promise, savedVisualizations) {
.directive('visualize', function (Notifier, Private, timefilter, getAppState, Promise) {
const notify = new Notifier({ location: 'Visualize' });
const requestHandlers = Private(VisRequestHandlersRegistryProvider);
const responseHandlers = Private(VisResponseHandlersRegistryProvider);
Expand All @@ -36,7 +37,7 @@ uiModules
showSpyPanel: '=?',
editorMode: '=?',
savedObj: '=?',
appState: '=',
appState: '=?',
uiState: '=?',
savedId: '=?',
timeRange: '=?'
Expand All @@ -45,36 +46,42 @@ uiModules
link: async function ($scope, $el) {
const resizeChecker = new ResizeChecker($el);

if (!$scope.savedObj) {
if (!$scope.savedId) throw(`saved object was not provided to <visualize> directive`);
$scope.savedObj = await savedVisualizations.get($scope.savedId);
}
if (!$scope.savedObj) throw(`saved object was not provided to <visualize> 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);

Expand Down