mirror of https://github.com/grafana/grafana.git
				
				
				
			feat(influxdb): new editor now supports field and tag lookup again
This commit is contained in:
		
							parent
							
								
									b3d494d4c8
								
							
						
					
					
						commit
						721b37a08e
					
				| 
						 | 
				
			
			@ -1,11 +1,8 @@
 | 
			
		|||
///<reference path="../../../headers/common.d.ts" />
 | 
			
		||||
///<amd-dependency path="./query_builder" name="InfluxQueryBuilder" />
 | 
			
		||||
 | 
			
		||||
import _ = require('lodash');
 | 
			
		||||
import queryPart = require('./query_part');
 | 
			
		||||
 | 
			
		||||
declare var InfluxQueryBuilder: any;
 | 
			
		||||
 | 
			
		||||
class InfluxQuery {
 | 
			
		||||
  target: any;
 | 
			
		||||
  selectModels: any[];
 | 
			
		||||
| 
						 | 
				
			
			@ -76,6 +73,23 @@ class InfluxQuery {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  removeGroupByPart(part, index) {
 | 
			
		||||
    var categories = queryPart.getCategories();
 | 
			
		||||
 | 
			
		||||
    if (part.def.type === 'time') {
 | 
			
		||||
      // remove fill
 | 
			
		||||
      this.target.groupBy = _.filter(this.target.groupBy, (g: any) => g.type !== 'fill');
 | 
			
		||||
      // remove aggregations
 | 
			
		||||
      this.target.select = _.map(this.target.select, (s: any) => {
 | 
			
		||||
        return _.filter(s, (part: any) => {
 | 
			
		||||
          var partModel = queryPart.create(part);
 | 
			
		||||
          if (partModel.def.category === categories.Aggregations) {
 | 
			
		||||
            return false;
 | 
			
		||||
          }
 | 
			
		||||
          return true;
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.target.groupBy.splice(index, 1);
 | 
			
		||||
    this.updateProjection();
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +180,7 @@ class InfluxQuery {
 | 
			
		|||
 | 
			
		||||
    var measurement = target.measurement;
 | 
			
		||||
    if (!measurement.match('^/.*/') && !measurement.match(/^merge\(.*\)/)) {
 | 
			
		||||
      measurement = '"' + measurement+ '"';
 | 
			
		||||
measurement = '"' + measurement+ '"';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    query += ' FROM ' + measurement + ' WHERE ';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,7 @@
 | 
			
		|||
					<span ng-show="$index === 0">SELECT</span>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li ng-repeat="part in selectParts">
 | 
			
		||||
					<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeSelectPart(selectParts, part)" part-updated="selectPartUpdated(selectParts, part)"></influx-query-part-editor>
 | 
			
		||||
					<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeSelectPart(selectParts, part)" part-updated="selectPartUpdated(selectParts, part)" get-options="getPartOptions(part)"></influx-query-part-editor>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li class="dropdown" dropdown-typeahead="selectMenu" dropdown-typeahead-on-select="addSelectPart(selectParts, $item, $subItem)">
 | 
			
		||||
				</li>
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +85,7 @@
 | 
			
		|||
					<span ng-show="$index === 0">GROUP BY</span>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li ng-repeat="part in queryModel.groupByParts">
 | 
			
		||||
					<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeGroupByPart(part, $index)" part-updated="get_data();"></influx-query-part-editor>
 | 
			
		||||
					<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="removeGroupByPart(part, $index)" part-updated="get_data();" get-options="getPartOptions(part)"></influx-query-part-editor>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li>
 | 
			
		||||
					<metric-segment segment="groupBySegment" get-options="getGroupByOptions()" on-change="groupByAction(part, $index)"></metric-segment>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,12 +124,6 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 | 
			
		|||
      $scope.get_data();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $scope.getFields = function() {
 | 
			
		||||
      var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
 | 
			
		||||
      return $scope.datasource.metricFindQuery(fieldsQuery)
 | 
			
		||||
      .then($scope.transformToSegments(false), $scope.handleQueryError);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $scope.toggleQueryMode = function () {
 | 
			
		||||
      $scope.target.rawQuery = !$scope.target.rawQuery;
 | 
			
		||||
    };
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +134,19 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 | 
			
		|||
      .then($scope.transformToSegments(true), $scope.handleQueryError);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $scope.getPartOptions = function(part) {
 | 
			
		||||
      if (part.def.type === 'field') {
 | 
			
		||||
        var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
 | 
			
		||||
        return $scope.datasource.metricFindQuery(fieldsQuery)
 | 
			
		||||
        .then($scope.transformToSegments(true), $scope.handleQueryError);
 | 
			
		||||
      }
 | 
			
		||||
      if (part.def.type === 'tag') {
 | 
			
		||||
        var tagsQuery = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
 | 
			
		||||
        return $scope.datasource.metricFindQuery(tagsQuery)
 | 
			
		||||
        .then($scope.transformToSegments(true), $scope.handleQueryError);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    $scope.handleQueryError = function(err) {
 | 
			
		||||
      $scope.parserError = err.message || 'Failed to issue metric query';
 | 
			
		||||
      return [];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ QueryPartDef.register({
 | 
			
		|||
  type: 'field',
 | 
			
		||||
  addStrategy: addFieldStrategy,
 | 
			
		||||
  category: categories.Fields,
 | 
			
		||||
  params: [{type: 'field'}],
 | 
			
		||||
  params: [{type: 'field', dynamicLookup: true}],
 | 
			
		||||
  defaultParams: ['value'],
 | 
			
		||||
  renderer: fieldRenderer,
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ QueryPartDef.register({
 | 
			
		|||
QueryPartDef.register({
 | 
			
		||||
  type: 'tag',
 | 
			
		||||
  category: groupByTimeFunctions,
 | 
			
		||||
  params: [{name: 'tag', type: 'string'}],
 | 
			
		||||
  params: [{name: 'tag', type: 'string', dynamicLookup: true}],
 | 
			
		||||
  defaultParams: ['tag'],
 | 
			
		||||
  renderer: fieldRenderer,
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ function (angular, _, $) {
 | 
			
		|||
          part: "=",
 | 
			
		||||
          removeAction: "&",
 | 
			
		||||
          partUpdated: "&",
 | 
			
		||||
          getOptions: "&",
 | 
			
		||||
        },
 | 
			
		||||
        link: function postLink($scope, elem) {
 | 
			
		||||
          var part = $scope.part;
 | 
			
		||||
| 
						 | 
				
			
			@ -75,18 +76,32 @@ function (angular, _, $) {
 | 
			
		|||
            this.style.width = (3 + this.value.length) * 8 + 'px';
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          function addTypeahead($input, paramIndex) {
 | 
			
		||||
            $input.attr('data-provide', 'typeahead');
 | 
			
		||||
          function addTypeahead($input, param, paramIndex) {
 | 
			
		||||
            if (!param.options && !param.dynamicLookup) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var options = partDef.params[paramIndex].options;
 | 
			
		||||
            if (partDef.params[paramIndex].type === 'int') {
 | 
			
		||||
            var typeaheadSource = function (query, callback) {
 | 
			
		||||
              if (param.options) { return param.options; }
 | 
			
		||||
 | 
			
		||||
              $scope.$apply(function() {
 | 
			
		||||
                $scope.getOptions().then(function(result) {
 | 
			
		||||
                  var dynamicOptions = _.map(result, function(op) { return op.value; });
 | 
			
		||||
                  callback(dynamicOptions);
 | 
			
		||||
                });
 | 
			
		||||
              });
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            $input.attr('data-provide', 'typeahead');
 | 
			
		||||
            var options = param.options;
 | 
			
		||||
            if (param.type === 'int') {
 | 
			
		||||
              options = _.map(options, function(val) { return val.toString(); });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $input.typeahead({
 | 
			
		||||
              source: options,
 | 
			
		||||
              source: typeaheadSource,
 | 
			
		||||
              minLength: 0,
 | 
			
		||||
              items: 20,
 | 
			
		||||
              items: 1000,
 | 
			
		||||
              updater: function (value) {
 | 
			
		||||
                setTimeout(function() {
 | 
			
		||||
                  inputBlur.call($input[0], paramIndex);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +113,8 @@ function (angular, _, $) {
 | 
			
		|||
            var typeahead = $input.data('typeahead');
 | 
			
		||||
            typeahead.lookup = function () {
 | 
			
		||||
              this.query = this.$element.val() || '';
 | 
			
		||||
              return this.process(this.source);
 | 
			
		||||
              var items = this.source(this.query, $.proxy(this.process, this));
 | 
			
		||||
              return items ? this.process(items) : items;
 | 
			
		||||
            };
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,9 +160,7 @@ function (angular, _, $) {
 | 
			
		|||
              $input.keypress(_.partial(inputKeyPress, index));
 | 
			
		||||
              $paramLink.click(_.partial(clickFuncParam, index));
 | 
			
		||||
 | 
			
		||||
              if (partDef.params[index].options) {
 | 
			
		||||
                addTypeahead($input, index);
 | 
			
		||||
              }
 | 
			
		||||
              addTypeahead($input, param, index);
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue