mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tempo: Group by template vars (#86022)
* Add template variables to group by field * Add test for interpolation * Add test to allow selecting template vars * Show custom value
This commit is contained in:
parent
9614126cb7
commit
306cea7350
@ -5,6 +5,7 @@ import React, { useState } from 'react';
|
|||||||
import { TraceqlSearchScope } from '../dataquery.gen';
|
import { TraceqlSearchScope } from '../dataquery.gen';
|
||||||
import { TempoDatasource } from '../datasource';
|
import { TempoDatasource } from '../datasource';
|
||||||
import TempoLanguageProvider from '../language_provider';
|
import TempoLanguageProvider from '../language_provider';
|
||||||
|
import { initTemplateSrv } from '../test_utils';
|
||||||
import { TempoQuery } from '../types';
|
import { TempoQuery } from '../types';
|
||||||
|
|
||||||
import { GroupByField } from './GroupByField';
|
import { GroupByField } from './GroupByField';
|
||||||
@ -40,6 +41,8 @@ describe('GroupByField', () => {
|
|||||||
// Need to use delay: null here to work with fakeTimers
|
// Need to use delay: null here to work with fakeTimers
|
||||||
// see https://github.com/testing-library/user-event/issues/833
|
// see https://github.com/testing-library/user-event/issues/833
|
||||||
user = userEvent.setup({ delay: null });
|
user = userEvent.setup({ delay: null });
|
||||||
|
|
||||||
|
initTemplateSrv([{ name: 'templateVariable1' }, { name: 'templateVariable2' }], {});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@ -132,4 +135,21 @@ describe('GroupByField', () => {
|
|||||||
expect(groupByFilter?.tag).toBe('http.method');
|
expect(groupByFilter?.tag).toBe('http.method');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow selecting template variables', async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<GroupByField datasource={datasource} query={query} onChange={onChange} isTagsLoading={false} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const tagSelect = container.querySelector(`input[aria-label="Select tag for filter 1"]`);
|
||||||
|
expect(tagSelect).not.toBeNull();
|
||||||
|
expect(tagSelect).toBeInTheDocument();
|
||||||
|
|
||||||
|
if (tagSelect) {
|
||||||
|
await user.click(tagSelect);
|
||||||
|
jest.advanceTimersByTime(1000);
|
||||||
|
expect(await screen.findByText('$templateVariable1')).toBeInTheDocument();
|
||||||
|
expect(await screen.findByText('$templateVariable2')).toBeInTheDocument();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,6 +11,7 @@ import { TempoDatasource } from '../datasource';
|
|||||||
import { TempoQuery } from '../types';
|
import { TempoQuery } from '../types';
|
||||||
|
|
||||||
import InlineSearchField from './InlineSearchField';
|
import InlineSearchField from './InlineSearchField';
|
||||||
|
import { withTemplateVariableOptions } from './SearchField';
|
||||||
import { replaceAt } from './utils';
|
import { replaceAt } from './utils';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -89,15 +90,20 @@ export const GroupByField = (props: Props) => {
|
|||||||
<Select
|
<Select
|
||||||
aria-label={`Select tag for filter ${i + 1}`}
|
aria-label={`Select tag for filter ${i + 1}`}
|
||||||
isClearable
|
isClearable
|
||||||
|
allowCustomValue
|
||||||
isLoading={isTagsLoading}
|
isLoading={isTagsLoading}
|
||||||
key={f.tag}
|
key={f.tag}
|
||||||
onChange={(v) => {
|
onChange={(v) => {
|
||||||
updateFilter({ ...f, tag: v?.value });
|
updateFilter({ ...f, tag: v?.value });
|
||||||
}}
|
}}
|
||||||
options={getTags(f)?.map((t) => ({
|
options={withTemplateVariableOptions(
|
||||||
label: t,
|
getTags(f)
|
||||||
value: t,
|
?.concat(f.tag !== undefined && !getTags(f)?.includes(f.tag) ? [f.tag] : [])
|
||||||
}))}
|
.map((t) => ({
|
||||||
|
label: t,
|
||||||
|
value: t,
|
||||||
|
}))
|
||||||
|
)}
|
||||||
placeholder="Select tag"
|
placeholder="Select tag"
|
||||||
value={f.tag || ''}
|
value={f.tag || ''}
|
||||||
/>
|
/>
|
||||||
|
@ -126,17 +126,6 @@ const SearchField = ({
|
|||||||
operatorList = numberOperators;
|
operatorList = numberOperators;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add to a list of options the current template variables.
|
|
||||||
*
|
|
||||||
* @param options a list of options
|
|
||||||
* @returns the list of given options plus the template variables
|
|
||||||
*/
|
|
||||||
const withTemplateVariableOptions = (options: SelectableValue[] | undefined) => {
|
|
||||||
const templateVariables = getTemplateSrv().getVariables();
|
|
||||||
return [...(options || []), ...templateVariables.map((v) => ({ label: `$${v.name}`, value: `$${v.name}` }))];
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HorizontalGroup spacing={'none'} width={'auto'}>
|
<HorizontalGroup spacing={'none'} width={'auto'}>
|
||||||
@ -220,4 +209,15 @@ const SearchField = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to a list of options the current template variables.
|
||||||
|
*
|
||||||
|
* @param options a list of options
|
||||||
|
* @returns the list of given options plus the template variables
|
||||||
|
*/
|
||||||
|
export const withTemplateVariableOptions = (options: SelectableValue[] | undefined) => {
|
||||||
|
const templateVariables = getTemplateSrv().getVariables();
|
||||||
|
return [...(options || []), ...templateVariables.map((v) => ({ label: `$${v.name}`, value: `$${v.name}` }))];
|
||||||
|
};
|
||||||
|
|
||||||
export default SearchField;
|
export default SearchField;
|
||||||
|
@ -170,6 +170,16 @@ describe('Tempo data source', () => {
|
|||||||
valueType: 'string',
|
valueType: 'string',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
groupBy: [
|
||||||
|
{
|
||||||
|
id: 'groupBy1',
|
||||||
|
tag: '$interpolationVar',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'groupBy2',
|
||||||
|
tag: '$interpolationVar',
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let templateSrv: TemplateSrv;
|
let templateSrv: TemplateSrv;
|
||||||
@ -202,6 +212,8 @@ describe('Tempo data source', () => {
|
|||||||
expect(queries[0].filters[0].value).toBe(textWithPipe);
|
expect(queries[0].filters[0].value).toBe(textWithPipe);
|
||||||
expect(queries[0].filters[1].value).toBe(text);
|
expect(queries[0].filters[1].value).toBe(text);
|
||||||
expect(queries[0].filters[1].tag).toBe(text);
|
expect(queries[0].filters[1].tag).toBe(text);
|
||||||
|
expect(queries[0].groupBy?.[0].tag).toBe(text);
|
||||||
|
expect(queries[0].groupBy?.[1].tag).toBe(text);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when applying template variables', async () => {
|
it('when applying template variables', async () => {
|
||||||
@ -214,6 +226,8 @@ describe('Tempo data source', () => {
|
|||||||
expect(resp.filters[0].value).toBe(textWithPipe);
|
expect(resp.filters[0].value).toBe(textWithPipe);
|
||||||
expect(resp.filters[1].value).toBe(scopedText);
|
expect(resp.filters[1].value).toBe(scopedText);
|
||||||
expect(resp.filters[1].tag).toBe(scopedText);
|
expect(resp.filters[1].tag).toBe(scopedText);
|
||||||
|
expect(resp.groupBy?.[0].tag).toBe(scopedText);
|
||||||
|
expect(resp.groupBy?.[1].tag).toBe(scopedText);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when serviceMapQuery is an array', async () => {
|
it('when serviceMapQuery is an array', async () => {
|
||||||
|
@ -486,6 +486,17 @@ export class TempoDatasource extends DataSourceWithBackend<TempoQuery, TempoJson
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (query.groupBy) {
|
||||||
|
expandedQuery.groupBy = query.groupBy.map((filter) => {
|
||||||
|
const updatedFilter = {
|
||||||
|
...filter,
|
||||||
|
tag: this.templateSrv.replace(filter.tag ?? '', scopedVars),
|
||||||
|
};
|
||||||
|
|
||||||
|
return updatedFilter;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...expandedQuery,
|
...expandedQuery,
|
||||||
query: this.templateSrv.replace(query.query ?? '', scopedVars, VariableFormatID.Pipe),
|
query: this.templateSrv.replace(query.query ?? '', scopedVars, VariableFormatID.Pipe),
|
||||||
|
Loading…
Reference in New Issue
Block a user