Преглед на файлове

work on tag dropdown behavior

Dan Cech преди 8 години
родител
ревизия
ebad19b232

+ 26 - 11
public/app/core/components/form_dropdown/form_dropdown.ts

@@ -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 || '&nbsp;'">
 </a>
 `;
 
@@ -250,6 +263,8 @@ export function formDropdownDirective() {
       allowCustom: '@',
       labelMode: '@',
       lookupText: '@',
+      placeholder: '@',
+      startOpen: '@',
     },
   };
 }

+ 1 - 1
public/app/core/directives/dropdown_typeahead.js

@@ -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>';
 

+ 0 - 4
public/app/core/services/segment_srv.js

@@ -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});
-    };
-
   });
 
 });

+ 1 - 1
public/app/plugins/datasource/graphite/add_graphite_func.js

@@ -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>';
 

+ 1 - 1
public/app/plugins/datasource/graphite/graphite_query.ts

@@ -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);

+ 28 - 12
public/app/plugins/datasource/graphite/partials/query.editor.html

@@ -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">

+ 2 - 2
public/app/plugins/datasource/graphite/query_ctrl.ts

@@ -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();

+ 2 - 2
public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts

@@ -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);
     });
   });