diff --git a/public/app/features/templating/TextBoxVariable.ts b/public/app/features/templating/TextBoxVariable.ts index 8e9d2c77ba3..fcf5bd79b58 100644 --- a/public/app/features/templating/TextBoxVariable.ts +++ b/public/app/features/templating/TextBoxVariable.ts @@ -1,19 +1,31 @@ -import { Variable, assignModelProperties, variableTypes } from './variable'; +import { + assignModelProperties, + TextBoxVariableModel, + VariableActions, + VariableHide, + VariableOption, + VariableType, + variableTypes, +} from './variable'; import { VariableSrv } from './variable_srv'; -export class TextBoxVariable implements Variable { - query: string; - current: any; - options: any[]; +export class TextBoxVariable implements TextBoxVariableModel, VariableActions { + type: VariableType; + name: string; + label: string; + hide: VariableHide; skipUrlSync: boolean; + query: string; + current: VariableOption; + options: VariableOption[]; - defaults: any = { + defaults: TextBoxVariableModel = { type: 'textbox', name: '', - hide: 0, label: '', + hide: VariableHide.dontHide, query: '', - current: {}, + current: {} as VariableOption, options: [], skipUrlSync: false, }; @@ -33,7 +45,7 @@ export class TextBoxVariable implements Variable { } updateOptions() { - this.options = [{ text: this.query.trim(), value: this.query.trim() }]; + this.options = [{ text: this.query.trim(), value: this.query.trim(), selected: false }]; this.current = this.options[0]; return Promise.resolve(); } diff --git a/public/app/features/templating/adhoc_variable.ts b/public/app/features/templating/adhoc_variable.ts index a75261f6cc4..f1016369656 100644 --- a/public/app/features/templating/adhoc_variable.ts +++ b/public/app/features/templating/adhoc_variable.ts @@ -1,18 +1,31 @@ import _ from 'lodash'; -import { Variable, assignModelProperties, variableTypes } from './variable'; +import { + AdHocVariableFilter, + AdHocVariableModel, + assignModelProperties, + VariableActions, + VariableHide, + VariableType, + variableTypes, +} from './variable'; -export class AdhocVariable implements Variable { - filters: any[]; +export class AdhocVariable implements AdHocVariableModel, VariableActions { + type: VariableType; + name: string; + label: string; + hide: VariableHide; skipUrlSync: boolean; + filters: AdHocVariableFilter[]; + datasource: string; - defaults: any = { + defaults: AdHocVariableModel = { type: 'adhoc', name: '', label: '', - hide: 0, + hide: VariableHide.dontHide, + skipUrlSync: false, datasource: null, filters: [], - skipUrlSync: false, }; /** @ngInject */ @@ -50,6 +63,7 @@ export class AdhocVariable implements Variable { key: values[0], operator: values[1], value: values[2], + condition: '', }; }); diff --git a/public/app/features/templating/constant_variable.ts b/public/app/features/templating/constant_variable.ts index 8862f4bc8ab..8525b02fc43 100644 --- a/public/app/features/templating/constant_variable.ts +++ b/public/app/features/templating/constant_variable.ts @@ -1,19 +1,31 @@ -import { Variable, assignModelProperties, variableTypes } from './variable'; +import { + assignModelProperties, + ConstantVariableModel, + VariableActions, + VariableHide, + VariableOption, + VariableType, + variableTypes, +} from './variable'; import { VariableSrv } from './all'; -export class ConstantVariable implements Variable { - query: string; - options: any[]; - current: any; +export class ConstantVariable implements ConstantVariableModel, VariableActions { + type: VariableType; + name: string; + label: string; + hide: VariableHide; skipUrlSync: boolean; + query: string; + options: VariableOption[]; + current: VariableOption; - defaults: any = { + defaults: ConstantVariableModel = { type: 'constant', name: '', - hide: 2, + hide: VariableHide.hideLabel, label: '', query: '', - current: {}, + current: {} as VariableOption, options: [], skipUrlSync: false, }; @@ -33,7 +45,7 @@ export class ConstantVariable implements Variable { } updateOptions() { - this.options = [{ text: this.query.trim(), value: this.query.trim() }]; + this.options = [{ text: this.query.trim(), value: this.query.trim(), selected: false }]; this.setValue(this.options[0]); return Promise.resolve(); } diff --git a/public/app/features/templating/custom_variable.ts b/public/app/features/templating/custom_variable.ts index 046175de956..d083824687b 100644 --- a/public/app/features/templating/custom_variable.ts +++ b/public/app/features/templating/custom_variable.ts @@ -1,27 +1,40 @@ import _ from 'lodash'; -import { Variable, assignModelProperties, variableTypes } from './variable'; +import { + assignModelProperties, + CustomVariableModel, + VariableActions, + VariableHide, + VariableOption, + VariableType, + variableTypes, +} from './variable'; import { VariableSrv } from './variable_srv'; -export class CustomVariable implements Variable { +export class CustomVariable implements CustomVariableModel, VariableActions { + type: VariableType; + name: string; + label: string; + hide: VariableHide; + skipUrlSync: boolean; query: string; - options: any; + options: VariableOption[]; includeAll: boolean; multi: boolean; - current: any; - skipUrlSync: boolean; + current: VariableOption; + allValue: string; - defaults: any = { + defaults: CustomVariableModel = { type: 'custom', name: '', label: '', - hide: 0, - options: [], - current: {}, + hide: VariableHide.dontHide, + skipUrlSync: false, query: '', + options: [], includeAll: false, multi: false, + current: {} as VariableOption, allValue: null, - skipUrlSync: false, }; /** @ngInject */ @@ -42,7 +55,7 @@ export class CustomVariable implements Variable { // extract options in comma separated string (use backslash to escape wanted commas) this.options = _.map(this.query.match(/(?:\\,|[^,])+/g), text => { text = text.replace(/\\,/g, ','); - return { text: text.trim(), value: text.trim() }; + return { text: text.trim(), value: text.trim(), selected: false }; }); if (this.includeAll) { @@ -53,7 +66,7 @@ export class CustomVariable implements Variable { } addAllOption() { - this.options.unshift({ text: 'All', value: '$__all' }); + this.options.unshift({ text: 'All', value: '$__all', selected: false }); } dependsOn(variable: any) { diff --git a/public/app/features/templating/datasource_variable.ts b/public/app/features/templating/datasource_variable.ts index 10d81a214b3..103dd57c934 100644 --- a/public/app/features/templating/datasource_variable.ts +++ b/public/app/features/templating/datasource_variable.ts @@ -1,10 +1,10 @@ -import { Variable, containsVariable, assignModelProperties, variableTypes } from './variable'; +import { assignModelProperties, containsVariable, VariableActions, variableTypes } from './variable'; import { stringToJsRegex } from '@grafana/data'; import { VariableSrv } from './variable_srv'; import { TemplateSrv } from './template_srv'; import { DatasourceSrv } from '../plugins/datasource_srv'; -export class DatasourceVariable implements Variable { +export class DatasourceVariable implements VariableActions { regex: any; query: string; options: any; diff --git a/public/app/features/templating/interval_variable.ts b/public/app/features/templating/interval_variable.ts index 62eefe59d3b..c49670e4b22 100644 --- a/public/app/features/templating/interval_variable.ts +++ b/public/app/features/templating/interval_variable.ts @@ -1,34 +1,46 @@ import _ from 'lodash'; import kbn from 'app/core/utils/kbn'; -import { Variable, assignModelProperties, variableTypes } from './variable'; +import { + assignModelProperties, + IntervalVariableModel, + VariableActions, + VariableHide, + VariableOption, + VariableRefresh, + VariableType, + variableTypes, +} from './variable'; import { TimeSrv } from '../dashboard/services/TimeSrv'; import { TemplateSrv } from './template_srv'; import { VariableSrv } from './variable_srv'; -export class IntervalVariable implements Variable { +export class IntervalVariable implements IntervalVariableModel, VariableActions { + type: VariableType; name: string; + label: string; + hide: VariableHide; + skipUrlSync: boolean; auto_count: number; // tslint:disable-line variable-name - auto_min: number; // tslint:disable-line variable-name - options: any; + auto_min: string; // tslint:disable-line variable-name + options: VariableOption[]; auto: boolean; query: string; - refresh: number; - current: any; - skipUrlSync: boolean; + refresh: VariableRefresh; + current: VariableOption; - defaults: any = { + defaults: IntervalVariableModel = { type: 'interval', name: '', - hide: 0, label: '', - refresh: 2, - options: [], - current: {}, - query: '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d', - auto: false, - auto_min: '10s', - auto_count: 30, + hide: VariableHide.dontHide, skipUrlSync: false, + auto_count: 30, + auto_min: '10s', + options: [], + auto: false, + query: '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d', + refresh: VariableRefresh.onTimeRangeChanged, + current: {} as VariableOption, }; /** @ngInject */ @@ -39,7 +51,7 @@ export class IntervalVariable implements Variable { private variableSrv: VariableSrv ) { assignModelProperties(this, model, this.defaults); - this.refresh = 2; + this.refresh = VariableRefresh.onTimeRangeChanged; } getSaveModel() { @@ -62,6 +74,7 @@ export class IntervalVariable implements Variable { this.options.unshift({ text: 'auto', value: '$__auto_interval_' + this.name, + selected: false, }); } @@ -75,7 +88,7 @@ export class IntervalVariable implements Variable { // extract options between quotes and/or comma this.options = _.map(this.query.match(/(["'])(.*?)\1|\w+/g), text => { text = text.replace(/["']+/g, ''); - return { text: text.trim(), value: text.trim() }; + return { text: text.trim(), value: text.trim(), selected: false }; }); this.updateAutoValue(); diff --git a/public/app/features/templating/query_variable.ts b/public/app/features/templating/query_variable.ts index 5e64f235d67..3a9838732e2 100644 --- a/public/app/features/templating/query_variable.ts +++ b/public/app/features/templating/query_variable.ts @@ -1,54 +1,69 @@ import _ from 'lodash'; -import { assignModelProperties, containsVariable, Variable, variableTypes } from './variable'; +import { + assignModelProperties, + containsVariable, + QueryVariableModel, + VariableActions, + VariableHide, + VariableOption, + VariableRefresh, + VariableSort, + VariableTag, + VariableType, + variableTypes, +} from './variable'; import { stringToJsRegex } from '@grafana/data'; import DatasourceSrv from '../plugins/datasource_srv'; import { TemplateSrv } from './template_srv'; import { VariableSrv } from './variable_srv'; import { TimeSrv } from '../dashboard/services/TimeSrv'; -function getNoneOption() { - return { text: 'None', value: '', isNone: true }; +function getNoneOption(): VariableOption { + return { text: 'None', value: '', isNone: true, selected: false }; } -export class QueryVariable implements Variable { - datasource: any; - query: any; - regex: any; - sort: any; - options: any; - current: any; - refresh: number; - hide: number; +export class QueryVariable implements QueryVariableModel, VariableActions { + type: VariableType; name: string; + label: string; + hide: VariableHide; + skipUrlSync: boolean; + datasource: string; + query: string; + regex: string; + sort: VariableSort; + options: VariableOption[]; + current: VariableOption; + refresh: VariableRefresh; multi: boolean; includeAll: boolean; useTags: boolean; tagsQuery: string; tagValuesQuery: string; - tags: any[]; - skipUrlSync: boolean; + tags: VariableTag[]; definition: string; + allValue: string; - defaults: any = { + defaults: QueryVariableModel = { type: 'query', + name: '', label: null, + hide: VariableHide.dontHide, + skipUrlSync: false, + datasource: null, query: '', regex: '', - sort: 0, - datasource: null, - refresh: 0, - hide: 0, - name: '', + sort: VariableSort.disabled, + refresh: VariableRefresh.never, multi: false, includeAll: false, allValue: null, options: [], - current: {}, + current: {} as VariableOption, tags: [], useTags: false, tagsQuery: '', tagValuesQuery: '', - skipUrlSync: false, definition: '', }; @@ -151,7 +166,7 @@ export class QueryVariable implements Variable { } addAllOption() { - this.options.unshift({ text: 'All', value: '$__all' }); + this.options.unshift({ text: 'All', value: '$__all', selected: false }); } metricNamesToVariableValues(metricNames: any[]) { diff --git a/public/app/features/templating/specs/query_variable.test.ts b/public/app/features/templating/specs/query_variable.test.ts index 81fc14bdd8a..e391c0cb50c 100644 --- a/public/app/features/templating/specs/query_variable.test.ts +++ b/public/app/features/templating/specs/query_variable.test.ts @@ -16,7 +16,7 @@ describe('QueryVariable', () => { it('get model should copy changes back to model', () => { const variable = new QueryVariable({}, null, null, null, null); - variable.options = [{ text: 'test' }]; + variable.options = [{ text: 'test', value: '', selected: false }]; variable.datasource = 'google'; variable.regex = 'asd'; variable.sort = 50; @@ -31,7 +31,7 @@ describe('QueryVariable', () => { it('if refresh != 0 then remove options in presisted mode', () => { const variable = new QueryVariable({}, null, null, null, null); - variable.options = [{ text: 'test' }]; + variable.options = [{ text: 'test', value: '', selected: false }]; variable.refresh = 1; const model = variable.getSaveModel(); diff --git a/public/app/features/templating/variable.ts b/public/app/features/templating/variable.ts index f7a0b1b06e8..60b79cea9b1 100644 --- a/public/app/features/templating/variable.ts +++ b/public/app/features/templating/variable.ts @@ -42,7 +42,107 @@ export const interpolateSearchFilter = (args: InterpolateSearchFilterOptions): s return query.replace(SEARCH_FILTER_VARIABLE, replaceValue); }; -export interface Variable { +export enum VariableRefresh { + never, + onDashboardLoad, + onTimeRangeChanged, +} + +export enum VariableHide { + dontHide, + hideVariable, + hideLabel, +} + +export enum VariableSort { + disabled, + alphabeticalAsc, + alphabeticalDesc, + numericalAsc, + numericalDesc, + alphabeticalCaseInsensitiveAsc, + alphabeticalCaseInsensitiveDesc, +} + +export interface VariableTag { + text: string | string[]; +} + +export interface VariableOption { + selected: boolean; + text: string | string[]; + value: string | string[]; + isNone?: boolean; +} + +export type VariableType = 'query' | 'adhoc' | 'constant' | 'datasource' | 'interval' | 'textbox' | 'custom'; + +export interface AdHocVariableFilter { + key: string; + operator: string; + value: string; + condition: string; +} + +export interface AdHocVariableModel extends VariableModel { + datasource: string; + filters: AdHocVariableFilter[]; +} + +export interface CustomVariableModel extends VariableWithOptions { + allValue: string; + includeAll: boolean; + multi: boolean; +} + +export interface DataSourceVariableModel extends VariableWithOptions { + includeAll: boolean; + multi: boolean; + refresh: VariableRefresh; + regex: string; +} + +export interface IntervalVariableModel extends VariableWithOptions { + auto: boolean; + auto_min: string; + auto_count: number; + refresh: VariableRefresh; +} + +export interface QueryVariableModel extends VariableWithOptions { + allValue: string; + datasource: string; + definition: string; + includeAll: boolean; + multi: boolean; + refresh: VariableRefresh; + regex: string; + sort: VariableSort; + tags: VariableTag[]; + tagsQuery: string; + tagValuesQuery: string; + useTags: boolean; +} + +export interface TextBoxVariableModel extends VariableWithOptions {} + +export interface ConstantVariableModel extends VariableWithOptions {} + +export interface VariableWithOptions extends VariableModel { + current: VariableOption; + options: VariableOption[]; + query: string; +} + +export interface VariableModel { + type: VariableType; + name: string; + label: string; + hide: VariableHide; + skipUrlSync: boolean; +} + +export interface VariableActions { setValue(option: any): any; updateOptions(searchFilter?: string): any; dependsOn(variable: any): any;