/// import _ from 'lodash'; import kbn from 'app/core/utils/kbn'; import {Variable, containsVariable, assignModelProperties, variableTypes} from './variable'; import {VariableSrv} from './variable_srv'; function getNoneOption() { return { text: 'None', value: '', isNone: true }; } export class QueryVariable implements Variable { datasource: any; query: any; regex: any; sort: any; options: any; current: any; refresh: number; hide: number; name: string; multi: boolean; includeAll: boolean; defaults = { type: 'query', query: '', regex: '', sort: 0, datasource: null, refresh: 0, hide: 0, name: '', multi: false, includeAll: false, allValue: null, options: [], current: {}, tagsQuery: null, tagValuesQuery: null, }; constructor(private model, private datasourceSrv, private templateSrv, private variableSrv, private $q) { // copy model properties to this instance assignModelProperties(this, model, this.defaults); } getModel() { // copy back model properties to model assignModelProperties(this.model, this, this.defaults); return this.model; } setValue(option){ return this.variableSrv.setOptionAsCurrent(this, option); } setValueFromUrl(urlValue) { return this.variableSrv.setOptionFromUrl(this, urlValue); } getValueForUrl() { if (this.current.text === 'All') { return 'All'; } return this.current.value; } updateOptions() { return this.datasourceSrv.get(this.datasource) .then(this.updateOptionsFromMetricFindQuery.bind(this)) .then(this.variableSrv.validateVariableSelectionState.bind(this.variableSrv, this)); } updateOptionsFromMetricFindQuery(datasource) { return datasource.metricFindQuery(this.query).then(results => { this.options = this.metricNamesToVariableValues(results); if (this.includeAll) { this.addAllOption(); } if (!this.options.length) { this.options.push(getNoneOption()); } return datasource; }); } addAllOption() { this.options.unshift({text: 'All', value: "$__all"}); } metricNamesToVariableValues(metricNames) { var regex, options, i, matches; options = []; if (this.regex) { regex = kbn.stringToJsRegex(this.templateSrv.replace(this.regex)); } for (i = 0; i < metricNames.length; i++) { var item = metricNames[i]; var value = item.value || item.text; var text = item.text || item.value; if (_.isNumber(value)) { value = value.toString(); } if (_.isNumber(text)) { text = text.toString(); } if (regex) { matches = regex.exec(value); if (!matches) { continue; } if (matches.length > 1) { value = matches[1]; text = matches[1]; } } options.push({text: text, value: value}); } options = _.uniqBy(options, 'value'); return this.sortVariableValues(options, this.sort); } sortVariableValues(options, sortOrder) { if (sortOrder === 0) { return options; } var sortType = Math.ceil(sortOrder / 2); var reverseSort = (sortOrder % 2 === 0); if (sortType === 1) { options = _.sortBy(options, 'text'); } else if (sortType === 2) { options = _.sortBy(options, function(opt) { var matches = opt.text.match(/.*?(\d+).*/); if (!matches) { return 0; } else { return parseInt(matches[1], 10); } }); } if (reverseSort) { options = options.reverse(); } return options; } dependsOn(variable) { return containsVariable(this.query, this.datasource, variable.name); } } variableTypes['query'] = { name: 'Query', ctor: QueryVariable, description: 'Variable values are fetched from a datasource query', supportsMulti: true, };