mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refacoring: more work on metric segment replacement
This commit is contained in:
parent
380e7e7f04
commit
6a95df403a
@ -1,13 +0,0 @@
|
||||
<input type="text"
|
||||
data-provide="typeahead"
|
||||
class="gf-form-input"
|
||||
spellcheck="false"
|
||||
style="display:none"></input>
|
||||
|
||||
<a class="gf-form-label"
|
||||
ng-class="ctrl.cssClass"
|
||||
tabindex="1"
|
||||
ng-click="ctrl.open()"
|
||||
give-focus="ctrl.focus"
|
||||
ng-bind-html="ctrl.display"></a>
|
||||
|
@ -15,15 +15,17 @@ function typeaheadMatcher(item) {
|
||||
export class FormDropdownCtrl {
|
||||
inputElement: any;
|
||||
linkElement: any;
|
||||
value: any;
|
||||
text: any;
|
||||
model: any;
|
||||
display: any;
|
||||
text: any;
|
||||
options: any;
|
||||
cssClass: any;
|
||||
allowCustom: any;
|
||||
linkMode: boolean;
|
||||
cancelBlur: any;
|
||||
onChange: any;
|
||||
getOptions: any;
|
||||
optionCache: any;
|
||||
|
||||
constructor(private $scope, $element, private $sce, private templateSrv) {
|
||||
this.inputElement = $element.find('input').first();
|
||||
@ -31,11 +33,15 @@ export class FormDropdownCtrl {
|
||||
this.linkMode = true;
|
||||
this.cancelBlur = null;
|
||||
|
||||
if (this.options) {
|
||||
var item = _.find(this.options, {value: this.value});
|
||||
this.updateDisplay(item ? item.text : this.value);
|
||||
if (!this.getOptions) {
|
||||
this.getOptions = () => {
|
||||
return Promise.resolve(this.options);
|
||||
};
|
||||
}
|
||||
|
||||
// listen to model changes
|
||||
$scope.$watch("ctrl.model", this.modelChanged.bind(this));
|
||||
|
||||
this.inputElement.attr('data-provide', 'typeahead');
|
||||
this.inputElement.typeahead({
|
||||
source: this.typeaheadSource.bind(this),
|
||||
@ -64,19 +70,40 @@ export class FormDropdownCtrl {
|
||||
this.inputElement.blur(this.inputBlur.bind(this));
|
||||
}
|
||||
|
||||
typeaheadSource(query, callback) {
|
||||
if (this.options) {
|
||||
var typeaheadOptions = _.map(this.options, 'text');
|
||||
modelChanged(newVal) {
|
||||
if (_.isObject(this.model)) {
|
||||
this.updateDisplay(this.model.text);
|
||||
} else {
|
||||
|
||||
// add current custom value
|
||||
// if we have text use it
|
||||
if (this.text) {
|
||||
this.updateDisplay(this.text);
|
||||
} else {
|
||||
// otherwise we need to do initial lookup, usually happens first time
|
||||
this.getOptions().then(options => {
|
||||
var item = _.find(options, {value: this.model});
|
||||
this.updateDisplay(item ? item.text : this.model);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typeaheadSource(query, callback) {
|
||||
this.getOptions({$query: query}).then(options => {
|
||||
this.optionCache = options;
|
||||
|
||||
// extract texts
|
||||
let optionTexts = _.map(options, 'text');
|
||||
|
||||
// add custom values
|
||||
if (this.allowCustom) {
|
||||
if (_.indexOf(typeaheadOptions, this.text) === -1) {
|
||||
typeaheadOptions.unshift(this.text);
|
||||
if (_.indexOf(optionTexts, this.text) === -1) {
|
||||
options.unshift(this.text);
|
||||
}
|
||||
}
|
||||
|
||||
callback(typeaheadOptions);
|
||||
}
|
||||
callback(optionTexts);
|
||||
});
|
||||
}
|
||||
|
||||
typeaheadUpdater(text) {
|
||||
@ -114,21 +141,29 @@ export class FormDropdownCtrl {
|
||||
}
|
||||
|
||||
this.$scope.$apply(() => {
|
||||
var option = _.find(this.options, {text: text});
|
||||
var option = _.find(this.optionCache, {text: text});
|
||||
|
||||
if (option) {
|
||||
this.value = option.value;
|
||||
this.updateDisplay(option.text);
|
||||
if (_.isObject(this.model)) {
|
||||
this.model = option;
|
||||
} else {
|
||||
this.model = option.value;
|
||||
}
|
||||
this.text = option.text;
|
||||
} else if (this.allowCustom) {
|
||||
this.value = text;
|
||||
this.updateDisplay(text);
|
||||
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();
|
||||
this.onChange({$option: option});
|
||||
});
|
||||
});
|
||||
|
||||
@ -157,17 +192,30 @@ export class FormDropdownCtrl {
|
||||
}
|
||||
}
|
||||
|
||||
const template = `
|
||||
<input type="text"
|
||||
data-provide="typeahead"
|
||||
class="gf-form-input"
|
||||
spellcheck="false"
|
||||
style="display:none"></input>
|
||||
|
||||
<a class="gf-form-label"
|
||||
ng-class="ctrl.cssClass"
|
||||
tabindex="1"
|
||||
ng-click="ctrl.open()"
|
||||
give-focus="ctrl.focus"
|
||||
ng-bind-html="ctrl.display"></a>
|
||||
`;
|
||||
|
||||
export function formDropdownDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'public/app/core/components/form_dropdown/form_dropdown.html',
|
||||
template: template,
|
||||
controller: FormDropdownCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {
|
||||
value: "=",
|
||||
model: "=",
|
||||
options: "=",
|
||||
getOptions: "&",
|
||||
onChange: "&",
|
||||
|
@ -35,7 +35,7 @@ function ($, angular, coreModule) {
|
||||
options.html = editViewMap[options.editview].html;
|
||||
}
|
||||
|
||||
if (lastEditView === options.editview) {
|
||||
if (lastEditView && lastEditView === options.editview) {
|
||||
hideEditorPane(false);
|
||||
return;
|
||||
}
|
||||
|
@ -143,6 +143,7 @@ function (_, $, coreModule) {
|
||||
$input.focus();
|
||||
|
||||
linkMode = false;
|
||||
|
||||
var typeahead = $input.data('typeahead');
|
||||
if (typeahead) {
|
||||
$input.val('');
|
||||
@ -151,6 +152,7 @@ function (_, $, coreModule) {
|
||||
});
|
||||
|
||||
$input.blur($scope.inputBlur);
|
||||
|
||||
$compile(elem.contents())($scope);
|
||||
}
|
||||
};
|
||||
|
@ -5,8 +5,6 @@ import _ from 'lodash';
|
||||
import {DashboardModel} from '../dashboard/model';
|
||||
|
||||
export class MetricsTabCtrl {
|
||||
dsSegment: any;
|
||||
mixedDsSegment: any;
|
||||
dsName: string;
|
||||
panel: any;
|
||||
panelCtrl: any;
|
||||
@ -14,30 +12,26 @@ export class MetricsTabCtrl {
|
||||
current: any;
|
||||
nextRefId: string;
|
||||
dashboard: DashboardModel;
|
||||
panelDsValue: any;
|
||||
addQueryDropdown: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, private uiSegmentSrv, datasourceSrv) {
|
||||
constructor($scope, private uiSegmentSrv, private datasourceSrv) {
|
||||
this.panelCtrl = $scope.ctrl;
|
||||
$scope.ctrl = this;
|
||||
|
||||
this.panel = this.panelCtrl.panel;
|
||||
this.dashboard = this.panelCtrl.dashboard;
|
||||
this.datasources = datasourceSrv.getMetricSources();
|
||||
|
||||
var dsValue = this.panelCtrl.panel.datasource || null;
|
||||
this.panelDsValue = this.panelCtrl.panel.datasource || null;
|
||||
|
||||
for (let ds of this.datasources) {
|
||||
if (ds.value === dsValue) {
|
||||
if (ds.value === this.panelDsValue) {
|
||||
this.current = ds;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.current) {
|
||||
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});
|
||||
this.addQueryDropdown = {text: 'Add Query', value: null, fake: true};
|
||||
|
||||
// update next ref id
|
||||
this.panelCtrl.nextRefId = this.dashboard.getNextQueryLetter(this.panel);
|
||||
@ -46,33 +40,28 @@ export class MetricsTabCtrl {
|
||||
getOptions(includeBuiltin) {
|
||||
return Promise.resolve(this.datasources.filter(value => {
|
||||
return includeBuiltin || !value.meta.builtIn;
|
||||
}).map(value => {
|
||||
return this.uiSegmentSrv.newSegment(value.name);
|
||||
}).map(ds => {
|
||||
return {value: ds.value, text: ds.name, datasource: ds};
|
||||
}));
|
||||
}
|
||||
|
||||
datasourceChanged() {
|
||||
var ds = _.find(this.datasources, {name: this.dsSegment.value});
|
||||
if (ds) {
|
||||
this.current = ds;
|
||||
this.panelCtrl.setDatasource(ds);
|
||||
datasourceChanged(option) {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.current = option.datasource;
|
||||
this.panelCtrl.setDatasource(option.datasource);
|
||||
}
|
||||
|
||||
mixedDatasourceChanged() {
|
||||
var target: any = {isNew: true};
|
||||
var ds = _.find(this.datasources, {name: this.mixedDsSegment.value});
|
||||
|
||||
if (ds) {
|
||||
target.datasource = ds.name;
|
||||
this.panelCtrl.addQuery(target);
|
||||
addMixedQuery(option) {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
|
||||
// metric segments are really bad, requires hacks to update
|
||||
const segment = this.uiSegmentSrv.newSegment({value: 'Add Query', selectMode: true, fake: true});
|
||||
this.mixedDsSegment.value = segment.value;
|
||||
this.mixedDsSegment.html = segment.html;
|
||||
this.mixedDsSegment.text = segment.text;
|
||||
var target: any = {isNew: true};
|
||||
this.panelCtrl.addQuery({isNew: true, datasource: option.datasource.name});
|
||||
this.addQueryDropdown = {text: 'Add Query', value: null, fake: true};
|
||||
}
|
||||
|
||||
addQuery() {
|
||||
|
@ -19,7 +19,10 @@
|
||||
</button>
|
||||
|
||||
<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>
|
||||
@ -30,10 +33,12 @@
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
Panel Data Source
|
||||
</label>
|
||||
<metric-segment segment="ctrl.dsSegment" get-options="ctrl.getOptions(true)" on-change="ctrl.datasourceChanged()"></metric-segment>
|
||||
<label class="gf-form-label">Panel Data Source</label>
|
||||
<gf-form-dropdown model="ctrl.panelDsValue"
|
||||
get-options="ctrl.getOptions(true)"
|
||||
on-change="ctrl.datasourceChanged($option)"
|
||||
css-class="width-10">
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user