mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'metric-segment-remake'
This commit is contained in:
commit
e9c8881d54
248
public/app/core/components/form_dropdown/form_dropdown.ts
Normal file
248
public/app/core/components/form_dropdown/form_dropdown.ts
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
///<reference path="../../../headers/common.d.ts" />
|
||||||
|
|
||||||
|
import config from 'app/core/config';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import $ from 'jquery';
|
||||||
|
import coreModule from '../../core_module';
|
||||||
|
|
||||||
|
function typeaheadMatcher(item) {
|
||||||
|
var str = this.query;
|
||||||
|
if (str[0] === '/') { str = str.substring(1); }
|
||||||
|
if (str[str.length - 1] === '/') { str = str.substring(0, str.length-1); }
|
||||||
|
return item.toLowerCase().match(str.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FormDropdownCtrl {
|
||||||
|
inputElement: any;
|
||||||
|
linkElement: any;
|
||||||
|
model: any;
|
||||||
|
display: any;
|
||||||
|
text: any;
|
||||||
|
options: any;
|
||||||
|
cssClass: any;
|
||||||
|
cssClasses: any;
|
||||||
|
allowCustom: any;
|
||||||
|
labelMode: boolean;
|
||||||
|
linkMode: boolean;
|
||||||
|
cancelBlur: any;
|
||||||
|
onChange: any;
|
||||||
|
getOptions: any;
|
||||||
|
optionCache: any;
|
||||||
|
lookupText: boolean;
|
||||||
|
|
||||||
|
constructor(private $scope, $element, private $sce, private templateSrv, private $q) {
|
||||||
|
this.inputElement = $element.find('input').first();
|
||||||
|
this.linkElement = $element.find('a').first();
|
||||||
|
this.linkMode = true;
|
||||||
|
this.cancelBlur = null;
|
||||||
|
|
||||||
|
// listen to model changes
|
||||||
|
$scope.$watch("ctrl.model", this.modelChanged.bind(this));
|
||||||
|
|
||||||
|
if (this.labelMode) {
|
||||||
|
this.cssClasses = 'gf-form-label ' + this.cssClass;
|
||||||
|
} else {
|
||||||
|
this.cssClasses = 'gf-form-input gf-form-input--dropdown ' + this.cssClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inputElement.attr('data-provide', 'typeahead');
|
||||||
|
this.inputElement.typeahead({
|
||||||
|
source: this.typeaheadSource.bind(this),
|
||||||
|
minLength: 0,
|
||||||
|
items: 10000,
|
||||||
|
updater: this.typeaheadUpdater.bind(this),
|
||||||
|
matcher: typeaheadMatcher,
|
||||||
|
});
|
||||||
|
|
||||||
|
// modify typeahead lookup
|
||||||
|
// this = typeahead
|
||||||
|
var typeahead = this.inputElement.data('typeahead');
|
||||||
|
typeahead.lookup = function () {
|
||||||
|
this.query = this.$element.val() || '';
|
||||||
|
var items = this.source(this.query, $.proxy(this.process, this));
|
||||||
|
return items ? this.process(items) : items;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.linkElement.keydown(evt => {
|
||||||
|
// trigger typeahead on down arrow or enter key
|
||||||
|
if (evt.keyCode === 40 || evt.keyCode === 13) {
|
||||||
|
this.linkElement.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.inputElement.keydown(evt => {
|
||||||
|
if (evt.keyCode === 13) {
|
||||||
|
this.inputElement.blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.inputElement.blur(this.inputBlur.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
getOptionsInternal(query) {
|
||||||
|
var result = this.getOptions({$query: query});
|
||||||
|
if (this.isPromiseLike(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return this.$q.when(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
isPromiseLike(obj) {
|
||||||
|
return obj && (typeof obj.then === 'function');
|
||||||
|
}
|
||||||
|
|
||||||
|
modelChanged() {
|
||||||
|
if (_.isObject(this.model)) {
|
||||||
|
this.updateDisplay(this.model.text);
|
||||||
|
} else {
|
||||||
|
// if we have text use it
|
||||||
|
if (this.lookupText) {
|
||||||
|
this.getOptionsInternal("").then(options => {
|
||||||
|
var item = _.find(options, {value: this.model});
|
||||||
|
this.updateDisplay(item ? item.text : this.model);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.updateDisplay(this.model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeaheadSource(query, callback) {
|
||||||
|
this.getOptionsInternal(query).then(options => {
|
||||||
|
this.optionCache = options;
|
||||||
|
|
||||||
|
// extract texts
|
||||||
|
let optionTexts = _.map(options, 'text');
|
||||||
|
|
||||||
|
// add custom values
|
||||||
|
if (this.allowCustom) {
|
||||||
|
if (_.indexOf(optionTexts, this.text) === -1) {
|
||||||
|
options.unshift(this.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(optionTexts);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
typeaheadUpdater(text) {
|
||||||
|
if (text === this.text) {
|
||||||
|
clearTimeout(this.cancelBlur);
|
||||||
|
this.inputElement.focus();
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inputElement.val(text);
|
||||||
|
this.switchToLink(true);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
switchToLink(fromClick) {
|
||||||
|
if (this.linkMode && !fromClick) { return; }
|
||||||
|
|
||||||
|
clearTimeout(this.cancelBlur);
|
||||||
|
this.cancelBlur = null;
|
||||||
|
this.linkMode = true;
|
||||||
|
this.inputElement.hide();
|
||||||
|
this.linkElement.show();
|
||||||
|
this.updateValue(this.inputElement.val());
|
||||||
|
}
|
||||||
|
|
||||||
|
inputBlur() {
|
||||||
|
// happens long before the click event on the typeahead options
|
||||||
|
// need to have long delay because the blur
|
||||||
|
this.cancelBlur = setTimeout(this.switchToLink.bind(this), 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateValue(text) {
|
||||||
|
if (text === '' || this.text === text) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$scope.$apply(() => {
|
||||||
|
var option = _.find(this.optionCache, {text: text});
|
||||||
|
|
||||||
|
if (option) {
|
||||||
|
if (_.isObject(this.model)) {
|
||||||
|
this.model = option;
|
||||||
|
} else {
|
||||||
|
this.model = option.value;
|
||||||
|
}
|
||||||
|
this.text = option.text;
|
||||||
|
} else if (this.allowCustom) {
|
||||||
|
if (_.isObject(this.model)) {
|
||||||
|
this.model.text = this.model.value = text;
|
||||||
|
} else {
|
||||||
|
this.model = text;
|
||||||
|
}
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// needs to call this after digest so
|
||||||
|
// property is synced with outerscope
|
||||||
|
this.$scope.$$postDigest(() => {
|
||||||
|
this.$scope.$apply(() => {
|
||||||
|
this.onChange({$option: option});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDisplay(text) {
|
||||||
|
this.text = text;
|
||||||
|
this.display = this.$sce.trustAsHtml(this.templateSrv.highlightVariablesAsHtml(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
this.inputElement.show();
|
||||||
|
|
||||||
|
this.inputElement.css('width', (Math.max(this.linkElement.width(), 80) + 16) + 'px');
|
||||||
|
this.inputElement.focus();
|
||||||
|
|
||||||
|
this.linkElement.hide();
|
||||||
|
this.linkMode = false;
|
||||||
|
|
||||||
|
var typeahead = this.inputElement.data('typeahead');
|
||||||
|
if (typeahead) {
|
||||||
|
this.inputElement.val('');
|
||||||
|
typeahead.lookup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = `
|
||||||
|
<input type="text"
|
||||||
|
data-provide="typeahead"
|
||||||
|
class="gf-form-input"
|
||||||
|
spellcheck="false"
|
||||||
|
style="display:none">
|
||||||
|
</input>
|
||||||
|
<a ng-class="ctrl.cssClasses"
|
||||||
|
tabindex="1"
|
||||||
|
ng-click="ctrl.open()"
|
||||||
|
give-focus="ctrl.focus"
|
||||||
|
ng-bind-html="ctrl.display">
|
||||||
|
</a>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function formDropdownDirective() {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
template: template,
|
||||||
|
controller: FormDropdownCtrl,
|
||||||
|
bindToController: true,
|
||||||
|
controllerAs: 'ctrl',
|
||||||
|
scope: {
|
||||||
|
model: "=",
|
||||||
|
getOptions: "&",
|
||||||
|
onChange: "&",
|
||||||
|
cssClass: "@",
|
||||||
|
allowCustom: "@",
|
||||||
|
labelMode: "@",
|
||||||
|
lookupText: "@",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
coreModule.directive('gfFormDropdown', formDropdownDirective);
|
@ -34,6 +34,7 @@ import {switchDirective} from './components/switch';
|
|||||||
import {dashboardSelector} from './components/dashboard_selector';
|
import {dashboardSelector} from './components/dashboard_selector';
|
||||||
import {queryPartEditorDirective} from './components/query_part/query_part_editor';
|
import {queryPartEditorDirective} from './components/query_part/query_part_editor';
|
||||||
import {WizardFlow} from './components/wizard/wizard';
|
import {WizardFlow} from './components/wizard/wizard';
|
||||||
|
import {formDropdownDirective} from './components/form_dropdown/form_dropdown';
|
||||||
import 'app/core/controllers/all';
|
import 'app/core/controllers/all';
|
||||||
import 'app/core/services/all';
|
import 'app/core/services/all';
|
||||||
import 'app/core/routes/routes';
|
import 'app/core/routes/routes';
|
||||||
@ -68,6 +69,7 @@ export {
|
|||||||
queryPartEditorDirective,
|
queryPartEditorDirective,
|
||||||
WizardFlow,
|
WizardFlow,
|
||||||
colors,
|
colors,
|
||||||
|
formDropdownDirective,
|
||||||
assignModelProperties,
|
assignModelProperties,
|
||||||
contextSrv,
|
contextSrv,
|
||||||
KeybindingSrv,
|
KeybindingSrv,
|
||||||
|
@ -35,7 +35,7 @@ function ($, angular, coreModule) {
|
|||||||
options.html = editViewMap[options.editview].html;
|
options.html = editViewMap[options.editview].html;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastEditView === options.editview) {
|
if (lastEditView && lastEditView === options.editview) {
|
||||||
hideEditorPane(false);
|
hideEditorPane(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ import _ from 'lodash';
|
|||||||
import {DashboardModel} from '../dashboard/model';
|
import {DashboardModel} from '../dashboard/model';
|
||||||
|
|
||||||
export class MetricsTabCtrl {
|
export class MetricsTabCtrl {
|
||||||
dsSegment: any;
|
|
||||||
mixedDsSegment: any;
|
|
||||||
dsName: string;
|
dsName: string;
|
||||||
panel: any;
|
panel: any;
|
||||||
panelCtrl: any;
|
panelCtrl: any;
|
||||||
@ -14,30 +12,26 @@ export class MetricsTabCtrl {
|
|||||||
current: any;
|
current: any;
|
||||||
nextRefId: string;
|
nextRefId: string;
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
|
panelDsValue: any;
|
||||||
|
addQueryDropdown: any;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor($scope, private uiSegmentSrv, datasourceSrv) {
|
constructor($scope, private uiSegmentSrv, private datasourceSrv) {
|
||||||
this.panelCtrl = $scope.ctrl;
|
this.panelCtrl = $scope.ctrl;
|
||||||
$scope.ctrl = this;
|
$scope.ctrl = this;
|
||||||
|
|
||||||
this.panel = this.panelCtrl.panel;
|
this.panel = this.panelCtrl.panel;
|
||||||
this.dashboard = this.panelCtrl.dashboard;
|
this.dashboard = this.panelCtrl.dashboard;
|
||||||
this.datasources = datasourceSrv.getMetricSources();
|
this.datasources = datasourceSrv.getMetricSources();
|
||||||
|
this.panelDsValue = this.panelCtrl.panel.datasource || null;
|
||||||
var dsValue = this.panelCtrl.panel.datasource || null;
|
|
||||||
|
|
||||||
for (let ds of this.datasources) {
|
for (let ds of this.datasources) {
|
||||||
if (ds.value === dsValue) {
|
if (ds.value === this.panelDsValue) {
|
||||||
this.current = ds;
|
this.current = ds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.current) {
|
this.addQueryDropdown = {text: 'Add Query', value: null, fake: true};
|
||||||
this.current = {name: dsValue + ' not found', value: null};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dsSegment = uiSegmentSrv.newSegment({value: this.current.name, selectMode: true});
|
|
||||||
this.mixedDsSegment = uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true});
|
|
||||||
|
|
||||||
// update next ref id
|
// update next ref id
|
||||||
this.panelCtrl.nextRefId = this.dashboard.getNextQueryLetter(this.panel);
|
this.panelCtrl.nextRefId = this.dashboard.getNextQueryLetter(this.panel);
|
||||||
@ -46,33 +40,28 @@ export class MetricsTabCtrl {
|
|||||||
getOptions(includeBuiltin) {
|
getOptions(includeBuiltin) {
|
||||||
return Promise.resolve(this.datasources.filter(value => {
|
return Promise.resolve(this.datasources.filter(value => {
|
||||||
return includeBuiltin || !value.meta.builtIn;
|
return includeBuiltin || !value.meta.builtIn;
|
||||||
}).map(value => {
|
}).map(ds => {
|
||||||
return this.uiSegmentSrv.newSegment(value.name);
|
return {value: ds.value, text: ds.name, datasource: ds};
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
datasourceChanged() {
|
datasourceChanged(option) {
|
||||||
var ds = _.find(this.datasources, {name: this.dsSegment.value});
|
if (!option) {
|
||||||
if (ds) {
|
return;
|
||||||
this.current = ds;
|
|
||||||
this.panelCtrl.setDatasource(ds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.current = option.datasource;
|
||||||
|
this.panelCtrl.setDatasource(option.datasource);
|
||||||
}
|
}
|
||||||
|
|
||||||
mixedDatasourceChanged() {
|
addMixedQuery(option) {
|
||||||
var target: any = {isNew: true};
|
if (!option) {
|
||||||
var ds = _.find(this.datasources, {name: this.mixedDsSegment.value});
|
return;
|
||||||
|
|
||||||
if (ds) {
|
|
||||||
target.datasource = ds.name;
|
|
||||||
this.panelCtrl.addQuery(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// metric segments are really bad, requires hacks to update
|
var target: any = {isNew: true};
|
||||||
const segment = this.uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true});
|
this.panelCtrl.addQuery({isNew: true, datasource: option.datasource.name});
|
||||||
this.mixedDsSegment.value = segment.value;
|
this.addQueryDropdown = {text: 'Add Query', value: null, fake: true};
|
||||||
this.mixedDsSegment.html = segment.html;
|
|
||||||
this.mixedDsSegment.text = segment.text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addQuery() {
|
addQuery() {
|
||||||
|
@ -19,7 +19,10 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="dropdown" ng-if="ctrl.current.meta.mixed">
|
<div class="dropdown" ng-if="ctrl.current.meta.mixed">
|
||||||
<metric-segment segment="ctrl.mixedDsSegment" get-options="ctrl.getOptions(false)" on-change="ctrl.mixedDatasourceChanged()"></metric-segment>
|
<gf-form-dropdown model="ctrl.addQueryDropdown"
|
||||||
|
get-options="ctrl.getOptions(false)"
|
||||||
|
on-change="ctrl.addMixedQuery($option)">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -30,10 +33,12 @@
|
|||||||
<div class="gf-form-group">
|
<div class="gf-form-group">
|
||||||
<div class="gf-form-inline">
|
<div class="gf-form-inline">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label">
|
<label class="gf-form-label">Panel Data Source</label>
|
||||||
Panel Data Source
|
<gf-form-dropdown model="ctrl.panelDsValue"
|
||||||
</label>
|
lookup-text="true"
|
||||||
<metric-segment segment="ctrl.dsSegment" get-options="ctrl.getOptions(true)" on-change="ctrl.datasourceChanged()"></metric-segment>
|
get-options="ctrl.getOptions(true)"
|
||||||
|
on-change="ctrl.datasourceChanged($option)">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,13 +26,21 @@ function (angular, _, queryDef) {
|
|||||||
var bucketAggs = $scope.target.bucketAggs;
|
var bucketAggs = $scope.target.bucketAggs;
|
||||||
|
|
||||||
$scope.orderByOptions = [];
|
$scope.orderByOptions = [];
|
||||||
$scope.bucketAggTypes = queryDef.bucketAggTypes;
|
|
||||||
$scope.orderOptions = queryDef.orderOptions;
|
$scope.getBucketAggTypes = function() {
|
||||||
$scope.sizeOptions = queryDef.sizeOptions;
|
return queryDef.bucketAggTypes;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getOrderOptions = function() {
|
||||||
|
return queryDef.orderOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getSizeOptions = function() {
|
||||||
|
return queryDef.sizeOptions;
|
||||||
|
};
|
||||||
|
|
||||||
$rootScope.onAppEvent('elastic-query-updated', function() {
|
$rootScope.onAppEvent('elastic-query-updated', function() {
|
||||||
$scope.validateModel();
|
$scope.validateModel();
|
||||||
$scope.updateOrderByOptions();
|
|
||||||
}, $scope);
|
}, $scope);
|
||||||
|
|
||||||
$scope.init = function() {
|
$scope.init = function() {
|
||||||
@ -166,11 +174,10 @@ function (angular, _, queryDef) {
|
|||||||
|
|
||||||
$scope.toggleOptions = function() {
|
$scope.toggleOptions = function() {
|
||||||
$scope.showOptions = !$scope.showOptions;
|
$scope.showOptions = !$scope.showOptions;
|
||||||
$scope.updateOrderByOptions();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updateOrderByOptions = function() {
|
$scope.getOrderByOptions = function() {
|
||||||
$scope.orderByOptions = queryDef.getOrderByOptions($scope.target);
|
return queryDef.getOrderByOptions($scope.target);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getFieldsInternal = function() {
|
$scope.getFieldsInternal = function() {
|
||||||
|
@ -5,8 +5,22 @@
|
|||||||
<span ng-hide="isFirst">Then by</span>
|
<span ng-hide="isFirst">Then by</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<metric-segment-model property="agg.type" options="bucketAggTypes" on-change="onTypeChanged()" custom="false" css-class="width-10"></metric-segment-model>
|
<gf-form-dropdown model="agg.type"
|
||||||
<metric-segment-model ng-if="agg.field" property="agg.field" get-options="getFieldsInternal()" on-change="onChange()" css-class="width-12"></metric-segment-model>
|
lookup-text="true"
|
||||||
|
get-options="getBucketAggTypes()"
|
||||||
|
on-change="onTypeChanged()"
|
||||||
|
allow-custom="false"
|
||||||
|
label-mode="true"
|
||||||
|
css-class="width-10">
|
||||||
|
</gf-form-dropdown>
|
||||||
|
<gf-form-dropdown ng-if="agg.field"
|
||||||
|
model="agg.field"
|
||||||
|
get-options="getFieldsInternal()"
|
||||||
|
on-change="onChange()"
|
||||||
|
allow-custom="false"
|
||||||
|
label-mode="true"
|
||||||
|
css-class="width-12">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
@ -33,7 +47,13 @@
|
|||||||
<div ng-if="agg.type === 'date_histogram'">
|
<div ng-if="agg.type === 'date_histogram'">
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
<label class="gf-form-label width-10">Interval</label>
|
<label class="gf-form-label width-10">Interval</label>
|
||||||
<metric-segment-model property="agg.settings.interval" get-options="getIntervalOptions()" on-change="onChangeInternal()" css-class="width-12" custom="true"></metric-segment-model>
|
<gf-form-dropdown model="agg.settings.interval"
|
||||||
|
get-options="getIntervalOptions()"
|
||||||
|
on-change="onChangeInternal()"
|
||||||
|
allow-custom="true"
|
||||||
|
label-mode="true"
|
||||||
|
css-class="width-12">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
@ -66,11 +86,23 @@
|
|||||||
<div ng-if="agg.type === 'terms'">
|
<div ng-if="agg.type === 'terms'">
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
<label class="gf-form-label width-10">Order</label>
|
<label class="gf-form-label width-10">Order</label>
|
||||||
<metric-segment-model property="agg.settings.order" options="orderOptions" on-change="onChangeInternal()" css-class="width-12"></metric-segment-model>
|
<gf-form-dropdown model="agg.settings.order"
|
||||||
|
lookup-text="true"
|
||||||
|
get-options="getOrderOptions()"
|
||||||
|
on-change="onChangeInternal()"
|
||||||
|
label-mode="true"
|
||||||
|
css-class="width-12">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
<label class="gf-form-label width-10">Size</label>
|
<label class="gf-form-label width-10">Size</label>
|
||||||
<metric-segment-model property="agg.settings.size" options="sizeOptions" on-change="onChangeInternal()" css-class="width-12"></metric-segment-model>
|
<gf-form-dropdown model="agg.settings.size"
|
||||||
|
lookup-text="true"
|
||||||
|
get-options="getSizeOptions()"
|
||||||
|
on-change="onChangeInternal()"
|
||||||
|
label-mode="true"
|
||||||
|
css-class="width-12">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
<label class="gf-form-label width-10">Min Doc Count</label>
|
<label class="gf-form-label width-10">Min Doc Count</label>
|
||||||
@ -78,7 +110,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
<label class="gf-form-label width-10">Order By</label>
|
<label class="gf-form-label width-10">Order By</label>
|
||||||
<metric-segment-model property="agg.settings.orderBy" options="orderByOptions" on-change="onChangeInternal()" css-class="width-12"></metric-segment-model>
|
<gf-form-dropdown model="agg.settings.orderBy"
|
||||||
|
lookup-text="true"
|
||||||
|
get-options="getOrderByOptions()"
|
||||||
|
on-change="onChangeInternal()"
|
||||||
|
label-mode="true"
|
||||||
|
css-class="width-12">
|
||||||
|
</gf-form-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form offset-width-7">
|
<div class="gf-form offset-width-7">
|
||||||
<label class="gf-form-label width-10">
|
<label class="gf-form-label width-10">
|
||||||
|
@ -31,11 +31,11 @@ export class ElasticQueryCtrl extends QueryCtrl {
|
|||||||
|
|
||||||
queryUpdated() {
|
queryUpdated() {
|
||||||
var newJson = angular.toJson(this.datasource.queryBuilder.build(this.target), true);
|
var newJson = angular.toJson(this.datasource.queryBuilder.build(this.target), true);
|
||||||
if (newJson !== this.rawQueryOld) {
|
if (this.rawQueryOld && newJson !== this.rawQueryOld) {
|
||||||
this.rawQueryOld = newJson;
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.rawQueryOld = newJson;
|
||||||
this.$rootScope.appEvent('elastic-query-updated');
|
this.$rootScope.appEvent('elastic-query-updated');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user