query_ctrl.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import _ from 'lodash';
  3. import kbn from 'app/core/utils/kbn';
  4. import { QueryCtrl } from 'app/plugins/sdk';
  5. export class OpenTsQueryCtrl extends QueryCtrl {
  6. static templateUrl = 'partials/query.editor.html';
  7. aggregators: any;
  8. fillPolicies: any;
  9. filterTypes: any;
  10. tsdbVersion: any;
  11. aggregator: any;
  12. downsampleInterval: any;
  13. downsampleAggregator: any;
  14. downsampleFillPolicy: any;
  15. errors: any;
  16. suggestMetrics: any;
  17. suggestTagKeys: any;
  18. suggestTagValues: any;
  19. addTagMode: boolean;
  20. addFilterMode: boolean;
  21. /** @ngInject **/
  22. constructor($scope, $injector) {
  23. super($scope, $injector);
  24. this.errors = this.validateTarget();
  25. this.aggregators = [
  26. 'avg',
  27. 'sum',
  28. 'min',
  29. 'max',
  30. 'dev',
  31. 'zimsum',
  32. 'mimmin',
  33. 'mimmax',
  34. ];
  35. this.fillPolicies = ['none', 'nan', 'null', 'zero'];
  36. this.filterTypes = [
  37. 'wildcard',
  38. 'iliteral_or',
  39. 'not_iliteral_or',
  40. 'not_literal_or',
  41. 'iwildcard',
  42. 'literal_or',
  43. 'regexp',
  44. ];
  45. this.tsdbVersion = this.datasource.tsdbVersion;
  46. if (!this.target.aggregator) {
  47. this.target.aggregator = 'sum';
  48. }
  49. if (!this.target.downsampleAggregator) {
  50. this.target.downsampleAggregator = 'avg';
  51. }
  52. if (!this.target.downsampleFillPolicy) {
  53. this.target.downsampleFillPolicy = 'none';
  54. }
  55. this.datasource.getAggregators().then(aggs => {
  56. if (aggs.length !== 0) {
  57. this.aggregators = aggs;
  58. }
  59. });
  60. this.datasource.getFilterTypes().then(filterTypes => {
  61. if (filterTypes.length !== 0) {
  62. this.filterTypes = filterTypes;
  63. }
  64. });
  65. // needs to be defined here as it is called from typeahead
  66. this.suggestMetrics = (query, callback) => {
  67. this.datasource
  68. .metricFindQuery('metrics(' + query + ')')
  69. .then(this.getTextValues)
  70. .then(callback);
  71. };
  72. this.suggestTagKeys = (query, callback) => {
  73. this.datasource.suggestTagKeys(this.target.metric).then(callback);
  74. };
  75. this.suggestTagValues = (query, callback) => {
  76. this.datasource
  77. .metricFindQuery('suggest_tagv(' + query + ')')
  78. .then(this.getTextValues)
  79. .then(callback);
  80. };
  81. }
  82. targetBlur() {
  83. this.errors = this.validateTarget();
  84. this.refresh();
  85. }
  86. getTextValues(metricFindResult) {
  87. return _.map(metricFindResult, function(value) {
  88. return value.text;
  89. });
  90. }
  91. addTag() {
  92. if (this.target.filters && this.target.filters.length > 0) {
  93. this.errors.tags =
  94. 'Please remove filters to use tags, tags and filters are mutually exclusive.';
  95. }
  96. if (!this.addTagMode) {
  97. this.addTagMode = true;
  98. return;
  99. }
  100. if (!this.target.tags) {
  101. this.target.tags = {};
  102. }
  103. this.errors = this.validateTarget();
  104. if (!this.errors.tags) {
  105. this.target.tags[this.target.currentTagKey] = this.target.currentTagValue;
  106. this.target.currentTagKey = '';
  107. this.target.currentTagValue = '';
  108. this.targetBlur();
  109. }
  110. this.addTagMode = false;
  111. }
  112. removeTag(key) {
  113. delete this.target.tags[key];
  114. this.targetBlur();
  115. }
  116. editTag(key, value) {
  117. this.removeTag(key);
  118. this.target.currentTagKey = key;
  119. this.target.currentTagValue = value;
  120. this.addTag();
  121. }
  122. closeAddTagMode() {
  123. this.addTagMode = false;
  124. return;
  125. }
  126. addFilter() {
  127. if (this.target.tags && _.size(this.target.tags) > 0) {
  128. this.errors.filters =
  129. 'Please remove tags to use filters, tags and filters are mutually exclusive.';
  130. }
  131. if (!this.addFilterMode) {
  132. this.addFilterMode = true;
  133. return;
  134. }
  135. if (!this.target.filters) {
  136. this.target.filters = [];
  137. }
  138. if (!this.target.currentFilterType) {
  139. this.target.currentFilterType = 'iliteral_or';
  140. }
  141. if (!this.target.currentFilterGroupBy) {
  142. this.target.currentFilterGroupBy = false;
  143. }
  144. this.errors = this.validateTarget();
  145. if (!this.errors.filters) {
  146. var currentFilter = {
  147. type: this.target.currentFilterType,
  148. tagk: this.target.currentFilterKey,
  149. filter: this.target.currentFilterValue,
  150. groupBy: this.target.currentFilterGroupBy,
  151. };
  152. this.target.filters.push(currentFilter);
  153. this.target.currentFilterType = 'literal_or';
  154. this.target.currentFilterKey = '';
  155. this.target.currentFilterValue = '';
  156. this.target.currentFilterGroupBy = false;
  157. this.targetBlur();
  158. }
  159. this.addFilterMode = false;
  160. }
  161. removeFilter(index) {
  162. this.target.filters.splice(index, 1);
  163. this.targetBlur();
  164. }
  165. editFilter(fil, index) {
  166. this.removeFilter(index);
  167. this.target.currentFilterKey = fil.tagk;
  168. this.target.currentFilterValue = fil.filter;
  169. this.target.currentFilterType = fil.type;
  170. this.target.currentFilterGroupBy = fil.groupBy;
  171. this.addFilter();
  172. }
  173. closeAddFilterMode() {
  174. this.addFilterMode = false;
  175. return;
  176. }
  177. validateTarget() {
  178. var errs: any = {};
  179. if (this.target.shouldDownsample) {
  180. try {
  181. if (this.target.downsampleInterval) {
  182. kbn.describe_interval(this.target.downsampleInterval);
  183. } else {
  184. errs.downsampleInterval =
  185. "You must supply a downsample interval (e.g. '1m' or '1h').";
  186. }
  187. } catch (err) {
  188. errs.downsampleInterval = err.message;
  189. }
  190. }
  191. if (
  192. this.target.tags &&
  193. _.has(this.target.tags, this.target.currentTagKey)
  194. ) {
  195. errs.tags = "Duplicate tag key '" + this.target.currentTagKey + "'.";
  196. }
  197. return errs;
  198. }
  199. }