diff --git a/public/app/core/components/form_dropdown/form_dropdown.html b/public/app/core/components/form_dropdown/form_dropdown.html deleted file mode 100644 index 34737eab27e..00000000000 --- a/public/app/core/components/form_dropdown/form_dropdown.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - diff --git a/public/app/core/components/form_dropdown/form_dropdown.ts b/public/app/core/components/form_dropdown/form_dropdown.ts index fd363d3b75e..eb8be1e0945 100644 --- a/public/app/core/components/form_dropdown/form_dropdown.ts +++ b/public/app/core/components/form_dropdown/form_dropdown.ts @@ -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 = ` + + +`; 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: "&", diff --git a/public/app/core/directives/dash_edit_link.js b/public/app/core/directives/dash_edit_link.js index 3e4bdd4c5c7..a4c1ad53b3c 100644 --- a/public/app/core/directives/dash_edit_link.js +++ b/public/app/core/directives/dash_edit_link.js @@ -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; } diff --git a/public/app/core/directives/metric_segment.js b/public/app/core/directives/metric_segment.js index 0605d54a815..2e9442c15a0 100644 --- a/public/app/core/directives/metric_segment.js +++ b/public/app/core/directives/metric_segment.js @@ -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); } }; diff --git a/public/app/features/panel/metrics_tab.ts b/public/app/features/panel/metrics_tab.ts index f2d99738040..c03c4d83bc2 100644 --- a/public/app/features/panel/metrics_tab.ts +++ b/public/app/features/panel/metrics_tab.ts @@ -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() { diff --git a/public/app/features/panel/partials/metrics_tab.html b/public/app/features/panel/partials/metrics_tab.html index a020a2edbd1..32f43f1d639 100644 --- a/public/app/features/panel/partials/metrics_tab.html +++ b/public/app/features/panel/partials/metrics_tab.html @@ -19,7 +19,10 @@ @@ -30,10 +33,12 @@
- - + + +