@@ -49,16 +49,23 @@ Inside your `DataSource` implementation:
4949import { DataQueryRequest , DataQueryResponse } from ' @grafana/schema' ;
5050
5151export class DataSource extends DataSourceApi <MyQuery > {
52+ constructor (
53+ instanceSettings : DataSourceInstanceSettings <PyroscopeDataSourceOptions >,
54+ private readonly templateSrv : TemplateSrv = getTemplateSrv ()
55+ ) {
56+ super (instanceSettings );
57+ }
58+
5259 async query(options : DataQueryRequest <MyQuery >): Promise <DataQueryResponse > {
5360 const targets = options .targets .filter ((t ) => ! t .hide );
5461
5562 const interpolatedTargets = targets .map ((target ) => {
56- const rawQuery = getTemplateSrv () .replace (
63+ const rawQuery = this . templateSrv .replace (
5764 target .rawQuery ?? ' ' ,
5865 options .scopedVars // include scoped vars for panel/time range
5966 );
6067
61- const namespace = getTemplateSrv () .replace (target .namespace ?? ' ' , options .scopedVars );
68+ const namespace = this . templateSrv .replace (target .namespace ?? ' ' , options .scopedVars );
6269
6370 return {
6471 ... target ,
@@ -149,18 +156,18 @@ import { getTemplateSrv } from '@grafana/runtime';
149156import { MyVariableQuery } from ' ./types' ;
150157
151158export class DataSource extends DataSourceApi <MyQuery > {
152- // existing query()…
159+ // existing constructor, query()...
153160
154161 async metricFindQuery(variableQuery : MyVariableQuery | string , options ? : any ): Promise <MetricFindValue []> {
155162 if (typeof variableQuery === ' string' ) {
156- const interpolated = getTemplateSrv () .replace (variableQuery );
163+ const interpolated = this . templateSrv .replace (variableQuery );
157164 const response = await this .fetchVariableValues ({ rawQuery: interpolated });
158165 return response .map ((name ) => ({ text: name }));
159166 }
160167
161168 // If using MyVariableQuery model:
162- const namespace = getTemplateSrv () .replace (variableQuery .namespace );
163- const rawQuery = getTemplateSrv () .replace (variableQuery .rawQuery );
169+ const namespace = this . templateSrv .replace (variableQuery .namespace );
170+ const rawQuery = this . templateSrv .replace (variableQuery .rawQuery );
164171
165172 const response = await this .fetchMetricNames (namespace , rawQuery );
166173
@@ -198,6 +205,7 @@ File: `src/VariableQueryEditor.tsx`
198205``` tsx
199206import React , { useState } from ' react' ;
200207import { MyVariableQuery } from ' ./types' ;
208+ import { InlineField , InlineFieldRow , LoadingPlaceholder , Select } from ' @grafana/ui' ;
201209
202210interface VariableQueryProps {
203211 query: MyVariableQuery ;
@@ -226,46 +234,74 @@ export const VariableQueryEditor = ({ query, onChange }: VariableQueryProps) =>
226234
227235 return (
228236 <>
229- <div className = " gf-form" >
230- <span className = " gf-form-label width-10" >Namespace</span >
231- <input
232- name = " namespace"
233- className = " gf-form-input"
234- value = { state .namespace }
235- onChange = { handleChange }
236- onBlur = { saveQuery }
237- />
238- </div >
239-
240- <div className = " gf-form" >
241- <span className = " gf-form-label width-10" >Query</span >
242- <input
243- name = " rawQuery"
244- className = " gf-form-input"
245- value = { state .rawQuery }
246- onChange = { handleChange }
247- onBlur = { saveQuery }
248- />
249- </div >
237+ <InlineFieldRow >
238+ <InlineField label = " Namespace" labelWidth = { 20 } >
239+ <Input
240+ type = " text"
241+ aria-label = " Namespace selector"
242+ placeholder = " Enter namespace"
243+ value = { state .namespace }
244+ onChange = { handleChange }
245+ onBlur = { saveQuery }
246+ />
247+ </InlineField >
248+ </InlineFieldRow >
249+ <InlineFieldRow >
250+ <InlineField label = " Query" labelWidth = { 20 } >
251+ <Input
252+ type = " text"
253+ aria-label = " Query selector"
254+ placeholder = " Enter query"
255+ value = { state .rawQuery }
256+ onChange = { handleChange }
257+ onBlur = { saveQuery }
258+ />
259+ </InlineField >
260+ </InlineFieldRow >
250261 </>
251262 );
252263};
253264```
254265
255- ### 3.2 Register ` VariableQueryEditor ` in the plugin
266+ ### 3.2 Create a ` VariableSupport ` file for the plugin
256267
257- File: ` src/module .ts `
268+ File: ` src/variableSupport .ts `
258269
259270``` ts
260- import { DataSourcePlugin } from ' @grafana/data' ;
261- import { DataSource } from ' ./datasource' ;
262- import { QueryEditor } from ' ./QueryEditor' ;
263- import { VariableQueryEditor } from ' ./VariableQueryEditor' ;
264- import { MyQuery , MyDataSourceOptions , MyVariableQuery } from ' ./types' ;
265-
266- export const plugin = new DataSourcePlugin <DataSource , MyQuery , MyDataSourceOptions >(DataSource )
267- .setQueryEditor (QueryEditor )
268- .setVariableQueryEditor (VariableQueryEditor );
271+ export class MyVariableSupport extends CustomVariableSupport <Datasource , MyVariableQuery > {
272+ editor = VariableQueryEditor ;
273+
274+ constructor (private datasource : Datasource ) {
275+ super ();
276+ }
277+
278+ query(request : DataQueryRequest <MyVariableQuery >): Observable <{ data: MetricFindValue [] }> {
279+ const [query] = request .targets ;
280+ const { range, scopedVars } = request ;
281+
282+ const result = this .datasource .metricFindQuery (query , { scopedVars , range });
283+ return from (result ).pipe (map ((data ) => ({ data })));
284+ }
285+ }
269286```
270287
271- - ` setVariableQueryEditor ` wires your editor into Grafana’s variable UI.
288+ - ` editor = VariableQueryEditor; ` wires your editor into Grafana’s variable UI.
289+
290+ ### 3.3 Assign ` VariableSupport ` to ` this.variables ` in the datasource
291+
292+ File: ` src/datasource.ts `
293+
294+ ``` ts
295+ export class DataSource extends DataSourceApi <MyQuery > {
296+ constructor (
297+ instanceSettings : DataSourceInstanceSettings <PyroscopeDataSourceOptions >,
298+ private readonly templateSrv : TemplateSrv = getTemplateSrv ()
299+ ) {
300+ super (instanceSettings );
301+ // assign the variable property to the new VariableSupport
302+ // to add variable support for this datasource
303+ this .variables = new VariableSupport (this );
304+ }
305+ // existing functions()…
306+ }
307+ ```
0 commit comments