mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 19:00:54 -06:00
work on tag dropdown behavior
This commit is contained in:
parent
3a4e05133e
commit
ebad19b232
@ -1,9 +1,11 @@
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import coreModule from '../../core_module';
|
||||
|
||||
function typeaheadMatcher(item) {
|
||||
var str = this.query;
|
||||
if (str === '') {
|
||||
return true;
|
||||
}
|
||||
if (str[0] === '/') {
|
||||
str = str.substring(1);
|
||||
}
|
||||
@ -30,6 +32,8 @@ export class FormDropdownCtrl {
|
||||
getOptions: any;
|
||||
optionCache: any;
|
||||
lookupText: boolean;
|
||||
placeholder: any;
|
||||
startOpen: any;
|
||||
|
||||
/** @ngInject **/
|
||||
constructor(private $scope, $element, private $sce, private templateSrv, private $q) {
|
||||
@ -47,6 +51,10 @@ export class FormDropdownCtrl {
|
||||
this.cssClasses = 'gf-form-input gf-form-input--dropdown ' + this.cssClass;
|
||||
}
|
||||
|
||||
if (this.placeholder) {
|
||||
this.inputElement.attr('placeholder', this.placeholder);
|
||||
}
|
||||
|
||||
this.inputElement.attr('data-provide', 'typeahead');
|
||||
this.inputElement.typeahead({
|
||||
source: this.typeaheadSource.bind(this),
|
||||
@ -61,8 +69,7 @@ export class FormDropdownCtrl {
|
||||
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.source(this.query, this.process.bind(this));
|
||||
};
|
||||
|
||||
this.linkElement.keydown(evt => {
|
||||
@ -81,6 +88,10 @@ export class FormDropdownCtrl {
|
||||
});
|
||||
|
||||
this.inputElement.blur(this.inputBlur.bind(this));
|
||||
|
||||
if (this.startOpen) {
|
||||
setTimeout(this.open.bind(this), 0);
|
||||
}
|
||||
}
|
||||
|
||||
getOptionsInternal(query) {
|
||||
@ -121,9 +132,9 @@ export class FormDropdownCtrl {
|
||||
});
|
||||
|
||||
// add custom values
|
||||
if (this.allowCustom) {
|
||||
if (this.allowCustom && this.text !== '') {
|
||||
if (_.indexOf(optionTexts, this.text) === -1) {
|
||||
options.unshift(this.text);
|
||||
optionTexts.unshift(this.text);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +176,7 @@ export class FormDropdownCtrl {
|
||||
updateValue(text) {
|
||||
text = _.unescape(text);
|
||||
|
||||
if (text === '' || this.text === text) {
|
||||
if ((!this.allowCustom && text === '') || this.text === text) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -214,7 +225,9 @@ export class FormDropdownCtrl {
|
||||
|
||||
var typeahead = this.inputElement.data('typeahead');
|
||||
if (typeahead) {
|
||||
this.inputElement.val('');
|
||||
if (!this.allowCustom) {
|
||||
this.inputElement.val('');
|
||||
}
|
||||
typeahead.lookup();
|
||||
}
|
||||
}
|
||||
@ -228,10 +241,10 @@ const template = `
|
||||
style="display:none">
|
||||
</input>
|
||||
<a ng-class="ctrl.cssClasses"
|
||||
tabindex="1"
|
||||
ng-click="ctrl.open()"
|
||||
give-focus="ctrl.focus"
|
||||
ng-bind-html="ctrl.display">
|
||||
tabindex="1"
|
||||
ng-click="ctrl.open()"
|
||||
give-focus="ctrl.focus"
|
||||
ng-bind-html="ctrl.display || ' '">
|
||||
</a>
|
||||
`;
|
||||
|
||||
@ -250,6 +263,8 @@ export function formDropdownDirective() {
|
||||
allowCustom: '@',
|
||||
labelMode: '@',
|
||||
lookupText: '@',
|
||||
placeholder: '@',
|
||||
startOpen: '@',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ function (_, $, coreModule) {
|
||||
' class="gf-form-input input-medium tight-form-input"' +
|
||||
' spellcheck="false" style="display:none"></input>';
|
||||
|
||||
var buttonTemplate = '<a class="gf-form-label tight-form-func dropdown-toggle"' +
|
||||
var buttonTemplate = '<a class="gf-form-label tight-form-func dropdown-toggle"' +
|
||||
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
||||
' data-placement="top"><i class="fa fa-plus"></i></a>';
|
||||
|
||||
|
@ -106,10 +106,6 @@ function (angular, _, coreModule) {
|
||||
return new MetricSegment({fake: true, html: '<i class="fa fa-plus "></i>', type: 'plus-button', cssClass: 'query-part' });
|
||||
};
|
||||
|
||||
this.newSelectTagValue = function() {
|
||||
return new MetricSegment({value: 'select tag value', fake: true});
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -13,7 +13,7 @@ function (angular, _, $) {
|
||||
' class="gf-form-input"' +
|
||||
' spellcheck="false" style="display:none"></input>';
|
||||
|
||||
var buttonTemplate = '<a class="gf-form-label query-part dropdown-toggle"' +
|
||||
var buttonTemplate = '<a class="gf-form-label query-part dropdown-toggle"' +
|
||||
' tabindex="1" gf-dropdown="functionMenu" data-toggle="dropdown">' +
|
||||
'<i class="fa fa-plus"></i></a>';
|
||||
|
||||
|
@ -209,7 +209,7 @@ export default class GraphiteQuery {
|
||||
}
|
||||
|
||||
splitSeriesByTagParams(func) {
|
||||
const tagPattern = /([^\!=~]+)([\!=~]+)([^\!=~]+)/;
|
||||
const tagPattern = /([^\!=~]+)(\!?=~?)(.*)/;
|
||||
return _.flatten(
|
||||
_.map(func.params, (param: string) => {
|
||||
let matches = tagPattern.exec(param);
|
||||
|
@ -11,29 +11,45 @@
|
||||
</div>
|
||||
|
||||
<div ng-repeat="tag in ctrl.queryModel.tags" class="gf-form">
|
||||
<gf-form-dropdown model="tag.key" lookup-text="false" allow-custom="false" label-mode="true" css-class="query-segment-key"
|
||||
<gf-form-dropdown
|
||||
model="tag.key"
|
||||
lookup-text="false"
|
||||
allow-custom="true"
|
||||
label-mode="true"
|
||||
css-class="query-segment-key"
|
||||
get-options="ctrl.getTags($index, $query)"
|
||||
on-change="ctrl.tagChanged(tag, $index)">
|
||||
</gf-form-dropdown>
|
||||
<gf-form-dropdown model="tag.operator" lookup-text="false" allow-custom="false" label-mode="true" css-class="query-segment-operator"
|
||||
on-change="ctrl.tagChanged(tag, $index)"
|
||||
/>
|
||||
<gf-form-dropdown
|
||||
model="tag.operator"
|
||||
lookup-text="false"
|
||||
allow-custom="false"
|
||||
label-mode="true"
|
||||
css-class="query-segment-operator"
|
||||
get-options="ctrl.getTagOperators()"
|
||||
on-change="ctrl.tagChanged(tag, $index)"
|
||||
min-input-width="30">
|
||||
</gf-form-dropdown>
|
||||
<gf-form-dropdown model="tag.value" lookup-text="false" allow-custom="false" label-mode="true" css-class="query-segment-value"
|
||||
min-input-width="30"
|
||||
/>
|
||||
<gf-form-dropdown
|
||||
model="tag.value"
|
||||
lookup-text="false"
|
||||
allow-custom="true"
|
||||
label-mode="true"
|
||||
css-class="query-segment-value"
|
||||
placeholder="select tag value"
|
||||
get-options="ctrl.getTagValues(tag, $index, $query)"
|
||||
on-change="ctrl.tagChanged(tag, $index)">
|
||||
</gf-form-dropdown>
|
||||
on-change="ctrl.tagChanged(tag, $index)"
|
||||
start-open="!ctrl.showDelimiter($index)"
|
||||
/>
|
||||
<label class="gf-form-label query-keyword" ng-if="ctrl.showDelimiter($index)">AND</label>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="segment in ctrl.segments" role="menuitem" class="gf-form">
|
||||
<metric-segment segment="segment" get-options="ctrl.getAltSegments($index)" on-change="ctrl.segmentValueChanged(segment, $index)"></metric-segment>
|
||||
<metric-segment segment="segment" get-options="ctrl.getAltSegments($index)" on-change="ctrl.segmentValueChanged(segment, $index)" />
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.queryModel.seriesByTagUsed" ng-repeat="segment in ctrl.addTagSegments" role="menuitem" class="gf-form">
|
||||
<metric-segment segment="segment" get-options="ctrl.getTagsAsSegments()" on-change="ctrl.addNewTag(segment)">
|
||||
</metric-segment>
|
||||
<metric-segment segment="segment" get-options="ctrl.getTagsAsSegments()" on-change="ctrl.addNewTag(segment)" />
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
|
@ -270,7 +270,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
|
||||
let newFunc = this.datasource.createFuncInstance('seriesByTag', {
|
||||
withDefaultParams: false,
|
||||
});
|
||||
let tagParam = `${tag}=select tag value`;
|
||||
let tagParam = `${tag}=`;
|
||||
newFunc.params = [tagParam];
|
||||
this.queryModel.addFunction(newFunc);
|
||||
newFunc.added = true;
|
||||
@ -353,7 +353,7 @@ export class GraphiteQueryCtrl extends QueryCtrl {
|
||||
|
||||
addNewTag(segment) {
|
||||
let newTagKey = segment.value;
|
||||
let newTag = { key: newTagKey, operator: '=', value: 'select tag value' };
|
||||
let newTag = { key: newTagKey, operator: '=', value: '' };
|
||||
this.queryModel.addTag(newTag);
|
||||
this.targetChanged();
|
||||
this.fixTagSegments();
|
||||
|
@ -284,12 +284,12 @@ describe('GraphiteQueryCtrl', function() {
|
||||
});
|
||||
|
||||
it('should update tags with default value', function() {
|
||||
const expected = [{ key: 'tag1', operator: '=', value: 'select tag value' }];
|
||||
const expected = [{ key: 'tag1', operator: '=', value: '' }];
|
||||
expect(ctx.ctrl.queryModel.tags).to.eql(expected);
|
||||
});
|
||||
|
||||
it('should update target', function() {
|
||||
const expected = "seriesByTag('tag1=select tag value')";
|
||||
const expected = "seriesByTag('tag1=')";
|
||||
expect(ctx.ctrl.target.target).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user